diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2010-02-03 09:51:57 -0500 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2010-02-03 21:55:58 -0500 |
commit | 8a1912c177e978574250cf80f8a50edf7424b158 (patch) | |
tree | 23b05f63d1a47ef01667a90703f0b0661f37e969 /src | |
parent | 1c21007bbcb62829b12dc7271fdbc183c4ca1aa2 (diff) |
Re-implement non-preemptive section support.
Layered on top of the LITMUS control page.
Diffstat (limited to 'src')
-rw-r--r-- | src/kernel_iface.c | 98 | ||||
-rw-r--r-- | src/syscalls.c | 12 |
2 files changed, 48 insertions, 62 deletions
diff --git a/src/kernel_iface.c b/src/kernel_iface.c index 7cc676f..dbc4baa 100644 --- a/src/kernel_iface.c +++ b/src/kernel_iface.c | |||
@@ -1,76 +1,74 @@ | |||
1 | #include <sys/mman.h> | ||
2 | #include <sys/fcntl.h> /* for O_RDWR */ | ||
3 | #include <sys/unistd.h> | ||
4 | #include <sched.h> /* for sched_yield() */ | ||
5 | |||
6 | |||
1 | #include <stdio.h> | 7 | #include <stdio.h> |
2 | 8 | ||
3 | #include "litmus.h" | 9 | #include "litmus.h" |
4 | #include "internal.h" | 10 | #include "internal.h" |
5 | #include "asm.h" | 11 | #include "asm.h" |
6 | 12 | ||
7 | /* per real-time thread kernel <-> user space flags */ | 13 | #define LITMUS_CTRL_DEVICE "/dev/litmus/ctrl" |
8 | 14 | #define CTRL_PAGES 1 | |
9 | 15 | ||
10 | struct np_flag { | 16 | static int map_file(const char* filename, void **addr, size_t size) |
11 | #define RT_PREEMPTIVE 0x2050 /* = NP */ | 17 | { |
12 | #define RT_NON_PREEMPTIVE 0x4e50 /* = P */ | 18 | int error = 0; |
13 | unsigned short preemptivity; | 19 | int fd; |
14 | |||
15 | #define RT_EXIT_NP_REQUESTED 0x5251 /* = RQ */ | ||
16 | unsigned short request; | ||
17 | |||
18 | unsigned int ctr; | ||
19 | }; | ||
20 | 20 | ||
21 | int register_np_flag(struct np_flag* flag); | ||
22 | int signal_exit_np(void); | ||
23 | 21 | ||
22 | if (size > 0) { | ||
23 | fd = open(filename, O_RDWR); | ||
24 | if (fd >= 0) { | ||
25 | *addr = mmap(NULL, size, | ||
26 | PROT_READ | PROT_WRITE, | ||
27 | MAP_PRIVATE, | ||
28 | fd, 0); | ||
29 | if (*addr == MAP_FAILED) | ||
30 | error = -1; | ||
31 | close(fd); | ||
32 | } else | ||
33 | error = fd; | ||
34 | } else | ||
35 | *addr = NULL; | ||
36 | return error; | ||
37 | } | ||
24 | 38 | ||
25 | #ifndef __sparc__ | 39 | /* thread-local pointer to control page */ |
26 | static __thread struct np_flag np_flag; | 40 | static __thread struct control_page *ctrl_page; |
27 | #endif | ||
28 | 41 | ||
29 | int init_kernel_iface(void) | 42 | int init_kernel_iface(void) |
30 | { | 43 | { |
31 | int ret = 0; | 44 | int err = 0; |
32 | #ifdef FALSE | 45 | long page_size = sysconf(_SC_PAGESIZE); |
33 | #ifndef __sparc__ /* currently not supported in sparc64 */ | 46 | |
34 | np_flag.preemptivity = RT_PREEMPTIVE; | 47 | err = map_file(LITMUS_CTRL_DEVICE, (void**) &ctrl_page, CTRL_PAGES * page_size); |
35 | np_flag.ctr = 0; | 48 | if (err) { |
36 | ret = register_np_flag(&np_flag); | 49 | fprintf(stderr, "%s: cannot open LITMUS^RT control page (%m)\n", |
37 | check("register_np_flag()"); | 50 | __FUNCTION__); |
38 | #endif | 51 | } |
39 | #endif | 52 | |
40 | return ret; | 53 | return err; |
41 | } | 54 | } |
42 | 55 | ||
43 | void enter_np(void) | 56 | void enter_np(void) |
44 | { | 57 | { |
45 | #ifdef FALSE | 58 | if (likely(ctrl_page != NULL) || init_kernel_iface() == 0) |
46 | #ifndef __sparc__ | 59 | ctrl_page->np_flag++; |
47 | if (++np_flag.ctr == 1) | 60 | else |
48 | { | 61 | fprintf(stderr, "enter_np: control page not mapped!\n"); |
49 | np_flag.request = 0; | ||
50 | barrier(); | ||
51 | np_flag.preemptivity = RT_NON_PREEMPTIVE; | ||
52 | } | ||
53 | #else | ||
54 | fprintf(stderr, "enter_np: not implemented!\n"); | ||
55 | #endif | ||
56 | #endif | ||
57 | } | 62 | } |
58 | 63 | ||
59 | 64 | ||
60 | void exit_np(void) | 65 | void exit_np(void) |
61 | { | 66 | { |
62 | #ifdef FALSE | 67 | if (likely(ctrl_page != NULL) && --ctrl_page->np_flag == 0) { |
63 | #ifndef __sparc__ | 68 | /* became preemptive, let's check for delayed preemptions */ |
64 | if (--np_flag.ctr == 0) | ||
65 | { | ||
66 | np_flag.preemptivity = RT_PREEMPTIVE; | ||
67 | barrier(); | 69 | barrier(); |
68 | if (np_flag.request == RT_EXIT_NP_REQUESTED) | 70 | if (ctrl_page->delayed_preemption) |
69 | signal_exit_np(); | 71 | sched_yield(); |
70 | } | 72 | } |
71 | #else | ||
72 | fprintf(stderr, "exit_np: not implemented!\n"); | ||
73 | #endif | ||
74 | #endif | ||
75 | } | 73 | } |
76 | 74 | ||
diff --git a/src/syscalls.c b/src/syscalls.c index 1df2ac3..77a6277 100644 --- a/src/syscalls.c +++ b/src/syscalls.c | |||
@@ -31,18 +31,6 @@ int sleep_next_period(void) | |||
31 | return syscall(__NR_complete_job); | 31 | return syscall(__NR_complete_job); |
32 | } | 32 | } |
33 | 33 | ||
34 | #ifdef false | ||
35 | int register_np_flag(struct np_flag *flag) | ||
36 | { | ||
37 | return syscall(__NR_register_np_flag, flag); | ||
38 | } | ||
39 | |||
40 | int signal_exit_np(void) | ||
41 | { | ||
42 | return syscall(__NR_exit_np); | ||
43 | } | ||
44 | #endif | ||
45 | |||
46 | int od_openx(int fd, obj_type_t type, int obj_id, void *config) | 34 | int od_openx(int fd, obj_type_t type, int obj_id, void *config) |
47 | { | 35 | { |
48 | return syscall(__NR_od_open, fd, type, obj_id, config); | 36 | return syscall(__NR_od_open, fd, type, obj_id, config); |