consumerd: send a buffer static sample on flush command
[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 <inttypes.h>
9
10 #include <urcu.h>
11 #include <urcu/list.h>
12
13 #include "macros.hpp"
14 #include "error.hpp"
15
16 #include "index-allocator.hpp"
17
18 struct lttng_index_allocator {
19 struct cds_list_head unused_list;
20 uint64_t size;
21 uint64_t position;
22 uint64_t nb_allocated_indexes;
23 };
24
25 namespace {
26 struct lttng_index {
27 uint64_t index;
28 struct cds_list_head head;
29 };
30 } /* namespace */
31
32 struct lttng_index_allocator *lttng_index_allocator_create(
33 uint64_t index_count)
34 {
35 struct lttng_index_allocator *allocator = NULL;
36
37 allocator = zmalloc<lttng_index_allocator>();
38 if (!allocator) {
39 PERROR("Failed to allocate index allocator");
40 goto end;
41 }
42
43 allocator->size = index_count;
44 allocator->position = 0;
45 allocator->nb_allocated_indexes = 0;
46
47 CDS_INIT_LIST_HEAD(&allocator->unused_list);
48
49 end:
50 return allocator;
51 }
52
53 uint64_t lttng_index_allocator_get_index_count(struct lttng_index_allocator *allocator)
54 {
55 return allocator->nb_allocated_indexes;
56 }
57
58 enum lttng_index_allocator_status lttng_index_allocator_alloc(
59 struct lttng_index_allocator *allocator,
60 uint64_t *allocated_index)
61 {
62 enum lttng_index_allocator_status status =
63 LTTNG_INDEX_ALLOCATOR_STATUS_OK;
64
65 if (cds_list_empty(&allocator->unused_list)) {
66 if (allocator->position >= allocator->size) {
67 /* No indices left. */
68 status = LTTNG_INDEX_ALLOCATOR_STATUS_EMPTY;
69 goto end;
70 }
71
72 *allocated_index = allocator->position++;
73 } else {
74 struct lttng_index *index;
75
76 index = cds_list_first_entry(&allocator->unused_list,
77 typeof(*index), head);
78 cds_list_del(&index->head);
79 *allocated_index = index->index;
80 free(index);
81 }
82
83 allocator->nb_allocated_indexes++;
84 end:
85 return status;
86 }
87
88 enum lttng_index_allocator_status lttng_index_allocator_release(
89 struct lttng_index_allocator *allocator, uint64_t idx)
90 {
91 struct lttng_index *index = NULL;
92 enum lttng_index_allocator_status status =
93 LTTNG_INDEX_ALLOCATOR_STATUS_OK;
94
95 LTTNG_ASSERT(idx < allocator->size);
96
97 index = zmalloc<lttng_index>();
98 if (!index) {
99 PERROR("Failed to allocate free index queue");
100 status = LTTNG_INDEX_ALLOCATOR_STATUS_ERROR;
101 goto end;
102 }
103
104 index->index = idx;
105 cds_list_add_tail(&index->head, &allocator->unused_list);
106 allocator->nb_allocated_indexes--;
107
108 end:
109 return status;
110 }
111
112 void lttng_index_allocator_destroy(struct lttng_index_allocator *allocator)
113 {
114 struct lttng_index *index = NULL, *tmp_index = NULL;
115
116 if (!allocator) {
117 return;
118 }
119
120 if (lttng_index_allocator_get_index_count(allocator) > 0) {
121 WARN("Destroying index allocator with %" PRIu64
122 " slot indexes still in use",
123 lttng_index_allocator_get_index_count(allocator));
124 }
125
126 cds_list_for_each_entry_safe(index, tmp_index,
127 &allocator->unused_list, head) {
128 cds_list_del(&index->head);
129 free(index);
130 }
131
132 free(allocator);
133 }
This page took 0.033686 seconds and 4 git commands to generate.