All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jan Kiszka <jan.kiszka@domain.hid>
To: xenomai-core <xenomai@xenomai.org>
Subject: [Xenomai-core] [RFC] shadow threads with prio 0 / SCHED_NORMAL
Date: Thu, 20 Apr 2006 00:01:44 +0200	[thread overview]
Message-ID: <4446B348.10403@domain.hid> (raw)


[-- Attachment #1.1: Type: text/plain, Size: 838 bytes --]

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

[-- Attachment #1.2: ipipe-prio0.hack --]
[-- Type: text/plain, Size: 494 bytes --]

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);

[-- Attachment #1.3: xeno-prio0.hack --]
[-- Type: text/plain, Size: 4200 bytes --]

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,&param);
+    if (iargs->prio > 0) {
+	param.sched_priority = sched_get_priority_max(SCHED_FIFO);
+	pthread_setschedparam(pthread_self(),SCHED_FIFO,&param);
+    }
 
     /* 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,&param);
 
     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)

[-- Attachment #1.4: demo-prio0.c --]
[-- Type: text/plain, Size: 1217 bytes --]

#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;
}

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 252 bytes --]

             reply	other threads:[~2006-04-19 22:01 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-04-19 22:01 Jan Kiszka [this message]
2006-04-20 12:55 ` [Xenomai-core] [RFC] shadow threads with prio 0 / SCHED_NORMAL Philippe Gerum
2006-04-21 10:46 ` Philippe Gerum
2006-04-21 15:21   ` Gilles Chanteperdrix
2006-04-21 15:47     ` Philippe Gerum
2006-04-21 16:00       ` Gilles Chanteperdrix
2006-04-21 16:41         ` Philippe Gerum
2006-04-21 17:40           ` Gilles Chanteperdrix
2006-04-21 17:50             ` Philippe Gerum
2006-04-21 18:18               ` Jan Kiszka
2006-04-21 21:40                 ` Philippe Gerum
2006-04-21 16:03     ` Jan Kiszka
2006-06-04 17:58 ` Philippe Gerum

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4446B348.10403@domain.hid \
    --to=jan.kiszka@domain.hid \
    --cc=xenomai@xenomai.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.