summaryrefslogtreecommitdiff
path: root/src/pool.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pool.c')
-rw-r--r--src/pool.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/src/pool.c b/src/pool.c
new file mode 100644
index 0000000..c7e7a88
--- /dev/null
+++ b/src/pool.c
@@ -0,0 +1,91 @@
+
+#include <string.h>
+#include <stdlib.h>
+#include "pool.h"
+
+#define DEFAULT_START_SIZE 16
+
+pool *pool_new(void)
+{
+ pool *p;
+ p = malloc(sizeof(*p));
+ if (!p)
+ return NULL;
+ memset(p, 0, sizeof(*p));
+
+ p->array = calloc(DEFAULT_START_SIZE, sizeof(void *));
+ if (!p->array) {
+ free(p);
+ return NULL;
+ }
+
+ p->len = DEFAULT_START_SIZE;
+ p->num = 0;
+ lock_init(&p->lock);
+ return p;
+}
+
+void pool_free(pool *p)
+{
+ if (p->array)
+ free(p->array);
+ free(p);
+}
+
+int pool_push(pool *p, void *v)
+{
+ if (p->num == p->len) {
+ /* expand array */
+ size_t newlen = p->len * 2 * sizeof(void *);
+ void **new = realloc(p->array, newlen);
+ if (new == NULL)
+ return -1;
+ p->len = newlen;
+ p->array = new;
+ }
+ p->array[p->num] = v;
+ p->num++;
+ return 0;
+}
+
+int pool_push_lock(pool *p, void *v)
+{
+ int ret = -1;
+ pool_lock(p);
+ ret = pool_push(p, v);
+ pool_unlock(p);
+ return ret;
+}
+
+void *pool_pop(pool *p)
+{
+ return p->num == 0 ? NULL : p->array[--p->num];
+}
+
+void *pool_pop_lock(pool *p)
+{
+ void *v;
+ pool_lock(p);
+ v = pool_pop(p);
+ pool_unlock(p);
+ return v;
+}
+
+void *pool_iter_next(pool *p)
+{
+ if (p->num <= p->idx)
+ return NULL;
+
+ void *v = p->array[p->idx];
+ p->idx++;
+ return v;
+}
+
+void *pool_iter_next_lock(pool *p)
+{
+ void *v = NULL;
+ pool_lock(p);
+ v = pool_iter_next(p);
+ pool_unlock(p);
+ return v;
+}