aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2013-04-26 22:23:08 +0200
committerDaniel Stenberg <daniel@haxx.se>2013-04-26 22:55:55 +0200
commit642067287931da64e485e402e5e1fa5096abcddd (patch)
treef1c843b46447d2e4607bfe029823352932c4d01f
parentc4067a5678321b1755f6027a5c7510b17e7c16a6 (diff)
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.
-rw-r--r--lib/conncache.c6
-rw-r--r--lib/conncache.h2
-rw-r--r--lib/easy.c5
-rw-r--r--lib/multi.c19
-rw-r--r--lib/multiif.h8
5 files changed, 28 insertions, 12 deletions
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 <curl/mprintf.h>
@@ -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, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, 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