Fix: syscall event rule: emission sites not compared in is_equal
[lttng-tools.git] / src / common / index-allocator.cpp
1 /*
2 * Copyright (C) 2020 Francis Deslauriers <francis.deslauriers@efficios.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8 #include "error.hpp"
9 #include "index-allocator.hpp"
10 #include "macros.hpp"
11
12 #include <inttypes.h>
13 #include <urcu.h>
14 #include <urcu/list.h>
15
16 struct lttng_index_allocator {
17 struct cds_list_head unused_list;
18 uint64_t size;
19 uint64_t position;
20 uint64_t nb_allocated_indexes;
21 };
22
23 namespace {
24 struct lttng_index {
25 uint64_t index;
26 struct cds_list_head head;
27 };
28 } /* namespace */
29
30 struct lttng_index_allocator *lttng_index_allocator_create(uint64_t index_count)
31 {
32 struct lttng_index_allocator *allocator = nullptr;
33
34 allocator = zmalloc<lttng_index_allocator>();
35 if (!allocator) {
36 PERROR("Failed to allocate index allocator");
37 goto end;
38 }
39
40 allocator->size = index_count;
41 allocator->position = 0;
42 allocator->nb_allocated_indexes = 0;
43
44 CDS_INIT_LIST_HEAD(&allocator->unused_list);
45
46 end:
47 return allocator;
48 }
49
50 uint64_t lttng_index_allocator_get_index_count(struct lttng_index_allocator *allocator)
51 {
52 return allocator->nb_allocated_indexes;
53 }
54
55 enum lttng_index_allocator_status
56 lttng_index_allocator_alloc(struct lttng_index_allocator *allocator, uint64_t *allocated_index)
57 {
58 enum lttng_index_allocator_status status = LTTNG_INDEX_ALLOCATOR_STATUS_OK;
59
60 if (cds_list_empty(&allocator->unused_list)) {
61 if (allocator->position >= allocator->size) {
62 /* No indices left. */
63 status = LTTNG_INDEX_ALLOCATOR_STATUS_EMPTY;
64 goto end;
65 }
66
67 *allocated_index = allocator->position++;
68 } else {
69 struct lttng_index *index;
70
71 index = cds_list_first_entry(&allocator->unused_list, typeof(*index), head);
72 cds_list_del(&index->head);
73 *allocated_index = index->index;
74 free(index);
75 }
76
77 allocator->nb_allocated_indexes++;
78 end:
79 return status;
80 }
81
82 enum lttng_index_allocator_status
83 lttng_index_allocator_release(struct lttng_index_allocator *allocator, uint64_t idx)
84 {
85 struct lttng_index *index = nullptr;
86 enum lttng_index_allocator_status status = LTTNG_INDEX_ALLOCATOR_STATUS_OK;
87
88 LTTNG_ASSERT(idx < allocator->size);
89
90 index = zmalloc<lttng_index>();
91 if (!index) {
92 PERROR("Failed to allocate free index queue");
93 status = LTTNG_INDEX_ALLOCATOR_STATUS_ERROR;
94 goto end;
95 }
96
97 index->index = idx;
98 cds_list_add_tail(&index->head, &allocator->unused_list);
99 allocator->nb_allocated_indexes--;
100
101 end:
102 return status;
103 }
104
105 void lttng_index_allocator_destroy(struct lttng_index_allocator *allocator)
106 {
107 struct lttng_index *index = nullptr, *tmp_index = nullptr;
108
109 if (!allocator) {
110 return;
111 }
112
113 if (lttng_index_allocator_get_index_count(allocator) > 0) {
114 WARN("Destroying index allocator with %" PRIu64 " slot indexes still in use",
115 lttng_index_allocator_get_index_count(allocator));
116 }
117
118 cds_list_for_each_entry_safe (index, tmp_index, &allocator->unused_list, head) {
119 cds_list_del(&index->head);
120 free(index);
121 }
122
123 free(allocator);
124 }
This page took 0.031909 seconds and 4 git commands to generate.