Ulrich Schwab wrote:
 > On Friday 09 December 2005 15:33, Paolo Gai wrote:
 > > Dear all,
 > >
 > > First of all, I would like to thank Philippe for the long and exaustive
 > > reply to my previous post about the scheduling example.
 > >
 > > I'm now trying the POSIX skin to write a very simple example using
 > > real-time priorities, RR and FIFO scheduling.
 > >
 > > The idea is that a high priority task creates two medium priority tasks
 > > (that just prints something using printf) and a low priority task (that
 > > prints a message).  The example is run twice, in one case the medium
 > > priority tasks have SCHED_FIFO, in another case they have SCHED_RR.
 > >
 > > I would expect that in both cases the two medium priority tasks would
 > > run printing their characters (either in a FIFO order or mixed when
 > > using RR), and at their end the low priority task would have run
 > > printing its message.
 > I did not look inside Your code, but if You are using printf the threads 
 > will 
 > be switched back to secondary domain (non-RT), this might screw up the order 
 > of scheduling.

What happens for certain is that the access to stdout buffer, when
compiling with the -D_REENTRANT flag, is serialized with a GNU libc
POSIX mutex. This account for the consistent behaviour between GNU libc
libpthread, or Xenomai POSIX skin library. The scheduling order is the
one of the libc POSIX library, and knowing exactly what happens would
require further investigation (there may be a difference between NPTL
and linuxthreads for example).

Working around this issue means using calls to unlocked versions of libc
functions protected with Xenomai POSIX mutexes, such as, for example,
myputs and myputchar (sufficient for Paolo example) defined as :

pthread_mutex_t xeno_stdout_lock;

int myputchar(int c)
{
    int err;

    pthread_mutex_lock(&xeno_stdout_lock);
    err = putchar_unlocked(c);
    pthread_mutex_unlock(&xeno_stdout_lock);

    return err;
}

int myputs(const char *s)
{
    int err;

    pthread_mutex_lock(&xeno_stdout_lock);
    err = puts_unlocked(s);
    pthread_mutex_unlock(&xeno_stdout_lock);

    return err;
}

defining myprintf is a bit more complicated if we want to avoid dynamic
allocation, and if we do not avoid dynamic allocation, malloc is
protected with another mutex, so we may run (less often, of course) into
a similar issue.

Now, your answer yields another important question: are domain
migrations inocuous from a scheduling point of view ?
Intuitively, if two tasks A and B in the same priority group are
runnable, and task A undergoes a migration from secondary to primary,
followed by a migration from primary to secondary without a suspension,
the scheduling order will be wrong.

The reason for this behaviour is that when task A migrates from
primary mode to secondary mode and will be waken up in Linux scheduler,
it should be put at the end of its priority group, so that B should
become the running task.

In short, the two successive migrations are equivalent to calling
sched_yield() from Linux scheduler point of view.

-- 


                                            Gilles Chanteperdrix.

_______________________________________________
Xenomai-help mailing list
Xenomai-help@gna.org
https://mail.gna.org/listinfo/xenomai-help

Reply via email to