#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
{
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 {
}
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. */
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);
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;
}
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;
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;
}
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);
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);
}
#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);
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;
}