aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2010-02-03 09:51:57 -0500
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2010-02-03 21:55:58 -0500
commit8a1912c177e978574250cf80f8a50edf7424b158 (patch)
tree23b05f63d1a47ef01667a90703f0b0661f37e969 /src
parent1c21007bbcb62829b12dc7271fdbc183c4ca1aa2 (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.c98
-rw-r--r--src/syscalls.c12
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
10struct np_flag { 16static 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
21int register_np_flag(struct np_flag* flag);
22int 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 */
26static __thread struct np_flag np_flag; 40static __thread struct control_page *ctrl_page;
27#endif
28 41
29int init_kernel_iface(void) 42int 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
43void enter_np(void) 56void 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
60void exit_np(void) 65void 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
35int register_np_flag(struct np_flag *flag)
36{
37 return syscall(__NR_register_np_flag, flag);
38}
39
40int signal_exit_np(void)
41{
42 return syscall(__NR_exit_np);
43}
44#endif
45
46int od_openx(int fd, obj_type_t type, int obj_id, void *config) 34int 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);