Make malloc chunk head a separate structure
diff --git a/preload.c b/preload.c
index 0e0c253..45d4a37 100644
--- a/preload.c
+++ b/preload.c
@@ -28,29 +28,30 @@
/* segment size. Matches hugepage size */
#define SEG_SIZE 2*1024*1024
-#define CHUNK_SIZE (2 * sizeof(size_t))
-#define CHUNK_ALIGNMENT 0xf
-
static int debug = 0;
#define DEBUG(...) do { if (debug) printf(__VA_ARGS__); } while(0)
-static size_t pad_request(size_t s)
-{
- return (s + CHUNK_SIZE + CHUNK_ALIGNMENT) & ~CHUNK_ALIGNMENT;
-}
#define PINUSE_BIT 0x01
#define CINUSE_BIT 0x02
#define FLAG_BITS (CINUSE_BIT | PINUSE_BIT)
-struct malloc_chunk {
- size_t prev_foot; /* Size of previous chunk (if free). */
- size_t head; /* Size and inuse bits. */
- struct malloc_chunk* fd; /* double links -- used only if free. */
- struct malloc_chunk* bk;
+struct malloc_chunk_head {
+ int prev_foot; /* size of previous if free */
+ int head; /* entire size of this chunk */
};
+struct malloc_chunk {
+ struct malloc_chunk_head h;
+ struct malloc_chunk *fd;
+ struct malloc_chunk *bk;
+};
+
+#define CHUNK_SIZE (sizeof(struct malloc_chunk_head))
+#define MIN_CHUNK 0x10
+#define CHUNK_ALIGNMENT (MIN_CHUNK - 1)
+
struct segptr {
char *base;
/* no size because they're always SEG_SIZE */
@@ -64,14 +65,19 @@
static struct malloc_state m;
+static size_t pad_request(size_t s)
+{
+ return (s + CHUNK_SIZE + CHUNK_ALIGNMENT) & ~CHUNK_ALIGNMENT;
+}
+
static int in_use(struct malloc_chunk *c)
{
- return c->head & CINUSE_BIT ? 1 : 0;
+ return c->h.head & CINUSE_BIT ? 1 : 0;
}
static int prev_in_use(struct malloc_chunk *c)
{
- return c->head & PINUSE_BIT ? 1 : 0;
+ return c->h.head & PINUSE_BIT ? 1 : 0;
}
static void check(int cond, const char *str)
@@ -105,7 +111,7 @@
static size_t chunk_size(struct malloc_chunk *c)
{
- return c->head & ~FLAG_BITS;
+ return c->h.head & ~FLAG_BITS;
}
static struct malloc_chunk *next_chunk(struct malloc_chunk *c)
@@ -127,7 +133,7 @@
static struct malloc_chunk *prev_chunk(struct malloc_chunk *c)
{
- return (struct malloc_chunk *)((char*)c - c->prev_foot);
+ return (struct malloc_chunk *)((char*)c - c->h.prev_foot);
}
static void link_free_chunk(struct malloc_chunk *c)
@@ -164,7 +170,7 @@
printf("SHOW SEGMENT %i\n", i);
for (c = (struct malloc_chunk *)seg->base; c != NULL; c = next_chunk(c)) {
printf("%p:%d:%d:%04x:%04x", c, in_use(c), prev_in_use(c),
- c->prev_foot, chunk_size(c));
+ c->h.prev_foot, chunk_size(c));
if (!in_use(c))
printf(":%p:%p", c->fd, c->bk);
printf("\n");
@@ -207,8 +213,8 @@
seg = chunk2mem(c);
memset(seg, 0, sizeof(*seg));
seg->base = p;
- c->head = ssize | CINUSE_BIT | PINUSE_BIT;
- c->prev_foot = 0;
+ c->h.head = ssize | CINUSE_BIT | PINUSE_BIT;
+ c->h.prev_foot = 0;
if (m.seg == NULL) {
m.seg = seg;
@@ -218,9 +224,9 @@
sp->next = seg;
}
c = next_chunk(c);
- c->head = (size_t)(((char *)p + SEG_SIZE) - (char *)c) | PINUSE_BIT;
- c->prev_foot = ssize;
- DEBUG("next chunk at 0x%p, head=%x, prev=%x\n", c, chunk_size(c), c->prev_foot);
+ c->h.head = (size_t)(((char *)p + SEG_SIZE) - (char *)c) | PINUSE_BIT;
+ c->h.prev_foot = ssize;
+ DEBUG("next chunk at 0x%p, head=%x, prev=%x\n", c, chunk_size(c), c->h.prev_foot);
link_free_chunk(c);
}
@@ -260,23 +266,23 @@
if (csize - size < pad_request(1)) {
/* nothing to split, just give everything up */
unlink_free_chunk(c);
- c->head |= CINUSE_BIT;
+ c->h.head |= CINUSE_BIT;
new_c = next_chunk(c);
if (new_c) {
ASSERT(!prev_in_use(new_c));
- ASSERT(new_c->prev_foot == chunk_size(c));
+ ASSERT(new_c->h.prev_foot == chunk_size(c));
- new_c->head |= PINUSE_BIT;
+ new_c->h.head |= PINUSE_BIT;
}
return;
}
/* set the old chunk to the size */
- c->head = size | CINUSE_BIT | PINUSE_BIT;
+ c->h.head = size | CINUSE_BIT | PINUSE_BIT;
/* get the new part of the split */
new_c = next_chunk(c);
- new_c->head = (csize - size) | PINUSE_BIT;
- new_c->prev_foot = size;
+ new_c->h.head = (csize - size) | PINUSE_BIT;
+ new_c->h.prev_foot = size;
/* now replace the new chunk with the old chunk */
new_c->fd = c->fd;
new_c->bk = c->bk;
@@ -286,8 +292,8 @@
n = next_chunk(new_c);
if (n) {
ASSERT(!prev_in_use(n));
- ASSERT(n->prev_foot == csize);
- n->prev_foot = chunk_size(new_c);
+ ASSERT(n->h.prev_foot == csize);
+ n->h.prev_foot = chunk_size(new_c);
}
}
@@ -339,9 +345,9 @@
if (!prev_in_use(c)) {
struct malloc_chunk *p = prev_chunk(c);
- p->head += chunk_size(c);
+ p->h.head += chunk_size(c);
if (n)
- n->prev_foot = chunk_size(p);
+ n->h.prev_foot = chunk_size(p);
/* the new consolidated chunk becomes our current
* chunk for the next free check below. The previous
@@ -355,14 +361,14 @@
/* and finally consolidation with next */
if (n && !in_use(n)) {
unlink_free_chunk(n);
- c->head += chunk_size(n);
+ c->h.head += chunk_size(n);
n = next_chunk(c);
if (n)
- n->prev_foot = chunk_size(c);
+ n->h.prev_foot = chunk_size(c);
} else if (n) {
ASSERT(prev_in_use(n));
- n->head &= ~PINUSE_BIT;
+ n->h.head &= ~PINUSE_BIT;
}
- c->head &= ~CINUSE_BIT;
+ c->h.head &= ~CINUSE_BIT;
show_segment();
}