All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai-help] Posix skin illegal seek on sem_wait
@ 2006-04-25 11:43 Daniel Simon
  2006-04-25 13:44 ` Gilles Chanteperdrix
  0 siblings, 1 reply; 5+ messages in thread
From: Daniel Simon @ 2006-04-25 11:43 UTC (permalink / raw)
  To: xenomai

[-- Attachment #1: Type: text/plain, Size: 1057 bytes --]

Hello all,

I am a xenomai newbie, and testing some of my existing test programs
with the xenomai posix skin.

While testing the file in attachment (testwait) the semaphore does not
block and returns errno 29 (illegal seek). What can be the reason? This
program runs (with a bad timing) under plain 2.6.15 linux.

Mining in the list archive I have found the following sentence (post on
Fri, 21 Oct 2005) : "Pending on a semaphore is forbidden for non-Xenomai
threads..."

What makes the difference between a Xenomai thread and an ordinary nptl
thread, other than the compilation and linking flags?

	Daniel

-- 
***********The difference between theory and practice****************
**************is larger in practice than in theory*******************

      Daniel SIMON    Projet POP ART  INRIA Rhone-Alpes
ZIRST, 655 avenue de l'Europe, 38330 MONTBONNOT SAINT MARTIN, FRANCE 
 Daniel.Simon@domain.hid Phone:(33)476615328 Fax:(33)476615252
	 http://pop-art.inrialpes.fr/people/simon/

*********************************************************************

[-- Attachment #2: testwait.c --]
[-- Type: text/x-csrc, Size: 7552 bytes --]

#include "testwait.h"

///Function that returns the cpu time in nanoseconds
inline long long GetCpuTime(void)
{
    clock_gettime(HORLOGE, &orctime);
    return (long long)((&orctime)->tv_sec) *NSEC_PER_SEC + (long long)((&orctime)->tv_nsec);
}

// Trap Ctrl C Interruption
void InterruptC_Handler(void)
{
    printf("Ctrl C Interrupt\n");
    printf ("jittermoy = %ld, jittermax = %ld \n", (long)moy / ji, (long)max);
    printf("sem_post(mainSem); \n");
    sem_post(mainSem);
}

int orcTimerSigMask(void)
{
    sigset_t set/* , oldsig */;
    /* int status; */

    sigfillset(&set);
    if (pthread_sigmask(SIG_BLOCK, &set, NULL) != OK)
    {
        printf("pthread_sigmask Failed %d \n", errno);
        return ERROR;
    }
    sigemptyset(&set);
    sigaddset(&set, SIGINT);
    if (pthread_sigmask(SIG_UNBLOCK, &set, NULL) != OK)
    {
        printf("pthread_sigmask Failed %d \n", errno);
        return ERROR;
    }

    return OK;
}
int orcTimerSigUnMask(void)
{
    sigset_t set/* , oldsig */;
    /* int status; */

    sigfillset(&set);
    if (pthread_sigmask(SIG_BLOCK, &set, NULL) != OK)
    {
        printf("pthread_sigmask Failed %d \n", errno);
        return ERROR;
    }

    sigemptyset(&set);
    sigaddset(&set, TIMER1_SIGNAL);
    if (pthread_sigmask(SIG_UNBLOCK, &set, NULL) != OK)
    {
        printf("pthread_sigmask Failed %d \n", errno);
        return ERROR;
    }
    sigemptyset(&set);
    sigaddset(&set, SIGINT);
    if (pthread_sigmask(SIG_UNBLOCK, &set, NULL) != OK)
    {
        printf("pthread_sigmask Failed %d \n", errno);
        return ERROR;
    }

    return OK;
}

void setTimer(void)
{

    printf("setTimer function\n");
    orcTimerSigMask();
    pthread_sigmask(SIG_SETMASK, NULL, &oldsig);
    if ((status = sigismember(&oldsig, TIMER1_SIGNAL)) == 0) printf("TIMER1_SIGNAL NOT BLOCKED in begin setTimer\n");
    else if (status == 1) printf("TIMER1_SIGNAL is BLOCKED in begin setTimer\n");
    else perror("error in sigismember()");

    printf("waiting mainSem...\n");

        err = sem_wait(mainSem);
        printf("mainSem returns %d  ", err);
        if (err != 0) {perror("mainSem");
	  printf("errno = %d \n", errno);}

    printf("finishing...\n");
    // Cancel the timer
    if (timer_delete(t1) == OK) printf("timer deleted\n");

    return ;

}
void clock_it(void)
{
  int Nsig;
  sigset_t clockset;
  
  orcTimerSigMask();
    sigemptyset(&clockset);
    sigaddset(&clockset,TIMER1_SIGNAL);
  printf("clock-it init\n");
    pthread_sigmask(SIG_SETMASK, NULL, &oldsig);
    status = sigismember(&oldsig, TIMER1_SIGNAL);
    if (status == 0) printf("TIMER1_SIGNAL NOT BLOCKED in clock-it\n");
    else if (status == 1) printf("TIMER1_SIGNAL is BLOCKED in clock-it\n");
    else perror("clock-it init error in sigismember()");

    while (1)
    {
      printf("before sigwait \n");
      sigwait(&clockset,&Nsig); 
      printf("clock_it loop\n");
        now = GetCpuTime();

        if (ji == 0)
        {
            max = moy = drift = 0;
            startime = now;
            ji++;
        }
        else if (ji == 1)
        {
            ji++;startime = now;
        }
        else
        {
            jinc = (now - startime) / 1000;
            jitter = (jinc - (long long) new_setting1.it_interval.tv_nsec / 1000);
            drift += jitter;
            hjitter = abs(jitter);
            moy += hjitter;
            ji++;
            if (hjitter > max) max = hjitter;
#ifdef DEBUG
            printf("increment %ld absjitter %ld drift %ld \n", (long)jinc, (long) hjitter, (long) drift);
#endif
            startime = now;
        }
    }
    return;
}

int main(void)
{
    signal(SIGINT, (void(*)(int))InterruptC_Handler);
    pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
    mysched.sched_priority = sched_get_priority_max(SCHED_FIFO) - 1;
    if ( sched_setscheduler( 0, SCHED_FIFO, &mysched ) == -1 )
    {
        printf("ERROR IN SETTING THE POSIX SCHEDULER\n");
        exit(1);
    }
    mlockall(MCL_CURRENT | MCL_FUTURE);
    orcTimerSigMask();
    pthread_sigmask(SIG_SETMASK, NULL, &oldsig);
    if ((status = sigismember(&oldsig, TIMER1_SIGNAL)) == 0) printf("TIMER1_SIGNAL NOT BLOCKED in main\n");
    else if (status == 1) printf("TIMER1_SIGNAL is BLOCKED in main\n");
    else perror("error in sigismember()");
    printf("RTSIG_MAX = %ld\n", sysconf(_SC_RTSIG_MAX));
    RTPRIO_MIN = sched_get_priority_min(SCHED_FIFO);
    RTPRIO_MAX = sched_get_priority_max(SCHED_FIFO);
    printf("RTPRIO_MIN = %d RTPRIO_MAX = %d\n", RTPRIO_MIN, RTPRIO_MAX);


    mainSem = malloc(sizeof(sem_t));
    if (mainSem == 0)
    {
        printf("ERROR mainSem init \n");
        return 0;
    }
    memset(mainSem, 0, sizeof(sem_t));

    if ((status = sem_init(mainSem, 0, 0)) == OK)
    {
#ifdef DEBUG
        printf("mainSemCreate %p\n", mainSem);
#endif

    }
    else
    {
        printf("mainSemCreate failed\n"); exit(1);
    }

    sig1.sigev_notify = SIGEV_SIGNAL;
    sig1.sigev_signo = TIMER1_SIGNAL;
    sig1.sigev_value.sival_ptr = &t1;

    new_setting1.it_value.tv_sec = 0;
    new_setting1.it_value.tv_nsec = 2000000;
    new_setting1.it_interval.tv_sec = 0;
    new_setting1.it_interval.tv_nsec = 2000000;
#ifdef DEBUG
    printf("TimerSetTime:: new_setting1.it_interval.tv_sec = %ld, new_setting1.it_interval.tv_nsec = %ld \n", new_setting1.it_interval.tv_sec, new_setting1.it_interval.tv_nsec);

    toto = clock_getres(HORLOGE, &clock_resolution);
    printf("Clock resolution is %ld seconds, %ld nanoseconds\n",
           clock_resolution.tv_sec, clock_resolution.tv_nsec);
#endif
    retval = timer_create(HORLOGE, &sig1, &t1);
    if (retval != 0)
    {
        printf("TIMER_CREATE() FAILED\n");
        exit(1);
    }
    else printf("timer created\n");
    if (timer_settime(t1, 0, &new_setting1, NULL) == 0) printf("posix timer runs\n");

    pthread_sigmask(SIG_SETMASK, NULL, &oldsig);
    if ((status = sigismember(&oldsig, TIMER1_SIGNAL)) == 0) printf("TIMER1_SIGNAL NOT BLOCKED in endof setTimer\n");
    else if (status == 1) printf("TIMER1_SIGNAL is BLOCKED in endof setTimer\n");
    else perror("error in sigismember()");

    if (((tid) = (pthread_t*) malloc (sizeof(pthread_t))) == NULL)
    {
        printf("Error malloc orcspawn\n" );
        exit(1);
    }
    if (pthread_create(tid, NULL, (FUNCPTR)clock_it, arg) != 0)
    {
        printf("pthread_create failed\n"); exit(1);
    }
    schedattributes.sched_priority = RTPRIO_MAX;
    pthread_setschedparam(*tid, SCHED_FIFO, &schedattributes);
    pthread_getschedparam(*tid, &pol, &schedattriget);
    prioget = schedattriget.sched_priority;
    printf("thr clock-it created pol %d prio %d Id %p \n", pol, prioget, tid);


    if (pthread_create(&thr_setTimer, NULL, (FUNCPTR)setTimer, NULL) != 0)
    {
        printf("thr_setTimer failed\n"); exit(1);
    }
    schedattributes.sched_priority = RTPRIO_MAX;
    pthread_setschedparam(thr_setTimer, SCHED_FIFO, &schedattributes);
    pthread_getschedparam(thr_setTimer, &pol, &schedattriget);
    prioget = schedattriget.sched_priority;
    printf("thr_setTimer created pol %d prio %d Id %p \n", pol, prioget,&thr_setTimer );
    //waiting...
    pthread_join(thr_setTimer, NULL);
    printf("pthread_join returns\n");

    j = sem_destroy(mainSem);
    if (j == OK)
    {
        free(mainSem); printf("mainSem deleted\n");
    }
    if (pthread_kill(*tid, 0) == OK)
    {
        printf("TaskDelete %p\n", tid);
        status = pthread_cancel(*tid);
    }
    if (status == OK) free(tid);
    return OK;
}


[-- Attachment #3: testwait.h --]
[-- Type: text/x-chdr, Size: 1734 bytes --]

#include <features.h>
#include <values.h>
#include <unistd.h>
#include <limits.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <errno.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <semaphore.h>
#include <pthread.h>
#include <sched.h>
#include <posix_time.h>
#include <bits/siginfo.h> 
#include <asm/mman.h>
#include <unistd.h> /* pour libc5 */
#include <sys/io.h> /* pour glibc */ 
#define ADR_LPT 0x378;  // ou 0x278
#include <linux/module.h>

typedef void * (*FUNCPTR) (void *);
typedef void * (*SOSO) (void *); /**< Special type to be used for casting in pthread_create() */

#define NSEC_PER_SEC 1000000000

#define OK 0
#define ERROR -1
#define STATUS int

#define FALSE 0
#define TRUE 1
//#define TIMER1_SIGNAL SIGALRM
#define TIMER1_SIGNAL SIGRTMAX
//#define HORLOGE CLOCK_REALTIME 
#define HORLOGE CLOCK_MONOTONIC
#define POLICY 1

static int ji = 0;
//static int togparport = 0;
static long long startime, now;
static long long hjitter, jinc, max, moy, drift, jitter;
struct timespec clock_resolution;
struct itimerspec new_setting1, current;
int toto;
struct timespec orctime, oldtime, inittime;
int cr = OK;
struct sched_param mysched;
struct sigevent sig1;
struct sigaction old_sa;
timer_t t1;
static sigset_t oldsig;
int j, retval;
sem_t * mainSem;
sem_t * handSem;
int status, err;
pthread_t * tid;
pthread_attr_t attributes;
struct sched_param schedattributes;
char *dummy;
int pol, prio = 99;
void * arg;
int prioget;
struct sched_param schedattriget;
union sigval sval;
siginfo_t t1info;
pthread_t thr_setTimer;
int RTPRIO_MIN, RTPRIO_MAX;

[-- Attachment #4: Makefile --]
[-- Type: application/octet-stream, Size: 1150 bytes --]


# To use this makefile with xeno-config not located in PATH, type :
# make XENO_CONFIG=/path/to/xeno-config
XENO_CONFIG=xeno-config
prefix := $(shell $(XENO_CONFIG) --prefix)


ifeq ($(prefix),)
$(error Please add <xenomai-install-path>/bin to your PATH variable or type: \
make XENO_CONFIG=<xenomai-install-path>/bin/xeno-config)
endif

VERSION = xposix 
ARCH   = linux
APPLI    = Testlat
BIN      =  .
INCLUDE  = -I. -I$(HOME)/include #-I/usr/src/linux-hrt/Documentation/high-res-timers/lib -I/usr/src/linux-hrt/Documentation/high-res-timers/usr_incl   
LIBDIRS_USR  = -L$(HOME)/lib/$(ARCH) #-L/usr/src/linux-hrt/Documentation/high-res-timers/lib
LIB_STATIC = -L/usr/lib/nptl 
LIBS_USR  = -lm -lrt -lpthread  
DEBUG    = -g -DDEBUG
#DEBUG    = -O2 -DDEBUG
CFLAGS   = $(DEBUG) -D_GNU_SOURCE -D_REENTRANT -Wall -Wstrict-prototypes -O2 
CFLAGS_RT:= $(shell $(XENO_CONFIG) --posix-cflags) -g
LDFLAGS_RT:= $(shell $(XENO_CONFIG) --posix-ldflags)

CC = gcc
LD = ld

all: testwait

testwait: testwait.c testwait.h
	$(CC) $(CFLAGS) $(CFLAGS_RT) $(LDFLAGS_RT) -o testwait testwait.c $(INCLUDE) $(LIBDIRS_USR) $(LIBS_USR)


clean: 
	rm -rf testwait  *.o *~

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Xenomai-help] Posix skin illegal seek on sem_wait
  2006-04-25 11:43 [Xenomai-help] Posix skin illegal seek on sem_wait Daniel Simon
@ 2006-04-25 13:44 ` Gilles Chanteperdrix
  2006-04-25 14:54   ` Daniel Simon
  0 siblings, 1 reply; 5+ messages in thread
From: Gilles Chanteperdrix @ 2006-04-25 13:44 UTC (permalink / raw)
  To: Daniel Simon; +Cc: xenomai

Daniel Simon wrote:
 > What makes the difference between a Xenomai thread and an ordinary nptl
 > thread, other than the compilation and linking flags?

The term "Xenomai thread" comes from the document "Life with Adeos":

http://snail.fsffrance.org/www.xenomai.org/documentation/trunk/pdf/Life-with-Adeos-rev-B.pdf

A Xenomai thread is a thread known by Xenomai scheduler. Ordinary
linuxthread or NPTL threads are known by Xenomai scheduler once they
acquire a "shadow" thread.

With the posix skin, an ordinary thread is created with a shadow thread
if you use the pthread_create service with the policy attribute (whether
explicit or inherited) set to SCHED_FIFO, or an ordinary thread may
acquire a shadow thread if this ordinary thread calls the
pthread_setschedparam service passing the value SCHED_FIFO as the policy
argument.

Please also note that for now, signals sent by the timer_* services will
cause migration of the target thread to secondary mode, which means that
the jitter will not be better for Xenomai threads than for ordinary
threads. For good timings, you should use the nanosleep or
clock_nanosleep services, or alternatively the non portable extensions
pthread_make_periodic_np and pthread_wait_np.

For other details about Xenomai implementation of the POSIX API, see:
http://snail.fsffrance.org/www.xenomai.org/documentation/trunk/html/api/group__posix.html

-- 


					    Gilles Chanteperdrix.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Xenomai-help] Posix skin illegal seek on sem_wait
  2006-04-25 13:44 ` Gilles Chanteperdrix
