2 * Copyright (C) 2020 Francis Deslauriers <francis.deslauriers@efficios.com>
4 * SPDX-License-Identifier: GPL-2.0-only
9 #include "index-allocator.hpp"
14 #include <urcu/list.h>
16 struct lttng_index_allocator
{
17 struct cds_list_head unused_list
;
20 uint64_t nb_allocated_indexes
;
26 struct cds_list_head head
;
30 struct lttng_index_allocator
*lttng_index_allocator_create(uint64_t index_count
)
32 struct lttng_index_allocator
*allocator
= nullptr;
34 allocator
= zmalloc
<lttng_index_allocator
>();
36 PERROR("Failed to allocate index allocator");
40 allocator
->size
= index_count
;
41 allocator
->position
= 0;
42 allocator
->nb_allocated_indexes
= 0;
44 CDS_INIT_LIST_HEAD(&allocator
->unused_list
);
50 uint64_t lttng_index_allocator_get_index_count(struct lttng_index_allocator
*allocator
)
52 return allocator
->nb_allocated_indexes
;
55 enum lttng_index_allocator_status
56 lttng_index_allocator_alloc(struct lttng_index_allocator
*allocator
, uint64_t *allocated_index
)
58 enum lttng_index_allocator_status status
= LTTNG_INDEX_ALLOCATOR_STATUS_OK
;
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
;
67 *allocated_index
= allocator
->position
++;
69 struct lttng_index
*index
;
71 index
= cds_list_first_entry(&allocator
->unused_list
, typeof(*index
), head
);
72 cds_list_del(&index
->head
);
73 *allocated_index
= index
->index
;
77 allocator
->nb_allocated_indexes
++;
82 enum lttng_index_allocator_status
83 lttng_index_allocator_release(struct lttng_index_allocator
*allocator
, uint64_t idx
)
85 struct lttng_index
*index
= nullptr;
86 enum lttng_index_allocator_status status
= LTTNG_INDEX_ALLOCATOR_STATUS_OK
;
88 LTTNG_ASSERT(idx
< allocator
->size
);
90 index
= zmalloc
<lttng_index
>();
92 PERROR("Failed to allocate free index queue");
93 status
= LTTNG_INDEX_ALLOCATOR_STATUS_ERROR
;
98 cds_list_add_tail(&index
->head
, &allocator
->unused_list
);
99 allocator
->nb_allocated_indexes
--;
105 void lttng_index_allocator_destroy(struct lttng_index_allocator
*allocator
)
107 struct lttng_index
*index
= nullptr, *tmp_index
= nullptr;
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
));
118 cds_list_for_each_entry_safe (index
, tmp_index
, &allocator
->unused_list
, head
) {
119 cds_list_del(&index
->head
);