Hi, this is an experimental hack to open the non-rt priority levels of Linux to Xenomai shadow threads, i.e. allow shadows to be scheduled under SCHED_NORMAL when in secondary mode. The scenario are typical borderline threads between RT and non-RT: they share a critical code path with RT threads, maybe mutex protected, but they are mostly time-sharing threads which do not need SCHED_FIFO for this.
The patch (be careful, quick-hack!) addresses the prio level 0 in the ipipe patch, the nucleus/shadow subsystem, and the native skin. A quick test with the attached demo showed the expected behaviour so far: no lock-up during busy-waiting in secondary mode, prio-boost when holding the lock (visible via /proc/xenomai/sched), no obvious side effects. Any comments? Does this break other things in a subtle way? Jan
Index: linux-2.6.15.3/kernel/sched.c =================================================================== --- linux-2.6.15.3.orig/kernel/sched.c 2006-04-19 11:07:51.000000000 +0200 +++ linux-2.6.15.3/kernel/sched.c 2006-04-19 23:14:43.000000000 +0200 @@ -5779,7 +5779,7 @@ int ipipe_setscheduler_root (struct task runqueue_t *rq; int oldprio; - if (prio < 1 || prio > MAX_RT_PRIO-1) + if (prio < 0 || prio > MAX_RT_PRIO-1) return -EINVAL; rq = task_rq_lock(p, &flags);
Index: include/nucleus/core.h =================================================================== --- include/nucleus/core.h (Revision 956) +++ include/nucleus/core.h (Arbeitskopie) @@ -38,7 +38,7 @@ #define XNCORE_NR_PRIO (XNCORE_MAX_PRIO - XNCORE_MIN_PRIO + 2) /* Priority sub-range used by core APIs. */ -#define XNCORE_LOW_PRIO 1 +#define XNCORE_LOW_PRIO 0 #define XNCORE_HIGH_PRIO 99 /* Priority of IRQ servers in user-space. */ Index: src/skins/native/task.c =================================================================== --- src/skins/native/task.c (Revision 956) +++ src/skins/native/task.c (Arbeitskopie) @@ -56,8 +56,10 @@ static void *rt_task_trampoline (void *c long err; /* Ok, this looks like weird, but we need this. */ - param.sched_priority = sched_get_priority_max(SCHED_FIFO); - pthread_setschedparam(pthread_self(),SCHED_FIFO,¶m); + if (iargs->prio > 0) { + param.sched_priority = sched_get_priority_max(SCHED_FIFO); + pthread_setschedparam(pthread_self(),SCHED_FIFO,¶m); + } /* rt_task_delete requires asynchronous cancellation */ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); @@ -132,8 +134,10 @@ int rt_task_create (RT_TASK *task, pthread_attr_setstacksize(&thattr,stksize); if (!(mode & T_JOINABLE)) pthread_attr_setdetachstate(&thattr,PTHREAD_CREATE_DETACHED); - pthread_attr_setschedpolicy(&thattr,SCHED_FIFO); - param.sched_priority = sched_get_priority_max(SCHED_FIFO); + if (prio > 0) { + pthread_attr_setschedpolicy(&thattr,SCHED_FIFO); + param.sched_priority = sched_get_priority_max(SCHED_FIFO); + } pthread_attr_setschedparam(&thattr,¶m); err = pthread_create(&thid,&thattr,&rt_task_trampoline,&iargs); Index: ksrc/nucleus/shadow.c =================================================================== --- ksrc/nucleus/shadow.c (Revision 956) +++ ksrc/nucleus/shadow.c (Arbeitskopie) @@ -120,7 +120,7 @@ static inline void request_syscall_resta static inline void set_linux_task_priority (struct task_struct *p, int prio) { - if (rthal_setsched_root(p,SCHED_FIFO,prio) < 0) + if (rthal_setsched_root(p,prio ? SCHED_FIFO : SCHED_NORMAL,prio) < 0) printk(KERN_WARNING "Xenomai: invalid Linux priority level: %d, task=%s\n",prio,p->comm); } @@ -577,7 +577,7 @@ void xnshadow_relax (int notify) xnthread_user_pid(thread)); #endif /* CONFIG_XENO_OPT_DEBUG */ cprio = thread->cprio < MAX_RT_PRIO ? thread->cprio : MAX_RT_PRIO-1; - rthal_reenter_root(get_switch_lock_owner(),SCHED_FIFO,cprio ?: 1); + rthal_reenter_root(get_switch_lock_owner(),cprio ? SCHED_FIFO : SCHED_NORMAL,cprio); xnthread_inc_ssw(thread); /* Account for secondary mode switch. */ @@ -671,11 +671,13 @@ static int xnshadow_wait_completion (xnc void xnshadow_exit (void) { - rthal_reenter_root(get_switch_lock_owner(),SCHED_FIFO,current->rt_priority); + rthal_reenter_root(get_switch_lock_owner(), + current->rt_priority ? SCHED_FIFO : SCHED_NORMAL, + current->rt_priority); do_exit(0); } -/*! +/*! * \fn int xnshadow_map(xnthread_t *thread, xncompletion_t __user *u_completion) * @internal * \brief Create a shadow thread context. @@ -762,7 +764,7 @@ int xnshadow_map (xnthread_t *thread, xnarch_init_shadow_tcb(xnthread_archtcb(thread),thread,xnthread_name(thread)); prio = xnthread_base_priority(thread) < MAX_RT_PRIO ? xnthread_base_priority(thread) : MAX_RT_PRIO-1; - set_linux_task_priority(current,prio ?: 1); + set_linux_task_priority(current,prio); xnshadow_thrptd(current) = thread; xnpod_suspend_thread(thread,XNRELAX,XN_INFINITE,NULL); @@ -919,7 +921,7 @@ void xnshadow_renice (xnthread_t *thread range, since the core pod's priority scale is a superset of Linux's priority scale. */ int prio = thread->cprio < MAX_RT_PRIO ? thread->cprio : MAX_RT_PRIO-1; - schedule_linux_call(LO_RENICE_REQ,p,prio ?: 1); + schedule_linux_call(LO_RENICE_REQ,p,prio); } void xnshadow_suspend (xnthread_t *thread)
#include <native/task.h> #include <native/mutex.h> #include <native/timer.h> #include <stdio.h> #include <sys/mman.h> RT_TASK task1, task2; RT_MUTEX mutex; void spin(long long time) { long long timeout = rt_timer_read() + time; while (rt_timer_read() < timeout); } void func1(void *arg) { printf("switching to secondary\n"); spin(3000000000LL); printf("back to primary\n"); rt_mutex_lock(&mutex, TM_INFINITE); rt_task_sleep(3000000000LL); spin(1000000000LL); rt_mutex_unlock(&mutex); printf("done with primary\n"); sleep(3); spin(3000000000LL); } void func2(void *arg) { rt_task_sleep(3500000000LL); rt_mutex_lock(&mutex, TM_INFINITE); rt_mutex_unlock(&mutex); } int main() { mlockall(MCL_CURRENT|MCL_FUTURE); rt_mutex_create(&mutex, NULL); spin(3000000000LL); printf("rt_task_spawn(task1) = %d\n", rt_task_spawn(&task1, "mytask", 0, 0, T_JOINABLE, func1, NULL)); printf("rt_task_spawn(task2) = %d\n", rt_task_spawn(&task2, "mytask2", 0, 10, T_JOINABLE, func2, NULL)); rt_task_join(&task1); rt_task_join(&task2); return 0; }
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core