@ 2006-04-25 14:54   ` Daniel Simon
  2006-04-25 15:12     ` Gilles Chanteperdrix
  2006-04-25 16:04     ` Gilles Chanteperdrix
  0 siblings, 2 replies; 5+ messages in thread
From: Daniel Simon @ 2006-04-25 14:54 UTC (permalink / raw)
  To: xenomai

On Tue, 25 Apr 2006 15:44:02 +0200
Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org> wrote:

> The term "Xenomai thread" comes from the document "Life with Adeos":

The shadowing process is not clear in this paper, e.g. bottom of page 6:

<<Xenomai allows to run real-time threads either strictly in kernel
space, or within the address space of a Linux process. In the rest of
this article, we will refer to the latter as the Xenomai threads, not
to be confused with regular Linux tasks (even when they belong to the
SCHED_FIFO class).>> 

I guess that "regular Linux tasks unknown to Xenomai, and which
only happen to belong to the SCHED_FIFO class" are those compiled and
linked against the regular pthread library?

Anyway, my threads are created with the SCHED_FIFO flag; may be there
is a conflict with main() which, as I understand, can be only a regular
thread?

>signals sent by the timer_* services will
>cause migration of the target thread to secondary mode

I notice that timer_settime(...) also returns an error (perror
says "Operation not permitted" while errno is set to 29 "illegal
seek", as for the sem_wait)

>signals [...] cause migration of the target thread to secondary mode

is it only a "not yet implemented" feature or is it a basic
conflict between signals and hard real-time?

	Thanks

		Daniel 




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Xenomai-help] Posix skin illegal seek on sem_wait
  2006-04-25 14:54   ` Daniel Simon
