All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Simon <Daniel.Simon@domain.hid>
To: Jan Kiszka <jan.kiszka@domain.hid>
Cc: xenomai-core <xenomai@xenomai.org>
Subject: Re: [Xenomai-core] measuring tasks execution time
Date: Mon, 25 Jun 2007 17:51:07 +0200	[thread overview]
Message-ID: <20070625175107.438849fa@domain.hid> (raw)
In-Reply-To: <46693B6B.1010201@domain.hid>

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

On Fri, 08 Jun 2007 13:20:11 +0200
Jan Kiszka <jan.kiszka@domain.hid> wrote:

Hello,

> Well, the best (==most comfortable :o) ) way from my POV would be if you
> could try rebasing your work on your own first. Questions, even on minor
> details, are always welcome, review on patches will be provided. Should
> be no problem to get this into Xenomai 2.4.
> 
> The rough to-do list would be:
> 
>  o add some persistent runtimer counter to xnthread::stat and maintain
>    it
>  o introduce an xnpod service (inline function) to obtain it (let that
>    thing return [0..LONGLONG_MAX] when stats are available, -1
>    otherwise)
>  o export the runtime via struct rt_task_info, maybe also the task start
>    time

Coming back on this topic:
please find attached a first draft of a patch following (more or less)  your
suggestions:
-there is an additional field "exectime" in  TASK_INFO, which can be set by
rt_task_inquire and read in the info structure (the computation is slightly
different for self and remote measurement);
-xnthread_get_exectime() and xnthread_get_lastswitch() pass the values of the
current thread's  timing out of xn;
-exectime and lastswitch times are stored in an extended xnstat_runtime_t,
updated by xnstat_runtime_update() (but not exactly like the "total" item)

it has been tested (only on  P3 single core cpu) with the testexec program also
attached : there are 2 periodic tasks, clockit and loop, which measure
either their exectime, or the one of the other task: the measures 
seems reasonable, except when the clockit task measures itself, in that case the
first and second printed values are always absurd for a reason I cannot
understand...)

Only works in primary mode... (also I hope that the tsc is monotonic?)

I have no idea of what may happen on a smp or when on the fly migrating tasks!

	Daniel

-- 
       Daniel SIMON    Projet NeCS  INRIA Rhone-Alpes
        Inovallee, 655 avenue de l'Europe, Montbonnot
             38 334 Saint Ismier Cedex France
 Daniel.Simon@domain.hid Phone:(33)476615328 Fax:(33)476615252
          http://necs.inrialpes.fr/people/simon/



[-- Attachment #2: exec-info-2.3.1.patch --]
[-- Type: text/x-patch, Size: 4341 bytes --]

diff -urN xenomai-2.3.1-orig/include/native/task.h xenomai-2.3.1/include/native/task.h
--- xenomai-2.3.1-orig/include/native/task.h	2006-12-26 19:38:57.000000000 +0100
+++ xenomai-2.3.1/include/native/task.h	2007-06-22 16:08:10.000000000 +0200
@@ -91,6 +91,8 @@
     
     char name[XNOBJECT_NAME_LEN];  /**< Symbolic name assigned at creation. */
 
+    xnticks_t exectime; /**<execution time in tsc ticks since the task started. */
+
 } RT_TASK_INFO;
 
 #define RT_MCB_FSTORE_LIMIT  64
diff -urN xenomai-2.3.1-orig/include/nucleus/stat.h xenomai-2.3.1/include/nucleus/stat.h
--- xenomai-2.3.1-orig/include/nucleus/stat.h	2006-12-26 19:38:59.000000000 +0100
+++ xenomai-2.3.1/include/nucleus/stat.h	2007-06-25 15:48:25.000000000 +0200
@@ -31,6 +31,10 @@
 
 	xnticks_t total; /* Accumulated execution time */
 
+	xnticks_t exectime; /* Overall execution time from taskspawn upto lastswitch*/
+
+	xnticks_t lastswitch; /* Last time the task was made active */
+
 } xnstat_runtime_t;
 
 /* Return current date which can be passed to other xnstat services for
@@ -42,6 +46,10 @@
 do { \
 	(sched)->current_account->total += \
 		start - (sched)->last_account_switch; \
+	(sched)->current_account->exectime += \
+                xnstat_runtime_now() - (sched)->last_account_switch; \
+	(sched)->current_account->lastswitch = \
+                xnstat_runtime_now(); \
 	(sched)->last_account_switch = start; \
 } while (0)
 
diff -urN xenomai-2.3.1-orig/include/nucleus/thread.h xenomai-2.3.1/include/nucleus/thread.h
--- xenomai-2.3.1-orig/include/nucleus/thread.h	2007-03-15 15:10:30.000000000 +0100
+++ xenomai-2.3.1/include/nucleus/thread.h	2007-06-22 16:17:24.000000000 +0200
@@ -228,6 +228,7 @@
 
     void *cookie;		/* Cookie to pass to the entry routine */
 
