diff options
Diffstat (limited to 'src/kernel_iface.c')
-rw-r--r-- | src/kernel_iface.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/src/kernel_iface.c b/src/kernel_iface.c new file mode 100644 index 0000000..5751ca6 --- /dev/null +++ b/src/kernel_iface.c | |||
@@ -0,0 +1,61 @@ | |||
1 | #include <stdio.h> | ||
2 | |||
3 | #include "litmus.h" | ||
4 | #include "internal.h" | ||
5 | |||
6 | struct np_flag { | ||
7 | #define RT_PREEMPTIVE 0x2050 /* = NP */ | ||
8 | #define RT_NON_PREEMPTIVE 0x4e50 /* = P */ | ||
9 | unsigned short preemptivity; | ||
10 | |||
11 | #define RT_EXIT_NP_REQUESTED 0x5251 /* = RQ */ | ||
12 | unsigned short request; | ||
13 | |||
14 | unsigned int ctr; | ||
15 | }; | ||
16 | |||
17 | int register_np_flag(struct np_flag* flag); | ||
18 | int signal_exit_np(void); | ||
19 | |||
20 | |||
21 | |||
22 | static struct np_flag np_flag; | ||
23 | |||
24 | |||
25 | int init_kernel_iface(void) | ||
26 | { | ||
27 | int ret; | ||
28 | np_flag.preemptivity = RT_PREEMPTIVE; | ||
29 | np_flag.ctr = 0; | ||
30 | ret = register_np_flag(&np_flag); | ||
31 | check("register_np_flag()"); | ||
32 | return ret; | ||
33 | } | ||
34 | |||
35 | static inline void barrier(void) | ||
36 | { | ||
37 | __asm__ __volatile__("sfence": : :"memory"); | ||
38 | } | ||
39 | |||
40 | void enter_np(void) | ||
41 | { | ||
42 | if (++np_flag.ctr == 1) | ||
43 | { | ||
44 | np_flag.request = 0; | ||
45 | barrier(); | ||
46 | np_flag.preemptivity = RT_NON_PREEMPTIVE; | ||
47 | } | ||
48 | } | ||
49 | |||
50 | |||
51 | void exit_np(void) | ||
52 | { | ||
53 | if (--np_flag.ctr == 0) | ||
54 | { | ||
55 | np_flag.preemptivity = RT_PREEMPTIVE; | ||
56 | barrier(); | ||
57 | if (np_flag.request == RT_EXIT_NP_REQUESTED) | ||
58 | signal_exit_np(); | ||
59 | } | ||
60 | } | ||
61 | |||