diff options
author | Mattias Andrée <maandree@kth.se> | 2020-05-11 19:41:16 +0200 |
---|---|---|
committer | Mattias Andrée <maandree@kth.se> | 2020-05-11 19:41:16 +0200 |
commit | 80bcfd86b16b990cac7c172d4f55740b27a1510b (patch) | |
tree | fbad87ac55543fc5f5563983b516325a1f9e07c6 /libaxl_deallocate_id.c | |
parent | m (diff) | |
download | libaxl-80bcfd86b16b990cac7c172d4f55740b27a1510b.tar.gz libaxl-80bcfd86b16b990cac7c172d4f55740b27a1510b.tar.bz2 libaxl-80bcfd86b16b990cac7c172d4f55740b27a1510b.tar.xz |
Documentation, use of liberror, and implement libaxl_deallocate_id
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
-rw-r--r-- | libaxl_deallocate_id.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/libaxl_deallocate_id.c b/libaxl_deallocate_id.c new file mode 100644 index 0000000..0a27de0 --- /dev/null +++ b/libaxl_deallocate_id.c @@ -0,0 +1,52 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +int +libaxl_deallocate_id(LIBAXL_CONTEXT *ctx, libaxl_id_t id) +{ + LIBAXL_CONNECTION *conn = ctx->conn; + struct id_pool *pool = NULL, *node; + uint32_t inc = (uint32_t)1 << conn->xid_shift; + int ret = 0; + + pool = atomic_exchange(&conn->xid_pool, pool); + if (pool) { + for (node = pool;; node = node->next) { + if (id + inc == node->first) { + node->first = id; + goto out; + } else if (node->last + inc == id) { + node->last = id; + goto out; + } + if (!node->next) + break; + } + node->next = liberror_malloc(sizeof(*node->next)); + if (node->next) { + node->next->first = id; + node->next->last = id; + atomic_init(&node->next->next, NULL); + } else { + ret = -1; + } + } else { + pool = liberror_malloc(sizeof(*pool)); + if (pool) { + pool->first = id; + pool->last = id; + atomic_init(&pool->next, NULL); + } else { + ret = -1; + } + } + +out: + while ((pool = atomic_exchange(&conn->xid_pool, pool))) { + for (node = pool; node->next; node = node->next); + node->next = atomic_exchange(&conn->xid_pool, NULL); + } + + return ret; +} + |