@ 2006-04-25 15:12     ` Gilles Chanteperdrix
  2006-04-25 16:04     ` Gilles Chanteperdrix
  1 sibling, 0 replies; 5+ messages in thread
From: Gilles Chanteperdrix @ 2006-04-25 15:12 UTC (permalink / raw)
  To: Daniel Simon; +Cc: xenomai

Daniel Simon wrote:
 > On Tue, 25 Apr 2006 15:44:02 +0200
 > Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org> wrote:
 > 
 > > The term "Xenomai thread" comes from the document "Life with Adeos":
 > 
 > The shadowing process is not clear in this paper, e.g. bottom of page 6:
 > 
 > <<Xenomai allows to run real-time threads either strictly in kernel
 > space, or within the address space of a Linux process. In the rest of
 > this article, we will refer to the latter as the Xenomai threads, not
 > to be confused with regular Linux tasks (even when they belong to the
 > SCHED_FIFO class).>> 
 > 
 > I guess that "regular Linux tasks unknown to Xenomai, and which
 > only happen to belong to the SCHED_FIFO class" are those compiled and
 > linked against the regular pthread library?

The difference between regular threads and Xenomai threads is rather a
run-time issue than a link-time issue. If Xenomai POSIX skin
pthread_create and pthread_setschedparam services are called with
incorrect arguments (not SCHED_FIFO), they fall back to the services of
the regular posix threading library.

 > 
 > Anyway, my threads are created with the SCHED_FIFO flag; may be there
 > is a conflict with main() which, as I understand, can be only a regular
 > thread?

