diff options
-rw-r--r-- | include/litmus/rt_param.h | 5 | ||||
-rw-r--r-- | include/litmus/unistd_32.h | 4 | ||||
-rw-r--r-- | include/litmus/unistd_64.h | 5 | ||||
-rw-r--r-- | litmus/litmus.c | 109 |
4 files changed, 99 insertions, 24 deletions
diff --git a/include/litmus/rt_param.h b/include/litmus/rt_param.h index 89ac0dda7d3d..21430623a940 100644 --- a/include/litmus/rt_param.h +++ b/include/litmus/rt_param.h | |||
@@ -157,6 +157,11 @@ struct rt_param { | |||
157 | */ | 157 | */ |
158 | struct task_struct* inh_task; | 158 | struct task_struct* inh_task; |
159 | 159 | ||
160 | |||
161 | struct task_struct* hp_group; | ||
162 | unsigned int is_slave:1; | ||
163 | |||
164 | |||
160 | #ifdef CONFIG_NP_SECTION | 165 | #ifdef CONFIG_NP_SECTION |
161 | /* For the FMLP under PSN-EDF, it is required to make the task | 166 | /* For the FMLP under PSN-EDF, it is required to make the task |
162 | * non-preemptive from kernel space. In order not to interfere with | 167 | * non-preemptive from kernel space. In order not to interfere with |
diff --git a/include/litmus/unistd_32.h b/include/litmus/unistd_32.h index 94264c27d9ac..bcb8f1183b4f 100644 --- a/include/litmus/unistd_32.h +++ b/include/litmus/unistd_32.h | |||
@@ -18,4 +18,6 @@ | |||
18 | #define __NR_release_ts __LSC(10) | 18 | #define __NR_release_ts __LSC(10) |
19 | #define __NR_null_call __LSC(11) | 19 | #define __NR_null_call __LSC(11) |
20 | 20 | ||
21 | #define NR_litmus_syscalls 12 | 21 | #define __NR_slave_non_rt_threads _LSC(12) |
22 | |||
23 | #define NR_litmus_syscalls 13 | ||
diff --git a/include/litmus/unistd_64.h b/include/litmus/unistd_64.h index d5ced0d2642c..5f56d5947343 100644 --- a/include/litmus/unistd_64.h +++ b/include/litmus/unistd_64.h | |||
@@ -30,4 +30,7 @@ __SYSCALL(__NR_release_ts, sys_release_ts) | |||
30 | #define __NR_null_call __LSC(11) | 30 | #define __NR_null_call __LSC(11) |
31 | __SYSCALL(__NR_null_call, sys_null_call) | 31 | __SYSCALL(__NR_null_call, sys_null_call) |
32 | 32 | ||
33 | #define NR_litmus_syscalls 12 | 33 | #define __NR_slave_non_rt_threads __LSC(12) |
34 | __SYSCALL(__NR_slave_non_rt_threads, sys_slave_non_rt_threads) | ||
35 | |||
36 | #define NR_litmus_syscalls 13 | ||
diff --git a/litmus/litmus.c b/litmus/litmus.c index 81384327e850..2300281b6b30 100644 --- a/litmus/litmus.c +++ b/litmus/litmus.c | |||
@@ -290,6 +290,60 @@ asmlinkage long sys_null_call(cycles_t __user *ts) | |||
290 | return ret; | 290 | return ret; |
291 | } | 291 | } |
292 | 292 | ||
293 | |||
294 | |||
295 | |||
296 | |||
297 | |||
298 | |||
299 | |||
300 | |||
301 | |||
302 | long __litmus_admit_task(struct task_struct* tsk); | ||
303 | |||
304 | asmlinkage long sys_slave_non_rt_threads(void) | ||
305 | { | ||
306 | long retval = 0; | ||
307 | struct task_struct *leader = current->group_leader; | ||
308 | struct task_struct *t; | ||
309 | struct task_struct *hp = NULL; | ||
310 | |||
311 | read_lock_irq(&tasklist_lock); | ||
312 | |||
313 | is_realtime(target) | ||
314 | |||
315 | t = leader; | ||
316 | do { | ||
317 | TRACE_CUR("threads in %s/%d: %s/%d:\n", leader->comm, leader->pid, t->comm, t->pid); | ||
318 | |||
319 | if (tsk_rt(t)->heap_node == NULL) { | ||
320 | retval = __litmus_admit_task(t); | ||
321 | |||
322 | if (retval != 0) break; | ||
323 | |||
324 | /* hasn't been admitted into rt. make it a slave. */ | ||
325 | tsk_rt(t)->slave = 1; | ||
326 | } | ||
327 | else if (is_realtime(t)) | ||
328 | if (litmus->compare(t, hp)) { | ||
329 | hp = t; | ||
330 | } | ||
331 | } | ||
332 | |||
333 | t = next_thread(t); | ||
334 | } while(t != leader); | ||
335 | |||
336 | if (hp) { | ||
337 | /* set up inheritance */ | ||
338 | |||
339 | } | ||
340 | |||
341 | read_unlock_irq(&tasklist_lock); | ||
342 | |||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | |||
293 | /* p is a real-time task. Re-init its state as a best-effort task. */ | 347 | /* p is a real-time task. Re-init its state as a best-effort task. */ |
294 | static void reinit_litmus_state(struct task_struct* p, int restore) | 348 | static void reinit_litmus_state(struct task_struct* p, int restore) |
295 | { | 349 | { |
@@ -318,32 +372,11 @@ static void reinit_litmus_state(struct task_struct* p, int restore) | |||
318 | } | 372 | } |
319 | } | 373 | } |
320 | 374 | ||
321 | long litmus_admit_task(struct task_struct* tsk) | 375 | long __litmus_admit_task(struct task_struct* tsk) |
322 | { | 376 | { |
323 | long retval = 0; | 377 | long retval = 0; |
324 | unsigned long flags; | 378 | unsigned long flags; |
325 | 379 | ||
326 | BUG_ON(is_realtime(tsk)); | ||
327 | |||
328 | if (get_rt_relative_deadline(tsk) == 0 || | ||
329 | get_exec_cost(tsk) > | ||
330 | min(get_rt_relative_deadline(tsk), get_rt_period(tsk)) ) { | ||
331 | TRACE_TASK(tsk, | ||
332 | "litmus admit: invalid task parameters " | ||
333 | "(e = %lu, p = %lu, d = %lu)\n", | ||
334 | get_exec_cost(tsk), get_rt_period(tsk), | ||
335 | get_rt_relative_deadline(tsk)); | ||
336 | retval = -EINVAL; | ||
337 | goto out; | ||
338 | } | ||
339 | |||
340 | if (!cpu_online(get_partition(tsk))) { | ||
341 | TRACE_TASK(tsk, "litmus admit: cpu %d is not online\n", | ||
342 | get_partition(tsk)); | ||
343 | retval = -EINVAL; | ||
344 | goto out; | ||
345 | } | ||
346 | |||
347 | INIT_LIST_HEAD(&tsk_rt(tsk)->list); | 380 | INIT_LIST_HEAD(&tsk_rt(tsk)->list); |
348 | 381 | ||
349 | /* avoid scheduler plugin changing underneath us */ | 382 | /* avoid scheduler plugin changing underneath us */ |
@@ -375,6 +408,38 @@ long litmus_admit_task(struct task_struct* tsk) | |||
375 | 408 | ||
376 | out_unlock: | 409 | out_unlock: |
377 | raw_spin_unlock_irqrestore(&task_transition_lock, flags); | 410 | raw_spin_unlock_irqrestore(&task_transition_lock, flags); |
411 | |||
412 | return retval; | ||
413 | } | ||
414 | |||
415 | long litmus_admit_task(struct task_struct* tsk) | ||
416 | { | ||
417 | long retval = 0; | ||
418 | unsigned long flags; | ||
419 | |||
420 | BUG_ON(is_realtime(tsk)); | ||
421 | |||
422 | if (get_rt_relative_deadline(tsk) == 0 || | ||
423 | get_exec_cost(tsk) > | ||
424 | min(get_rt_relative_deadline(tsk), get_rt_period(tsk)) ) { | ||
425 | TRACE_TASK(tsk, | ||
426 | "litmus admit: invalid task parameters " | ||
427 | "(e = %lu, p = %lu, d = %lu)\n", | ||
428 | get_exec_cost(tsk), get_rt_period(tsk), | ||
429 | get_rt_relative_deadline(tsk)); | ||
430 | retval = -EINVAL; | ||
431 | goto out; | ||
432 | } | ||
433 | |||
434 | if (!cpu_online(get_partition(tsk))) { | ||
435 | TRACE_TASK(tsk, "litmus admit: cpu %d is not online\n", | ||
436 | get_partition(tsk)); | ||
437 | retval = -EINVAL; | ||
438 | goto out; | ||
439 | } | ||
440 | |||
441 | retval = __litmus_admit_task(tsk); | ||
442 | |||
378 | out: | 443 | out: |
379 | return retval; | 444 | return retval; |
380 | } | 445 | } |