common: Add index allocator for error counters
authorFrancis Deslauriers <francis.deslauriers@efficios.com>
Mon, 24 Aug 2020 21:02:05 +0000 (17:02 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 24 Mar 2021 21:48:22 +0000 (17:48 -0400)
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: I677a8f5b774315eadb8e3b2c2f2a5b1aae02133f

src/common/Makefile.am
src/common/index-allocator.c [new file with mode: 0644]
src/common/index-allocator.h [new file with mode: 0644]

index caf588e4093e9017a8138a3883c934bed6bef57c..a56775e310a3b24ee35a880cff2e73707a4652b1 100644 (file)
@@ -71,6 +71,7 @@ libcommon_la_SOURCES = \
        fs-handle.c fs-handle.h fs-handle-internal.h \
        futex.c futex.h \
        kernel-probe.c \
        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 \
        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 (file)
index 0000000..3de09a8
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2020 Francis Deslauriers <francis.deslauriers@efficios.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ */
+
+#include <assert.h>
+#include <inttypes.h>
+
+#include <urcu.h>
+#include <urcu/list.h>
+
+#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 (file)
index 0000000..3da733e
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2020 Francis Deslauriers <francis.deslauriers@efficios.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ */
+
+#ifndef _COMMON_INDEX_ALLOCATOR_H
+#define _COMMON_INDEX_ALLOCATOR_H
+
+#include <inttypes.h>
+
+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 */
This page took 0.02752 seconds and 4 git commands to generate.