Commit | Line | Data |
---|---|---|
246611b0 FD |
1 | /* |
2 | * Copyright (C) 2020 Francis Deslauriers <francis.deslauriers@efficios.com> | |
3 | * | |
4 | * SPDX-License-Identifier: GPL-2.0-only | |
5 | * | |
6 | */ | |
7 | ||
28ab034a JG |
8 | #include "error.hpp" |
9 | #include "index-allocator.hpp" | |
10 | #include "macros.hpp" | |
246611b0 | 11 | |
28ab034a | 12 | #include <inttypes.h> |
246611b0 FD |
13 | #include <urcu.h> |
14 | #include <urcu/list.h> | |
15 | ||
246611b0 FD |
16 | struct lttng_index_allocator { |
17 | struct cds_list_head unused_list; | |
18 | uint64_t size; | |
19 | uint64_t position; | |
5e09ab50 | 20 | uint64_t nb_allocated_indexes; |
246611b0 FD |
21 | }; |
22 | ||
f1494934 | 23 | namespace { |
246611b0 FD |
24 | struct lttng_index { |
25 | uint64_t index; | |
26 | struct cds_list_head head; | |
27 | }; | |
f1494934 | 28 | } /* namespace */ |
246611b0 | 29 | |
28ab034a | 30 | struct lttng_index_allocator *lttng_index_allocator_create(uint64_t index_count) |
246611b0 | 31 | { |
cd9adb8b | 32 | struct lttng_index_allocator *allocator = nullptr; |
246611b0 | 33 | |
64803277 | 34 | allocator = zmalloc<lttng_index_allocator>(); |
246611b0 FD |
35 | if (!allocator) { |
36 | PERROR("Failed to allocate index allocator"); | |
37 | goto end; | |
38 | } | |
39 | ||
40 | allocator->size = index_count; | |
41 | allocator->position = 0; | |
5e09ab50 | 42 | allocator->nb_allocated_indexes = 0; |
246611b0 FD |
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 | { | |
5e09ab50 | 52 | return allocator->nb_allocated_indexes; |
246611b0 FD |
53 | } |
54 | ||
28ab034a JG |
55 | enum lttng_index_allocator_status |
56 | lttng_index_allocator_alloc(struct lttng_index_allocator *allocator, uint64_t *allocated_index) | |
246611b0 | 57 | { |
28ab034a | 58 | enum lttng_index_allocator_status status = LTTNG_INDEX_ALLOCATOR_STATUS_OK; |
246611b0 FD |
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 | ||
28ab034a | 71 | index = cds_list_first_entry(&allocator->unused_list, typeof(*index), head); |
246611b0 FD |
72 | cds_list_del(&index->head); |
73 | *allocated_index = index->index; | |
74 | free(index); | |
75 | } | |
76 | ||
5e09ab50 | 77 | allocator->nb_allocated_indexes++; |
246611b0 FD |
78 | end: |
79 | return status; | |
80 | } | |
81 | ||
28ab034a JG |
82 | enum lttng_index_allocator_status |
83 | lttng_index_allocator_release(struct lttng_index_allocator *allocator, uint64_t idx) | |
246611b0 | 84 | { |
cd9adb8b | 85 | struct lttng_index *index = nullptr; |
28ab034a | 86 | enum lttng_index_allocator_status status = LTTNG_INDEX_ALLOCATOR_STATUS_OK; |
246611b0 | 87 | |
a0377dfe | 88 | LTTNG_ASSERT(idx < allocator->size); |
246611b0 | 89 | |
64803277 | 90 | index = zmalloc<lttng_index>(); |
246611b0 FD |
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); | |
5e09ab50 | 99 | allocator->nb_allocated_indexes--; |
246611b0 FD |
100 | |
101 | end: | |
102 | return status; | |
103 | } | |
104 | ||
105 | void lttng_index_allocator_destroy(struct lttng_index_allocator *allocator) | |
106 | { | |
cd9adb8b | 107 | struct lttng_index *index = nullptr, *tmp_index = nullptr; |
246611b0 FD |
108 | |
109 | if (!allocator) { | |
110 | return; | |
111 | } | |
112 | ||
113 | if (lttng_index_allocator_get_index_count(allocator) > 0) { | |
28ab034a JG |
114 | WARN("Destroying index allocator with %" PRIu64 " slot indexes still in use", |
115 | lttng_index_allocator_get_index_count(allocator)); | |
246611b0 FD |
116 | } |
117 | ||
28ab034a | 118 | cds_list_for_each_entry_safe (index, tmp_index, &allocator->unused_list, head) { |
246611b0 FD |
119 | cds_list_del(&index->head); |
120 | free(index); | |
121 | } | |
122 | ||
123 | free(allocator); | |
124 | } |