3d62317ac76d7a6fbe2d731a9991aa788181db78
[lttng-tools.git] / src / bin / lttng-relayd / tracefile-array.c
1 /*
2 * Copyright (C) 2015 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License, version 2 only, as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 51
15 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 */
17
18 #define _LGPL_SOURCE
19 #include <assert.h>
20 #include <common/common.h>
21 #include <common/utils.h>
22 #include <common/defaults.h>
23
24 #include "tracefile-array.h"
25
26 struct tracefile_array *tracefile_array_create(size_t count)
27 {
28 struct tracefile_array *tfa = NULL;
29 int i;
30
31 tfa = zmalloc(sizeof(*tfa));
32 if (!tfa) {
33 goto error;
34 }
35 tfa->tf = zmalloc(sizeof(*tfa->tf) * count);
36 if (!tfa->tf) {
37 goto error;
38 }
39 tfa->count = count;
40 for (i = 0; i < count; i++) {
41 tfa->tf[i].seq_head = -1ULL;
42 tfa->tf[i].seq_tail = -1ULL;
43 }
44 tfa->seq_head = -1ULL;
45 tfa->seq_tail = -1ULL;
46 return tfa;
47
48 error:
49 if (tfa) {
50 free(tfa->tf);
51 }
52 free(tfa);
53 return NULL;
54 }
55
56 void tracefile_array_destroy(struct tracefile_array *tfa)
57 {
58 if (!tfa) {
59 return;
60 }
61 free(tfa->tf);
62 free(tfa);
63 }
64
65 void tracefile_array_file_rotate(struct tracefile_array *tfa,
66 enum tracefile_rotate_type type)
67 {
68 uint64_t *headp, *tailp;
69
70 if (!tfa->count) {
71 /* Not in tracefile rotation mode. */
72 return;
73 }
74 switch (type) {
75 case TRACEFILE_ROTATE_READ:
76 /*
77 * Rotate read head to write head position, thus allowing
78 * reader to consume the newly rotated head file.
79 */
80 tfa->file_head_read = tfa->file_head_write;
81 break;
82 case TRACEFILE_ROTATE_WRITE:
83 /* Rotate write head to next file, pushing tail if needed. */
84 tfa->file_head_write = (tfa->file_head_write + 1) % tfa->count;
85 if (tfa->file_head_write == tfa->file_tail) {
86 /* Move tail. */
87 tfa->file_tail = (tfa->file_tail + 1) % tfa->count;
88 }
89 headp = &tfa->tf[tfa->file_head_write].seq_head;
90 tailp = &tfa->tf[tfa->file_head_write].seq_tail;
91 /*
92 * If we overwrite a file with content, we need to push the tail
93 * to the position following the content we are overwriting.
94 */
95 if (*headp != -1ULL) {
96 tfa->seq_tail = tfa->tf[tfa->file_tail].seq_tail;
97 }
98 /* Reset this file head/tail (overwrite). */
99 *headp = -1ULL;
100 *tailp = -1ULL;
101 break;
102 default:
103 abort();
104 }
105 }
106
107 void tracefile_array_commit_seq(struct tracefile_array *tfa)
108 {
109 uint64_t *headp, *tailp;
110
111 /* Increment overall head. */
112 tfa->seq_head++;
113 /* If we are committing our first index overall, set tail to 0. */
114 if (tfa->seq_tail == -1ULL) {
115 tfa->seq_tail = 0;
116 }
117 if (!tfa->count) {
118 /* Not in tracefile rotation mode. */
119 return;
120 }
121 headp = &tfa->tf[tfa->file_head_write].seq_head;
122 tailp = &tfa->tf[tfa->file_head_write].seq_tail;
123 /* Update head tracefile seq_head. */
124 *headp = tfa->seq_head;
125 /*
126 * If we are committing our first index in this packet, set tail
127 * to this index seq count.
128 */
129 if (*tailp == -1ULL) {
130 *tailp = tfa->seq_head;
131 }
132 }
133
134 uint64_t tracefile_array_get_read_file_index_head(struct tracefile_array *tfa)
135 {
136 return tfa->file_head_read;
137 }
138
139 uint64_t tracefile_array_get_seq_head(struct tracefile_array *tfa)
140 {
141 return tfa->seq_head;
142 }
143
144 uint64_t tracefile_array_get_file_index_tail(struct tracefile_array *tfa)
145 {
146 return tfa->file_tail;
147 }
148
149 uint64_t tracefile_array_get_seq_tail(struct tracefile_array *tfa)
150 {
151 return tfa->seq_tail;
152 }
153
154 bool tracefile_array_seq_in_file(struct tracefile_array *tfa,
155 uint64_t file_index, uint64_t seq)
156 {
157 if (!tfa->count) {
158 /*
159 * Not in tracefile rotation mode; we are guaranteed to have the
160 * index in this file.
161 */
162 return true;
163 }
164 assert(file_index < tfa->count);
165 if (seq == -1ULL) {
166 return false;
167 }
168 if (seq >= tfa->tf[file_index].seq_tail
169 && seq <= tfa->tf[file_index].seq_head) {
170 return true;
171 } else {
172 return false;
173 }
174 }
This page took 0.046795 seconds and 3 git commands to generate.