From 642067287931da64e485e402e5e1fa5096abcddd Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 26 Apr 2013 22:23:08 +0200 Subject: curl_easy_init: use less mallocs By introducing an internal alternative to curl_multi_init() that accepts parameters to set the hash sizes, easy handles will now use tiny socket and connection hash tables since it will only ever add a single easy handle to that multi handle. This decreased the number mallocs in test 40 (which is a rather simple and typical easy interface use case) from 1142 to 138. The maximum amount of memory allocated used went down from 118969 to 78805. --- lib/conncache.c | 6 ++---- lib/conncache.h | 2 +- lib/easy.c | 5 ++++- lib/multi.c | 19 ++++++++++++++----- lib/multiif.h | 8 +++++++- 5 files changed, 28 insertions(+), 12 deletions(-) (limited to 'lib') diff --git a/lib/conncache.c b/lib/conncache.c index 530cdc2ec..48271f751 100644 --- a/lib/conncache.c +++ b/lib/conncache.c @@ -38,8 +38,6 @@ /* The last #include file should be: */ #include "memdebug.h" -#define CONNECTION_HASH_SIZE 97 - static void free_bundle_hash_entry(void *freethis) { struct connectbundle *b = (struct connectbundle *) freethis; @@ -47,7 +45,7 @@ static void free_bundle_hash_entry(void *freethis) Curl_bundle_destroy(b); } -struct conncache *Curl_conncache_init(void) +struct conncache *Curl_conncache_init(int size) { struct conncache *connc; @@ -55,7 +53,7 @@ struct conncache *Curl_conncache_init(void) if(!connc) return NULL; - connc->hash = Curl_hash_alloc(CONNECTION_HASH_SIZE, Curl_hash_str, + connc->hash = Curl_hash_alloc(size, Curl_hash_str, Curl_str_key_compare, free_bundle_hash_entry); if(!connc->hash) { diff --git a/lib/conncache.h b/lib/conncache.h index fad17d8f7..f5e41f187 100644 --- a/lib/conncache.h +++ b/lib/conncache.h @@ -27,7 +27,7 @@ struct conncache { size_t num_connections; }; -struct conncache *Curl_conncache_init(void); +struct conncache *Curl_conncache_init(int size); void Curl_conncache_destroy(struct conncache *connc); diff --git a/lib/easy.c b/lib/easy.c index 72e1206f4..eb45bd717 100644 --- a/lib/easy.c +++ b/lib/easy.c @@ -73,6 +73,7 @@ #include "non-ascii.h" #include "warnless.h" #include "conncache.h" +#include "multiif.h" #define _MPRINTF_REPLACE /* use our functions only */ #include @@ -437,7 +438,9 @@ CURLcode curl_easy_perform(CURL *easy) if(data->multi_easy) multi = data->multi_easy; else { - multi = curl_multi_init(); + /* this multi handle will only ever have a single easy handled attached + to it, so make it use minimal hashes */ + multi = Curl_multi_handle(1, 3); if(!multi) return CURLE_OUT_OF_MEMORY; data->multi_easy = multi; diff --git a/lib/multi.c b/lib/multi.c index 7d795cf3d..77262fc34 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -58,6 +58,7 @@ #define CURL_SOCKET_HASH_TABLE_SIZE 911 #endif +#define CURL_CONNECTION_HASH_SIZE 97 #define CURL_MULTI_HANDLE 0x000bab1e @@ -246,9 +247,9 @@ static size_t hash_fd(void *key, size_t key_length, size_t slots_num) * per call." * */ -static struct curl_hash *sh_init(void) +static struct curl_hash *sh_init(int hashsize) { - return Curl_hash_alloc(CURL_SOCKET_HASH_TABLE_SIZE, hash_fd, fd_key_compare, + return Curl_hash_alloc(hashsize, hash_fd, fd_key_compare, sh_freeentry); } @@ -278,7 +279,8 @@ static void multi_freeamsg(void *a, void *b) (void)b; } -CURLM *curl_multi_init(void) +struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */ + int chashsize) /* connection hash */ { struct Curl_multi *multi = calloc(1, sizeof(struct Curl_multi)); @@ -291,11 +293,11 @@ CURLM *curl_multi_init(void) if(!multi->hostcache) goto error; - multi->sockhash = sh_init(); + multi->sockhash = sh_init(hashsize); if(!multi->sockhash) goto error; - multi->conn_cache = Curl_conncache_init(); + multi->conn_cache = Curl_conncache_init(chashsize); if(!multi->conn_cache) goto error; @@ -325,6 +327,13 @@ CURLM *curl_multi_init(void) return NULL; } +CURLM *curl_multi_init(void) +{ + return Curl_multi_handle(CURL_SOCKET_HASH_TABLE_SIZE, + CURL_CONNECTION_HASH_SIZE); +} + + CURLMcode curl_multi_add_handle(CURLM *multi_handle, CURL *easy_handle) { diff --git a/lib/multiif.h b/lib/multiif.h index 0dcdec76e..799daebcc 100644 --- a/lib/multiif.h +++ b/lib/multiif.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2013, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -22,6 +22,8 @@ * ***************************************************************************/ + + /* * Prototypes for library-wide functions provided by multi.c */ @@ -30,6 +32,10 @@ void Curl_expire(struct SessionHandle *data, long milli); bool Curl_multi_pipeline_enabled(const struct Curl_multi* multi); void Curl_multi_handlePipeBreak(struct SessionHandle *data); +/* Internal version of curl_multi_init() accepts size parameters for the + socket and connection hashes */ +struct Curl_multi *Curl_multi_handle(int hashsize, int chashsize); + /* the write bits start at bit 16 for the *getsock() bitmap */ #define GETSOCK_WRITEBITSTART 16 -- cgit v1.2.3