From 8a1912c177e978574250cf80f8a50edf7424b158 Mon Sep 17 00:00:00 2001 From: "Bjoern B. Brandenburg" Date: Wed, 3 Feb 2010 09:51:57 -0500 Subject: Re-implement non-preemptive section support. Layered on top of the LITMUS control page. --- src/kernel_iface.c | 98 ++++++++++++++++++++++++++---------------------------- src/syscalls.c | 12 ------- 2 files changed, 48 insertions(+), 62 deletions(-) (limited to 'src') 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 @@ +#include +#include /* for O_RDWR */ +#include +#include /* for sched_yield() */ + + #include #include "litmus.h" #include "internal.h" #include "asm.h" -/* per real-time thread kernel <-> user space flags */ - +#define LITMUS_CTRL_DEVICE "/dev/litmus/ctrl" +#define CTRL_PAGES 1 -struct np_flag { - #define RT_PREEMPTIVE 0x2050 /* = NP */ - #define RT_NON_PREEMPTIVE 0x4e50 /* = P */ - unsigned short preemptivity; - - #define RT_EXIT_NP_REQUESTED 0x5251 /* = RQ */ - unsigned short request; - - unsigned int ctr; -}; +static int map_file(const char* filename, void **addr, size_t size) +{ + int error = 0; + int fd; -int register_np_flag(struct np_flag* flag); -int signal_exit_np(void); + if (size > 0) { + fd = open(filename, O_RDWR); + if (fd >= 0) { + *addr = mmap(NULL, size, + PROT_READ | PROT_WRITE, + MAP_PRIVATE, + fd, 0); + if (*addr == MAP_FAILED) + error = -1; + close(fd); + } else + error = fd; + } else + *addr = NULL; + return error; +} -#ifndef __sparc__ -static __thread struct np_flag np_flag; -#endif +/* thread-local pointer to control page */ +static __thread struct control_page *ctrl_page; int init_kernel_iface(void) { - int ret = 0; -#ifdef FALSE -#ifndef __sparc__ /* currently not supported in sparc64 */ - np_flag.preemptivity = RT_PREEMPTIVE; - np_flag.ctr = 0; - ret = register_np_flag(&np_flag); - check("register_np_flag()"); -#endif -#endif - return ret; + int err = 0; + long page_size = sysconf(_SC_PAGESIZE); + + err = map_file(LITMUS_CTRL_DEVICE, (void**) &ctrl_page, CTRL_PAGES * page_size); + if (err) { + fprintf(stderr, "%s: cannot open LITMUS^RT control page (%m)\n", + __FUNCTION__); + } + + return err; } void enter_np(void) { -#ifdef FALSE -#ifndef __sparc__ - if (++np_flag.ctr == 1) - { - np_flag.request = 0; - barrier(); - np_flag.preemptivity = RT_NON_PREEMPTIVE; - } -#else - fprintf(stderr, "enter_np: not implemented!\n"); -#endif -#endif + if (likely(ctrl_page != NULL) || init_kernel_iface() == 0) + ctrl_page->np_flag++; + else + fprintf(stderr, "enter_np: control page not mapped!\n"); } void exit_np(void) { -#ifdef FALSE -#ifndef __sparc__ - if (--np_flag.ctr == 0) - { - np_flag.preemptivity = RT_PREEMPTIVE; + if (likely(ctrl_page != NULL) && --ctrl_page->np_flag == 0) { + /* became preemptive, let's check for delayed preemptions */ barrier(); - if (np_flag.request == RT_EXIT_NP_REQUESTED) - signal_exit_np(); + if (ctrl_page->delayed_preemption) + sched_yield(); } -#else - fprintf(stderr, "exit_np: not implemented!\n"); -#endif -#endif } 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) return syscall(__NR_complete_job); } -#ifdef false -int register_np_flag(struct np_flag *flag) -{ - return syscall(__NR_register_np_flag, flag); -} - -int signal_exit_np(void) -{ - return syscall(__NR_exit_np); -} -#endif - int od_openx(int fd, obj_type_t type, int obj_id, void *config) { return syscall(__NR_od_open, fd, type, obj_id, config); -- cgit v1.2.2