Tests: Add test to check shared-memory FD leaks after relayd dies
[lttng-tools.git] / src / bin / lttng-relayd / tracefile-array.cpp
1 /*
2 * Copyright (C) 2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8 #define _LGPL_SOURCE
9 #include "tracefile-array.hpp"
10
11 #include <common/common.hpp>
12 #include <common/defaults.hpp>
13 #include <common/utils.hpp>
14
15 struct tracefile_array *tracefile_array_create(size_t count)
16 {
17 struct tracefile_array *tfa = nullptr;
18 int i;
19
20 tfa = zmalloc<tracefile_array>();
21 if (!tfa) {
22 goto error;
23 }
24 tfa->tf = calloc<tracefile>(count);
25 if (!tfa->tf) {
26 goto error;
27 }
28 tfa->count = count;
29 for (i = 0; i < count; i++) {
30 tfa->tf[i].seq_head = -1ULL;
31 tfa->tf[i].seq_tail = -1ULL;
32 }
33 tfa->seq_head = -1ULL;
34 tfa->seq_tail = -1ULL;
35 return tfa;
36
37 error:
38 if (tfa) {
39 free(tfa->tf);
40 }
41 free(tfa);
42 return nullptr;
43 }
44
45 void tracefile_array_destroy(struct tracefile_array *tfa)
46 {
47 if (!tfa) {
48 return;
49 }
50 free(tfa->tf);
51 free(tfa);
52 }
53
54 void tracefile_array_reset(struct tracefile_array *tfa)
55 {
56 size_t count, i;
57
58 count = tfa->count;
59 for (i = 0; i < count; i++) {
60 tfa->tf[i].seq_head = -1ULL;
61 tfa->tf[i].seq_tail = -1ULL;
62 }
63 tfa->seq_head = -1ULL;
64 tfa->seq_tail = -1ULL;
65 tfa->file_head_read = 0;
66 tfa->file_head_write = 0;
67 tfa->file_tail = 0;
68 }
69
70 void tracefile_array_file_rotate(struct tracefile_array *tfa, enum tracefile_rotate_type type)
71 {
72 uint64_t *headp, *tailp;
73
74 if (!tfa->count) {
75 /* Not in tracefile rotation mode. */
76 return;
77 }
78 switch (type) {
79 case TRACEFILE_ROTATE_READ:
80 /*
81 * Rotate read head to write head position, thus allowing
82 * reader to consume the newly rotated head file.
83 */
84 tfa->file_head_read = tfa->file_head_write;
85 break;
86 case TRACEFILE_ROTATE_WRITE:
87 /* Rotate write head to next file, pushing tail if needed. */
88 tfa->file_head_write = (tfa->file_head_write + 1) % tfa->count;
89 if (tfa->file_head_write == tfa->file_tail) {
90 /* Move tail. */
91 tfa->file_tail = (tfa->file_tail + 1) % tfa->count;
92 }
93 headp = &tfa->tf[tfa->file_head_write].seq_head;
94 tailp = &tfa->tf[tfa->file_head_write].seq_tail;
95 /*
96 * If we overwrite a file with content, we need to push the tail
97 * to the position following the content we are overwriting.
98 */
99 if (*headp != -1ULL) {
100 tfa->seq_tail = tfa->tf[tfa->file_tail].seq_tail;
101 }
102 /* Reset this file head/tail (overwrite). */
103 *headp = -1ULL;
104 *tailp = -1ULL;
105 break;
106 default:
107 abort();
108 }
109 }
110
111 void tracefile_array_commit_seq(struct tracefile_array *tfa, uint64_t new_seq_head)
112 {
113 uint64_t *headp, *tailp;
114
115 /* Increment overall head. */
116 tfa->seq_head = new_seq_head;
117 /* If we are committing our first index overall, set tail to head. */
118 if (tfa->seq_tail == -1ULL) {
119 tfa->seq_tail = new_seq_head;
120 }
121 if (!tfa->count) {
122 /* Not in tracefile rotation mode. */
123 return;
124 }
125 headp = &tfa->tf[tfa->file_head_write].seq_head;
126 tailp = &tfa->tf[tfa->file_head_write].seq_tail;
127 /* Update head tracefile seq_head. */
128 *headp = tfa->seq_head;
129 /*
130 * If we are committing our first index in this packet, set tail
131 * to this index seq count.
132 */
133 if (*tailp == -1ULL) {
134 *tailp = tfa->seq_head;
135 }
136 }
137
138 uint64_t tracefile_array_get_read_file_index_head(struct tracefile_array *tfa)
139 {
140 return tfa->file_head_read;
141 }
142
143 uint64_t tracefile_array_get_seq_head(struct tracefile_array *tfa)
144 {
145 return tfa->seq_head;
146 }
147
148 uint64_t tracefile_array_get_file_index_tail(struct tracefile_array *tfa)
149 {
150 return tfa->file_tail;
151 }
152
153 uint64_t tracefile_array_get_seq_tail(struct tracefile_array *tfa)
154 {
155 return tfa->seq_tail;
156 }
157
158 bool tracefile_array_seq_in_file(struct tracefile_array *tfa, uint64_t file_index, uint64_t seq)
159 {
160 if (!tfa->count) {
161 /*
162 * Not in tracefile rotation mode; we are guaranteed to have the
163 * index in this file.
164 */
165 return true;
166 }
167 LTTNG_ASSERT(file_index < tfa->count);
168 if (seq == -1ULL) {
169 return false;
170 }
171 return seq >= tfa->tf[file_index].seq_tail && seq <= tfa->tf[file_index].seq_head;
172 }
This page took 0.031834 seconds and 4 git commands to generate.