summaryrefslogtreecommitdiff
path: root/librabbitmq/amqp_mem.c
diff options
context:
space:
mode:
authorTony Garnock-Jones <tonyg@kcbbs.gen.nz>2009-04-25 19:41:56 +0100
committerTony Garnock-Jones <tonyg@kcbbs.gen.nz>2009-04-25 19:41:56 +0100
commit67970c9c56ebd49b57e61d50255b04fa1ac7d27d (patch)
treeec02d63a0a7b8f31b7a0c0426eeaab25f5884e1f /librabbitmq/amqp_mem.c
parent8bf174bc0a3d682ff9c8c11435008f1adf3c288f (diff)
downloadrabbitmq-c-github-ask-67970c9c56ebd49b57e61d50255b04fa1ac7d27d.tar.gz
Codegen, codec
Diffstat (limited to 'librabbitmq/amqp_mem.c')
-rw-r--r--librabbitmq/amqp_mem.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/librabbitmq/amqp_mem.c b/librabbitmq/amqp_mem.c
new file mode 100644
index 0000000..64d06de
--- /dev/null
+++ b/librabbitmq/amqp_mem.c
@@ -0,0 +1,102 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <assert.h>
+
+#include "amqp.h"
+#include "../config.h"
+
+char const *amqp_version(void) {
+ return VERSION; /* defined in config.h */
+}
+
+void init_amqp_pool(amqp_pool_t *pool, size_t pagesize) {
+ pool->pagesize = pagesize ? pagesize : 4096;
+
+ pool->pages.num_blocks = 0;
+ pool->pages.blocklist = NULL;
+
+ pool->large_blocks.num_blocks = 0;
+ pool->large_blocks.blocklist = NULL;
+
+ pool->next_page = 0;
+ pool->alloc_block = NULL;
+ pool->alloc_used = 0;
+}
+
+static void empty_blocklist(amqp_pool_blocklist_t *x) {
+ int i;
+
+ for (i = 0; i < x->num_blocks; i++) {
+ free(x->blocklist[i]);
+ }
+ if (x->blocklist != NULL) {
+ free(x->blocklist);
+ }
+ x->num_blocks = 0;
+ x->blocklist = NULL;
+}
+
+void recycle_amqp_pool(amqp_pool_t *pool) {
+ empty_blocklist(&pool->large_blocks);
+ pool->next_page = 0;
+ pool->alloc_block = NULL;
+ pool->alloc_used = 0;
+}
+
+void empty_amqp_pool(amqp_pool_t *pool) {
+ recycle_amqp_pool(pool);
+ empty_blocklist(&pool->pages);
+}
+
+static void record_pool_block(amqp_pool_blocklist_t *x, void *block) {
+ size_t blocklistlength = sizeof(void *) * (x->num_blocks + 1);
+
+ if (x->blocklist == NULL) {
+ x->blocklist = malloc(blocklistlength);
+ } else {
+ x->blocklist = realloc(x->blocklist, blocklistlength);
+ }
+
+ x->blocklist[x->num_blocks] = block;
+ x->num_blocks++;
+}
+
+void *amqp_pool_alloc(amqp_pool_t *pool, size_t amount) {
+ if (amount == 0) {
+ return NULL;
+ }
+
+ amount = (amount + 7) & (~7); /* round up to nearest 8-byte boundary */
+
+ if (amount > pool->pagesize) {
+ void *result = calloc(1, amount);
+ record_pool_block(&pool->large_blocks, result);
+ return result;
+ }
+
+ if (pool->alloc_block != NULL) {
+ assert(pool->alloc_used <= pool->pagesize);
+
+ if (pool->alloc_used + amount <= pool->pagesize) {
+ void *result = pool->alloc_block + pool->alloc_used;
+ pool->alloc_used += amount;
+ return result;
+ }
+ }
+
+ if (pool->next_page >= pool->pages.num_blocks) {
+ pool->alloc_block = calloc(1, pool->pagesize);
+ record_pool_block(&pool->pages, pool->alloc_block);
+ pool->next_page = pool->pages.num_blocks;
+ } else {
+ pool->alloc_block = pool->pages.blocklist[pool->next_page];
+ pool->next_page++;
+ }
+
+ pool->alloc_used = amount;
+
+ return pool->alloc_block;
+}