X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fcommon%2Findex-allocator.c;fp=src%2Fcommon%2Findex-allocator.c;h=ff5e2c88619182a540afe6dedfc1fab8cb18ef2e;hp=0000000000000000000000000000000000000000;hb=2463b7879c00298daa79744cdaae82ac061a4ed8;hpb=3a4595c2469472dee1656cde5f8882c2123efd3c diff --git a/src/common/index-allocator.c b/src/common/index-allocator.c new file mode 100644 index 000000000..ff5e2c886 --- /dev/null +++ b/src/common/index-allocator.c @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2020 Francis Deslauriers + * + * SPDX-License-Identifier: GPL-2.0-only + * + */ + +#include +#include + +#include +#include + +#include "macros.h" +#include "error.h" + +#include "index-allocator.h" + +struct lttng_index_allocator { + struct cds_list_head unused_list; + uint64_t size; + uint64_t position; +}; + +struct lttng_index { + uint64_t index; + struct cds_list_head head; +}; + +struct lttng_index_allocator *lttng_index_allocator_create( + uint64_t index_count) +{ + struct lttng_index_allocator *allocator = NULL; + + allocator = zmalloc(sizeof(*allocator)); + if (!allocator) { + PERROR("Failed to allocate free index queue"); + goto end; + } + allocator->size = index_count; + allocator->position = 0; + + CDS_INIT_LIST_HEAD(&allocator->unused_list); + +end: + return allocator; +} + +uint64_t lttng_index_allocator_get_index_count(struct lttng_index_allocator *allocator) +{ + return allocator->size; +} + +enum lttng_index_allocator_status lttng_index_allocator_alloc( + struct lttng_index_allocator *allocator, + uint64_t *allocated_index) +{ + enum lttng_index_allocator_status status = + LTTNG_INDEX_ALLOCATOR_STATUS_OK; + + if (cds_list_empty(&allocator->unused_list)) { + if (allocator->position >= allocator->size) { + /* No indices left. */ + status = LTTNG_INDEX_ALLOCATOR_STATUS_EMPTY; + goto end; + } + + *allocated_index = allocator->position++; + } else { + struct lttng_index *index; + + index = cds_list_first_entry(&allocator->unused_list, + typeof(*index), head); + cds_list_del(&index->head); + *allocated_index = index->index; + free(index); + } + +end: + return status; +} + +enum lttng_index_allocator_status lttng_index_allocator_release( + struct lttng_index_allocator *allocator, uint64_t idx) +{ + struct lttng_index *index = NULL; + enum lttng_index_allocator_status status = + LTTNG_INDEX_ALLOCATOR_STATUS_OK; + + assert(idx < allocator->size); + + index = zmalloc(sizeof(*index)); + if (!index) { + PERROR("Failed to allocate free index queue"); + status = LTTNG_INDEX_ALLOCATOR_STATUS_ERROR; + goto end; + } + + index->index = idx; + cds_list_add_tail(&index->head, &allocator->unused_list); + +end: + return status; +} + +void lttng_index_allocator_destroy(struct lttng_index_allocator *allocator) +{ + struct lttng_index *index = NULL, *tmp_index = NULL; + + if (!allocator) { + return; + } + + cds_list_for_each_entry_safe(index, tmp_index, + &allocator->unused_list, head) { + cds_list_del(&index->head); + free(index); + } + + free(allocator); +}