Gilles Chanteperdrix wrote:
Paolo Gai wrote:
> Gilles Chanteperdrix wrote:
> >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 :
> >[...]
> >
> >
> Ok! I tried it, and I also tried another slightly modified version of
> the demo, that simply replaces putchars with an unprotected array of
> chars (let's suppose there are no race conditions) that is printed out
> to stdout at the end of the game.
There is no race condition in the SCHED_FIFO case or ahem, there should
be none.
Yes, that's true...
Please also note that the "volatile" qualifier seem misplaced
in your declaration of buf_current, it may matter since the compiler
will probably inline calls to myputchar in the "medium" function, and
buf_current will end up in a register. But this would have no effect
only in the SCHED_FIFO case.
Ouch! I just added it in the last tries and I forgot to remove it - sorry;
However, I checked the source code produced by the compiler on i386 with
the default compiler of FC3 and the code produced is the same with and
without volatile;
> the results are the following, where the first part is RR and the second
> is FIFO (it's quite strange for me that FIFO has more contect changes
> than RR (?))
Please also note that any thread created with the SCHED_RR attribute
will be a plain Linux thread, and due to a bug in glibc, the thread will
use the default policy. The results are strange indeed for SCHED_FIFO,
it may be a bug, this needs a closer look... Maybe threads are not
Xenomai threads using SCHED_FIFO policy at all ?
Ok... I've done some more experiments. here are some results, with
screenshots :-)
First thing, I found this snippet
http://sources.redhat.com/ml/glibc-bugs/2004-05/msg00003.html
that shows how on Linux and NPTL setting realtime priorities simply
fails... I tried it on my FC3, and the behavior is the same, confirming
the bug on my distro.
Then, I slightly modified the example of the previous posts, setting the
thread priorities with pthread_setschedparam.
----------------------------
Case 1/Linux: Printing on the console using stdio, Linux real-time threads
Screenshot:
[EMAIL PROTECTED] xenomai-demos]# ./ex_rr3
thread id = 0xb7f0dbb0, policy = SCHED_OTHER, priority = 0
thread id = 0xb7f0dbb0, policy = SCHED_RR, priority = 3
...........###########............############...........###########...........###########............############...........###########...........###########............############...........###########............###########...........############...........###########............############...........###########...........###########............############...........###########...........###########............############...........###########............###########...........############...........###########............############...........###########...........###########.....#####LOW
priority thread!!!
............................................................................................................................................................................................................................................................................................................############################################################################################################################################################################################################################################################################################################LOW
priority thread!!!
[EMAIL PROTECTED] xenomai-demos]#
everything is fine, SCHED_RR and SCHED_FIFO works as expected, while the
demo runs the XServer is freezed.
----------------------------
Case 1/Xenomai: Printing on the console using stdio, Xenomai real-time
threads
Screenshot:
[EMAIL PROTECTED] xenomai-demos]# ./rt_ex_rr3
thread id = 0xb7fc7bb0, policy = SCHED_OTHER, priority = 0
pthread_setschedparam failed: Success
thread id = 0xb7fc7bb0, policy = SCHED_OTHER, priority = 0
pthread_setschedparam failed: Success
pthread_setschedparam failed: Success
.....########LOW priority thread!!!
##################################################################################################....................................................................................................##################################################################################################................................................................................................################################################################################################...............................................................................................................................................................................................................................................................................................................................................................................................................############################################################################################################################################################################################################################################################################################################LOW
priority thread!!!
[EMAIL PROTECTED] xenomai-demos]#
1) why do i get "pthread_setschedparam failed: Success" ?? Why the
policy is not changed (am I still calling the Linux functions?)
2) The SCHED_FIFO seems to work as expected, whereas SCHED_RR seems to
have a strange behavior when it starts (the low priority thread is
started before the others...
3) the XServer freezes but for a SHORTER time - I guess they are the
Xenomai threads, one thing I do not understand is why with Linux the
XServer stops for around 10 seconds, and in Xenomai less than one second!!!
----------------------------
Case 2/Linux: Printing on the console using a shared buffer, Linux
real-time threads
Screenshot:
[EMAIL PROTECTED] xenomai-demos]# ./ex_rr4
thread id = 0xb7fcabb0, policy = SCHED_OTHER, priority = 0
thread id = 0xb7fcabb0, policy = SCHED_RR, priority = 3
.............############...........###########...........###########...........############............###########...........###########...........############............###########...........###########...........###########............############...........###########...........###########...........############............###########...........###########...........############............###########...........###########............############...........###########...........############............###########...........###########...........############............###########....#####L
............................................................................................................................................................................................................................................................................................................############################################################################################################################################################################################################################################################################################################L
[EMAIL PROTECTED] xenomai-demos]#
works as expected, the same behavior as Case1/Linux.
----------------------------
Case 2/xenomai: Printing on the console using a shared buffer, Xenomai
real-time threads
Screenshot:
[EMAIL PROTECTED] xenomai-demos]# ./rt_ex_rr4
thread id = 0xb7f25bb0, policy = SCHED_OTHER, priority = 0
pthread_setschedparam failed: Success
thread id = 0xb7f25bb0, policy = SCHED_OTHER, priority = 0
pthread_setschedparam failed: Success
pthread_setschedparam failed: Success
...............#############L................................................................................................................................................................##################################################################################################################################################################.............................................................................................................................#############################################################################################################################
............................................................................................................................................................................................................................................................................................................############################################################################################################################################################################################################################################################################################################L
[EMAIL PROTECTED] xenomai-demos]#
Again, the same behavior as before in Case 1/Xenomai
which make me think that
- the behavior on Xenomai does not depend a lot on the fact i called
stdio functions
- the SCHED_RR maybe still has some problems (???)
ok, that's all for now, sorry again for the long mail.
Paolo
/*
* this version uses pthread_setschedparam as a workaround of the
* glibc bug, prints using stdio
*/
#include <string.h>
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
/* for sched_param.c */
#include <sched.h>
/* --------------------------------------------- */
/* source from http://sources.redhat.com/ml/glibc-bugs/2004-05/msg00003.html */
#define LPRIO 1
#define MPRIO 2
#define HPRIO 3
void show_sched(void)
{
struct sched_param sp;
int policy;
const char *pstr;
if (pthread_getschedparam(pthread_self(), &policy, &sp) != 0) {
perror("pthread_getschedparam failed");
return;
}
switch(policy) {
case SCHED_OTHER:
pstr = "SCHED_OTHER";
break;
case SCHED_FIFO:
pstr = "SCHED_FIFO";
break;
case SCHED_RR:
pstr = "SCHED_RR";
break;
default:
pstr = "unknown";
}
printf("thread id = 0x%lx, policy = %s, priority = %d\n",
pthread_self(), pstr, sp.sched_priority);
return;
}
void set_sched(int policy, int priority)
{
struct sched_param schedp;
memset(&schedp, 0, sizeof(schedp));
schedp.sched_priority = priority;
if (pthread_setschedparam(pthread_self(), policy, &schedp) != 0)
perror("pthread_setschedparam failed");
}
/* --------------------------------------------- */
void *low(void *arg)
{
set_sched(SCHED_FIFO, LPRIO);
printf("LOW priority thread!!!\n");
return NULL;
}
struct medium_par_t {
int policy;
char *c;
} mp1, mp2;
void *medium(void *arg)
{
int i,j;
struct medium_par_t *p = (struct medium_par_t *)arg;
set_sched(p->policy, MPRIO);
for (i=0; i<300; i++) {
for (j=0; j<1000000; j++) ;
printf(p->c);
}
return NULL;
}
void my_create(int policy)
{
pthread_t th1, th2, th3;
pthread_attr_t medium_attr, low_attr;
struct sched_param medium_policy, low_policy;
pthread_attr_init(&medium_attr);
pthread_attr_setschedpolicy(&medium_attr, policy);
medium_policy.sched_priority = 2;
pthread_attr_setschedparam(&medium_attr, &medium_policy);
pthread_attr_init(&low_attr);
pthread_attr_setschedpolicy(&low_attr, SCHED_FIFO);
low_policy.sched_priority = 1;
pthread_attr_setschedparam(&low_attr, &low_policy);
mp1.policy = mp2.policy = policy;
mp1.c = ".";
mp2.c = "#";
pthread_create(&th1, &medium_attr, medium, (void *)&mp1);
pthread_create(&th2, &medium_attr, medium, (void *)&mp2);
pthread_create(&th3, &low_attr, low, NULL);
pthread_attr_destroy(&medium_attr);
pthread_attr_destroy(&low_attr);
pthread_join(th1, NULL);
pthread_join(th2, NULL);
pthread_join(th3, NULL);
}
void *high(void *arg)
{
show_sched();
set_sched(SCHED_RR, HPRIO);
show_sched();
/* first experiment:
- two medium priority thread scheduled with RR
- one low priority thread scheduled with FIFO
*/
my_create(SCHED_RR);
/* second experiment:
- two medium priority thread scheduled with FIFO
- one low priority thread scheduled with FIFO
*/
my_create(SCHED_FIFO);
return NULL;
}
int main()
{
pthread_t mythread;
pthread_attr_t myattr;
struct sched_param myparam;
int err;
int parameter;
void *returnvalue;
/* initializes the thread attribute */
pthread_attr_init(&myattr);
pthread_attr_setschedpolicy(&myattr, SCHED_FIFO);
myparam.sched_priority = 3;
pthread_attr_setschedparam(&myattr, &myparam);
err = pthread_create(&mythread, &myattr, high, (void *)¶meter);
if (err) {
perror("ERROR");
exit(1);
}
pthread_attr_destroy(&myattr);
/* wait the end of the thread we just created */
pthread_join(mythread, &returnvalue);
return 0;
}
/*
* this version uses pthread_setschedparam as a workaround of the
* glibc bug, prints using a shared buffer
*/
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
/* for sched_param.c */
#include <sched.h>
/* --------------------------------------------- */
/* source from http://sources.redhat.com/ml/glibc-bugs/2004-05/msg00003.html */
#define LPRIO 1
#define MPRIO 2
#define HPRIO 3
void show_sched(void)
{
struct sched_param sp;
int policy;
const char *pstr;
if (pthread_getschedparam(pthread_self(), &policy, &sp) != 0) {
perror("pthread_getschedparam failed");
return;
}
switch(policy) {
case SCHED_OTHER:
pstr = "SCHED_OTHER";
break;
case SCHED_FIFO:
pstr = "SCHED_FIFO";
break;
case SCHED_RR:
pstr = "SCHED_RR";
break;
default:
pstr = "unknown";
}
printf("thread id = 0x%lx, policy = %s, priority = %d\n",
pthread_self(), pstr, sp.sched_priority);
return;
}
void set_sched(int policy, int priority)
{
struct sched_param schedp;
memset(&schedp, 0, sizeof(schedp));
schedp.sched_priority = priority;
if (pthread_setschedparam(pthread_self(), policy, &schedp) != 0)
perror("pthread_setschedparam failed");
}
/* --------------------------------------------- */
/* ------------------------------------------------------------ */
/* unprotected buffer to avoid migrations */
char buf[10000];
char *buf_current=buf;
void myputchar(char c)
{
*buf_current++ = c;
}
void myprintbuf(void)
{
*buf_current=0;
puts(buf);
}
/* ------------------------------------------------------------ */
void *low(void *arg)
{
set_sched(SCHED_FIFO, LPRIO);
myputchar('L');
return NULL;
}
struct medium_par_t {
int policy;
char *c;
} mp1, mp2;
void *medium(void *arg)
{
int i,j;
struct medium_par_t *p = (struct medium_par_t *)arg;
set_sched(p->policy, MPRIO);
for (i=0; i<300; i++) {
for (j=0; j<1000000; j++) ;
myputchar(p->c[0]);
}
return NULL;
}
void my_create(int policy)
{
pthread_t th1, th2, th3;
pthread_attr_t medium_attr, low_attr;
struct sched_param medium_policy, low_policy;
pthread_attr_init(&medium_attr);
pthread_attr_setschedpolicy(&medium_attr, policy);
medium_policy.sched_priority = 2;
pthread_attr_setschedparam(&medium_attr, &medium_policy);
pthread_attr_init(&low_attr);
pthread_attr_setschedpolicy(&low_attr, SCHED_FIFO);
low_policy.sched_priority = 1;
pthread_attr_setschedparam(&low_attr, &low_policy);
mp1.policy = mp2.policy = policy;
mp1.c = ".";
mp2.c = "#";
pthread_create(&th1, &medium_attr, medium, (void *)&mp1);
pthread_create(&th2, &medium_attr, medium, (void *)&mp2);
pthread_create(&th3, &low_attr, low, NULL);
pthread_attr_destroy(&medium_attr);
pthread_attr_destroy(&low_attr);
pthread_join(th1, NULL);
pthread_join(th2, NULL);
pthread_join(th3, NULL);
myputchar(' ');
myputchar(' ');
myputchar(' ');
}
void *high(void *arg)
{
show_sched();
set_sched(SCHED_RR, HPRIO);
show_sched();
/* first experiment:
- two medium priority thread scheduled with RR
- one low priority thread scheduled with FIFO
*/
my_create(SCHED_RR);
/* second experiment:
- two medium priority thread scheduled with FIFO
- one low priority thread scheduled with FIFO
*/
my_create(SCHED_FIFO);
return NULL;
}
int main()
{
pthread_t mythread;
pthread_attr_t myattr;
struct sched_param myparam;
int err;
void *returnvalue;
/* initializes the thread attribute */
pthread_attr_init(&myattr);
pthread_attr_setschedpolicy(&myattr, SCHED_FIFO);
myparam.sched_priority = 3;
pthread_attr_setschedparam(&myattr, &myparam);
err = pthread_create(&mythread, &myattr, high, NULL);
if (err) {
perror("ERROR");
exit(1);
}
pthread_attr_destroy(&myattr);
/* wait the end of the thread we just created */
pthread_join(mythread, &returnvalue);
myprintbuf();
return 0;
}
_______________________________________________
Xenomai-help mailing list
Xenomai-help@gna.org
https://mail.gna.org/listinfo/xenomai-help