+struct btr_pool *btr_pool_new(const char *name, size_t area_size)
+{
+ struct btr_pool *btrp;
+
+ PARA_INFO_LOG("%s, %zu bytes\n", name, area_size);
+ btrp = para_malloc(sizeof(*btrp));
+ btrp->area_start = para_malloc(area_size);
+ btrp->area_end = btrp->area_start + area_size;
+ btrp->rhead = btrp->area_start;
+ btrp->whead = btrp->area_start;
+ btrp->name = para_strdup(name);
+ return btrp;
+}
+
+/* whead = NULL means area full */
+
+void btr_pool_free(struct btr_pool *btrp)
+{
+ if (!btrp)
+ return;
+ free(btrp->area_start);
+ free(btrp->name);
+ free(btrp);
+}
+
+size_t btr_pool_size(struct btr_pool *btrp)
+{
+ return btrp->area_end - btrp->area_start;
+}
+
+size_t btr_pool_filled(struct btr_pool *btrp)
+{
+ if (!btrp->whead)
+ return btr_pool_size(btrp);
+ if (btrp->rhead <= btrp->whead)
+ return btrp->whead - btrp->rhead;
+ return btr_pool_size(btrp) - (btrp->rhead - btrp->whead);
+}
+
+size_t btr_pool_unused(struct btr_pool *btrp)
+{
+ return btr_pool_size(btrp) - btr_pool_filled(btrp);
+}
+
+size_t btr_pool_available(struct btr_pool *btrp)
+{
+ if (!btrp->whead)
+ return 0;
+ if (btrp->rhead <= btrp->whead)
+ return btrp->area_end - btrp->whead;
+ return btrp->rhead - btrp->whead;
+}
+
+size_t btr_pool_get_buffer(struct btr_pool *btrp, char **result)
+{
+ if (result)
+ *result = btrp->whead;
+ return btr_pool_available(btrp);
+}
+
+void btr_pool_allocate(struct btr_pool *btrp, size_t size)
+{
+ char *end;
+
+ if (size == 0)
+ return;
+ //PARA_CRIT_LOG("filled: %zu, alloc %zu\n", btr_pool_filled(btrp), size);
+ assert(size <= btr_pool_available(btrp));
+ end = btrp->whead + size;
+ assert(end <= btrp->area_end);
+
+ if (end == btrp->area_end) {
+ PARA_DEBUG_LOG("%s: end of pool area reached\n", btrp->name);
+ end = btrp->area_start;
+ }
+ if (end == btrp->rhead) {
+ PARA_DEBUG_LOG("btrp buffer full\n");
+ end = NULL; /* buffer full */
+ }
+ btrp->whead = end;
+ //PARA_CRIT_LOG("filled: %zu\n", btr_pool_filled(btrp));
+}
+
+static void btr_pool_deallocate(struct btr_pool *btrp, size_t size)
+{
+ char *end = btrp->rhead + size;
+
+ //PARA_CRIT_LOG("filled: %zu, dealloc %zu\n", btr_pool_filled(btrp), size);
+ if (size == 0)
+ return;
+ assert(end <= btrp->area_end);
+ assert(size <= btr_pool_filled(btrp));
+ if (end == btrp->area_end)
+ end = btrp->area_start;
+ if (!btrp->whead)
+ btrp->whead = btrp->rhead;
+ btrp->rhead = end;
+ if (btrp->rhead == btrp->whead)
+ btrp->rhead = btrp->whead = btrp->area_start;
+ //PARA_CRIT_LOG("filled: %zu\n", btr_pool_filled(btrp));
+}
+