1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
#include <sys/mman.h>
#include <sys/fcntl.h> /* for O_RDWR */
#include <sys/unistd.h>
#include <sched.h> /* for sched_yield() */
#include <stdio.h>
#include "litmus.h"
#include "internal.h"
#include "asm/atomic.h"
#define LITMUS_CTRL_DEVICE "/dev/litmus/ctrl"
#define CTRL_PAGES 1
static int map_file(const char* filename, void **addr, size_t size)
{
int error = 0;
int fd;
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;
}
/* thread-local pointer to control page */
static __thread struct control_page *ctrl_page;
int init_kernel_iface(void)
{
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)
{
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)
{
if (likely(ctrl_page != NULL) && --ctrl_page->np_flag == 0) {
/* became preemptive, let's check for delayed preemptions */
barrier();
if (ctrl_page->delayed_preemption)
sched_yield();
}
}
/* init and return a ptr to the control page for
* preemption and migration overhead analysis
*
* FIXME it may be desirable to have a RO control page here
*/
struct control_page* get_ctrl_page(void)
{
if((ctrl_page != NULL) || init_kernel_iface() == 0)
return ctrl_page;
else
return NULL;
}
|