Real-time shadows are listed in /proc/xenomai/sched; do you see them
there ? You may use pthread_set_name_np to set their name.

 > 
 > >signals sent by the timer_* services will
 > >cause migration of the target thread to secondary mode
 > 
 > I notice that timer_settime(...) also returns an error (perror
 > says "Operation not permitted" while errno is set to 29 "illegal
 > seek", as for the sem_wait)

As documented, if the caller context is invalid, the error should be
EPERM (Operation not permitted), not ESPIPE (illegal seek). Anyway, I am
trying to run your program here to see what is wrong.

 > 
 > >signals [...] cause migration of the target thread to secondary mode
 > 
 > is it only a "not yet implemented" feature or is it a basic
 > conflict between signals and hard real-time?

It is not yet implemented.

-- 


					    Gilles Chanteperdrix.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Xenomai-help] Posix skin illegal seek on sem_wait
  2006-04-25 14:54   ` Daniel Simon
  2006-04-25 15:12     ` Gilles Chanteperdrix
@ 2006-04-25 16:04     ` Gilles Chanteperdrix
  1 sibling, 0 replies; 5+ messages in thread
From: Gilles Chanteperdrix @ 2006-04-25 16:04 UTC (permalink / raw)
  To: Daniel Simon; +Cc: xenomai

Daniel Simon wrote:
 > Anyway, my threads are created with the SCHED_FIFO flag; may be there
 > is a conflict with main() which, as I understand, can be only a regular
 > thread?

A thread may only shadow itself, so, pthread_setschedparam has to be
called from the threads that need to be shadowed. Alternatively you may
pass scheduling parameters when pthread_create is called. Your threads
are not really created real-time, this is the reason why the Xenomai
posix skin services you call return an error of EPERM. Note however that
calling pthread_setschedparam is more portable than passing thread
creation attributes to pthread_create.

 > 
 > I notice that timer_settime(...) also returns an error (perror
 > says "Operation not permitted" while errno is set to 29 "illegal
 > seek", as for the sem_wait)
 > 

The reason why you see errno set to ESPIPE, is because you call perror
before printing errno, and perror seems to overwrite errno. In order to
access errno safely, you should store its value immediately after a
service returning an error.

Another issue is that signals sent by Xenomai posix skin are directed to
the thread that issued the call to timer_settime, regardless of threads
signal mask, so timer_settime should be moved to the clock_it()
thread.

A last issue is that pthread_sigmask errors are returned directly, and
not through errno.

-- 


					    Gilles Chanteperdrix.


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2006-04-25 16:04 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-04-25 11:43 [Xenomai-help] Posix skin illegal seek on sem_wait Daniel Simon
2006-04-25 13:44 ` Gilles Chanteperdrix
2006-04-25 14:54   ` Daniel Simon
2006-04-25 15:12     ` Gilles Chanteperdrix
2006-04-25 16:04     ` Gilles Chanteperdrix

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.