+
     XNARCH_DECL_DISPLAY_CONTEXT();
 
 } xnthread_t;
@@ -277,7 +278,8 @@
 #define xnthread_user_pid(thread) \
     (xnthread_test_state((thread),XNROOT) || !xnthread_user_task(thread) ? \
     0 : xnarch_user_pid(xnthread_archtcb(thread)))
-
+#define xnthread_get_exectime(thread)      ((thread)->stat.account.exectime)
+#define xnthread_get_lastswitch(thread)    ((thread)->stat.account.lastswitch)
 #ifdef __cplusplus
 extern "C" {
 #endif
diff -urN xenomai-2.3.1-orig/ksrc/nucleus/thread.c xenomai-2.3.1/ksrc/nucleus/thread.c
--- xenomai-2.3.1-orig/ksrc/nucleus/thread.c	2007-02-02 02:17:32.000000000 +0100
+++ xenomai-2.3.1/ksrc/nucleus/thread.c	2007-06-22 16:55:08.000000000 +0200
@@ -89,7 +89,10 @@
 	thread->registry.waitkey = NULL;
 #endif /* CONFIG_XENO_OPT_REGISTRY */
 	memset(&thread->stat, 0, sizeof(thread->stat));
-
+#ifdef CONFIG_XENO_OPT_STATS
+	thread->stat.account.exectime = 0;
+	thread->stat.account.lastswitch = 0;
+#endif
 	/* These will be filled by xnpod_start_thread() */
 	thread->imask = 0;
 	thread->imode = 0;
diff -urN xenomai-2.3.1-orig/ksrc/skins/native/task.c xenomai-2.3.1/ksrc/skins/native/task.c
--- xenomai-2.3.1-orig/ksrc/skins/native/task.c	2007-02-28 18:25:52.000000000 +0100
+++ xenomai-2.3.1/ksrc/skins/native/task.c	2007-06-25 16:20:58.000000000 +0200
@@ -1102,15 +1102,22 @@
 
 int rt_task_inquire(RT_TASK *task, RT_TASK_INFO *info)
 {
-	int err = 0;
-	spl_t s;
-
-	if (!task) {
+  int err = 0;
+  spl_t s;
+	/* xnprintf("1- task value ptr = %p \n", (task)); */
+	if (!task) {		
+	 /*  xnprintf("if(!task) est vrai\n"); */
 		if (!xnpod_primary_p())
 			return -EPERM;
-
 		task = xeno_current_task();
 	}
+/* 	else  */
+/* 	  { */
+/* 	     xnprintf("if(!task) est fx\n"); */
+/* 	  } */
+
+/* 	xnprintf("2- task value ptr = %p\n",(task)); */
+	
 
 	xnlock_get_irqsave(&nklock, s);
 
@@ -1126,7 +1133,12 @@
 	info->cprio = xnthread_current_priority(&task->thread_base);
 	info->status = xnthread_state_flags(&task->thread_base);
 	info->relpoint = xntimer_get_date(&task->thread_base.ptimer);
-
+	if(task == xeno_current_task()){
+	  info->exectime = xnthread_get_exectime(&task->thread_base) + (xnstat_runtime_now() - xnthread_get_lastswitch(&task->thread_base));
+	  xnprintf("self inquire runtime_now %llu lastswitch %llu exectime %llu\n", (xnstat_runtime_now()), xnthread_get_lastswitch(&task->thread_base), (info->exectime));}
+	else {
+	  info->exectime = xnthread_get_exectime(&task->thread_base);
+	  xnprintf("not self %lld \n", (long long)info->exectime);}
       unlock_and_exit:
 
 	xnlock_put_irqrestore(&nklock, s);

[-- Attachment #3: testexec.c --]
[-- Type: text/x-csrc, Size: 16605 bytes --]

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/io.h>
#include <sys/mman.h>
#include <native/types.h>
#include <native/task.h>
#include <native/queue.h>
#include <native/intr.h>
#include <native/timer.h>
#include <native/sem.h>
#include <native/alarm.h>
#include <native/heap.h>
#include <native/queue.h>
#include <native/syscall.h>
#define STACK_SIZE 8192
#define MIN_PRIO 1
#define MAX_PRIO 99
#define PRI_MT_MAX MAX_PRIO - 6
#define PRI_MT_MIN MIN_PRIO

typedef void * (*FUNCPTR) (void *);
typedef void (*SOSO) (void *); /**< Special type to be used for casting in task_create() */
#define ORCMSGQ RT_QUEUE *  /**< Message Queue Type */
#define ORCSEM_ID RT_SEM *  /**< Semaphore Type */
#define ORCFULL  1        /**< State of a Full Binary Semaphore */
#define ORCEMPTY 0        /**< State of a Empty Binary Semaphore */
#define ORCFOREVER TM_INFINITE     /**< State of a ??? Binary Semaphore */
#define SIZE_QUEUE  100       /**< Size of the Message Queue */
#define SIZE_MES_MAX 4056    /**< Maximum size of a message in Message Queue */
#define SIZE_MES_MIN 128     /**< Minimum size of a message in Message Queue */ 
/*-------Tasks----------*/
#define ORCTHR_ID RT_TASK * /**< Xeno RT-Task Type */
#define STACKSIZE int      /**< Stack size Type */
#define SCHED_OTHER             0
#define SCHED_FIFO              1
#define SCHED_RR                2
#define SCHEDPOLICY SCHED_FIFO  /**< Scheduling policy (see schedbits.h, sched.h )*/
#define SMALL_STACK  1000           /**< Small task stack size PTHREAD_STACK_MIN not defined */
#define NORMAL_STACK (5*SMALL_STACK)  /**< Normal task stack size */
#define BIG_STACK    (15*SMALL_STACK) /**< Big task stack size */ 
//                     --s-ms-us-ns
RTIME task_period_ns = 500000000llu;
#define NSEC_PER_SEC 1000000000

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

#define FALSE 0
#define TRUE 1
#define POLICY 1

static int ji = 0;
//static int togparport = 0;
static RTIME startime, now; // inittime, nexttime;
struct timespec clock_resolution;
static int message_counter = 0;

RT_ALARM BaseClk;
int status, err, end = 0, loops = 10;

char *dummy;

ORCTHR_ID thr_clockit;
ORCTHR_ID thr_loop;
ORCMSGQ Queue;

ORCSEM_ID SynchroSem;

static int cpt_sem = 10000;
char nameSem[10];
int crexec, cr;
long past = 0;
ORCTHR_ID MAIN_RT;
/*-------Message Queues----------*/
/**
 * Function to create a message queue
 *
 * @param
 * @return ORCMSGQ pointer if message queue created, NULL otherwise and errno is set
 * @see ORCMSGQ
 * @see <sys/msg.h>#msgget
 * @see <sys/msg.h>#msgctl
 */
ORCMSGQ orcMsgQCreate()
{
    size_t size;
    ORCMSGQ OrcQueue;
    message_counter = 0;
    size = SIZE_MES_MAX;
    int err;

    OrcQueue = malloc(sizeof(RT_QUEUE));
    if (OrcQueue == 0)
    {
        printf("ERROR  orcMsgQCreate malloc\n");
        return 0;
    }
    memset(OrcQueue, 0, sizeof(RT_QUEUE));
    if ((err = rt_queue_create(OrcQueue, "OrcRTQ", SIZE_MES_MAX*SIZE_QUEUE, SIZE_QUEUE, Q_FIFO | Q_SHARED)) != 0)
    {
      printf("orcMsgQCreate ERROR %d \n", err);
    }
    else printf("orcMsgQCreate OK\n");
    return OrcQueue;
}

/**
 * Function to get the number of messages pending in a message queue
 *
 * @param queue pointer to the message queue 
 * @return long number of messages if no error occurs otherwise ERROR and errno is set
 * @see <sys/msg.h>#msgctl
 */
long orcMsgQNumMsgs(ORCMSGQ queue)
{
    return (long)message_counter;
}

/**
 * Function to send a message on a message queue
 * Sending the message is done according to a priority level such as :
 *
 * @param queue pointer to the message queue
 * @param msg message to be sent
 * @param prio message priority level
 * @return OK if successfull, ERROR otherwise and errno is set
 * @see <sys/msg.h>#msgsnd
 */
int orcMsgQSend(ORCMSGQ OrcQueue, int msg, int prio)
{
    int i;
    void * tmpbuf;
    size_t orcEventSize;
    orcEventSize = (size_t)sizeof(int);
    if ((tmpbuf = rt_queue_alloc(OrcQueue, orcEventSize)) == 0)
    {
        printf("ERROR orcMsgQSend tmpbuf not created \n");
        return ERROR;
    }
    memcpy(tmpbuf, &msg, orcEventSize);
    if ((i = rt_queue_send(OrcQueue, tmpbuf, orcEventSize, Q_NORMAL)) < 0)
    {
        printf("ERROR orcMsgQSend %d \n", i);
        return ERROR;
    }
    message_counter++;
    return OK;
}

/**
 * Function to receive messages on a message queue
 *
 * @param queue pointer to the message queue
 * @param msg pointer to the received message 
 * @return OK if successfull, ERROR otherwise and errno is set
 * @see <sys/msg.h>#msgrcv
 *
 */
int orcMsgQReceive(ORCMSGQ OrcQueue, int *msg)
{
    ssize_t i;
    void *message;

    if ((i = rt_queue_receive(OrcQueue, &message, TM_INFINITE )) < 0)
    {
        printf("ERREUR orcMsgQReceive %d \n", i);
        return ERROR;
    }
    else
    {
      memcpy(msg, message, i);
        rt_queue_free(OrcQueue, message);
        message_counter--;
        return OK;
    }
}

/**
 * Function to close and erase a message queue
 *
 * @param queue pointer to the message queue 
 * @return OK if successfull, ERROR otherwise and errno is set
 * @see <sys/msg.h>#msgctl
 */
int orcMsgQClose(ORCMSGQ OrcQueue)
{
    int i;
    if (OrcQueue == 0)
        return ERROR;
    if ((i = rt_queue_delete(OrcQueue)) != 0)
    {
        printf("ERREUR orcMsgQClose %d \n", i);
        return ERROR;
    }

    else
    {
        free(OrcQueue);
        return OK;
    }
}

/*-------Semaphores----------*/
/**
 * Function to create a semaphore
 *
 * @param initState semaphore initial creation state, eg ORCFULL, ORCEMPTY
 * @return ORCSEM_ID semaphore pointer created if successfull, NULL otherwise 
 * @see ORCFULL
 * @see ORCEMPTY
 * @see <semaphore.h>#sem_init
 */

ORCSEM_ID orcSemCreate(int initState)
{
    ORCSEM_ID newSem;
    int status;

    sprintf(nameSem,"%d",cpt_sem);
    newSem = malloc(sizeof(RT_SEM));
    if (newSem == 0)
    {
        printf("ERROR orcSem init \n");
        return 0;
    }
    memset(newSem, 0, sizeof(RT_SEM));
    if(initState == ORCFULL)
{
        status = rt_sem_create(newSem, nameSem, initState, S_FIFO);
#ifdef DEBUG
        printf("WARNING binary Sem created FULL \n");
#endif 
}
    else
        status = rt_sem_create(newSem, nameSem, initState, S_FIFO|S_PULSE);
    if (status == OK)
    {
#ifdef DEBUG
        printf("orcSemCreate %p\n", newSem);
#endif
        cpt_sem++;
        return newSem;
    }
    else
    {
#ifdef DEBUG
        printf("orcSemCreate ERROR %d\n", status);
#endif
        return NULL;
    }
}

ORCSEM_ID orcSemCreate_count(int initState)
{
    RT_SEM * newSem;
    int status;

    sprintf(nameSem,"%d",cpt_sem);
    newSem = malloc(sizeof(RT_SEM));
    if (newSem == 0)
    {
        printf("ERROR SemCreate_count init \n");
        return 0;
    }
    memset(newSem, 0, sizeof(RT_SEM));

    status = rt_sem_create(newSem, nameSem, initState, S_FIFO);
    if (status == OK)
    {
#ifdef DEBUG
        printf("orcSemCreate_count %p\n", newSem);
#endif
        cpt_sem++;
        return newSem;
    }
    else
    {
#ifdef DEBUG
        printf("orcSemCreate ERROR %d \n", status);
#endif
        return NULL;
    }

}

/**
 * Function to delete a given semaphore
 * 
 * @param sem semaphore to be deleted
 * @return sem_destroy() returned value
 * @see <semaphore.h>#sem_destroy
 */
int orcSemDelete(ORCSEM_ID sem)
{
    if (sem == 0)
        return ERROR;
    if (rt_sem_delete(sem) == 0)
    {
        free(sem);
        return OK;
    }
    printf("Erreur:orcSemDelete\n");
    return ERROR;
}

/**
 * Function to give a semaphore
 *
 * @param sem semaphore id
 * @return sem_post) returned value
 * @see <semaphore.h>#sem_post
 */
int orcSemGive(ORCSEM_ID sem)
{
#ifdef DEBUG
    printf("SemGive %p\n", sem);
#endif
    return (rt_sem_v(sem));
}

/**
 * Function to take a semaphore
 * TODO : no timeout in Posix semaphores
 *
 * @param sem semaphore
 * @param timeout value 
 * @return sem_wait() returned value
 * @see <semaphore.h>#sem_wait
 */
int orcSemTake(ORCSEM_ID sem, int timeout)
{
#ifdef DEBUG
    printf("SemTake %p\n", sem);
#endif
    return (rt_sem_p(sem, timeout));
}

/*-------Tasks----------*/
/**
 * Function for suspending current process
 * TODO : no taskDelay in Posix (sleep uses seconds, delay ?, nanosleep ?)
 *
 * @param delay
 * @return OK
 */
int orcTaskDelay(int delay)
{
    //int dummy = delay; // set to avoid compilation warnings

    return OK;
}

/// Function to set relative linux task priority
int orcScalePriority(int os_priority)
{
    if ((PRI_MT_MIN + os_priority < PRI_MT_MAX) && os_priority > 0)
        return ( PRI_MT_MIN + os_priority );
    printf("ERROR orcScalePriority, priority=%d\n", os_priority);
    return PRI_MT_MAX;
}


/**
 * Function to check if a task is still valid or not
 *
 * @param Id task identifier 
 * @return OK if task is valid, ERROR otherwise
 * @see ORCTHR_ID
 * @see pthread_kill
 */
int orcTaskIdVerify(ORCTHR_ID Id)
{
    if (Id != NULL)
    {
        return OK;
    }
    printf("orcTaskIdVerify ERROR \n");
    return ERROR;
}

/**
 * Function to kill a task (pthread)
 *
 * @param Id task identifier
 * @return ERROR or pthread_cancel returned value
 * @see ORCTHR_ID
 * @see <pthread.h>#pthread_kill
 * @see <pthread.h>#pthread_cancel
 */
int orcTaskDelete(ORCTHR_ID task)
{
    int result;

    if (task == 0)
    {
        printf("ERROR rt_task_delete, task == 0\n");
        return ERROR;
    }
    result = rt_task_delete(task);
    if (result != 0)
    {
        printf("ERROR rt_task_delete  %p error %d\n", task, result);
        return ERROR;
    }
    //    if (result == 0)
    free(task);
    return OK;
}

/**
 * Function to spawn a task
 *
 * @param tid task identifier
 * @param name name descripting the task
 * @param prio task priority level
 * @param stackSize stack size to be allocated for the task
 * @param funcptr routine to be spawn by the task
 * @param arg argument needed for the routine to be spawn
 * @return pthread_create returned value
 * @see ORCTHR_ID
 * @see STACKSIZE
 * @see FUNCPTR
 * @see <pthread.h>#pthread_create
 */
int orcSpawn(ORCTHR_ID *tid, const char *name, int prio, STACKSIZE stackSize, SOSO funcptr, void * arg)
{
    int err;

    //Allocate memory
    if (((*tid) = (RT_TASK*) malloc (sizeof(RT_TASK))) == NULL)
    {
        printf("Error malloc orcspawn\n" );
        return ERROR;
    }
    if ((err = rt_task_spawn(*tid, name, stackSize, prio, T_FPU|T_JOINABLE|T_CPU(0), (SOSO) funcptr, arg)) != 0)
      //if ((err = rt_task_spawn(*tid, name, stackSize, prio, T_FPU, (SOSO) funcptr, arg)) != 0)

    {
        printf("ERROR %d rt_task_init\n", err);
        return ERROR;
    }
    //#ifdef DEBUG
    printf("rt_task create %s prio %d StackSize %d Id %p \n", name, prio, stackSize, tid);
    //#endif
    return OK;
}
int orcSpawn1(ORCTHR_ID *tid, const char *name, int prio, STACKSIZE stackSize, SOSO funcptr, void * arg)
{
    int err;

    //Allocate memory
    if (((*tid) = (RT_TASK*) malloc (sizeof(RT_TASK))) == NULL)
    {
        printf("Error malloc orcspawn\n" );
        return ERROR;
    }
    if ((err = rt_task_spawn(*tid, name, stackSize, prio, T_FPU|T_JOINABLE|T_CPU(1), (SOSO) funcptr, arg)) != 0)
      //if ((err = rt_task_spawn(*tid, name, stackSize, prio, T_FPU, (SOSO) funcptr, arg)) != 0)

    {
        printf("ERROR %d rt_task_init\n", err);
        return ERROR;
    }
    //#ifdef DEBUG
    printf("rt_task create %s prio %d StackSize %d Id %p \n", name, prio, stackSize, tid);
    //#endif
    return OK;
}

/**
 * Function to lock a task
 * This function does nothing : defined for interoperability between OS needs
 * 
 * @param 
 * @return OK
 */
int orcTaskLock()
{
    return OK;
}

/**
 * Function to unlock a task
 * This function does nothing : defined for interoperability between OS needs
 * 
 * @param 
 * @return OK
 */
int orcTaskUnlock()
{
    return OK;
}

int orcTaskSuspend(ORCTHR_ID task)
{
    return rt_task_suspend(task);
}

///Function that returns the cpu time in nanoseconds
inline long long GetCpuTime(void)
{
    return (long long)rt_timer_ticks2ns(rt_timer_read());
}

inline  unsigned long long orcGetExecTime(ORCTHR_ID task)
{
RT_TASK_INFO info;
crexec = rt_task_inquire(task,&info);
  if (crexec != 0){
    printf("rt_task_get_exectime error %d \n", crexec);
    return (unsigned long long)0;}
  else return (unsigned long long)rt_timer_tsc2ns((SRTIME)info.exectime);
}

inline long long orcGetStartTime(ORCTHR_ID task)
{
    return (long long)0;
}

int orcMakeRealTime(void)
{
int prio_main = PRI_MT_MAX + 1;
    mlockall(MCL_CURRENT | MCL_FUTURE);
    if ((cr = rt_task_shadow(MAIN_RT, "MAIN_PRR", prio_main, T_FPU | T_JOINABLE)) != 0)
      {printf("rt_task_shadow error %d \n", cr);}
    else {printf("rt_task_shadow done priority %d \n", prio_main);}
    return cr;
}

int orcTaskJoin(ORCTHR_ID task)
{
cr = rt_task_join(task);
 if (cr != 0){
   printf("rt_task_join error %d on task %p \n", cr, task);
   return cr;}
 else return OK;
}

// Trap Ctrl C Interruption
void clean_exit(int dummy)
{
    printf("Ctrl C Interrupt\n");
    end = 1;
    err = rt_task_join(thr_clockit);
    if (err != 0)printf("rt_task_join() error %d \n", err);
    err = rt_task_join(thr_loop);
    if (err != 0)printf("rt_task_join() error %d \n", err);

    printf("deleting rt devices \n");
    err = rt_alarm_delete(&BaseClk);
    if (err != 0)printf("rt_alarm_delete() error %d \n", err);

    orcMsgQClose(Queue);
    orcSemDelete(SynchroSem);
    return ;
}

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

    return OK;
}

void setTimer(void)
{
    /***starting timer ***/
    err = rt_alarm_create(&BaseClk, "BaseClock");
    if (err != 0)printf("rt_alarm_create() error %d \n", err);
    err = rt_alarm_start(&BaseClk,
                         rt_timer_ns2ticks(task_period_ns),
                         rt_timer_ns2ticks(task_period_ns));
    if (err != 0)printf("rt_alarm_start() error %d \n", err);

    else printf("alarm started with period %llu ns \n", task_period_ns);
    printf("period in ticks %ld \n", (long)rt_timer_ns2ticks(task_period_ns));
    return ;

}

void clock_it(void)
{
    int msg = 1;    
    unsigned long long clockexectime, clockdiff;
    static unsigned long long clockpast = 0;
    while (!end)
    {
        err = rt_alarm_wait(&BaseClk);

	//rt_timer_spin((RTIME)rt_timer_ns2ticks(100000000));	
/*       clockexectime = orcGetExecTime(NULL); */
/*       if(msg > 2){ */
/*       clockdiff = clockexectime - clockpast; */
/*       clockpast  = clockexectime; */
/*       printf("clockexectime %llu clockdiff %llu \n", clockexectime, clockdiff );} */
/*       else clockpast  = clockexectime; */

            orcMsgQSend(Queue, msg, 0);
            msg++;
    }
/*     printf("clocktotal %llu clockdiffexec moyen %llu \n", clockexectime, (clockexectime/msg)); */
    return ;
}
void func_loop()
{
    int msg;
    unsigned long long loopexectime, loopdiff;
    static unsigned long long looppast;
    while (!end)
    {
      //printf("WAITING FOR MESSAGE  \n");
      orcMsgQReceive(Queue, &msg);
      printf("RECEIVED MESSAGE  \n");
      rt_timer_spin((RTIME)rt_timer_ns2ticks(100000000));
      loopexectime = orcGetExecTime(NULL);
      if(msg > 2){
	  loopdiff = loopexectime - looppast;
	  looppast  = loopexectime;
      printf("loopexectime  %llu loopdiff %llu \n", loopexectime, loopdiff );}
      else looppast  = loopexectime;
      printf("received msg = %d \n", msg);
	    }
    printf("ENDING msg = %d \n", msg); 
/*     printf("looptotal %llu loopdiffexec moyen %llu \n", loopexectime, (loopexectime/msg)); */
    printf("convert 1000 ticks = %llu ns \n", rt_timer_tsc2ns(1000));
    return;
}
int main(void)
{

    orcTimerSigMask();

    signal(SIGTERM, clean_exit);
    signal(SIGINT, clean_exit);

    orcMakeRealTime();

    setTimer();

    SynchroSem = orcSemCreate(ORCEMPTY);
    Queue = orcMsgQCreate();
    
    orcSpawn(&thr_clockit, "AlarmServer", MAX_PRIO, NORMAL_STACK, (SOSO) clock_it, NULL);
    orcSpawn(&thr_loop, "Loop", MAX_PRIO - 1, NORMAL_STACK, (SOSO) func_loop, NULL);

    pause();
    fflush(NULL);

    return 0;
}




  parent reply	other threads:[~2007-06-25 15:51 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-06-07 16:23 [Xenomai-help] real time task disapears... memory problem ? desvages
2007-06-07 17:44 ` Jan Kiszka
2007-06-08 10:49   ` [Xenomai-help] measuring tasks execution time Daniel Simon
2007-06-08 11:20     ` [Xenomai-core] " Jan Kiszka
2007-06-08 13:09       ` Daniel Simon
2007-06-08 15:24         ` Jan Kiszka
2007-06-08 16:04           ` Jan Kiszka
2007-06-25 15:51       ` Daniel Simon [this message]
2007-06-25 16:55         ` [Xenomai-core] " Jan Kiszka
2007-06-27  8:57           ` Daniel Simon
2007-06-27 11:56             ` Jan Kiszka
2007-06-29 14:43               ` Daniel Simon
2007-06-29 15:00                 ` Jan Kiszka
2007-06-29 15:29                   ` Daniel Simon
2007-06-29 15:47                     ` Philippe Gerum
2007-06-29 15:56                       ` Gilles Chanteperdrix
2007-06-29 15:52                     ` Jan Kiszka
2007-07-08 10:11                 ` Jan Kiszka
2007-07-09  8:49                   ` Daniel Simon
2007-07-11 13:59                   ` Daniel Simon
2007-07-11 14:30                     ` Jan Kiszka
2007-07-11 15:35                       ` Daniel Simon
2007-07-11 15:56                         ` Jan Kiszka
2007-07-11 16:55                           ` Daniel Simon
2007-07-11 21:20                             ` Jan Kiszka
2007-07-12  9:30                               ` Daniel Simon
2007-07-12 11:02                                 ` Jan Kiszka
2007-07-16 16:19                                   ` Daniel Simon
     [not found]   ` <1753.194.254.210.7.1181246882.squirrel@domain.hid>
2007-06-08 15:19     ` [Xenomai-help] real time task disapears... memory problem ? Jan Kiszka
2007-06-09 16:06       ` desvages
2007-06-09 17:10         ` Jan Kiszka

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=20070625175107.438849fa@domain.hid \
    --to=daniel.simon@domain.hid \
    --cc=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.