Fix: waiter: futex wait: handle spurious futex wakeups
[lttng-tools.git] / src / common / index-allocator.cpp
CommitLineData
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
246611b0
FD
8#include <inttypes.h>
9
10#include <urcu.h>
11#include <urcu/list.h>
12
c9e313bc
SM
13#include "macros.hpp"
14#include "error.hpp"
246611b0 15
c9e313bc 16#include "index-allocator.hpp"
246611b0
FD
17
18struct lttng_index_allocator {
19 struct cds_list_head unused_list;
20 uint64_t size;
21 uint64_t position;
5e09ab50 22 uint64_t nb_allocated_indexes;
246611b0
FD
23};
24
f1494934 25namespace {
246611b0
FD
26struct lttng_index {
27 uint64_t index;
28 struct cds_list_head head;
29};
f1494934 30} /* namespace */
246611b0
FD
31
32struct lttng_index_allocator *lttng_index_allocator_create(
33 uint64_t index_count)
34{
35 struct lttng_index_allocator *allocator = NULL;
36
64803277 37 allocator = zmalloc<lttng_index_allocator>();
246611b0
FD
38 if (!allocator) {
39 PERROR("Failed to allocate index allocator");
40 goto end;
41 }
42
43 allocator->size = index_count;
44 allocator->position = 0;
5e09ab50 45 allocator->nb_allocated_indexes = 0;
246611b0
FD
46
47 CDS_INIT_LIST_HEAD(&allocator->unused_list);
48
49end:
50 return allocator;
51}
52
53uint64_t lttng_index_allocator_get_index_count(struct lttng_index_allocator *allocator)
54{
5e09ab50 55 return allocator->nb_allocated_indexes;
246611b0
FD
56}
57
58enum lttng_index_allocator_status lttng_index_allocator_alloc(
59 struct lttng_index_allocator *allocator,
60 uint64_t *allocated_index)
61{
62 enum lttng_index_allocator_status status =
63 LTTNG_INDEX_ALLOCATOR_STATUS_OK;
64
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;
69 goto end;
70 }
71
72 *allocated_index = allocator->position++;
73 } else {
74 struct lttng_index *index;
75
76 index = cds_list_first_entry(&allocator->unused_list,
77 typeof(*index), head);
78 cds_list_del(&index->head);
79 *allocated_index = index->index;
80 free(index);
81 }
82
5e09ab50 83 allocator->nb_allocated_indexes++;
246611b0
FD
84end:
85 return status;
86}
87
88enum lttng_index_allocator_status lttng_index_allocator_release(
89 struct lttng_index_allocator *allocator, uint64_t idx)
90{
91 struct lttng_index *index = NULL;
92 enum lttng_index_allocator_status status =
93 LTTNG_INDEX_ALLOCATOR_STATUS_OK;
94
a0377dfe 95 LTTNG_ASSERT(idx < allocator->size);
246611b0 96
64803277 97 index = zmalloc<lttng_index>();
246611b0
FD
98 if (!index) {
99 PERROR("Failed to allocate free index queue");
100 status = LTTNG_INDEX_ALLOCATOR_STATUS_ERROR;
101 goto end;
102 }
103
104 index->index = idx;
105 cds_list_add_tail(&index->head, &allocator->unused_list);
5e09ab50 106 allocator->nb_allocated_indexes--;
246611b0
FD
107
108end:
109 return status;
110}
111
112void lttng_index_allocator_destroy(struct lttng_index_allocator *allocator)
113{
114 struct lttng_index *index = NULL, *tmp_index = NULL;
115
116 if (!allocator) {
117 return;
118 }
119
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));
124 }
125
126 cds_list_for_each_entry_safe(index, tmp_index,
127 &allocator->unused_list, head) {
128 cds_list_del(&index->head);
129 free(index);
130 }
131
132 free(allocator);
133}
This page took 0.040692 seconds and 4 git commands to generate.