From: Francis Deslauriers Date: Mon, 24 Aug 2020 21:02:05 +0000 (-0400) Subject: common: Add index allocator for error counters X-Git-Tag: v2.13.0-rc1~186 X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=commitdiff_plain;h=246611b0dffa58fbc0e2329ddf6f9dc9d9eff7ce;hp=566190c494083c9a460fbcb9052b5143a14a6e56 common: Add index allocator for error counters Signed-off-by: Francis Deslauriers Signed-off-by: Jérémie Galarneau Change-Id: I677a8f5b774315eadb8e3b2c2f2a5b1aae02133f --- diff --git a/src/common/Makefile.am b/src/common/Makefile.am index caf588e40..a56775e31 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -71,6 +71,7 @@ libcommon_la_SOURCES = \ fs-handle.c fs-handle.h fs-handle-internal.h \ futex.c futex.h \ kernel-probe.c \ + index-allocator.c index-allocator.h \ location.c \ log-level-rule.c \ mi-lttng.c mi-lttng.h \ diff --git a/src/common/index-allocator.c b/src/common/index-allocator.c new file mode 100644 index 000000000..3de09a831 --- /dev/null +++ b/src/common/index-allocator.c @@ -0,0 +1,128 @@ +/* + * 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 index allocator"); + 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; + } + + 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); +} diff --git a/src/common/index-allocator.h b/src/common/index-allocator.h new file mode 100644 index 000000000..3da733e9e --- /dev/null +++ b/src/common/index-allocator.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2020 Francis Deslauriers + * + * SPDX-License-Identifier: GPL-2.0-only + * + */ + +#ifndef _COMMON_INDEX_ALLOCATOR_H +#define _COMMON_INDEX_ALLOCATOR_H + +#include + +struct lttng_index_allocator; + +enum lttng_index_allocator_status { + LTTNG_INDEX_ALLOCATOR_STATUS_OK, + LTTNG_INDEX_ALLOCATOR_STATUS_EMPTY, + LTTNG_INDEX_ALLOCATOR_STATUS_ERROR, +}; + +/* + * Create an index allocator of `index_count` slots. + */ +struct lttng_index_allocator *lttng_index_allocator_create( + uint64_t index_count); + +/* + * Get the number of indexes currently in use. + */ +uint64_t lttng_index_allocator_get_index_count( + struct lttng_index_allocator *allocator); + +/* + * Allocate (i.e. reserve) a slot. + */ +enum lttng_index_allocator_status lttng_index_allocator_alloc( + struct lttng_index_allocator *allocator, + uint64_t *index); + +/* + * Release a slot by index. The slot will be re-used by the index allocator + * in future 'alloc' calls. + */ +enum lttng_index_allocator_status lttng_index_allocator_release( + struct lttng_index_allocator *allocator, uint64_t index); + +/* + * Destroy an index allocator. + */ +void lttng_index_allocator_destroy(struct lttng_index_allocator *allocator); + +#endif /* _COMMON_INDEX_ALLOCATOR_H */