C Microkernel Realtime eXecutive
Realtime Operating System for Cortex-M based microcontrollers
 
Loading...
Searching...
No Matches
algo.h
1#pragma once
2
3#include <stdint.h>
55#define BINARY_SEARCH(_ARRAY, _KEY, _VALUE, _SIZE) \
56({\
57 unsigned lower = 0, upper = (_SIZE);\
58 /* Binary search until range is small */\
59 while (upper - lower > 8) {\
60 unsigned mid = lower + ((upper - lower) >> 1);\
61 if (_ARRAY[mid]._KEY < _VALUE)\
62 lower = mid + 1;\
63 else\
64 upper = mid;\
65 }\
66 /* Linear scan for final elements */\
67 while (lower < upper && _ARRAY[lower]._KEY < _VALUE) {\
68 lower++;\
69 }\
70 lower;\
71})
72
82#define ARRAY_INSERT(_ARRAY, _POS, _SIZE) \
83 for (unsigned q = _SIZE; q > _POS; --q)\
84 {\
85 _ARRAY[q] = _ARRAY[q - 1];\
86 }\
87 _SIZE++;
88
97#define ARRAY_DELETE(_ARRAY, _POS, _SIZE) \
98 for (unsigned _q = _POS + 1; _q < _SIZE; ++_q)\
99 {\
100 _ARRAY[_q - 1] = _ARRAY[_q];\
101 }\
102 _SIZE--;
103
155#define INSERT_SORT(_ARRAY, _KEY, _VALUE, _SIZE, _MAX) \
156({\
157 unsigned pos = BINARY_SEARCH(_ARRAY, _KEY, _VALUE, _SIZE);\
158 if (((_ARRAY[pos]._KEY != _VALUE) || (pos == _SIZE)) \
159 && (_SIZE < _MAX)) \
160 {\
161 for (unsigned q = _SIZE; q > pos; --q)\
162 {\
163 _ARRAY[q] = _ARRAY[q - 1];\
164 }\
165 _SIZE++;\
166 }\
167 pos;\
168})
169
170#ifndef CMRX_USE_FAST_HASH
171/* Prospector-generated hash function.
172 * Source for constants: https://github.com/skeeto/hash-prospector/issues/19 */
173inline uint32_t os_hash_key(uint32_t key) {
174 key ^= key >> 16;
175 key *= 0x21f0aaadU;
176 key ^= key >> 15;
177 key *= 0xf35a2d97U;
178 key ^= key >> 15;
179 return key;
180}
181#else
182/* Minimal mixer */
183inline uint32_t os_hash_key(uint32_t key)
184{
185 key ^= key >> 16;
186 key *= 0x45D9F3BU;
187 key ^= key >> 16;
188 return key;
189}
190#endif
191
193#define HASH_EMPTY 0xFFFFFFFFU
194
233#define HASH_SEARCH(_HASHTABLE, _KEY, _VALUE, _MAX) \
234({\
235 _Static_assert(((_MAX) & ((_MAX) - 1)) == 0 && (_MAX) != 0, "HASH_SEARCH: _MAX must be a power of 2");\
236 const uint32_t hash = os_hash_key((uint32_t)_VALUE);\
237 const uint32_t mask = (_MAX) - 1;\
238 uint32_t pos = hash & mask;\
239 uint32_t stride = 1;\
240 while (_HASHTABLE[pos]._KEY != _VALUE && _HASHTABLE[pos]._KEY != (typeof(_HASHTABLE[0]._KEY)) HASH_EMPTY) {\
241 pos = (pos + stride) & mask;\
242 stride++;\
243 }\
244 pos;\
245})
246
254#define BITMAP_SET(_BITMAP, _POS, _SIZE) _BITMAP[(_POS) >> 5] |= (1U << ((_POS) & 31));
255
263#define BITMAP_CLEAR(_BITMAP, _POS, _SIZE) _BITMAP[(_POS) >> 5] &= ~(1U << ((_POS) & 31));
264
272#define BITMAP_TEST(_BITMAP, _POS, _SIZE) ((_BITMAP[(_POS) >> 5] & (1U << ((_POS) & 31))) != 0)
273
281#define BITMAP_FIRST(_BITMAP, _SIZE) \
282({\
283 uint32_t first = ~0;\
284 for (unsigned word = 0; word < _SIZE; ++word) {\
285 uint32_t ready = _BITMAP[word];\
286 if (ready) {\
287 uint8_t bit = __builtin_ctz(ready);\
288 first = (word << 5) + bit;\
289 break;\
290 }\
291 }\
292 first;\
293})
294#define BITMAP_COPY(_TARGET, _SOURCE, _SIZE) \
295 for (unsigned q = 0; q < _SIZE; ++q) _TARGET[q] = _SOURCE[q];
296
297
298/* }@ */
uint32_t os_hash_key(uint32_t key)
Definition algo.h:173