diff options
| author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2007-10-05 12:41:53 -0400 |
|---|---|---|
| committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2007-10-05 12:41:53 -0400 |
| commit | 9de8f0850ce4b34a849384d119fc9e5a6f3f8d17 (patch) | |
| tree | 236622c3b41231bb74507cd5e3b7f29d61170c43 | |
| parent | 7ddb0d79edf783b5cf45af8052195df198788b07 (diff) | |
Implement user space adaptive task launching interface.
| -rw-r--r-- | Makefile | 4 | ||||
| -rw-r--r-- | include/adaptive.h | 23 | ||||
| -rw-r--r-- | include/litmus.h | 8 | ||||
| -rw-r--r-- | src/adaptive.c | 45 | ||||
| -rw-r--r-- | src/litmus.c | 60 | ||||
| -rw-r--r-- | src/rt_launch.c | 85 |
6 files changed, 191 insertions, 34 deletions
| @@ -39,5 +39,5 @@ rt_launch: liblitmus.a litmus.h rt_launch.o | |||
| 39 | edfhsb: liblitmus.a edf-hsb.o litmus.h edf-hsb.h hrt.o | 39 | edfhsb: liblitmus.a edf-hsb.o litmus.h edf-hsb.h hrt.o |
| 40 | cc -o edfhsb hrt.o edf-hsb.o ${LIBS} | 40 | cc -o edfhsb hrt.o edf-hsb.o ${LIBS} |
| 41 | 41 | ||
| 42 | liblitmus.a: litmus.o litmus.h edf-hsb.o edf-hsb.h | 42 | liblitmus.a: litmus.o adaptive.o adaptive.h litmus.h edf-hsb.o edf-hsb.h |
| 43 | ${AR} rcs liblitmus.a litmus.o edf-hsb.o | 43 | ${AR} rcs liblitmus.a litmus.o adaptive.o edf-hsb.o |
diff --git a/include/adaptive.h b/include/adaptive.h new file mode 100644 index 0000000..a67c540 --- /dev/null +++ b/include/adaptive.h | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | #ifndef ADAPTIVE_H | ||
| 2 | #define ADAPTIVE_H | ||
| 3 | |||
| 4 | #define MAX_SERVICE_LEVELS 10 | ||
| 5 | |||
| 6 | typedef struct { | ||
| 7 | unsigned long exec_cost; | ||
| 8 | unsigned long period; | ||
| 9 | /* fixed point */ | ||
| 10 | unsigned long utility; | ||
| 11 | } service_level_t; | ||
| 12 | |||
| 13 | int set_service_levels(pid_t pid, | ||
| 14 | unsigned int nr_levels, | ||
| 15 | service_level_t* levels); | ||
| 16 | |||
| 17 | int get_cur_service_level(void); | ||
| 18 | |||
| 19 | int create_adaptive_rt_task(rt_fn_t rt_prog, void *arg, | ||
| 20 | unsigned int no_levels, service_level_t* levels); | ||
| 21 | |||
| 22 | |||
| 23 | #endif | ||
diff --git a/include/litmus.h b/include/litmus.h index 3595919..01503aa 100644 --- a/include/litmus.h +++ b/include/litmus.h | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #define CLONE_REALTIME 0x10000000 | 8 | #define CLONE_REALTIME 0x10000000 |
| 9 | 9 | ||
| 10 | typedef int (*rt_fn_t)(void*); | 10 | typedef int (*rt_fn_t)(void*); |
| 11 | typedef int (*rt_setup_fn_t)(int pid, void* arg); | ||
| 11 | 12 | ||
| 12 | /* Litmus scheduling policies */ | 13 | /* Litmus scheduling policies */ |
| 13 | typedef enum { | 14 | typedef enum { |
| @@ -99,6 +100,7 @@ void init_litmus(void); | |||
| 99 | #define exit_litmus() {} | 100 | #define exit_litmus() {} |
| 100 | 101 | ||
| 101 | 102 | ||
| 103 | |||
| 102 | int create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, int period); | 104 | int create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, int period); |
| 103 | int __create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, | 105 | int __create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, |
| 104 | int period, task_class_t cls); | 106 | int period, task_class_t cls); |
| @@ -111,4 +113,10 @@ void exit_np(void); | |||
| 111 | 113 | ||
| 112 | int litmus_task_active(); | 114 | int litmus_task_active(); |
| 113 | 115 | ||
| 116 | |||
| 117 | /* low level operations, not intended for API use */ | ||
| 118 | int fork_rt(void); | ||
| 119 | int __launch_rt_task(rt_fn_t rt_prog, void *rt_arg, | ||
| 120 | rt_setup_fn_t setup, void* setup_arg); | ||
| 121 | |||
| 114 | #endif | 122 | #endif |
diff --git a/src/adaptive.c b/src/adaptive.c new file mode 100644 index 0000000..ebf662d --- /dev/null +++ b/src/adaptive.c | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | #include <sys/types.h> | ||
| 2 | #include <unistd.h> | ||
| 3 | |||
| 4 | #include "litmus.h" | ||
| 5 | #include "adaptive.h" | ||
| 6 | |||
| 7 | #define __NR_set_service_levels 346 | ||
| 8 | #define __NR_get_cur_service_level 347 | ||
| 9 | |||
| 10 | |||
| 11 | |||
| 12 | int set_service_levels(pid_t pid, | ||
| 13 | unsigned int nr_levels, | ||
| 14 | service_level_t* levels) | ||
| 15 | { | ||
| 16 | return syscall(__NR_set_service_levels, pid, nr_levels, levels); | ||
| 17 | } | ||
| 18 | |||
| 19 | |||
| 20 | int get_cur_service_level(void) | ||
| 21 | { | ||
| 22 | return syscall(__NR_get_cur_service_level); | ||
| 23 | } | ||
| 24 | |||
| 25 | |||
| 26 | struct adaptive_param { | ||
| 27 | unsigned int no_levels; | ||
| 28 | service_level_t* levels; | ||
| 29 | }; | ||
| 30 | |||
| 31 | int setup_adaptive(int pid, struct adaptive_param* arg) | ||
| 32 | { | ||
| 33 | return set_service_levels(pid, arg->no_levels, arg->levels); | ||
| 34 | } | ||
| 35 | |||
| 36 | int create_adaptive_rt_task(rt_fn_t rt_prog, void *arg, | ||
| 37 | unsigned int no_levels, service_level_t* levels) | ||
| 38 | { | ||
| 39 | struct adaptive_param p; | ||
| 40 | p.no_levels = no_levels; | ||
| 41 | p.levels = levels; | ||
| 42 | return __launch_rt_task(rt_prog, arg, | ||
| 43 | (rt_setup_fn_t) setup_adaptive, &p); | ||
| 44 | } | ||
| 45 | |||
diff --git a/src/litmus.c b/src/litmus.c index 9a2ebea..b39da7f 100644 --- a/src/litmus.c +++ b/src/litmus.c | |||
| @@ -63,6 +63,12 @@ type name(type1 arg1,type2 arg2) \ | |||
| 63 | 63 | ||
| 64 | _syscall2(int, raw_clone, unsigned long, flags, unsigned long, child_stack) | 64 | _syscall2(int, raw_clone, unsigned long, flags, unsigned long, child_stack) |
| 65 | 65 | ||
| 66 | int fork_rt(void) | ||
| 67 | { | ||
| 68 | int rt_task = raw_clone(CLONE_LITMUS, 0); | ||
| 69 | return rt_task; | ||
| 70 | } | ||
| 71 | |||
| 66 | 72 | ||
| 67 | const char* get_scheduler_name(spolicy scheduler) | 73 | const char* get_scheduler_name(spolicy scheduler) |
| 68 | { | 74 | { |
| @@ -103,27 +109,20 @@ const char* get_scheduler_name(spolicy scheduler) | |||
| 103 | return name; | 109 | return name; |
| 104 | } | 110 | } |
| 105 | 111 | ||
| 106 | int create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, int period) { | ||
| 107 | return __create_rt_task(rt_prog, arg, cpu, wcet, period, RT_CLASS_HARD); | ||
| 108 | } | ||
| 109 | 112 | ||
| 110 | int __create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, int period, | 113 | /* common launch routine */ |
| 111 | task_class_t class) | 114 | int __launch_rt_task(rt_fn_t rt_prog, void *rt_arg, rt_setup_fn_t setup, |
| 115 | void* setup_arg) | ||
| 112 | { | 116 | { |
| 113 | int ret; | 117 | int ret; |
| 114 | rt_param_t params; | 118 | int rt_task = fork_rt(); |
| 115 | int rt_task = raw_clone(CLONE_LITMUS, 0); | ||
| 116 | 119 | ||
| 117 | if (rt_task < 0) | 120 | if (rt_task < 0) |
| 118 | return rt_task; | 121 | return rt_task; |
| 119 | 122 | ||
| 120 | if (rt_task > 0) { | 123 | if (rt_task > 0) { |
| 121 | /* we are the controller task */ | 124 | /* we are the controller task */ |
| 122 | params.period = period; | 125 | ret = setup(rt_task, setup_arg); |
| 123 | params.exec_cost = wcet; | ||
| 124 | params.cpu = cpu; | ||
| 125 | params.cls = class; | ||
| 126 | ret = set_rt_task_param(rt_task, ¶ms); | ||
| 127 | if (ret < 0) { | 126 | if (ret < 0) { |
| 128 | /* we have a problem: we created the task but | 127 | /* we have a problem: we created the task but |
| 129 | * for some stupid reason we cannot set the real-time | 128 | * for some stupid reason we cannot set the real-time |
| @@ -138,7 +137,7 @@ int __create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, int period, | |||
| 138 | ret = prepare_rt_task(rt_task); | 137 | ret = prepare_rt_task(rt_task); |
| 139 | if (ret < 0) { | 138 | if (ret < 0) { |
| 140 | /* same problem as above*/ | 139 | /* same problem as above*/ |
| 141 | //kill(rt_task, SIGKILL); | 140 | kill(rt_task, SIGKILL); |
| 142 | rt_task = -1; | 141 | rt_task = -1; |
| 143 | } | 142 | } |
| 144 | return rt_task; | 143 | return rt_task; |
| @@ -148,10 +147,43 @@ int __create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, int period, | |||
| 148 | * launch task and die when it is done | 147 | * launch task and die when it is done |
| 149 | */ | 148 | */ |
| 150 | 149 | ||
| 151 | exit(rt_prog(arg)); | 150 | exit(rt_prog(rt_arg)); |
| 152 | } | 151 | } |
| 153 | } | 152 | } |
| 154 | 153 | ||
| 154 | struct create_rt_param { | ||
| 155 | int cpu; | ||
| 156 | int wcet; | ||
| 157 | int period; | ||
| 158 | task_class_t class; | ||
| 159 | }; | ||
| 160 | |||
| 161 | int setup_create_rt(int pid, struct create_rt_param* arg) | ||
| 162 | { | ||
| 163 | rt_param_t params; | ||
| 164 | params.period = arg->period; | ||
| 165 | params.exec_cost = arg->wcet; | ||
| 166 | params.cpu = arg->cpu; | ||
| 167 | params.cls = arg->class; | ||
| 168 | return set_rt_task_param(pid, ¶ms); | ||
| 169 | } | ||
| 170 | |||
| 171 | int __create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, int period, | ||
| 172 | task_class_t class) | ||
| 173 | { | ||
| 174 | struct create_rt_param params; | ||
| 175 | params.cpu = cpu; | ||
| 176 | params.period = period; | ||
| 177 | params.wcet = wcet; | ||
| 178 | params.class = class; | ||
