From: Martin Mares Date: Fri, 10 Feb 2012 21:57:03 +0000 (+0100) Subject: Growing arrays now support auto-zeroing mode X-Git-Tag: v5.0~78 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=642f0a819012e20452319eeea4321a75035d48f8;p=libucw.git Growing arrays now support auto-zeroing mode --- diff --git a/TODO b/TODO index 2e63b0cd..688e7b60 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,4 @@ - Clean up free/ -- gary: Add automatic zeroing - Remove sighandler.[ch] - ipaccess: support IPv6 - lfs-test: generalize or kill diff --git a/ucw/gary.c b/ucw/gary.c index 801981ae..579d6ab1 100644 --- a/ucw/gary.c +++ b/ucw/gary.c @@ -1,7 +1,7 @@ /* * UCW Library -- A simple growing array of an arbitrary type * - * (c) 2010 Martin Mares + * (c) 2010--2012 Martin Mares */ #undef LOCAL_DEBUG @@ -9,14 +9,19 @@ #include "ucw/lib.h" #include "ucw/gary.h" +#include + void * -gary_init(size_t elt_size, size_t num_elts) +gary_init(size_t elt_size, size_t num_elts, int zeroed) { DBG("GARY: Init to %zd elements", num_elts); struct gary_hdr *h = xmalloc(GARY_HDR_SIZE + elt_size * num_elts); h->num_elts = h->have_space = num_elts; h->elt_size = elt_size; - return (byte *)h + GARY_HDR_SIZE; + h->zeroed = zeroed; + if (zeroed) + bzero(GARY_BODY(h), elt_size * num_elts); + return GARY_BODY(h); } void @@ -28,12 +33,16 @@ gary_free(void *array) static struct gary_hdr * gary_realloc(struct gary_hdr *h, size_t n) { + size_t old_size = h->have_space; if (n > 2*h->have_space) h->have_space = n; else h->have_space *= 2; - DBG("GARY: Resize to %zd elements (need %zd)", h->have_space, n); - return xrealloc(h, GARY_HDR_SIZE + h->have_space * h->elt_size); + DBG("GARY: Resize from %zd to %zd elements (need %zd)", old_size, h->have_space, n); + h = xrealloc(h, GARY_HDR_SIZE + h->have_space * h->elt_size); + if (h->zeroed) + bzero(GARY_BODY(h) + h->elt_size * old_size, h->elt_size * (h->have_space - old_size)); + return h; } void * @@ -76,11 +85,15 @@ gary_fix(void *array) int main(void) { int *a; - GARY_INIT(a, 5); + GARY_INIT_ZERO(a, 5); for (int i=0; i<5; i++) - a[i] = i+1; + { + ASSERT(!a[i]); + a[i] = i+1; + } + GARY_PUSH(a, 1); *GARY_PUSH(a, 1) = 10; *GARY_PUSH(a, 1) = 20; *GARY_PUSH(a, 1) = 30; diff --git a/ucw/gary.h b/ucw/gary.h index 89760ffc..942f9b9c 100644 --- a/ucw/gary.h +++ b/ucw/gary.h @@ -1,7 +1,7 @@ /* * UCW Library -- A simple growing array of an arbitrary type * - * (c) 2010 Martin Mares + * (c) 2010--2012 Martin Mares */ #ifndef _UCW_GARY_H @@ -11,13 +11,15 @@ struct gary_hdr { size_t num_elts; size_t have_space; size_t elt_size; + int zeroed; }; #define GARY_HDR_SIZE ALIGN_TO(sizeof(struct gary_hdr), CPU_STRUCT_ALIGN) #define GARY_HDR(ptr) ((struct gary_hdr *)((byte*)(ptr) - GARY_HDR_SIZE)) #define GARY_BODY(ptr) ((byte *)(ptr) + GARY_HDR_SIZE) -#define GARY_INIT(ptr, n) (ptr) = gary_init(sizeof(*(ptr)), (n)) +#define GARY_INIT(ptr, n) (ptr) = gary_init(sizeof(*(ptr)), (n), 0) +#define GARY_INIT_ZERO(ptr, n) (ptr) = gary_init(sizeof(*(ptr)), (n), 1) #define GARY_FREE(ptr) do { if (ptr) xfree(GARY_HDR(ptr)); } while (0) #define GARY_SIZE(ptr) (GARY_HDR(ptr)->num_elts) #define GARY_RESIZE(ptr, n) (ptr) = gary_set_size((ptr), (n)) @@ -36,7 +38,7 @@ struct gary_hdr { #define GARY_FIX(ptr) (ptr) = gary_fix((ptr)) /* Internal functions */ -void *gary_init(size_t elt_size, size_t num_elts); +void *gary_init(size_t elt_size, size_t num_elts, int zeroed); void gary_free(void *array); void *gary_set_size(void *array, size_t n); void *gary_push_helper(void *array, size_t n, byte **cptr);