GCC Code Coverage Report


Directory: csrc/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 64 / 0 / 64
Functions: 100.0% 1 / 0 / 1
Branches: -% 0 / 0 / 0

evt21.c
Line Branch Exec Source
1 #include "evutils/evt21.h"
2
3
4 enum EVT21_PacketType{
5 EVT21_CD_OFF = 0x0,
6 EVT21_CD_ON = 0x1,
7 EVT21_EVT_TIME_HIGH = 0x8,
8 EVT21_EXT_TRIGGER = 0xA,
9 EVT21_OTHERS = 0xE,
10 };
11
12
13
14 typedef struct evt21_state_s {
15 uint64_t last_ts_high; /* current TIME_HIGH << 6 (bits 6..33) */
16 uint64_t ts_high_high; /* accumulated overflow of the 28-bit field (34+) */
17 } evt21_state_t;
18
19
20 62 size_t EVT21_state_size(void) {
21 62 return sizeof(evt21_state_t);
22 }
23
24 /* The TIME_HIGH field is 28 bits carrying time base bits 6..33, so it wraps at
25 * 2^34. Bump the overflow accumulator by 2^34 on each wrap. */
26 #define EVT21_TS_WRAP (1ULL << 34)
27
28
29 /* A single CD vector packet can emit up to 32 events (one per valid bit), so we
30 * stop the main loop this far from capacity to guarantee the inner emit never
31 * overruns the output buffer. */
32 #define EVT21_MAX_VECTOR_EVENTS 32
33
34
35 EVUTILS_TARGET_CLONES
36 307 parser_result_t EVT21_parse_chunk_soa(
37 evt21_state_t *state,
38 const evt21_input_buffer_t *input_buffer,
39 event_buffer_soa_t *event_buffer,
40 trigger_buffer_soa_t *trigger_buffer)
41 {
42
43 307 const uint64_t *restrict current = input_buffer->begin;
44 307 const uint64_t *restrict end = input_buffer->end;
45
46 // Event output buffers
47 307 size_t n_events_read = event_buffer->size;
48 307 const size_t events_capacity = event_buffer->capacity;
49 307 const size_t events_capacity_offset =
50 307 events_capacity > EVT21_MAX_VECTOR_EVENTS ? events_capacity - EVT21_MAX_VECTOR_EVENTS : 0;
51
52 307 timestamp_t* restrict out_ts = event_buffer->t;
53 307 uint16_t* restrict out_x = event_buffer->x;
54 307 uint16_t* restrict out_y = event_buffer->y;
55 307 uint8_t* restrict out_p = event_buffer->p;
56
57 // Trigger output buffers
58 307 timestamp_t* restrict trigger_ts = trigger_buffer->t;
59 307 uint8_t* restrict trigger_id = trigger_buffer->id;
60 307 uint8_t* restrict trigger_p = trigger_buffer->p;
61
62 307 size_t n_triggers_read = trigger_buffer->size;
63 307 const size_t triggers_capacity = trigger_buffer->capacity;
64
65 // State variables
66 307 uint64_t last_ts_high = state->last_ts_high;
67 307 uint64_t ts_high_high = state->ts_high_high;
68
69 307 parse_status_t status = EVUTILS_PARSE_OK;
70
71 307 while(
72 38362318 current < end &&
73 76724429 n_events_read < events_capacity_offset &&
74 n_triggers_read < triggers_capacity
75 ) {
76 38362061 const uint64_t word = *current;
77 38362061 current++;
78
79 // 31-28 type
80 38362061 uint64_t type = (word & 0xF0000000) >> 28;
81
82 // 27-22 ts (6 low bits of the time base)
83 38362061 uint64_t ts = ts_high_high | last_ts_high | ((word & 0x0FC00000) >> 22);
84
85 // 21-11 x (11 bits)
86 38362061 uint64_t x = (word & 0x003FF800) >> 11;
87
88 // 10-0 y (11 bits)
89 38362061 uint64_t y = (word & 0x000007FF);
90
91 // upper 32 bits: per-column validity mask
92 38362061 uint32_t valid = (uint32_t)(word >> 32);
93
94 38362061 if((type == EVT21_CD_OFF || type == EVT21_CD_ON)){
95 28070907 uint32_t p = !!type;
96 260174395 while(valid){
97 232103488 int lz = __builtin_ctz(valid);
98 232103488 valid &= valid - 1;
99
100 232103488 out_ts[n_events_read] = ts;
101 232103488 out_x[n_events_read] = (uint16_t)(x + lz);
102 232103488 out_y[n_events_read] = (uint16_t)y;
103 232103488 out_p[n_events_read] = (uint8_t)p;
104 232103488 n_events_read++;
105 }
106 28070907 continue;
107 }
108
109 10291154 switch(type){
110 8942217 case EVT21_EVT_TIME_HIGH:
111 {
112 8942217 uint64_t new_ts_high = (word & 0x0FFFFFFF) << 6;
113 8942217 if (new_ts_high < last_ts_high) {
114 393 ts_high_high += EVT21_TS_WRAP;
115 }
116 8942217 last_ts_high = new_ts_high;
117 }
118 8942217 break;
119 801 case EVT21_EXT_TRIGGER:
120 801 trigger_ts[n_triggers_read] = ts;
121 // Trigger id bits 44..40 (5 bits)
122 801 trigger_id[n_triggers_read] = (word >> 40) & 0x1F;
123 801 trigger_p[n_triggers_read] = (word >> 32) & 0x1;
124 801 n_triggers_read++;
125 801 break;
126 1348136 case EVT21_OTHERS:
127 default:
128 1348136 break;
129 }
130 }
131
132 307 event_buffer->size = n_events_read;
133 307 trigger_buffer->size = n_triggers_read;
134 307 state->last_ts_high = last_ts_high;
135 307 state->ts_high_high = ts_high_high;
136
137 /* Report why parsing stopped: output space exhausted vs input drained. */
138 307 if (n_events_read >= events_capacity_offset || n_triggers_read >= triggers_capacity) {
139 257 status = EVUTILS_PARSE_OUTPUT_FULL;
140 }
141
142 307 return (parser_result_t){
143 .current = (const void *)current,
144 .status = status
145 };
146 }
147