Commit 9144921c authored by yoogx's avatar yoogx

* Adjust the initial start time of tasks

    For issue #11
parent 5d4ddaaa
......@@ -56,6 +56,17 @@ typedef struct
* The granularity of the time is in microsecond (10^-6)
*/
#define ORIGIN_OF_TIME ((__po_hi_time_t) { 0, 0 })
__po_hi_time_t get_epoch(void);
void set_epoch (void);
int milliseconds_since_epoch (void);
/* Set/get PolyORB-HI/C runtime epoch: the common starting date of all
tasks. Note: the epoch should be set relative to the completion of
the initialization of the runtime and all threads. See po_hi_main.h
for details.
*/
#define __PO_HI_TIME_TO_US(value) ((value.sec*1000000)+(value.nsec / 1000))
#define __PO_HI_TIME_TO_MS(value) ((value.sec*1000)+(value.nsec / 1000000))
......@@ -92,7 +103,7 @@ int __po_hi_milliseconds (__po_hi_time_t* time,
* argument milliseconds.
*/
int __po_hi_microseconds (__po_hi_time_t* time,
int __po_hi_microseconds (__po_hi_time_t* time,
const __po_hi_uint32_t microseconds);
/*
* Build a __po_hi_time_t value which contains the
......
......@@ -5,12 +5,13 @@
*
* For more informations, please visit http://taste.tuxfamily.org/wiki
*
* Copyright (C) 2010-2014 ESA & ISAE.
* Copyright (C) 2010-2016 ESA & ISAE.
*/
#include <deployment.h>
/* included files from the generated code */
#include <po_hi_time.h>
#include <po_hi_config.h>
#include <po_hi_common.h>
#include <po_hi_returns.h>
......@@ -77,8 +78,6 @@ RT_TASK* main_task_id;
*/
#endif
int __po_hi_initialized_tasks = 0;
/* The barrier is initialized with __PO_HI_NB_TASKS +1
* members, because the main function must pass the barrier.
......@@ -167,6 +166,7 @@ int __po_hi_initialize_early ()
}
#endif
#if defined (RTEMS_POSIX) || defined (RTEMS_PURE)
rtems_status_code ret;
rtems_time_of_day time;
......@@ -287,19 +287,19 @@ int __po_hi_initialize ()
}
#endif
/*!
* Initialize the monitoring trace if needed
*/
/*!
* Initialize the monitoring trace if needed
*/
#if defined (MONITORING)
trace_initialize ();
trace_initialize ();
#endif
return (__PO_HI_SUCCESS);
return (__PO_HI_SUCCESS);
}
int __po_hi_wait_initialization ()
int __po_hi_wait_initialization (void)
{
#if defined (POSIX) || defined (RTEMS_POSIX) || defined (XENO_POSIX)
int cstate;
if (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, &cstate) != 0)
......@@ -322,11 +322,16 @@ int __po_hi_wait_initialization ()
__DEBUGMSG ("[MAIN] %d task(s) initialized (total to init =%d)\n", __po_hi_initialized_tasks, __po_hi_nb_tasks_to_init);
while (__po_hi_initialized_tasks < __po_hi_nb_tasks_to_init)
{
if (__po_hi_initialized_tasks < __po_hi_nb_tasks_to_init) {
while (__po_hi_initialized_tasks < __po_hi_nb_tasks_to_init) {
pthread_cond_wait (&cond_init, &mutex_init);
}
}
pthread_cond_broadcast (&cond_init);
else {
pthread_cond_broadcast (&cond_init);
set_epoch();
}
pthread_mutex_unlock (&mutex_init);
__PO_HI_INSTRUMENTATION_VCD_INIT
......
......@@ -63,15 +63,18 @@
/* Headers from run-time verification */
#include <deployment.h>
/* Header files from generated code */
typedef enum __po_hi_task_category_t { TASK_PERIODIC, TASK_SPORADIC, TASK_BACKGROUND }
__po_hi_task_category;
int nb_tasks; /* number of created tasks */
typedef struct
{
__po_hi_task_id id; /* Identifier of the task in the system */
__po_hi_task_category task_category;
__po_hi_time_t period;
#if defined (RTEMS_POSIX) || defined (POSIX) || defined (XENO_POSIX)
__po_hi_time_t timer;
......@@ -150,13 +153,38 @@ void __po_hi_wait_for_tasks ()
/*
* compute next period for a task
* The argument is the task-id
* The task must be a periodic task
* The task must be a cyclic task (periodic or sporadic)
*/
int __po_hi_compute_next_period (__po_hi_task_id task)
{
#if defined (RTEMS_POSIX) || defined (POSIX) || defined (XENO_POSIX) || defined (_WIN32)
__po_hi_add_times(&(tasks[task].timer), &(tasks[task].timer), &tasks[task].period );
/* If we call this function for the first time, we need to configure
+ the initial timer to epoch */
if (tasks[task].timer.sec == 0 && tasks[task].timer.nsec == 0) {
tasks[task].timer = get_epoch();
return (__PO_HI_SUCCESS);
}
/* Otherwise, we increment either using an absoulte timeline
(periodic), or relative to the latest dispatch time (sporadic task) */
switch (tasks[task].task_category) {
case TASK_PERIODIC:
__po_hi_add_times(&(tasks[task].timer), &(tasks[task].timer), &tasks[task].period );
break;
case TASK_SPORADIC: {
__po_hi_time_t mytime;
if (__po_hi_get_time (&mytime) != __PO_HI_SUCCESS) {
return (__PO_HI_ERROR_CLOCK);
}
__po_hi_add_times(&(tasks[task].timer), &mytime, &tasks[task].period );
break;
}
}
return (__PO_HI_SUCCESS);
......@@ -446,7 +474,7 @@ rtems_id __po_hi_rtems_create_thread (__po_hi_priority_t priority,
#ifdef RTEMS411
/* Thread affinity API for SMP systems appeared in RTEMS 4.11,
section 25 of RTEMS Applications C Users Guide */
section 25 of RTEMS Applications C User's Guide */
cpu_set_t cpuset;
......@@ -530,6 +558,7 @@ int __po_hi_create_generic_task (const __po_hi_task_id id,
my_task = &(tasks[id]);
__po_hi_time_copy (&(my_task->period), period);
my_task->id = id;
my_task->timer = ORIGIN_OF_TIME;
#if defined (POSIX) || defined (RTEMS_POSIX) || defined (XENO_POSIX)
my_task->tid = __po_hi_posix_create_thread
......@@ -582,10 +611,16 @@ int __po_hi_create_periodic_task (const __po_hi_task_id id,
*__po_hi_time* functions.
*/
#if defined (RTEMS_POSIX) || defined (POSIX) || defined (XENO_POSIX)
if (__po_hi_compute_next_period (id) != __PO_HI_SUCCESS)
// XXX The following is (a priori) not necessary, it should be
// reviewed for all runtimes: the body of a periodic task already
// call __po_hi_compute_next_period() as part of its skeleton
/*if (__po_hi_compute_next_period (id) != __PO_HI_SUCCESS)
{
return (__PO_HI_ERROR_CLOCK);
}
*/
#elif defined (XENO_NATIVE)
int ret;
......@@ -602,8 +637,8 @@ int __po_hi_create_periodic_task (const __po_hi_task_id id,
__DEBUGMSG ("ERROR when starting the task\n");
}
#endif
return (__PO_HI_SUCCESS);
tasks[id].task_category = TASK_PERIODIC;
return (__PO_HI_SUCCESS);
}
void __po_hi_task_wait_offset (const __po_hi_time_t* time)
......@@ -659,8 +694,8 @@ int __po_hi_create_sporadic_task (const __po_hi_task_id id,
__DEBUGMSG ("ERROR when starting the task\n");
}
#endif
return (__PO_HI_SUCCESS);
tasks[id].task_category = TASK_SPORADIC;
return (__PO_HI_SUCCESS);
}
int __po_hi_task_delay_until (__po_hi_time_t* time, __po_hi_task_id task)
......
......@@ -288,3 +288,27 @@ int __po_hi_time_copy (__po_hi_time_t* dst, const __po_hi_time_t* src)
dst->nsec = src->nsec;
return (__PO_HI_SUCCESS);
}
__po_hi_time_t epoch = ORIGIN_OF_TIME;
__po_hi_time_t get_epoch(void) {
return epoch;
}
void set_epoch (void) {
static bool initialized = false;
if (!initialized) {
__po_hi_get_time (&epoch);
initialized = true;
}
}
int milliseconds_since_epoch (void) {
__po_hi_time_t my_time;
__po_hi_get_time (&my_time);
return (my_time.sec - epoch.sec) * 1000 +
(int) (((int) my_time.nsec - (int)epoch.nsec)/1000000.0);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment