2 * Copyright (C) 2020 Francis Deslauriers <francis.deslauriers@efficios.com>
4 * SPDX-License-Identifier: GPL-2.0-only
11 #include <urcu/list.h>
16 #include "index-allocator.hpp"
18 struct lttng_index_allocator
{
19 struct cds_list_head unused_list
;
22 uint64_t nb_allocated_indexes
;
27 struct cds_list_head head
;
30 struct lttng_index_allocator
*lttng_index_allocator_create(
33 struct lttng_index_allocator
*allocator
= NULL
;
35 allocator
= zmalloc
<lttng_index_allocator
>();
37 PERROR("Failed to allocate index allocator");
41 allocator
->size
= index_count
;
42 allocator
->position
= 0;
43 allocator
->nb_allocated_indexes
= 0;
45 CDS_INIT_LIST_HEAD(&allocator
->unused_list
);
51 uint64_t lttng_index_allocator_get_index_count(struct lttng_index_allocator
*allocator
)
53 return allocator
->nb_allocated_indexes
;
56 enum lttng_index_allocator_status
lttng_index_allocator_alloc(
57 struct lttng_index_allocator
*allocator
,
58 uint64_t *allocated_index
)
60 enum lttng_index_allocator_status status
=
61 LTTNG_INDEX_ALLOCATOR_STATUS_OK
;
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
;
70 *allocated_index
= allocator
->position
++;
72 struct lttng_index
*index
;
74 index
= cds_list_first_entry(&allocator
->unused_list
,
75 typeof(*index
), head
);
76 cds_list_del(&index
->head
);
77 *allocated_index
= index
->index
;
81 allocator
->nb_allocated_indexes
++;
86 enum lttng_index_allocator_status
lttng_index_allocator_release(
87 struct lttng_index_allocator
*allocator
, uint64_t idx
)
89 struct lttng_index
*index
= NULL
;
90 enum lttng_index_allocator_status status
=
91 LTTNG_INDEX_ALLOCATOR_STATUS_OK
;
93 LTTNG_ASSERT(idx
< allocator
->size
);
95 index
= zmalloc
<lttng_index
>();
97 PERROR("Failed to allocate free index queue");
98 status
= LTTNG_INDEX_ALLOCATOR_STATUS_ERROR
;
103 cds_list_add_tail(&index
->head
, &allocator
->unused_list
);
104 allocator
->nb_allocated_indexes
--;
110 void lttng_index_allocator_destroy(struct lttng_index_allocator
*allocator
)
112 struct lttng_index
*index
= NULL
, *tmp_index
= NULL
;
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
));
124 cds_list_for_each_entry_safe(index
, tmp_index
,
125 &allocator
->unused_list
, head
) {
126 cds_list_del(&index
->head
);