diff options
author | Andrew Tridgell <tridge@samba.org> | 2005-07-04 07:10:21 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:19:12 -0500 |
commit | b9e8935188c75a007683979b208757e6c5c7aa67 (patch) | |
tree | 8ea02ec738da074dd43eb128c3c9dd9868611f72 /source4/lib/talloc/talloc.c | |
parent | 65ae28dfa714d1f4b1006093f65ec3f9d904ebb9 (diff) | |
download | samba-b9e8935188c75a007683979b208757e6c5c7aa67.tar.gz samba-b9e8935188c75a007683979b208757e6c5c7aa67.tar.bz2 samba-b9e8935188c75a007683979b208757e6c5c7aa67.zip |
r8126: - moved to 16 byte alignment for talloc. This is in response to a bug
report from robert collins.
- updated talloc guide to reflect the fact that over the last few
months talloc overhead compared to malloc has dropped, probably due
to a bunch of small changes. It now costs about 4% more than malloc
on my box
(This used to be commit 689a9ccf91f9de560a500787d85321abe096b948)
Diffstat (limited to 'source4/lib/talloc/talloc.c')
-rw-r--r-- | source4/lib/talloc/talloc.c | 103 |
1 files changed, 53 insertions, 50 deletions
diff --git a/source4/lib/talloc/talloc.c b/source4/lib/talloc/talloc.c index 3a068f4eaa..1081302d09 100644 --- a/source4/lib/talloc/talloc.c +++ b/source4/lib/talloc/talloc.c @@ -97,23 +97,26 @@ struct talloc_chunk { struct talloc_chunk *next, *prev; struct talloc_chunk *parent, *child; struct talloc_reference_handle *refs; - size_t size; talloc_destructor_t destructor; const char *name; - union { - unsigned flags; - double align_dummy; - } u; + size_t size; + unsigned flags; }; +/* 16 byte alignment seems to keep everyone happy */ +#define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15) +#define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc)) + /* panic if we get a bad magic value */ static struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr) { - struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, ptr)-1; - if ((tc->u.flags & ~0xF) != TALLOC_MAGIC) { + const char *pp = ptr; + pp -= TC_HDR_SIZE; + struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp); + if ((tc->flags & ~0xF) != TALLOC_MAGIC) { TALLOC_ABORT("Bad talloc magic value - unknown value"); } - if (tc->u.flags & TALLOC_FLAG_FREE) { + if (tc->flags & TALLOC_FLAG_FREE) { TALLOC_ABORT("Bad talloc magic value - double free"); } return tc; @@ -160,7 +163,7 @@ static struct talloc_chunk *talloc_parent_chunk(const void *ptr) void *talloc_parent(const void *ptr) { struct talloc_chunk *tc = talloc_parent_chunk(ptr); - return (void *)(tc+1); + return TC_PTR_FROM_CHUNK(tc); } /* @@ -178,11 +181,11 @@ void *_talloc(const void *context, size_t size) return NULL; } - tc = malloc(sizeof(*tc)+size); + tc = malloc(TC_HDR_SIZE+size); if (tc == NULL) return NULL; tc->size = size; - tc->u.flags = TALLOC_MAGIC; + tc->flags = TALLOC_MAGIC; tc->destructor = NULL; tc->child = NULL; tc->name = NULL; @@ -202,7 +205,7 @@ void *_talloc(const void *context, size_t size) tc->next = tc->prev = tc->parent = NULL; } - return (void *)(tc+1); + return TC_PTR_FROM_CHUNK(tc); } @@ -287,7 +290,7 @@ static int talloc_unreference(const void *context, const void *ptr) for (h=tc->refs;h;h=h->next) { struct talloc_chunk *p = talloc_parent_chunk(h); - if ((p==NULL && context==NULL) || p+1 == context) break; + if ((p==NULL && context==NULL) || TC_PTR_FROM_CHUNK(p) == context) break; } if (h == NULL) { return -1; @@ -338,7 +341,7 @@ int talloc_unlink(const void *context, void *ptr) new_p = talloc_parent_chunk(tc_p->refs); if (new_p) { - new_parent = new_p+1; + new_parent = TC_PTR_FROM_CHUNK(new_p); } else { new_parent = NULL; } @@ -497,16 +500,16 @@ void talloc_free_children(void *ptr) choice is owner of any remaining reference to this pointer, the second choice is our parent, and the final choice is the null context. */ - void *child = tc->child+1; + void *child = TC_PTR_FROM_CHUNK(tc->child); const void *new_parent = null_context; if (tc->child->refs) { struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs); - if (p) new_parent = p+1; + if (p) new_parent = TC_PTR_FROM_CHUNK(p); } if (talloc_free(child) == -1) { if (new_parent == null_context) { struct talloc_chunk *p = talloc_parent_chunk(ptr); - if (p) new_parent = p+1; + if (p) new_parent = TC_PTR_FROM_CHUNK(p); } talloc_steal(new_parent, child); } @@ -536,7 +539,7 @@ int talloc_free(void *ptr) return -1; } - if (tc->u.flags & TALLOC_FLAG_LOOP) { + if (tc->flags & TALLOC_FLAG_LOOP) { /* we have a free loop - stop looping */ return 0; } @@ -554,7 +557,7 @@ int talloc_free(void *ptr) tc->destructor = NULL; } - tc->u.flags |= TALLOC_FLAG_LOOP; + tc->flags |= TALLOC_FLAG_LOOP; talloc_free_children(ptr); @@ -568,7 +571,7 @@ int talloc_free(void *ptr) if (tc->next) tc->next->prev = tc->prev; } - tc->u.flags |= TALLOC_FLAG_FREE; + tc->flags |= TALLOC_FLAG_FREE; free(tc); return 0; @@ -608,24 +611,24 @@ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *n } /* by resetting magic we catch users of the old memory */ - tc->u.flags |= TALLOC_FLAG_FREE; + tc->flags |= TALLOC_FLAG_FREE; #if ALWAYS_REALLOC - new_ptr = malloc(size + sizeof(*tc)); + new_ptr = malloc(size + TC_HDR_SIZE); if (new_ptr) { - memcpy(new_ptr, tc, tc->size + sizeof(*tc)); + memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE); free(tc); } #else - new_ptr = realloc(tc, size + sizeof(*tc)); + new_ptr = realloc(tc, size + TC_HDR_SIZE); #endif if (!new_ptr) { - tc->u.flags &= ~TALLOC_FLAG_FREE; + tc->flags &= ~TALLOC_FLAG_FREE; return NULL; } tc = new_ptr; - tc->u.flags &= ~TALLOC_FLAG_FREE; + tc->flags &= ~TALLOC_FLAG_FREE; if (tc->parent) { tc->parent->child = new_ptr; } @@ -641,9 +644,9 @@ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *n } tc->size = size; - talloc_set_name_const(tc+1, name); + talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name); - return (void *)(tc+1); + return TC_PTR_FROM_CHUNK(tc); } /* @@ -720,18 +723,18 @@ off_t talloc_total_size(const void *ptr) tc = talloc_chunk_from_ptr(ptr); - if (tc->u.flags & TALLOC_FLAG_LOOP) { + if (tc->flags & TALLOC_FLAG_LOOP) { return 0; } - tc->u.flags |= TALLOC_FLAG_LOOP; + tc->flags |= TALLOC_FLAG_LOOP; total = tc->size; for (c=tc->child;c;c=c->next) { - total += talloc_total_size(c+1); + total += talloc_total_size(TC_PTR_FROM_CHUNK(c)); } - tc->u.flags &= ~TALLOC_FLAG_LOOP; + tc->flags &= ~TALLOC_FLAG_LOOP; return total; } @@ -744,18 +747,18 @@ off_t talloc_total_blocks(const void *ptr) off_t total = 0; struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr); - if (tc->u.flags & TALLOC_FLAG_LOOP) { + if (tc->flags & TALLOC_FLAG_LOOP) { return 0; } - tc->u.flags |= TALLOC_FLAG_LOOP; + tc->flags |= TALLOC_FLAG_LOOP; total++; for (c=tc->child;c;c=c->next) { - total += talloc_total_blocks(c+1); + total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c)); } - tc->u.flags &= ~TALLOC_FLAG_LOOP; + tc->flags &= ~TALLOC_FLAG_LOOP; return total; } @@ -782,29 +785,29 @@ void talloc_report_depth(const void *ptr, FILE *f, int depth) { struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr); - if (tc->u.flags & TALLOC_FLAG_LOOP) { + if (tc->flags & TALLOC_FLAG_LOOP) { return; } - tc->u.flags |= TALLOC_FLAG_LOOP; + tc->flags |= TALLOC_FLAG_LOOP; for (c=tc->child;c;c=c->next) { if (c->name == TALLOC_MAGIC_REFERENCE) { - struct talloc_reference_handle *handle = (void *)(c+1); + struct talloc_reference_handle *handle = TC_PTR_FROM_CHUNK(c); const char *name2 = talloc_get_name(handle->ptr); fprintf(f, "%*sreference to: %s\n", depth*4, "", name2); } else { - const char *name = talloc_get_name(c+1); + const char *name = talloc_get_name(TC_PTR_FROM_CHUNK(c)); fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n", depth*4, "", name, - (unsigned long)talloc_total_size(c+1), - (unsigned long)talloc_total_blocks(c+1), - talloc_reference_count(c+1)); - talloc_report_depth(c+1, f, depth+1); + (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c)), + (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c)), + talloc_reference_count(TC_PTR_FROM_CHUNK(c))); + talloc_report_depth(TC_PTR_FROM_CHUNK(c), f, depth+1); } } - tc->u.flags &= ~TALLOC_FLAG_LOOP; + tc->flags &= ~TALLOC_FLAG_LOOP; } /* @@ -847,9 +850,9 @@ void talloc_report(const void *ptr, FILE *f) for (c=tc->child;c;c=c->next) { fprintf(f, "\t%-30s contains %6lu bytes in %3lu blocks\n", - talloc_get_name(c+1), - (unsigned long)talloc_total_size(c+1), - (unsigned long)talloc_total_blocks(c+1)); + talloc_get_name(TC_PTR_FROM_CHUNK(c)), + (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c)), + (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c))); } fflush(f); } @@ -1175,7 +1178,7 @@ void *talloc_find_parent_byname(const void *context, const char *name) tc = talloc_chunk_from_ptr(context); while (tc) { if (tc->name && strcmp(tc->name, name) == 0) { - return (void*)(tc+1); + return TC_PTR_FROM_CHUNK(tc); } while (tc && tc->prev) tc = tc->prev; tc = tc->parent; @@ -1198,7 +1201,7 @@ void talloc_show_parents(const void *context, FILE *file) tc = talloc_chunk_from_ptr(context); fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context)); while (tc) { - fprintf(file, "\t'%s'\n", talloc_get_name(tc+1)); + fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc))); while (tc && tc->prev) tc = tc->prev; tc = tc->parent; } |