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
;
28 struct cds_list_head head
;
32 struct lttng_index_allocator
*lttng_index_allocator_create(
35 struct lttng_index_allocator
*allocator
= NULL
;
37 allocator
= zmalloc
<lttng_index_allocator
>();
39 PERROR("Failed to allocate index allocator");
43 allocator
->size
= index_count
;
44 allocator
->position
= 0;
45 allocator
->nb_allocated_indexes
= 0;
47 CDS_INIT_LIST_HEAD(&allocator
->unused_list
);
53 uint64_t lttng_index_allocator_get_index_count(struct lttng_index_allocator
*allocator
)
55 return allocator
->nb_allocated_indexes
;
58 enum lttng_index_allocator_status
lttng_index_allocator_alloc(
59 struct lttng_index_allocator
*allocator
,
60 uint64_t *allocated_index
)
62 enum lttng_index_allocator_status status
=
63 LTTNG_INDEX_ALLOCATOR_STATUS_OK
;
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
;
72 *allocated_index
= allocator
->position
++;
74 struct lttng_index
*index
;
76 index
= cds_list_first_entry(&allocator
->unused_list
,
77 typeof(*index
), head
);
78 cds_list_del(&index
->head
);
79 *allocated_index
= index
->index
;
83 allocator
->nb_allocated_indexes
++;
88 enum lttng_index_allocator_status
lttng_index_allocator_release(
89 struct lttng_index_allocator
*allocator
, uint64_t idx
)
91 struct lttng_index
*index
= NULL
;
92 enum lttng_index_allocator_status status
=
93 LTTNG_INDEX_ALLOCATOR_STATUS_OK
;
95 LTTNG_ASSERT(idx
< allocator
->size
);
97 index
= zmalloc
<lttng_index
>();
99 PERROR("Failed to allocate free index queue");
100 status
= LTTNG_INDEX_ALLOCATOR_STATUS_ERROR
;
105 cds_list_add_tail(&index
->head
, &allocator
->unused_list
);
106 allocator
->nb_allocated_indexes
--;
112 void lttng_index_allocator_destroy(struct lttng_index_allocator
*allocator
)
114 struct lttng_index
*index
= NULL
, *tmp_index
= NULL
;
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
));
126 cds_list_for_each_entry_safe(index
, tmp_index
,
127 &allocator
->unused_list
, head
) {
128 cds_list_del(&index
->head
);