X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fcommon%2Findex-allocator.cpp;fp=src%2Fcommon%2Findex-allocator.cpp;h=c48d708d0ea2759e8806aa5558d949ae2ec12e8d;hp=0000000000000000000000000000000000000000;hb=a6bc4ca9d659caf016ef932fcd944029737ac57c;hpb=97535efaa975ca52bf02c2d5e76351bfd2e3defa diff --git a/src/common/index-allocator.cpp b/src/common/index-allocator.cpp new file mode 100644 index 000000000..c48d708d0 --- /dev/null +++ b/src/common/index-allocator.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2020 Francis Deslauriers + * + * SPDX-License-Identifier: GPL-2.0-only + * + */ + +#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; + uint64_t nb_allocated_indexes; +}; + +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 = (lttng_index_allocator *) zmalloc(sizeof(*allocator)); + if (!allocator) { + PERROR("Failed to allocate index allocator"); + goto end; + } + + allocator->size = index_count; + allocator->position = 0; + allocator->nb_allocated_indexes = 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->nb_allocated_indexes; +} + +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); + } + + allocator->nb_allocated_indexes++; +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; + + LTTNG_ASSERT(idx < allocator->size); + + index = (lttng_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); + allocator->nb_allocated_indexes--; + +end: + return status; +} + +void lttng_index_allocator_destroy(struct lttng_index_allocator *allocator) +{ + struct lttng_index *index = NULL, *tmp_index = NULL; + + if (!allocator) { + return; + } + + if (lttng_index_allocator_get_index_count(allocator) > 0) { + WARN("Destroying index allocator with %" PRIu64 + " slot indexes still in use", + lttng_index_allocator_get_index_count(allocator)); + } + + cds_list_for_each_entry_safe(index, tmp_index, + &allocator->unused_list, head) { + cds_list_del(&index->head); + free(index); + } + + free(allocator); +}