summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 53e0e11)
raw | patch | inline | side by side (parent: 53e0e11)
author | oetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa> | |
Mon, 29 Mar 2010 15:48:24 +0000 (15:48 +0000) | ||
committer | oetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa> | |
Mon, 29 Mar 2010 15:48:24 +0000 (15:48 +0000) |
* Introduce "-m" argument to reduce calls to realloc(). -- kevin
git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk/program@2053 a5681a0c-68f1-0310-ab6d-d61299d08faa
git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk/program@2053 a5681a0c-68f1-0310-ab6d-d61299d08faa
doc/librrd.pod | patch | blob | history | |
doc/rrdcached.pod | patch | blob | history | |
src/rrd.h | patch | blob | history | |
src/rrd_daemon.c | patch | blob | history | |
src/rrd_utils.c | patch | blob | history |
diff --git a/doc/librrd.pod b/doc/librrd.pod
index dfe6f29c48ba5d9be69065cd47ddbdcbe717c138..0d05f6eeaa0f8c50b5a6e363299d34828b1a50af 100644 (file)
--- a/doc/librrd.pod
+++ b/doc/librrd.pod
if (!rrd_add_ptr(&arr, &arr_size, elem))
handle_failure();
+=item B<rrd_add_ptr_chunk(void ***dest, size_t *dest_size, void *src, size_t *alloc, size_t chunk)>
+
+Like C<rrd_add_ptr>, except the destination is allocated in chunks of
+C<chunk>. C<alloc> points to the number of entries allocated, whereas
+C<dest_size> points to the number of valid pointers. If more pointers are
+needed, C<chunk> pointers are allocated and C<alloc> is increased
+accordingly. C<alloc> must be E<gt>= C<dest_size>.
+
+This method improves performance on hosts with expensive C<realloc()>.
+
=item B<rrd_add_strdup(char ***dest, size_t *dest_size, char *src)>
Like C<rrd_add_ptr>, except adds a C<strdup> of the source string.
if (!rrd_add_strdup(&arr, &arr_size, str))
handle_failure();
+=item B<rrd_add_strdup_chunk(char ***dest, size_t *dest_size, char *src, size_t *alloc, size_t chunk)>
+
+Like C<rrd_add_strdup>, except the destination is allocated in chunks of
+C<chunk>. C<alloc> points to the number of entries allocated, whereas
+C<dest_size> points to the number of valid pointers. If more pointers are
+needed, C<chunk> pointers are allocated and C<alloc> is increased
+accordingly. C<alloc> must be E<gt>= C<dest_size>.
+
=item B<rrd_free_ptrs(void ***src, size_t *cnt)>
Free an array of pointers allocated by C<rrd_add_ptr> or
diff --git a/doc/rrdcached.pod b/doc/rrdcached.pod
index d6bfec39c41bbd2afb071c65d268b841a5b219fa..57eb6553720428b9959ed2481342eb426b020a99 100644 (file)
--- a/doc/rrdcached.pod
+++ b/doc/rrdcached.pod
[-F]
[-g]
[B<-b>E<nbsp>I<base_dir>E<nbsp>[B<-B>]]
+[B<-m>E<nbsp>I<alloc_size>]
=head1 DESCRIPTION
sub-directories). This does B<NOT> detect symbolic links. Paths
containing C<../> will also be blocked.
+=item B<-m> I<alloc_size>
+
+Allocate value pointers in chunks of I<alloc_size>. This may improve CPU
+utilization on machines with slow C<realloc()> implementations, in
+exchange for slightly higher memory utilization. The default isE<nbsp>1.
+Do not set this more than the B<-w> value divided by your average RRD step
+size.
+
=back
=head1 AFFECTED RRDTOOL COMMANDS
diff --git a/src/rrd.h b/src/rrd.h
index 31148c804ab057eb15a2e32a8b34b9a3e1b95c01..28a50d7bf18e2532965bff032fcb4a9c56591d89 100644 (file)
--- a/src/rrd.h
+++ b/src/rrd.h
long rrd_random(void);
+ int rrd_add_ptr_chunk(void ***dest, size_t *dest_size, void *src,
+ size_t *alloc, size_t chunk);
int rrd_add_ptr(void ***dest, size_t *dest_size, void *src);
int rrd_add_strdup(char ***dest, size_t *dest_size, char *src);
+ int rrd_add_strdup_chunk(char ***dest, size_t *dest_size, char *src,
+ size_t *alloc, size_t chunk);
void rrd_free_ptrs(void ***src, size_t *cnt);
int rrd_mkdir_p(const char *pathname, mode_t mode);
diff --git a/src/rrd_daemon.c b/src/rrd_daemon.c
index 128f3c444afe0bdde1d75331532f73ea388df0c2..9b8d9ee30cb59ae59d8d27de6b96f4b0a72cde95 100644 (file)
--- a/src/rrd_daemon.c
+++ b/src/rrd_daemon.c
{
char *file;
char **values;
- size_t values_num;
+ size_t values_num; /* number of valid pointers */
+ size_t values_alloc; /* number of allocated pointers */
time_t last_flush_time;
time_t last_update_stamp;
#define CI_FLAGS_IN_TREE (1<<0)
static char *config_base_dir = NULL;
static size_t _config_base_dir_len = 0;
static int config_write_base_only = 0;
+static size_t config_alloc_chunk = 1;
static listen_socket_t **config_listen_address_list = NULL;
static size_t config_listen_address_list_len = 0;
{
ci->values = NULL;
ci->values_num = 0;
+ ci->values_alloc = 0;
ci->last_flush_time = when;
if (config_write_jitter > 0)
else
ci->last_update_stamp = stamp;
- if (!rrd_add_strdup(&ci->values, &ci->values_num, value))
+ if (!rrd_add_strdup_chunk(&ci->values, &ci->values_num, value,
+ &ci->values_alloc, config_alloc_chunk))
{
RRDD_LOG (LOG_ERR, "handle_request_update: rrd_add_strdup failed.");
continue;
gid_t socket_group = (gid_t)-1;
mode_t socket_permissions = (mode_t)-1;
- while ((option = getopt(argc, argv, "gl:s:m:P:f:w:z:t:Bb:p:Fj:h?")) != -1)
+ while ((option = getopt(argc, argv, "gl:s:m:P:f:w:z:t:Bb:p:Fj:m:h?")) != -1)
{
switch (option)
{
}
break;
+ case 'm':
+ {
+ int temp = atoi(optarg);
+ if (temp > 0)
+ config_alloc_chunk = temp;
+ else
+ {
+ fprintf(stderr, "Invalid allocation size: %s\n", optarg);
+ status = 10;
+ }
+ }
+ break;
+
case 'h':
case '?':
printf ("RRDCacheD %s\n"
diff --git a/src/rrd_utils.c b/src/rrd_utils.c
index 3936cffd1d2e6689bd4ac5117e6404f54c09b35e..6853c66dacef29fd655d9c60d90d80597c1313ba 100644 (file)
--- a/src/rrd_utils.c
+++ b/src/rrd_utils.c
return random();
}
-/* rrd_add_ptr: add a pointer to a dynamically sized array of pointers,
- * realloc as necessary. returns 1 on success, 0 on failure.
+/* rrd_add_ptr_chunk: add a pointer to a dynamically sized array of
+ * pointers, realloc as necessary in multiples of "chunk".
+ *
+ * "alloc" is the number of pointers allocated
+ * "dest_size" is the number of valid pointers
+ *
+ * returns 1 on success, 0 on failure.
*/
-int rrd_add_ptr(void ***dest, size_t *dest_size, void *src)
+int rrd_add_ptr_chunk(void ***dest, size_t *dest_size, void *src,
+ size_t *alloc, size_t chunk)
{
void **temp;
assert(dest != NULL);
+ assert(alloc != NULL);
+ assert(*alloc >= *dest_size);
- temp = (void **) rrd_realloc(*dest, (*dest_size+1) * sizeof(*dest));
- if (!temp)
- return 0;
+ if (*alloc == *dest_size)
+ {
+ temp = (void **) rrd_realloc(*dest, (*alloc+chunk) * sizeof(*dest));
+ if (!temp)
+ return 0;
- *dest = temp;
- temp[*dest_size] = src;
+ *dest = temp;
+ *alloc += chunk;
+ }
+
+ (*dest)[*dest_size] = src;
(*dest_size)++;
return 1;
}
-/* like rrd_add_ptr, but calls strdup() on a string first. */
-int rrd_add_strdup(char ***dest, size_t *dest_size, char *src)
+/* rrd_add_ptr: add a pointer to a dynamically sized array of pointers,
+ * realloc as necessary. returns 1 on success, 0 on failure.
+ */
+int rrd_add_ptr(void ***dest, size_t *dest_size, void *src)
+{
+ size_t alloc = *dest_size;
+
+ return rrd_add_ptr_chunk(dest, dest_size, src, &alloc, 1);
+}
+
+/* like rrd_add_ptr_chunk, but calls strdup() on a string first. */
+int rrd_add_strdup_chunk(char ***dest, size_t *dest_size, char *src,
+ size_t *alloc, size_t chunk)
{
char *dup_src;
int add_ok;
if (!dup_src)
return 0;
- add_ok = rrd_add_ptr((void ***)dest, dest_size, (void *)dup_src);
+ add_ok = rrd_add_ptr_chunk((void ***)dest, dest_size, (void *)dup_src, alloc, chunk);
if (!add_ok)
free(dup_src);
return add_ok;
}
+int rrd_add_strdup(char ***dest, size_t *dest_size, char *src)
+{
+ size_t alloc = *dest_size;
+
+ return rrd_add_strdup_chunk(dest, dest_size, src, &alloc, 1);
+}
+
void rrd_free_ptrs(void ***src, size_t *cnt)
{
void **sp;