GCC Code Coverage Report


Directory: csrc/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 62 / 0 / 62
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 34 size_t EVT21_state_size(void) {
21 34 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 245 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 245 const uint64_t *restrict current = input_buffer->begin;
44 245 const uint64_t *restrict end = input_buffer->end;
45
46 // Event output buffers
47 245 size_t n_events_read = event_buffer->size;
48 245 const size_t events_capacity = event_buffer->capacity;
49 245 const size_t events_capacity_offset =
50 245 events_capacity > EVT21_MAX_VECTOR_EVENTS ? events_capacity - EVT21_MAX_VECTOR_EVENTS : 0;
51
52 245 timestamp_t* restrict out_ts = event_buffer->t;
53 245 uint16_t* restrict out_x = event_buffer->x;
54 245 uint16_t* restrict out_y = event_buffer->y;
55 245 uint8_t* restrict out_p = event_buffer->p;
56
57 // Trigger output buffers
58 245 timestamp_t* restrict trigger_ts = trigger_buffer->t;
59 245 uint8_t* restrict trigger_id = trigger_buffer->id;
60 245 uint8_t* restrict trigger_p = trigger_buffer->p;
61
62 245 size_t n_triggers_read = trigger_buffer->size;
63 245 const size_t triggers_capacity = trigger_buffer->capacity;
64
65 // State variables
66 245 uint64_t last_ts_high = state->last_ts_high;
67 245 uint64_t ts_high_high = state->ts_high_high;
68
69 245 parse_status_t status = EVUTILS_PARSE_OK;
70
71 245 while(
72 42663601 current < end &&
73 85327001 n_events_read < events_capacity_offset &&
74 n_triggers_read < triggers_capacity
75 ) {
76 42663378 const uint64_t word = *current;
77 42663378 current++;
78
79 // 31-28 type
80 42663378 uint64_t type = (word & 0xF0000000) >> 28;
81
82 // 27-22 ts (6 low bits of the time base)
83 42663378 uint64_t ts = ts_high_high | last_ts_high | ((word & 0x0FC00000) >> 22);
84
85 // 21-11 x (11 bits)
86 42663378 uint64_t x = (word & 0x003FF800) >> 11;
87
88 // 10-0 y (11 bits)
89 42663378 uint64_t y = (word & 0x000007FF);
90
91 // upper 32 bits: per-column validity mask
92 42663378 uint32_t valid = (uint32_t)(word >> 32);
93
94 42663378 if((type == EVT21_CD_OFF || type == EVT21_CD_ON)){
95 30617317 uint32_t p = !!type;
96 267524099 while(valid){
97 236906782 int lz = __builtin_ctz(valid);
98 236906782 valid &= valid - 1;
99
100 236906782 out_ts[n_events_read] = ts;
101 236906782 out_x[n_events_read] = (uint16_t)(x + lz);
102 236906782 out_y[n_events_read] = (uint16_t)y;
103 236906782 out_p[n_events_read] = (uint8_t)p;
104 236906782 n_events_read++;
105 }
106 30617317 continue;
107 }
108
109 12046061 switch(type){
110 10385928 case EVT21_EVT_TIME_HIGH:
111 {
112 10385928 uint64_t new_ts_high = (word & 0x0FFFFFFF) << 6;
113 10385928 if (new_ts_high < last_ts_high) {
114 2 ts_high_high += EVT21_TS_WRAP;
115 }
116 10385928 last_ts_high = new_ts_high;
117 }
118 10385928 break;
119 3 case EVT21_EXT_TRIGGER:
120 3 trigger_ts[n_triggers_read] = ts;
121 // Trigger id bits 44..40 (5 bits)
122 3 trigger_id[n_triggers_read] = (word >> 40) & 0x1F;
123 3 trigger_p[n_triggers_read] = (word >> 32) & 0x1;
124 3 n_triggers_read++;
125 3 break;
126 1660130 case EVT21_OTHERS:
127 default:
128 1660130 break;
129 }
130 }
131
132 245 event_buffer->size = n_events_read;
133 245 trigger_buffer->size = n_triggers_read;
134 245 state->last_ts_high = last_ts_high;
135 245 state->ts_high_high = ts_high_high;
136
137 245 return (parser_result_t){
138 .current = (const void *)current,
139 .status = status
140 };
141 }
142