2 * Copyright (C) 2015 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
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.
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
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.
20 #include <common/common.h>
21 #include <common/utils.h>
22 #include <common/defaults.h>
24 #include "tracefile-array.h"
26 struct tracefile_array
*tracefile_array_create(size_t count
)
28 struct tracefile_array
*tfa
= NULL
;
31 tfa
= zmalloc(sizeof(*tfa
));
35 tfa
->tf
= zmalloc(sizeof(*tfa
->tf
) * count
);
40 for (i
= 0; i
< count
; i
++) {
41 tfa
->tf
[i
].seq_head
= -1ULL;
42 tfa
->tf
[i
].seq_tail
= -1ULL;
44 tfa
->seq_head
= -1ULL;
45 tfa
->seq_tail
= -1ULL;
56 void tracefile_array_destroy(struct tracefile_array
*tfa
)
65 void tracefile_array_reset(struct tracefile_array
*tfa
)
70 for (i
= 0; i
< count
; i
++) {
71 tfa
->tf
[i
].seq_head
= -1ULL;
72 tfa
->tf
[i
].seq_tail
= -1ULL;
74 tfa
->seq_head
= -1ULL;
75 tfa
->seq_tail
= -1ULL;
76 tfa
->file_head_read
= 0;
77 tfa
->file_head_write
= 0;
81 void tracefile_array_file_rotate(struct tracefile_array
*tfa
,
82 enum tracefile_rotate_type type
)
84 uint64_t *headp
, *tailp
;
87 /* Not in tracefile rotation mode. */
91 case TRACEFILE_ROTATE_READ
:
93 * Rotate read head to write head position, thus allowing
94 * reader to consume the newly rotated head file.
96 tfa
->file_head_read
= tfa
->file_head_write
;
98 case TRACEFILE_ROTATE_WRITE
:
99 /* Rotate write head to next file, pushing tail if needed. */
100 tfa
->file_head_write
= (tfa
->file_head_write
+ 1) % tfa
->count
;
101 if (tfa
->file_head_write
== tfa
->file_tail
) {
103 tfa
->file_tail
= (tfa
->file_tail
+ 1) % tfa
->count
;
105 headp
= &tfa
->tf
[tfa
->file_head_write
].seq_head
;
106 tailp
= &tfa
->tf
[tfa
->file_head_write
].seq_tail
;
108 * If we overwrite a file with content, we need to push the tail
109 * to the position following the content we are overwriting.
111 if (*headp
!= -1ULL) {
112 tfa
->seq_tail
= tfa
->tf
[tfa
->file_tail
].seq_tail
;
114 /* Reset this file head/tail (overwrite). */
123 void tracefile_array_commit_seq(struct tracefile_array
*tfa
,
124 uint64_t new_seq_head
)
126 uint64_t *headp
, *tailp
;
128 /* Increment overall head. */
129 tfa
->seq_head
= new_seq_head
;
130 /* If we are committing our first index overall, set tail to head. */
131 if (tfa
->seq_tail
== -1ULL) {
132 tfa
->seq_tail
= new_seq_head
;
135 /* Not in tracefile rotation mode. */
138 headp
= &tfa
->tf
[tfa
->file_head_write
].seq_head
;
139 tailp
= &tfa
->tf
[tfa
->file_head_write
].seq_tail
;
140 /* Update head tracefile seq_head. */
141 *headp
= tfa
->seq_head
;
143 * If we are committing our first index in this packet, set tail
144 * to this index seq count.
146 if (*tailp
== -1ULL) {
147 *tailp
= tfa
->seq_head
;
151 uint64_t tracefile_array_get_read_file_index_head(struct tracefile_array
*tfa
)
153 return tfa
->file_head_read
;
156 uint64_t tracefile_array_get_seq_head(struct tracefile_array
*tfa
)
158 return tfa
->seq_head
;
161 uint64_t tracefile_array_get_file_index_tail(struct tracefile_array
*tfa
)
163 return tfa
->file_tail
;
166 uint64_t tracefile_array_get_seq_tail(struct tracefile_array
*tfa
)
168 return tfa
->seq_tail
;
171 bool tracefile_array_seq_in_file(struct tracefile_array
*tfa
,
172 uint64_t file_index
, uint64_t seq
)
176 * Not in tracefile rotation mode; we are guaranteed to have the
177 * index in this file.
181 assert(file_index
< tfa
->count
);
185 if (seq
>= tfa
->tf
[file_index
].seq_tail
186 && seq
<= tfa
->tf
[file_index
].seq_head
) {