2 * Copyright (C) 2020 Francis Deslauriers <francis.deslauriers@efficios.com>
4 * SPDX-License-Identifier: GPL-2.0-only
12 #include <urcu/list.h>
17 #include "index-allocator.h"
19 struct lttng_index_allocator
{
20 struct cds_list_head unused_list
;
23 uint64_t nb_allocated_indexes
;
28 struct cds_list_head head
;
31 struct lttng_index_allocator
*lttng_index_allocator_create(
34 struct lttng_index_allocator
*allocator
= NULL
;
36 allocator
= zmalloc(sizeof(*allocator
));
38 PERROR("Failed to allocate index allocator");
42 allocator
->size
= index_count
;
43 allocator
->position
= 0;
44 allocator
->nb_allocated_indexes
= 0;
46 CDS_INIT_LIST_HEAD(&allocator
->unused_list
);
52 uint64_t lttng_index_allocator_get_index_count(struct lttng_index_allocator
*allocator
)
54 return allocator
->nb_allocated_indexes
;
57 enum lttng_index_allocator_status
lttng_index_allocator_alloc(
58 struct lttng_index_allocator
*allocator
,
59 uint64_t *allocated_index
)
61 enum lttng_index_allocator_status status
=
62 LTTNG_INDEX_ALLOCATOR_STATUS_OK
;
64 if (cds_list_empty(&allocator
->unused_list
)) {
65 if (allocator
->position
>= allocator
->size
) {
66 /* No indices left. */
67 status
= LTTNG_INDEX_ALLOCATOR_STATUS_EMPTY
;
71 *allocated_index
= allocator
->position
++;
73 struct lttng_index
*index
;
75 index
= cds_list_first_entry(&allocator
->unused_list
,
76 typeof(*index
), head
);
77 cds_list_del(&index
->head
);
78 *allocated_index
= index
->index
;
82 allocator
->nb_allocated_indexes
++;
87 enum lttng_index_allocator_status
lttng_index_allocator_release(
88 struct lttng_index_allocator
*allocator
, uint64_t idx
)
90 struct lttng_index
*index
= NULL
;
91 enum lttng_index_allocator_status status
=
92 LTTNG_INDEX_ALLOCATOR_STATUS_OK
;
94 assert(idx
< allocator
->size
);
96 index
= zmalloc(sizeof(*index
));
98 PERROR("Failed to allocate free index queue");
99 status
= LTTNG_INDEX_ALLOCATOR_STATUS_ERROR
;
104 cds_list_add_tail(&index
->head
, &allocator
->unused_list
);
105 allocator
->nb_allocated_indexes
--;
111 void lttng_index_allocator_destroy(struct lttng_index_allocator
*allocator
)
113 struct lttng_index
*index
= NULL
, *tmp_index
= NULL
;
119 if (lttng_index_allocator_get_index_count(allocator
) > 0) {
120 WARN("Destroying index allocator with %" PRIu64
121 " slot indexes still in use",
122 lttng_index_allocator_get_index_count(allocator
));
125 cds_list_for_each_entry_safe(index
, tmp_index
,
126 &allocator
->unused_list
, head
) {
127 cds_list_del(&index
->head
);