1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
|
/* SPDX-License-Identifier: GPL-3.0-or-later */
/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */
#ifndef APOS_UTILS_H
#define APOS_UTILS_H
/**
* @file utils.h
* Misc utils and helpers.
*/
/**
* Get absolute value of expression.
*
* @param a Value to take the absolute value of.
* @return \c a if \c a >= 0, \c -a otherwise.
* \sideeffects
*/
#define ABS(a) (a < 0 ? -a : a)
/**
* Get the larger of two values.
*
* @param a First value.
* @param b Second value.
* @return \c a if \code a >= b \endcode, \c b otherwise.
* \sideeffects
*/
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
/**
* Get the largest of three values.
*
* @param a First value.
* @param b Second value.
* @param c Third value.
* @return Largest of the three values.
* \sideeffects
*/
#define MAX3(a, b, c) (MAX(a, b) >= MAX(b, c) ? MAX(a, b) : MAX(b, c))
/**
* Get the largest of four values.
*
* @param a First value.
* @param b Second value.
* @param c Third value.
* @param d Fourth value.
* @return Largest of the four values.
* \sideeffects
*/
#define MAX4(a, b, c, d) \
(MAX3(a, b, c) >= MAX3(b, c, d) ? MAX3(a, b, c) : MAX3(b, c, d))
/* etc... */
/**
* Get the smaller of two values.
*
* @param a First value.
* @param b Second value.
* @return The larger of the two values.
* \sideeffects
*/
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
/**
* Get the smallest of three values.
*
* @param a First value.
* @param b Second value.
* @param c Third value.
* @return The largest of the three values.
* \sideeffects
*/
#define MIN3(a, b, c) (MIN(a, b) <= MIN(b, c) ? MIN(a, b) : MIN(b, c))
/**
* Get the largest of four values.
*
* @param a First value.
* @param b Second value.
* @param c Third value.
* @param d Fourth value.
* @return The largest of the three values.
* \sideeffects
*/
#define MIN4(a, b, c, d) \
(MIN3(a, b, c) <= MIN3(b, c, d) ? MIN3(a, b, c) : MIN3(b, c, d))
/* etc... */
/**
* Helper for \ref GLUE().
* Makes sure any macros are expanded all the way.
*
* @param x Head part of the string.
* @param y Tail part of the string.
* \see GLUE().
*/
#define GLUE2(x, y) x##y
/**
* Glue two strings together.
*
* @param x Head part of the string.
* @param y Tail part of the string.
*/
#define GLUE(x, y) GLUE2(x, y)
/**
* Helper for \ref QUOTE().
* Makes sure any macros are expanded all the way.
*
* @param x String to be quoted.
* \see QUOTE().
*/
#define QUOTE2(x) #x
/**
* Quote string.
*
* @param x String to be quoted.
*/
#define QUOTE(x) QUOTE2(x)
/**
* Silence warnings about unused parameters.
*
* @param x Parameter that is unused.
*/
#define UNUSED(x) ((void)(x))
/**
* Semantic wrapper around \ref UNUSED().
* If something might be unused, depending on the configuration, it's more
* accurate to say that it might be unused rather than stating that it is
* unused.
*
* @param x Symbol that might be unused.
*/
#define MAYBE_UNUSED(x) UNUSED(x)
#include <apos/builtin.h>
/**
* Get offset of member inside structure.
*
* @param type Structure to look in.
* @param member Member whose offset to get.
* @return Offset of \c member in \c type.
*/
#if __has_builtin(__builtin_offsetof)
#define offsetof(type, member) __builtin_offsetof(type, member)
#else
#define offsetof(type, member) ((uintptr_t) &((type *)0)->member)
#endif
/**
* Signal to the compiler that some expression is likely to be true.
* Might aid in optimisation and branch prediction manipulation.
*
* @param x Expression that is likely to be true.
* @return Value of \c x.
*
* Example:
* \code if (likely(x)) { ... } \endcode
*
* \see unlikely()
*/
#if __has_builtin(__builtin_expect)
#define likely(x) __builtin_expect(!!(x), 1)
#else
#define likely(x) (x)
#endif
/**
* Signal to the compiler that some expression is unlikely to be true.
*
* @param x Expression that is unlikely to be true.
* @return Value of \c x.
*
* \see likely().
*/
#if __has_builtin(__builtin_expect)
#define unlikely(x) __builtin_expect(!!(x), 0)
#else
#define unlikely(x) (x)
#endif
/**
* Signal to the compiler that some region is unreachable.
* Mainly used for debugging with instrumentation, though it could provide some
* micro-optimisations.
*/
#if __has_builtin(__builtin_unreachable)
#define unreachable() __builtin_unreachable()
#else
#define unreachable()
#endif
/**
* Get container of some member.
*
* @param ptr Pointer to member in some structure.
* @param type Structure member is part of.
* @param member Member pointer is pointing to.
* @return Pointer to structure itself instead of member.
*/
#define container_of(ptr, type, member) \
((type *)((char *)(ptr)-offsetof(type, member)))
/**
* Get array size in number of elements.
*
* @param x Array whose size should be calculated.
* @return Number of elements in array.
*/
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
/**
* Check if value is aligned to some other value.
*
* @param x Value whose alignment to check.
* @param a Value to check alignment to.
* @return \ref true if \c x is aligned, \ref false otherwise.
*/
#define ALIGNED(x, a) ((x) % a == 0)
/**
* Add value to pointer in bytes instead of elements.
*
* @param x Pointer to add value to.
* @param y Value to add to pointer.
* @return \c x with \c y added to it.
*/
#define ptradd(x, y) (((vm_t)(x)) + ((vm_t)(y)))
#include <apos/types.h>
/* clang-format doesn't like _Generic, but I guess that's fine.
* Uncrustify just ignores it, as far as I can tell. */
/**
* Align value upwards.
* Type is deduced from \c x.
*
* @param x Value to align up.
* @param y Value to align to.
* @return \c x aligned to \c y.
*/
#define align_up(x, y) \
_Generic((x), signed char \
: align_up_c, signed short \
: align_up_s, signed int \
: align_up_i, signed long \
: align_up_l, signed long long \
: align_up_ll, \
\
unsigned char \
: align_up_uc, unsigned short \
: align_up_us, unsigned int \
: align_up_ui, unsigned long \
: align_up_ul, unsigned long long \
: align_up_ull)((x), (y))
/**
* Helper macro for defining type specific aligning.
*
* @param name Name of type in function name.
* @param type Actual type.
*/
#define DEFINE_ALIGN_UP(name, type) \
static inline type align_up_##name(type val, type a) \
{ \
if (!a) { \
return val; \
} \
\
type rem = val % a; \
\
if (rem == 0) { \
return val; \
} \
\
return val + a - rem; \
}
/**
* Align signed char up.
*
* @param val Value to align.
* @param a Value to align to.
* @return \c val aligned up to nearest multiple of \c a.
*/
DEFINE_ALIGN_UP(c, signed char);
/**
* Align signed short up.
*
* @param val Value to align.
* @param a Value to align to.
* @return \c val aligned up to nearest multiple of \c a.
*/
DEFINE_ALIGN_UP(s, signed short);
/**
* Align signed int up.
*
* @param val Value to align.
* @param a Value to align to.
* @return \c val aligned up to nearest multiple of \c a.
*/
DEFINE_ALIGN_UP(i, signed int);
/**
* Align signed long up.
*
* @param val Value to align.
* @param a Value to align to.
* @return \c val aligned up to nearest multiple of \c a.
*/
DEFINE_ALIGN_UP(l, signed long);
/**
* Align signed long long up.
*
* @param val Value to align.
* @param a Value to align to.
* @return \c val aligned up to nearest multiple of \c a.
*/
DEFINE_ALIGN_UP(ll, signed long long);
/**
* Align unsigned char up.
*
* @param val Value to align.
* @param a Value to align to.
* @return \c val aligned up to nearest multiple of \c a.
*/
DEFINE_ALIGN_UP(uc, unsigned char);
/**
* Align unsigned short up.
*
* @param val Value to align.
* @param a Value to align to.
* @return \c val aligned up to nearest multiple of \c a.
*/
DEFINE_ALIGN_UP(us, unsigned short);
/**
* Align unsigned int up.
*
* @param val Value to align.
* @param a Value to align to.
* @return \c val aligned up to nearest multiple of \c a.
*/
DEFINE_ALIGN_UP(ui, unsigned int);
/**
* Align unsigned long up.
*
* @param val Value to align.
* @param a Value to align to.
* @return \c val aligned up to nearest multiple of \c a.
*/
DEFINE_ALIGN_UP(ul, unsigned long);
/**
* Align unsigned long long up.
*
* @param val Value to align.
* @param a Value to align to.
* @return \c val aligned up to nearest multiple of \c a.
*/
DEFINE_ALIGN_UP(ull, unsigned long long);
/**
* Align value downwards.
* Type is deduced from \c x.
*
* @param x Value to align.
* @param y Value to align to.
* @return \c x aligned to down \c y.
*/
#define align_down(x, y) \
_Generic((x), signed char \
: align_down_c, signed short \
: align_down_s, signed int \
: align_down_i, signed long \
: align_down_l, signed long long \
: align_down_ll, \
\
unsigned char \
: align_down_uc, unsigned short \
: align_down_us, unsigned int \
: align_down_ui, unsigned long \
: align_down_ul, unsigned long long \
: align_down_ull)((x), (y))
/**
* Helper macro for defining type specific aligning.
*
* @param name Name of type in function name.
* @param type Actual type.
*/
#define DEFINE_ALIGN_DOWN(name, type) \
static inline type align_down_##name(type val, type a) \
{ \
if (!a) { \
return val; \
} \
\
return val - (val % a); \
}
/**
* Align signed char down.
*
* @param val Value to align.
* @param a Value to align to.
* @return \c val aligned down to nearest multiple of \c a.
*/
DEFINE_ALIGN_DOWN(c, signed char);
/**
* Align signed short down.
*
* @param val Value to align.
* @param a Value to align to.
* @return \c val aligned down to nearest multiple of \c a.
*/
DEFINE_ALIGN_DOWN(s, signed short);
/**
* Align signed int down.
*
* @param val Value to align.
* @param a Value to align to.
* @return \c val aligned down to nearest multiple of \c a.
*/
DEFINE_ALIGN_DOWN(i, signed int);
/**
* Align signed long down.
*
* @param val Value to align.
* @param a Value to align to.
* @return \c val aligned down to nearest multiple of \c a.
*/
DEFINE_ALIGN_DOWN(l, signed long);
/**
* Align signed long long down.
*
* @param val Value to align.
* @param a Value to align to.
* @return \c val aligned down to nearest multiple of \c a.
*/
DEFINE_ALIGN_DOWN(ll, signed long long);
/**
* Align unsigned char down.
*
* @param val Value to align.
* @param a Value to align to.
* @return \c val aligned down to nearest multiple of \c a.
*/
DEFINE_ALIGN_DOWN(uc, unsigned char);
/**
* Align unsigned short down.
*
* @param val Value to align.
* @param a Value to align to.
* @return \c val aligned down to nearest multiple of \c a.
*/
DEFINE_ALIGN_DOWN(us, unsigned short);
/**
* Align unsigned int down.
*
* @param val Value to align.
* @param a Value to align to.
* @return \c val aligned down to nearest multiple of \c a.
*/
DEFINE_ALIGN_DOWN(ui, unsigned int);
/**
* Align unsigned long down.
*
* @param val Value to align.
* @param a Value to align to.
* @return \c val aligned down to nearest multiple of \c a.
*/
DEFINE_ALIGN_DOWN(ul, unsigned long);
/**
* Align unsigned long long down.
*
* @param val Value to align.
* @param a Value to align to.
* @return \c val aligned down to nearest multiple of \c a.
*/
DEFINE_ALIGN_DOWN(ull, unsigned long long);
/**
* Check if value is aligned.
*
* @param x Value to check.
* @param y Alignment to check to.
* @return \ref true if \c x is aligned to \c y, \ref false otherwise.
*/
#define is_aligned(x, y) \
_Generic((x), signed char \
: is_aligned_c, signed short \
: is_aligned_s, signed int \
: is_aligned_i, signed long \
: is_aligned_l, signed long long \
: is_aligned_ll, \
\
unsigned char \
: is_aligned_uc, unsigned short \
: is_aligned_us, unsigned int \
: is_aligned_ui, unsigned long \
: is_aligned_ul, unsigned long long \
: is_aligned_ll)((x), (y))
/**
* Helper macro for defining type specific alignment checks.
*
* @param name Name of type in function name.
* @param type Actual type.
*/
#define DEFINE_ALIGNED(name, type) \
static inline bool is_aligned_##name(type val, type a) \
{ \
if (!a) { \
return true; \
} \
\
return val % a == 0; \
}
/**
* Check if signed char is aligned.
*
* @param val Value to check.
* @param a Alignment to check to.
* @return \ref true if \c val is aligned to \c a, \ref false otherwise.
*/
DEFINE_ALIGNED(c, signed char);
/**
* Check if signed short is aligned.
*
* @param val Value to check.
* @param a Alignment to check to.
* @return \ref true if \c val is aligned to \c a, \ref false otherwise.
*/
DEFINE_ALIGNED(s, signed short);
/**
* Check if signed int is aligned.
*
* @param val Value to check.
* @param a Alignment to check to.
* @return \ref true if \c val is aligned to \c a, \ref false otherwise.
*/
DEFINE_ALIGNED(i, signed int);
/**
* Check if signed long is aligned.
*
* @param val Value to check.
* @param a Alignment to check to.
* @return \ref true if \c val is aligned to \c a, \ref false otherwise.
*/
DEFINE_ALIGNED(l, signed long);
/**
* Check if signed long long is aligned.
*
* @param val Value to check.
* @param a Alignment to check to.
* @return \ref true if \c val is aligned to \c a, \ref false otherwise.
*/
DEFINE_ALIGNED(ll, signed long long);
/**
* Check if unsigned char is aligned.
*
* @param val Value to check.
* @param a Alignment to check to.
* @return \ref true if \c val is aligned to \c a, \ref false otherwise.
*/
DEFINE_ALIGNED(uc, unsigned char);
/**
* Check if unsigned short is aligned.
*
* @param val Value to check.
* @param a Alignment to check to.
* @return \ref true if \c val is aligned to \c a, \ref false otherwise.
*/
DEFINE_ALIGNED(us, unsigned short);
/**
* Check if unsigned int is aligned.
*
* @param val Value to check.
* @param a Alignment to check to.
* @return \ref true if \c val is aligned to \c a, \ref false otherwise.
*/
DEFINE_ALIGNED(ui, unsigned int);
/**
* Check if unsigned long is aligned.
*
* @param val Value to check.
* @param a Alignment to check to.
* @return \ref true if \c val is aligned to \c a, \ref false otherwise.
*/
DEFINE_ALIGNED(ul, unsigned long);
/**
* Check if unsigned long long is aligned.
*
* @param val Value to check.
* @param a Alignment to check to.
* @return \ref true if \c val is aligned to \c a, \ref false otherwise.
*/
DEFINE_ALIGNED(ull, unsigned long long);
/**
* Get numeric value of ASCII character.
*
* @param c Character representing a number.
* @return Corresponding number. -1 if parsing failed.
*/
static inline int asciinum(char c)
{
if (c >= '0' && c <= '9')
return c - '0';
else if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
else if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
else
return -1;
}
/**
* Convert string representing number to actual number.
*
* @param c String representing number.
* @param len Length of \c str.
* @param base Base of number.
* @return Corresponding number.
*/
static inline uintmax_t convnum(const char *c, size_t len, size_t base)
{
size_t multiplier = 1;
size_t sum = 0;
for (size_t i = 0; i < len; ++i) {
sum += asciinum(c[len - 1 - i]) * multiplier;
multiplier *= base;
}
return sum;
}
#endif /* APOS_UTILS_H */
|