summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2018-11-27 12:20:27 -0800
committerVito Caputo <vcaputo@pengaru.com>2018-11-27 12:20:27 -0800
commit16b9b42cecc81f7540aef85459cf1fa191fa641c (patch)
treefe3a91276b9ccebb692643e00d7acc54fea632c3
parentadb18cde6ca95b7c0533fad70edaf3f78d3597a2 (diff)
libpad: add pad flags and flag for zeroing memory
-rw-r--r--src/example.c2
-rw-r--r--src/pad.c25
-rw-r--r--src/pad.h4
3 files changed, 26 insertions, 5 deletions
diff --git a/src/example.c b/src/example.c
index 12383fa..8d5529c 100644
--- a/src/example.c
+++ b/src/example.c
@@ -13,7 +13,7 @@ int main(int argc, char *argv[])
foo_t *f[10 * CHUNK_CNT];
pad_t *p;
- p = pad_new(sizeof(foo_t) * 256);
+ p = pad_new(sizeof(foo_t) * 256, PAD_FLAGS_ZERO);
assert(p);
for (int n = 0; n < 10; n++) {
diff --git a/src/pad.c b/src/pad.c
index e0bc56d..bac5291 100644
--- a/src/pad.c
+++ b/src/pad.c
@@ -71,6 +71,7 @@ typedef struct alloc_t {
struct pad_t {
chunk_t *chunk; /* current chunk allocations come from */
unsigned chunk_size; /* size chunks are allocated in */
+ unsigned flags; /* flags of this pad */
list_head_t free_chunks; /* list of completely free chunks */
list_head_t pinned_chunks; /* list of chunks pinned because they have an outstanding allocation */
};
@@ -96,7 +97,12 @@ static inline void chunk_unref(chunk_t *chunk)
assert(chunk->n_refs > 0);
if (chunk->n_refs == 1) {
- list_move(&chunk->chunks, &chunk->pad->free_chunks);
+ pad_t *pad = chunk->pad;
+
+ list_move(&chunk->chunks, &pad->free_chunks);
+
+ if ((pad->flags & PAD_FLAGS_ZERO))
+ memset(chunk->mem, 0, pad->chunk_size);
return;
}
@@ -126,7 +132,11 @@ static chunk_t * chunk_get(pad_t *pad)
list_del(&chunk->chunks);
} else {
/* No free chunks, must ask libc for memory */
- chunk = malloc(chunk_alloc_size(pad));
+ if ((pad->flags & PAD_FLAGS_ZERO))
+ chunk = calloc(1, chunk_alloc_size(pad));
+ else
+ chunk = malloc(chunk_alloc_size(pad));
+
if (!chunk)
return NULL;
}
@@ -145,7 +155,7 @@ static chunk_t * chunk_get(pad_t *pad)
/* Create a new pad. */
-pad_t * pad_new(unsigned chunk_size)
+pad_t * pad_new(unsigned chunk_size, unsigned flags)
{
pad_t *pad;
@@ -158,6 +168,7 @@ pad_t * pad_new(unsigned chunk_size)
/* XXX: pad->chunk_size does not include the size of the chunk_t container */
pad->chunk_size = ALIGN(chunk_size, CHUNK_ALIGNMENT);
+ pad->flags = flags;
return pad;
}
@@ -172,6 +183,14 @@ void pad_reset(pad_t *pad)
assert(pad);
pad->chunk = NULL;
+
+ if ((pad->flags & PAD_FLAGS_ZERO)) {
+ chunk_t *c;
+
+ list_for_each_entry(c, &pad->pinned_chunks, chunks)
+ memset(c->mem, 0, pad->chunk_size);
+ }
+
list_splice_init(&pad->pinned_chunks, &pad->free_chunks);
}
diff --git a/src/pad.h b/src/pad.h
index 2efb0f2..e9927e8 100644
--- a/src/pad.h
+++ b/src/pad.h
@@ -19,7 +19,9 @@
typedef struct pad_t pad_t;
-pad_t * pad_new(unsigned chunk_size);
+#define PAD_FLAGS_ZERO 0x1
+
+pad_t * pad_new(unsigned chunk_size, unsigned flags);
void pad_reset(pad_t *pad);
void pad_free(pad_t *pad);
void * pad_get(pad_t *pad, unsigned size);
© All Rights Reserved