X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/51ce67d59968560f0e975dc97bb0a22a7edb0610..9411292489496984c8d5d9a446bf071afac3866d:/lib/pool_alloc.c diff --git a/lib/pool_alloc.c b/lib/pool_alloc.c index c48e4c97..5856d591 100644 --- a/lib/pool_alloc.c +++ b/lib/pool_alloc.c @@ -2,7 +2,7 @@ #define POOL_DEF_EXTENT (32 * 1024) -#define POOL_QALIGN_P2 (1<<16) +#define POOL_QALIGN_P2 (1<<16) /* power-of-2 qalign */ struct alloc_pool { @@ -24,10 +24,10 @@ struct alloc_pool struct pool_extent { + struct pool_extent *next; void *start; /* starting address */ size_t free; /* free bytecount */ size_t bound; /* trapped free bytes */ - struct pool_extent *next; }; struct align_test { @@ -72,8 +72,8 @@ pool_create(size_t size, size_t quantum, void (*bomb)(const char *), int flags) } if (quantum <= 1) - flags &= ~(POOL_QALIGN | POOL_QALIGN_P2); - else if (flags & POOL_QALIGN) { + flags = (flags | POOL_NO_QALIGN) & ~POOL_QALIGN_P2; + else if (!(flags & POOL_NO_QALIGN)) { if (size % quantum) size += quantum - size % quantum; /* If quantum is a power of 2, we'll avoid using modulus. */ @@ -101,7 +101,7 @@ pool_destroy(alloc_pool_t p) for (cur = pool->extents; cur; cur = next) { next = cur->next; if (pool->flags & POOL_PREPEND) - free(cur->start - sizeof (struct pool_extent)); + free(PTR_ADD(cur->start, -sizeof (struct pool_extent))); else { free(cur->start); free(cur); @@ -123,7 +123,7 @@ pool_alloc(alloc_pool_t p, size_t len, const char *bomb_msg) else if (pool->flags & POOL_QALIGN_P2) { if (len & (pool->quantum - 1)) len += pool->quantum - (len & (pool->quantum - 1)); - } else if (pool->flags & POOL_QALIGN) { + } else if (!(pool->flags & POOL_NO_QALIGN)) { if (len % pool->quantum) len += pool->quantum - len % pool->quantum; } @@ -148,7 +148,7 @@ pool_alloc(alloc_pool_t p, size_t len, const char *bomb_msg) if (pool->flags & POOL_PREPEND) { ext = start; - start += sizeof (struct pool_extent); + start = PTR_ADD(start, sizeof (struct pool_extent)); } else if (!(ext = new(struct pool_extent))) goto bomb_out; ext->start = start; @@ -185,12 +185,21 @@ pool_free(alloc_pool_t p, size_t len, void *addr) if (!pool) return; + if (!addr) { + /* A NULL addr starts a fresh extent for new allocations. */ + if ((cur = pool->extents) != NULL && cur->free != pool->size) { + cur->bound += cur->free; + cur->free = 0; + } + return; + } + if (!len) len = pool->quantum; else if (pool->flags & POOL_QALIGN_P2) { if (len & (pool->quantum - 1)) len += pool->quantum - (len & (pool->quantum - 1)); - } else if (pool->flags & POOL_QALIGN) { + } else if (!(pool->flags & POOL_NO_QALIGN)) { if (len % pool->quantum) len += pool->quantum - len % pool->quantum; } @@ -227,7 +236,7 @@ pool_free(alloc_pool_t p, size_t len, void *addr) if (cur->free + cur->bound >= pool->size) { prev->next = cur->next; if (pool->flags & POOL_PREPEND) - free(cur->start - sizeof (struct pool_extent)); + free(PTR_ADD(cur->start, -sizeof (struct pool_extent))); else { free(cur->start); free(cur); @@ -284,7 +293,7 @@ pool_free_old(alloc_pool_t p, void *addr) while ((cur = next) != NULL) { next = cur->next; if (pool->flags & POOL_PREPEND) - free(cur->start - sizeof (struct pool_extent)); + free(PTR_ADD(cur->start, -sizeof (struct pool_extent))); else { free(cur->start); free(cur); @@ -317,24 +326,30 @@ pool_boundary(alloc_pool_t p, size_t len) } #define FDPRINT(label, value) \ - snprintf(buf, sizeof buf, label, value), \ - write(fd, buf, strlen(buf)) + do { \ + int len = snprintf(buf, sizeof buf, label, value); \ + if (write(fd, buf, len) != len) \ + ret = -1; \ + } while (0) #define FDEXTSTAT(ext) \ - snprintf(buf, sizeof buf, " %12ld %5ld\n", \ - (long) ext->free, \ - (long) ext->bound), \ - write(fd, buf, strlen(buf)) - -void + do { \ + int len = snprintf(buf, sizeof buf, " %12ld %5ld\n", \ + (long)ext->free, (long)ext->bound); \ + if (write(fd, buf, len) != len) \ + ret = -1; \ + } while (0) + +int pool_stats(alloc_pool_t p, int fd, int summarize) { struct alloc_pool *pool = (struct alloc_pool *) p; struct pool_extent *cur; char buf[BUFSIZ]; + int ret = 0; if (!pool) - return; + return ret; FDPRINT(" Extent size: %12ld\n", (long) pool->size); FDPRINT(" Alloc quantum: %12ld\n", (long) pool->quantum); @@ -346,13 +361,16 @@ pool_stats(alloc_pool_t p, int fd, int summarize) FDPRINT(" Bytes freed: %12.0f\n", (double) pool->b_freed); if (summarize) - return; + return ret; if (!pool->extents) - return; + return ret; - write(fd, "\n", 1); + if (write(fd, "\n", 1) != 1) + ret = -1; for (cur = pool->extents; cur; cur = cur->next) FDEXTSTAT(cur); + + return ret; }