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