Add the 'current_kthread' helper
[akaros.git] / kern / include / ros / bitfield.h
1 /* Copyright (c) 2015 Google Inc
2  * Davide Libenzi <dlibenzi@google.com>
3  * See LICENSE for details.
4  *
5  * This file provide an interface for dealing with bitfields, without
6  * having to explicitly create by hand masks and shifts definitions
7  * and operational macros.
8  * Example use:
9  *
10  * #define MYBF_X MKBITFIELD(0, 4)
11  * #define MYBF_Y MKBITFIELD(4, 3)
12  * #define MYBF_Z MKBITFIELD(7, 25)
13  *
14  * #define MYBF_GET_X(v)    BF_GETFIELD(v, MYBF_X)
15  * #define MYBF_SET_X(v, x) BF_SETFIELD(v, x, MYBF_X)
16  * #define MYBF_GET_Y(v)    BF_GETFIELD(v, MYBF_Y)
17  * #define MYBF_SET_Y(v, x) BF_SETFIELD(v, x, MYBF_Y)
18  * #define MYBF_GET_Z(v)    BF_GETFIELD(v, MYBF_Z)
19  * #define MYBF_SET_Z(v, x) BF_SETFIELD(v, x, MYBF_Z)
20  */
21
22 #pragma once
23
24 #include <stdint.h>
25
26 struct bitfield_conf {
27     uint8_t shift;
28     uint8_t nbits;
29 };
30
31 #define MKBITFIELD(s, n)                                                                        \
32     ((struct bitfield_conf) { .shift = (s), .nbits = (n) })
33
34 #define BF_MKMASK(type, bfc) ((((type) 1 << bfc.nbits) - 1) << bfc.shift)
35
36 #define BF_GETFIELD(val, bfc) \
37         ({ ((val) >> bfc.shift) & (((typeof(val)) 1 << bfc.nbits) - 1); })
38
39 #define BF_SETFIELD(val, x, bfc)                                           \
40         ({ typeof(val) m = BF_MKMASK(typeof(val), bfc);    \
41                 (val) = ((val) & ~m) |                                             \
42                         (((typeof(val)) (x) << bfc.shift) & m); })