aboutsummaryrefslogtreecommitdiffstats
path: root/src/kernel_iface.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel_iface.c')
-rw-r--r--src/kernel_iface.c61
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
6struct 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
17int register_np_flag(struct np_flag* flag);
18int signal_exit_np(void);
19
20
21
22static struct np_flag np_flag;
23
24
25int 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
35static inline void barrier(void)
36{
37 __asm__ __volatile__("sfence": : :"memory");
38}
39
40void 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
51void 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