@@ -35,77 +35,6 @@ u64 OtelContexts::bytesToU64(const uint8_t* in) {
3535 return val;
3636}
3737
38- void OtelContexts::set (OtelThreadContextRecord* record, u64 trace_id_high, u64 trace_id_low, u64 span_id, u64 local_root_span_id) {
39- if (record == nullptr ) {
40- return ;
41- }
42-
43- // OTEP publication protocol:
44- // 1. Detach — external readers see no record during construction
45- __atomic_store_n (&custom_labels_current_set_v2, (OtelThreadContextRecord*)nullptr , __ATOMIC_RELEASE);
46-
47- // 2. Invalidate — internal readers (signal handlers using cached pointer) see invalid record
48- __atomic_store_n (&record->valid , (uint8_t )0 , __ATOMIC_RELEASE);
49-
50- // 3. Populate record fields
51- u64ToBytes (trace_id_high, record->trace_id );
52- u64ToBytes (trace_id_low, record->trace_id + 8 );
53- u64ToBytes (span_id, record->span_id );
54-
55- // 4. Rebuild attrs_data: preserve user entries (key_index != 0), replace LRS entry.
56- // LOCAL_ROOT_SPAN_ATTR_INDEX = 0 is reserved; user attrs use key_index >= 1.
57- // Use a temp buffer because source and destination regions overlap.
58- uint16_t old_size = record->attrs_data_size ;
59- uint8_t user_buf[OTEL_MAX_ATTRS_DATA_SIZE];
60- uint16_t user_size = 0 ;
61-
62- uint16_t pos = 0 ;
63- while (pos + 2 <= old_size) {
64- uint8_t k = record->attrs_data [pos];
65- uint8_t len = record->attrs_data [pos + 1 ];
66- if (pos + 2 + len > old_size) break ;
67- if (k != 0 ) {
68- memcpy (user_buf + user_size, record->attrs_data + pos, 2 + len);
69- user_size += 2 + len;
70- }
71- pos += 2 + len;
72- }
73-
74- uint16_t new_size = 0 ;
75-
76- // Write local_root_span_id as decimal string attribute at reserved index 0
77- if (local_root_span_id != 0 ) {
78- // Max digits for u64: 20 ("18446744073709551615"). Entry = 2 + digits.
79- uint8_t digits[20 ];
80- int ndigits = 0 ;
81- u64 v = local_root_span_id;
82- do {
83- digits[ndigits++] = ' 0' + (v % 10 );
84- v /= 10 ;
85- } while (v > 0 );
86- record->attrs_data [0 ] = 0 ; // key_index = LOCAL_ROOT_SPAN_ATTR_INDEX
87- record->attrs_data [1 ] = ndigits; // length
88- for (int i = 0 ; i < ndigits; i++) {
89- record->attrs_data [2 + i] = digits[ndigits - 1 - i]; // reverse into big-endian order
90- }
91- new_size = 2 + ndigits;
92- }
93-
94- // Re-append preserved user entries
95- if (user_size > 0 && new_size + user_size <= OTEL_MAX_ATTRS_DATA_SIZE) {
96- memcpy (record->attrs_data + new_size, user_buf, user_size);
97- new_size += user_size;
98- }
99-
100- record->attrs_data_size = new_size;
101-
102- // 5. Mark record valid
103- __atomic_store_n (&record->valid , (uint8_t )1 , __ATOMIC_RELEASE);
104-
105- // 6. Attach — publish completed record
106- __atomic_store_n (&custom_labels_current_set_v2, record, __ATOMIC_RELEASE);
107- }
108-
10938bool OtelContexts::getSpanId (OtelThreadContextRecord* record, u64 & span_id) {
11039 if (record == nullptr ) {
11140 return false ;
@@ -117,67 +46,3 @@ bool OtelContexts::getSpanId(OtelThreadContextRecord* record, u64& span_id) {
11746 return true ;
11847}
11948
120- bool OtelContexts::setAttribute (OtelThreadContextRecord* record, uint8_t key_index, const char * value, uint8_t value_len) {
121- if (record == nullptr ) {
122- return false ;
123- }
124-
125- // Entry size: 1 (key_index) + 1 (length) + value_len
126- uint16_t entry_size = 2 + value_len;
127- uint16_t current_size = record->attrs_data_size ;
128-
129- // Detach (external readers) and invalidate (signal handler readers)
130- __atomic_store_n (&custom_labels_current_set_v2, (OtelThreadContextRecord*)nullptr , __ATOMIC_RELEASE);
131- __atomic_store_n (&record->valid , (uint8_t )0 , __ATOMIC_RELEASE);
132-
133- // Scan for duplicate key and compact if found
134- uint16_t read_pos = 0 ;
135- uint16_t write_pos = 0 ;
136- bool found = false ;
137- while (read_pos + 2 <= current_size) {
138- uint8_t k = record->attrs_data [read_pos];
139- uint8_t len = record->attrs_data [read_pos + 1 ];
140- if (read_pos + 2 + len > current_size) break ; // corrupt length guard
141- if (k == key_index) {
142- found = true ;
143- read_pos += 2 + len;
144- } else {
145- if (found && write_pos < read_pos) {
146- memmove (record->attrs_data + write_pos, record->attrs_data + read_pos, 2 + len);
147- }
148- write_pos += 2 + len;
149- read_pos += 2 + len;
150- }
151- }
152- if (found) {
153- current_size = write_pos;
154- }
155-
156- // Re-check fit after compaction
157- if (current_size + entry_size > OTEL_MAX_ATTRS_DATA_SIZE) {
158- record->attrs_data_size = current_size;
159- __atomic_store_n (&record->valid , (uint8_t )1 , __ATOMIC_RELEASE);
160- __atomic_store_n (&custom_labels_current_set_v2, record, __ATOMIC_RELEASE);
161- return false ;
162- }
163-
164- // Append the new entry
165- record->attrs_data [current_size] = key_index;
166- record->attrs_data [current_size + 1 ] = value_len;
167- memcpy (record->attrs_data + current_size + 2 , value, value_len);
168- record->attrs_data_size = current_size + entry_size;
169-
170- // Re-publish
171- __atomic_store_n (&record->valid , (uint8_t )1 , __ATOMIC_RELEASE);
172- __atomic_store_n (&custom_labels_current_set_v2, record, __ATOMIC_RELEASE);
173- return true ;
174- }
175-
176- void OtelContexts::clear (OtelThreadContextRecord* record) {
177- if (record != nullptr ) {
178- __atomic_store_n (&record->valid , (uint8_t )0 , __ATOMIC_RELEASE);
179- record->attrs_data_size = 0 ;
180- }
181- // OTEP context detachment: set TLS pointer to nullptr
182- __atomic_store_n (&custom_labels_current_set_v2, (OtelThreadContextRecord*)nullptr , __ATOMIC_RELEASE);
183- }
0 commit comments