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