...
 
Commits (6)
......@@ -5,13 +5,12 @@
*
* For more informations, please visit http://taste.tuxfamily.org/wiki
*
* Copyright (C) 2007-2009 Telecom ParisTech, 2010-2018 ESA & ISAE.
* Copyright (C) 2007-2009 Telecom ParisTech, 2010-2020 ESA & ISAE.
*/
#ifndef __PO_HI_PROTECTED_H__
#define __PO_HI_PROTECTED_H__
#include <stdint.h>
#include <deployment.h>
......@@ -70,6 +69,9 @@ typedef struct
#if defined (_WIN32)
HANDLE win32_mutex;
#endif
#if defined (SIMULATOR)
int previous_priority;
#endif
}__po_hi_mutex_t;
typedef uint8_t __po_hi_protected_t;
......
......@@ -5,7 +5,7 @@
*
* For more informations, please visit http://taste.tuxfamily.org/wiki
*
* Copyright (C) 2018 ESA & ISAE.
* Copyright (C) 2018-2020 ESA & ISAE.
*/
#ifndef __PO_HI_SEMAPHORE_H__
......@@ -31,6 +31,9 @@
#elif defined (_WIN32)
#include <windows.h>
#elif defined (SIMULATOR)
#include <um_threads.h>
#endif
/**
......@@ -38,21 +41,23 @@
* \brief Structure defining a semaphore.
*/
typedef struct __po_hi_sem_t __po_hi_sem_t;
struct __po_hi_sem_t
{
struct __po_hi_sem_t {
#if defined (POSIX) || defined (RTEMS_POSIX) || defined (XENO_POSIX)
__po_hi_mutex_t mutex;
pthread_cond_t posix_condvar;
pthread_condattr_t posix_condattr;
__po_hi_mutex_t mutex;
pthread_cond_t posix_condvar;
pthread_condattr_t posix_condattr;
#elif defined (__PO_HI_RTEMS_CLASSIC_API)
rtems_id rtems_sem;
rtems_id rtems_barrier;
rtems_id rtems_sem;
rtems_id rtems_barrier;
#elif defined (XENO_NATIVE)
__po_hi_mutex_t mutex;
RT_COND xeno_condvar;
__po_hi_mutex_t mutex;
RT_COND xeno_condvar;
#elif defined (_WIN32)
HANDLE win32_event;
CRITICAL_SECTION win32_criticalsection;
HANDLE win32_event;
CRITICAL_SECTION win32_criticalsection;
#elif defined (SIMULATOR)
semaphore* um_mutex;
semaphore* um_barrier;
#endif
};
......@@ -102,7 +107,7 @@ int __po_hi_sem_mutex_wait(__po_hi_sem_t* sem);
/**
* \brief The semaphore is released.
*
*
* The semaphore is COMPLETELY RELEASED. (both condvar and mutex).
* \param sem Semaphore structure to be worked on.
* \return __PO_HI_SUCCESS if successful.
......@@ -112,7 +117,7 @@ int __po_hi_sem_release(__po_hi_sem_t* sem);
/**
* \brief The mutex attribute of a semaphore is released.
*
*
* This function is used when you don't want to do a condvar_signal, and
* want to let it stay on a wait mode.
* This function is also used when only a mutex is needed in the gqueue.
......@@ -127,7 +132,7 @@ int __po_hi_sem_mutex_release(__po_hi_sem_t* sem);
/**
* \brief Used to do the po_hi_sem_init function on a semaphore contained in the semaphore array.
*
*
* \param array The array of semaphores used in the gqueue.
* \param id Identifier of the task.
* \return __PO_HI_SUCCESS if successful.
......@@ -137,7 +142,7 @@ int __po_hi_sem_init_gqueue(__po_hi_sem_t array[__PO_HI_NB_TASKS], __po_hi_task_
/**
* \brief Used to do the po_hi_sem_wait function on a semaphore contained in the semaphore array.
*
*
* \param array The array of semaphores used in the gqueue.
* \param id Identifier of the task.
* \return __PO_HI_SUCCESS if successful.
......@@ -147,7 +152,7 @@ int __po_hi_sem_wait_gqueue(__po_hi_sem_t array[__PO_HI_NB_TASKS], __po_hi_task_
/**
* \brief Used to do the po_hi_sem_mutex_wait function on a semaphore contained in the semaphore array.
*
*
* \param array The array of semaphores used in the gqueue.
* \param id Identifier of the task.
* \return __PO_HI_SUCCESS if successful.
......@@ -157,7 +162,7 @@ int __po_hi_sem_mutex_wait_gqueue(__po_hi_sem_t array[__PO_HI_NB_TASKS], __po_hi
/**
* \brief Used to do the po_hi_sem_release function on a semaphore contained in the semaphore array.
*
*
* \param array The array of semaphores used in the gqueue.
* \param id Identifier of the task.
* \return __PO_HI_SUCCESS if successful.
......@@ -167,7 +172,7 @@ int __po_hi_sem_release_gqueue(__po_hi_sem_t array[__PO_HI_NB_TASKS], __po_hi_ta
/**
* \brief Used to do the po_hi_sem_mutex_release function on a semaphore contained in the semaphore array.
*
*
* \param array The array of semaphores used in the gqueue.
* \param id Identifier of the task.
* \return __PO_HI_SUCCESS if successful.
......
......@@ -5,7 +5,7 @@
*
* For more informations, please visit http://taste.tuxfamily.org/wiki
*
* Copyright (C) 2007-2009 Telecom ParisTech, 2010-2019 ESA & ISAE.
* Copyright (C) 2007-2009 Telecom ParisTech, 2010-2020 ESA & ISAE.
*/
#ifndef __PO_HI_TIME_H__
......@@ -38,8 +38,8 @@ LARGE_INTEGER __po_hi_unix_seconds_to_windows_tick(unsigned sec, unsigned nsec);
typedef struct
{
__po_hi_uint32_t sec; /* amount of second */
__po_hi_uint32_t nsec; /* amount of nanosecond */
__po_hi_int32_t sec; /* amount of second */
__po_hi_int32_t nsec; /* amount of nanosecond */
}__po_hi_time_t;
/*
* Represent the time in PolyORB-HI.
......
......@@ -304,7 +304,10 @@ int __po_hi_transport_xtratum_get_port (const __po_hi_port_t portno);
#endif
#ifdef AIR_HYPERVISOR
void __po_hi_transport_air_init (void);
void __po_hi_transport_air_port_init (const __po_hi_port_t portno, long int val);
long int __po_hi_transport_air_get_port (const __po_hi_port_t portno);
#endif
......
......@@ -9,23 +9,35 @@
#define __UM_THREADS_H__
#include<ucontext.h>
#include<deployment.h>
#include<po_hi_task.h>
#include<po_hi_time.h>
#include<stdint.h>
#include<time.h>
#include<stdbool.h>
#include<po_hi_time.h>
#include<po_hi_protected.h>
#define MAX(a,b) (((a)>(b))?(a):(b))
/*****************************************************************************/
/* CONSTANTS */
#define MAX_THREADS 10 /* Maximum number of threads */
#define STACKSIZE (1024 * 1024) /* Default stack size */
#define INTERVAL 700 /* timer interval in microseconds */
#define MAX_CORE 1
#define STACKSIZE (128 * 1024) /* Default stack size */
#define INTERVAL 700 /* timer interval in microseconds */
/*****************************************************************************/
typedef struct __po_hi_time_t abs_time;
//typedef struct timespec abs_time;
/******************************************************************************/
/* Thread entities */
/* Thread entities */
typedef uint32_t um_thread_id; /* id of a thread */
typedef uint32_t um_thread_id; /* id of a thread */
typedef uint32_t stack_size_t; /* stack size of a thread */
typedef uint32_t priority_t; /* priority */
typedef enum { IDLE, READY, RUNNING } thread_state_t;
typedef enum { WAITING, READY, RUNNING } thread_state_t;
typedef struct { /* thread control block */
ucontext_t um_context;
......@@ -33,8 +45,17 @@ typedef struct { /* thread control block */
stack_size_t stack_size;
priority_t priority;
thread_state_t state;
__po_hi_time_t period;
__po_hi_time_t next_activation; /* the reactivation time of a task is
* relatif to the simulated clock */
} um_thread_t;
extern um_thread_t threads[MAX_THREADS];
/* Array of threads currently configured in the program */
extern uint32_t um_thread_index;
extern uint32_t nb_waiting_threads;
um_thread_id um_thread_create
(void (*function)(void),
stack_size_t stack_size,
......@@ -46,40 +67,118 @@ um_thread_id um_thread_create
* - function to execute
*/
/*
* Create a periodic task.
*
* The task created have the identifier given by the first
* parameter. It is created according to the period created
* with __po_hi_* functions (like __po_hi_milliseconds())
* and priority parameters (use the OS priority). The task execute
* periodically start_routine.
*
* This function returns SUCCESS if there is no error. Else,
* it returns the negative value ERROR_CREATE_TASK.
*/
int um_thread_sim_create
(void* (*function)(void),
um_thread_id um_thread_periodic_create
(void (*function)(void),
stack_size_t stack_size,
priority_t priority,
const __po_hi_task_id po_hi_id);
__po_hi_time_t period);
void um_thread_yield (void);
/* um_thread_yield: relinquish CPU */
void um_wait_all (void);
/* block until all threads joined this function */
void swap_to_scheduler_context (void);
ucontext_t *get_context (um_thread_id tid);
ucontext_t *get_current_context (void);
um_thread_id get_current_context_id (void);
um_thread_id get_nb_waiting_threads (void);
__po_hi_time_t get_thread_period (um_thread_id tid);
/*****************************************************************************/
void set_next_activation (um_thread_id tid, __po_hi_time_t next_activation);
__po_hi_time_t shift(__po_hi_uint32_t second, __po_hi_uint32_t nanosecond);
/******************************************************************************/
/* Scheduler */
__po_hi_time_t add_times (__po_hi_time_t left, __po_hi_time_t right);
/* convert_seconds_to_abs_time converts the amount of time in seconds
* to an abs_time value.
*/
__po_hi_time_t convert_seconds_to_abs_time (uint32_t seconds);
/*****************************************************************************/
/* Scheduler */
typedef um_thread_id (* scheduler_function) (void);
void configure_scheduler (scheduler_function s);
void start_scheduler (void);
void scheduler(void);
void control_scheduler (void);
/* FIFO within priority scheduling policy. */
um_thread_id scheduler_fifo (void);
void configure_fifo_scheduler (void);
/* Configure the FIFO within priority scheduler, Only one thread by priority. */
/*****************************************************************************/
/* Waiting List */
typedef struct _waiting_list {
__po_hi_time_t t; /* deadline of the waiting thread */
um_thread_id tid;
struct _waiting_list *next;
} waiting_list;
extern waiting_list *w_list;
void delay_until(um_thread_id tid, __po_hi_time_t n_time);
void delay_until_for_a_given_thread(um_thread_id tid, __po_hi_time_t n_time);
void do_awake_list(void);
/*****************************************************************************/
/* Timer utilities */
void setup_timer(uint32_t period, bool periodic);
/* activate a periodic timer of "period" ms */
void init_timer();
void stop_timer();
void set_timer_next(void);
void set_timer_after_resuming_execution(__po_hi_time_t resume_execution_time);
/*****************************************************************************/
/* Semaphore */
typedef struct _wait_list {
um_thread_id tid;
struct _wait_list *next;
} wait_list;
typedef struct _semaphore {
int value;
um_thread_id tid;
wait_list *h_list;
wait_list *t_list;
int name;
} semaphore;
void semaphore_init(semaphore *s, int value, int name);
void semaphore_wait(semaphore *s);
void semaphore_post(semaphore *s);
/*****************************************************************************/
/* Mutex */
typedef struct _mutex {
int priority;
int previous_priority;
} mutex;
void mutex_init(__po_hi_mutex_t* m, int priority);
void mutex_lock(__po_hi_mutex_t* m);
/******************************************************************************/
void mutex_unlock(__po_hi_mutex_t* m);
/*****************************************************************************/
#endif /* __UM_THREADS_H__ */
......@@ -5,7 +5,7 @@
*
* For more informations, please visit http://taste.tuxfamily.org/wiki
*
* Copyright (C) 2010-2018 ESA & ISAE.
* Copyright (C) 2010-2020 ESA & ISAE.
*/
#include <deployment.h>
......@@ -93,7 +93,7 @@ int __po_hi_c_sockets_write_sockets[__PO_HI_NB_DEVICES];
/* Sockets we write to, used by the __po_hi_drivers_socket_send() function */
__po_hi_msg_t __po_hi_c_sockets_send_msg;
/* Message, heap allocated, used by the __po_hi_sockets_send() funtion */
/* Message, heap allocated, used by the __po_hi_sockets_send() function */
__po_hi_mutex_t __po_hi_c_sockets_send_mutex;
......
......@@ -318,8 +318,11 @@ __po_hi_port_id_t __po_hi_gqueue_store_in (__po_hi_task_id id,
__DEBUGMSG ("__po_hi_gqueue_store_in : NULL POINTER\n");
}
#endif
/* Locking only a mutex */
__PO_HI_DEBUG_DEBUG ("\nWaiting on Store_in on task %d, port = %d, size of port = %d\n", id, port,__po_hi_gqueue_get_port_size(id, port));
__PO_HI_DEBUG_DEBUG ("\nWaiting on Store_in on task %d, port = %d, size of port = %d\n",
id, port,__po_hi_gqueue_get_port_size(id, port));
int result = __po_hi_sem_mutex_wait_gqueue(__po_hi_gqueues_semaphores,id);
__DEBUGMSG("GQUEUE_SEM_MUTEX_WAIT on task %d result = %d\n", id, result);
assert(result == __PO_HI_SUCCESS);
......@@ -367,10 +370,10 @@ __po_hi_port_id_t __po_hi_gqueue_store_in (__po_hi_task_id id,
__PO_HI_DEBUG_DEBUG ("\nBefore used_size ++, Store_in for task = %d, __po_hi_gqueues_used_size[id][port] = %d\n", id, __po_hi_gqueues_used_size[id][port]);
__po_hi_gqueues_used_size[id][port]++;
__PO_HI_DEBUG_DEBUG ("\nAfter used_size ++ , Store_in for task = %d, __po_hi_gqueues_used_size[id][port] = %d\n",id, __po_hi_gqueues_used_size[id][port]);
#if defined(__PO_HI_USE_VCD) && defined(__unix__)
__po_hi_save_event_in_vcd_trace(__po_hi_compute_timestamp(), __po_hi_store_in_port_queue, id, port, __po_hi_gqueue_used_size(id,port));
#endif
#endif
/* The port where information has been written is stored */
__po_hi_gqueues_global_history[id][__po_hi_gqueues_global_history_woffset[id]] = port;
__po_hi_gqueues_global_history_woffset[id] = (__po_hi_gqueues_global_history_woffset[id] + 1 ) % __po_hi_gqueues_total_fifo_size[id];
......@@ -425,36 +428,36 @@ __po_hi_bool_t __po_hi_gqueue_compute_index_transition_to_execute (__po_hi_task_
int* initial_sizes_of_dispatch_triggers_of_all_transitions,
__po_hi_int32_t* index_transition_to_execute)
{
__po_hi_int32_t i = 0;
__po_hi_bool_t dispatch_condition_of_any_transition_is_verified = 0;
__po_hi_int32_t tmp = 0;
__po_hi_int32_t j = 0;
__po_hi_bool_t dispatch_condition;
while (i < next_complete_state->nb_transitions && ! dispatch_condition_of_any_transition_is_verified)
{
dispatch_condition = 1;
while (j < (tmp + next_complete_state->nb_dispatch_triggers_of_each_transition[i]) && dispatch_condition)
{
dispatch_condition = (initial_sizes_of_dispatch_triggers_of_all_transitions[j] < __po_hi_gqueue_get_count (id, next_complete_state->dispatch_triggers_of_all_transitions[j]));
j++;
}
if (dispatch_condition)
{
*index_transition_to_execute = i + 1;
}
tmp = tmp + next_complete_state->nb_dispatch_triggers_of_each_transition[i];
j = tmp;
dispatch_condition_of_any_transition_is_verified = dispatch_condition;
i++;
__po_hi_int32_t i = 0;
__po_hi_bool_t dispatch_condition_of_any_transition_is_verified = 0;
__po_hi_int32_t tmp = 0;
__po_hi_int32_t j = 0;
__po_hi_bool_t dispatch_condition;
while (i < next_complete_state->nb_transitions && ! dispatch_condition_of_any_transition_is_verified)
{
dispatch_condition = 1;
while (j < (tmp + next_complete_state->nb_dispatch_triggers_of_each_transition[i]) && dispatch_condition)
{
dispatch_condition = (initial_sizes_of_dispatch_triggers_of_all_transitions[j] < __po_hi_gqueue_get_count (id, next_complete_state->dispatch_triggers_of_all_transitions[j]));
j++;
}
if (dispatch_condition)
{
*index_transition_to_execute = i + 1;
}
tmp = tmp + next_complete_state->nb_dispatch_triggers_of_each_transition[i];
j = tmp;
dispatch_condition_of_any_transition_is_verified = dispatch_condition;
i++;
}
return dispatch_condition;
return dispatch_condition;
}
/******************************************************************************/
......@@ -466,17 +469,21 @@ void __po_hi_gqueue_wait_for_specific_incoming_events (__po_hi_task_id id,
int result = __po_hi_sem_mutex_wait_gqueue(__po_hi_gqueues_semaphores,id);
__DEBUGMSG("GQUEUE_SEM_MUTEX_WAIT %d %d\n", id, result);
assert(result == __PO_HI_SUCCESS);
int initial_sizes_of_dispatch_triggers_of_all_transitions[next_complete_state->nb_of_all_dispatch_events];
for(int i=0;i<(next_complete_state->nb_of_all_dispatch_events);i++)
{
initial_sizes_of_dispatch_triggers_of_all_transitions[i] = __po_hi_gqueue_get_count (id, next_complete_state->dispatch_triggers_of_all_transitions[i]);
initial_sizes_of_dispatch_triggers_of_all_transitions[i] = __po_hi_gqueue_get_count (id, next_complete_state->dispatch_triggers_of_all_transitions[i]);
}
*index_transition_to_execute = -1;
while (! __po_hi_gqueue_compute_index_transition_to_execute(id, next_complete_state, initial_sizes_of_dispatch_triggers_of_all_transitions, index_transition_to_execute))
while (! __po_hi_gqueue_compute_index_transition_to_execute
(id,
next_complete_state,
initial_sizes_of_dispatch_triggers_of_all_transitions,
index_transition_to_execute))
{
/* Telling the semaphore to wait with putting its condvar on wait mode */
int res_sem = __po_hi_sem_wait_gqueue(__po_hi_gqueues_semaphores,id);
......@@ -490,9 +497,9 @@ void __po_hi_gqueue_wait_for_specific_incoming_events (__po_hi_task_id id,
#if defined(__PO_HI_USE_VCD) && defined(__unix__)
__po_hi_save_event_in_vcd_trace (__po_hi_compute_timestamp(), __po_hi_task_dispatched, id, invalid_local_port_t, -1);
#endif
#endif
/** Releasing only the mutex of the semaphore*/
int res = __po_hi_sem_mutex_release_gqueue(__po_hi_gqueues_semaphores,id);
__DEBUGMSG("GQUEUE_SEM_MTUEX_RELEASE %d %d\n", id, res);
assert(res == __PO_HI_SUCCESS);
......@@ -532,7 +539,7 @@ void __po_hi_gqueue_wait_for_incoming_event (__po_hi_task_id id,
__po_hi_save_event_in_vcd_trace (__po_hi_compute_timestamp(), __po_hi_task_dispatched, id, invalid_local_port_t, -1);
#endif
/** Releasing only the mutex of the semaphore*/
int res = __po_hi_sem_mutex_release_gqueue(__po_hi_gqueues_semaphores,id);
__DEBUGMSG("GQUEUE_SEM_MTUEX_RELEASE %d %d\n", id, res);
assert(res == __PO_HI_SUCCESS);
......
......@@ -45,6 +45,12 @@ pthread_mutex_t mutex_init;
rtems_id __po_hi_main_initialization_barrier;
#endif
#if defined (SIMULATOR)
#include <um_threads.h>
#include <po_hi_semaphore.h>
#endif
#ifdef _WIN32
CRITICAL_SECTION __po_hi_main_initialization_critical_section;
HANDLE __po_hi_main_initialization_event;
......@@ -330,6 +336,8 @@ int __po_hi_initialize ()
__DEBUGMSG("Initializing partition %ld...\n", self_id);
__po_hi_transport_air_init ();
mynode = __po_hi_transport_get_mynode ();
for (tmp = 0 ; tmp < __PO_HI_NB_PORTS ; tmp++)
......@@ -424,8 +432,9 @@ int __po_hi_initialize ()
("[MAIN] Cannot open port %d, name=%s, return=%ld\n",
tmp, __po_hi_transport_get_model_name (tmp), portno);
// In the case of duplicate AIR port, we iterate on the
// list of ports already initialized
// In the case of duplicate AIR port, we iterate on the list
// of ports already initialized and attach this existing
// port to this port.
for (tmp2 = 0; tmp2 < tmp; tmp2++) {
__PO_HI_DEBUG_CRITICAL ("Testing %d\n", tmp2);
if (!strcmp (__po_hi_transport_get_model_name (tmp2),
......@@ -523,6 +532,9 @@ int __po_hi_wait_initialization (void)
LeaveCriticalSection (&__po_hi_main_initialization_critical_section);
return (__PO_HI_SUCCESS);
#elif defined (SIMULATOR)
um_wait_all();
#elif defined (__PO_HI_RTEMS_CLASSIC_API)
rtems_status_code ret;
......
......@@ -5,7 +5,7 @@
*
* For more informations, please visit http://taste.tuxfamily.org/wiki
*
* Copyright (C) 2007-2009 Telecom ParisTech, 2010-2018 ESA & ISAE.
* Copyright (C) 2007-2009 Telecom ParisTech, 2010-2020 ESA & ISAE.
*/
#include <po_hi_config.h>
......@@ -35,6 +35,10 @@
#include <rtems.h>
#endif
#ifdef SIMULATOR
#include <um_threads.h>
#endif
#if __PO_HI_NB_PROTECTED > 0
/* Declare only needed mutexes according to the generated
......@@ -160,6 +164,12 @@ int __po_hi_mutex_init (__po_hi_mutex_t* mutex, const __po_hi_mutex_protocol_t p
return __PO_HI_ERROR_UNKNOWN;
}
#endif
#if defined (SIMULATOR)
if (priority == 0)
mutex->priority = __PO_HI_MAX_PRIORITY - 1;
else
mutex->priority = priority;
#endif
#if defined (XENO_NATIVE)
if (rt_mutex_create (&mutex->xeno_mutex, NULL) != 0)
{
......@@ -195,6 +205,9 @@ int __po_hi_mutex_lock (__po_hi_mutex_t* mutex)
return __PO_HI_ERROR_MUTEX_LOCK;
}
#endif
#if defined (SIMULATOR)
mutex_lock(mutex);
#endif
#ifdef __PO_HI_RTEMS_CLASSIC_API
if (rtems_semaphore_obtain (mutex->rtems_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT) != RTEMS_SUCCESSFUL)
{
......@@ -237,6 +250,9 @@ int __po_hi_mutex_unlock (__po_hi_mutex_t* mutex)
return __PO_HI_ERROR_MUTEX_UNLOCK;
}
#endif
#if defined (SIMULATOR)
mutex_unlock(mutex);
#endif
#ifdef __PO_HI_RTEMS_CLASSIC_API
if (rtems_semaphore_release (mutex->rtems_mutex) != RTEMS_SUCCESSFUL)
{
......
......@@ -5,7 +5,7 @@
*
* For more informations, please visit http://taste.tuxfamily.org/wiki
*
* Copyright (C) 2018 ESA & ISAE.
* Copyright (C) 2018-2020 ESA & ISAE.
*/
#include <po_hi_returns.h>
......@@ -38,7 +38,7 @@
/* TO INITIALIZE THE STRUCTURES */
int __po_hi_sem_init(__po_hi_sem_t* sem, const __po_hi_mutex_protocol_t protocol, const int priority, int id)
{
__PO_HI_DEBUG_INFO ("[SEM] Sem Task %d is initialized", id);
__PO_HI_DEBUG_INFO ("[SEM] Sem Task %d is initialized\n", id);
#if defined (RTEMS_POSIX) || defined (POSIX) || defined (XENO_POSIX)
/* Attribute and mutex initialization */
......@@ -60,6 +60,15 @@ int __po_hi_sem_init(__po_hi_sem_t* sem, const __po_hi_mutex_protocol_t protocol
return __PO_HI_ERROR_SEM_CREATE;
}
#elif defined (SIMULATOR)
static int _name = 0;
sem->um_barrier = (semaphore *) malloc (sizeof (semaphore));
sem->um_mutex = (semaphore *) malloc (sizeof (semaphore));
semaphore_init(sem->um_barrier, 0, ++_name);
__PO_HI_DEBUG_INFO ("[SEM] Task %d barrier is: %d\n", id, _name);
semaphore_init(sem->um_mutex, 1, ++_name);
__PO_HI_DEBUG_INFO ("[SEM] Task %d mutex: %d\n", id, _name);
#elif defined (XENO_NATIVE)
/* Mutex initialization */
/* The protocol and priority are unused here */
......@@ -105,6 +114,7 @@ int __po_hi_sem_init(__po_hi_sem_t* sem, const __po_hi_mutex_protocol_t protocol
#else
#error Unsupported platform
#endif
return (__PO_HI_SUCCESS);
}
......@@ -118,7 +128,7 @@ int __po_hi_sem_wait(__po_hi_sem_t* sem)
if (pthread_mutex_trylock(&sem->mutex.posix_mutex) == 0 ) {
pthread_mutex_lock(&sem->mutex.posix_mutex);
}
/* Waiting on a condition and unlocking the mutex while doing so */
if (pthread_cond_wait(&sem->posix_condvar, &sem->mutex.posix_mutex) != 0 )
{
......@@ -126,6 +136,14 @@ int __po_hi_sem_wait(__po_hi_sem_t* sem)
return __PO_HI_ERROR_SEM_WAIT;
}
#elif defined (SIMULATOR)
if ((sem->um_mutex)->value == 0) {
semaphore_post (sem->um_mutex);///
}
//assert((sem->um_barrier)->value !=0);
semaphore_wait(sem->um_barrier);
#elif defined (__PO_HI_RTEMS_CLASSIC_API)
if (rtems_semaphore_release (sem->rtems_sem) != RTEMS_SUCCESSFUL)
{
......@@ -165,9 +183,8 @@ int __po_hi_sem_wait(__po_hi_sem_t* sem)
}
/* Waiting for ownership of the specified critical section object */
EnterCriticalSection(&sem->win32_criticalsection);
#endif
return __PO_HI_SUCCESS;
}
......@@ -181,6 +198,9 @@ int __po_hi_sem_mutex_wait(__po_hi_sem_t* sem){
return __PO_HI_ERROR_SEM_WAIT;
}
#elif defined (SIMULATOR)
semaphore_wait(sem->um_mutex);
#elif defined (__PO_HI_RTEMS_CLASSIC_API)
if (rtems_semaphore_obtain (sem->rtems_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT) != RTEMS_SUCCESSFUL)
{
......@@ -211,6 +231,10 @@ int __po_hi_sem_release(__po_hi_sem_t* sem)
return __PO_HI_ERROR_SEM_RELEASE;
}
#elif defined (SIMULATOR)
semaphore_post(sem->um_barrier);
semaphore_post(sem->um_mutex); //
#elif defined(__PO_HI_RTEMS_CLASSIC_API)
if (rtems_semaphore_release (sem->rtems_sem) != RTEMS_SUCCESSFUL)
{
......@@ -240,6 +264,7 @@ int __po_hi_sem_release(__po_hi_sem_t* sem)
__DEBUGMSG("SetEvent failed (%d)\n", GetLastError());
return __PO_HI_ERROR_SEM_RELEASE;
}
#endif
return __PO_HI_SUCCESS;
}
......@@ -252,6 +277,9 @@ int __po_hi_sem_mutex_release(__po_hi_sem_t* sem){
__PO_HI_DEBUG_CRITICAL ("[SEMAPHORE MUTEX] Error when trying to unlock the mutex\n");
return __PO_HI_ERROR_SEM_RELEASE;
}
#elif defined (SIMULATOR)
semaphore_post(sem->um_mutex);
#elif defined (__PO_HI_RTEMS_CLASSIC_API)
if (rtems_semaphore_release (sem->rtems_sem) != RTEMS_SUCCESSFUL)
{
......
......@@ -21,6 +21,7 @@
#include <sched.h>
#endif /* __linux__ */
//#include <um_threads.h>
#if defined (SIMULATOR)
#include <um_threads.h>
#undef POSIX
......@@ -209,8 +210,8 @@ void __po_hi_wait_for_tasks ()
}
}
#elif defined (SIMULATOR)
configure_fifo_scheduler();
start_scheduler();
return (__PO_HI_SUCCESS);
#endif
......@@ -384,6 +385,33 @@ int __po_hi_wait_for_next_period (__po_hi_task_id task)
}
return (__PO_HI_SUCCESS);
#elif defined(SIMULATOR)
#if defined(__PO_HI_USE_VCD) && defined(__unix__)
uint64_t current_timestamp = __po_hi_compute_timestamp();
#endif
int ret;
#if defined(__PO_HI_USE_VCD) && defined(__unix__)
if ((tasks[task].task_category) == TASK_PERIODIC || (tasks[task].task_category) == TASK_SPORADIC)
{
__po_hi_save_event_in_vcd_trace(current_timestamp, __po_hi_task_wait_dispatch, task, invalid_local_port_t, -1);
}
#endif
set_next_activation(tasks[task].um_id, shift(threads[tasks[task].um_id].period.sec, threads[tasks[task].um_id].period.nsec));
__po_hi_task_delay_until (&(tasks[task].period), task);
#if defined(__PO_HI_USE_VCD) && defined(__unix__)
current_timestamp = __po_hi_compute_timestamp();
if ((tasks[task].task_category) == TASK_PERIODIC)
{
__po_hi_save_event_in_vcd_trace (current_timestamp, __po_hi_task_dispatched, task, invalid_local_port_t, -1);
}
#endif
return (__PO_HI_SUCCESS);
#else
return (__PO_HI_UNAVAILABLE);
#endif
......@@ -708,7 +736,8 @@ int __po_hi_create_generic_task (const __po_hi_task_id id,
my_task->xeno_id = __po_hi_xenomai_create_thread
(priority, stack_size, start_routine, arg);
#elif defined (SIMULATOR)
my_task->um_id = um_thread_create (start_routine, stack_size, priority);
my_task->um_id = um_thread_periodic_create(start_routine, stack_size,
priority, *period);
#else
return (__PO_HI_UNAVAILABLE);
#endif
......@@ -892,6 +921,9 @@ int __po_hi_task_delay_until (__po_hi_time_t* time, __po_hi_task_id task)
return (__PO_HI_ERROR_PTHREAD_COND);
}
return (__PO_HI_SUCCESS);
#elif defined(SIMULATOR)
delay_until(tasks[task].um_id, shift(time->sec,time->nsec));
return (__PO_HI_SUCCESS);
#endif
return (__PO_HI_UNAVAILABLE);
}
......
......@@ -5,7 +5,7 @@
*
* For more informations, please visit http://taste.tuxfamily.org/wiki
*
* Copyright (C) 2007-2009 Telecom ParisTech, 2010-2017 ESA & ISAE.
* Copyright (C) 2007-2009 Telecom ParisTech, 2010-2020 ESA & ISAE.
*/
#include <time.h>
......@@ -93,7 +93,7 @@ LARGE_INTEGER __po_hi_unix_seconds_to_windows_tick(unsigned sec, unsigned nsec)
int __po_hi_get_time (__po_hi_time_t* mytime)
{
#if defined (POSIX) || defined (RTEMS_POSIX) || defined (XENO_POSIX)
#if defined (POSIX) || defined (RTEMS_POSIX) || defined (XENO_POSIX) || defined (SIMULATOR)
struct timespec ts;
if (clock_gettime (CLOCK_REALTIME, &ts)!=0)
......@@ -105,6 +105,7 @@ int __po_hi_get_time (__po_hi_time_t* mytime)
mytime->nsec = ts.tv_nsec;
return (__PO_HI_SUCCESS);
#elif defined (_WIN32)
SYSTEMTIME st;
FILETIME ft;
......@@ -120,6 +121,7 @@ int __po_hi_get_time (__po_hi_time_t* mytime)
mytime->nsec *= 100;
return (__PO_HI_SUCCESS);
#elif defined (__PO_HI_RTEMS_CLASSIC_API)
rtems_time_of_day current_time;
......
......@@ -5,7 +5,7 @@
*
* For more informations, please visit http://taste.tuxfamily.org/wiki
*
* Copyright (C) 2007-2009 Telecom ParisTech, 2010-2018 ESA & ISAE.
* Copyright (C) 2007-2009 Telecom ParisTech, 2010-2020 ESA & ISAE.
*/
#include<stddef.h>
......@@ -68,6 +68,12 @@ extern __po_hi_protocol_t __po_hi_ports_protocols[__PO_HI_NB_PORTS][__PO_
long int __po_hi_air_port[__PO_HI_NB_PORTS];
/* Store either SAMPLING_PORT_ID_TYPE or QUEUING_PORT_ID_TYPE */
__po_hi_msg_t __po_hi_c_send_msg;
/* Message, heap allocated */
__po_hi_mutex_t __po_hi_c_send_mutex;
#endif
#ifdef XM3_RTEMS_MODE
......@@ -83,7 +89,7 @@ int __po_hi_xtratum_port[__PO_HI_NB_PORTS];
int __po_hi_transport_send (__po_hi_task_id id, __po_hi_port_t port)
{
__po_hi_request_t* request;
__po_hi_uint8_t ndest;
__po_hi_uint8_t i;
......@@ -133,7 +139,7 @@ int __po_hi_transport_send (__po_hi_task_id id, __po_hi_port_t port)
/* The gqueue on the destination port is full, error message transmitted */
__PO_HI_DEBUG_CRITICAL("[TRANSPORT] QUEUE FULL ON THE DESTINATION PORT, NOT TRANSMITTED, task-id=%d, port=%d", id, destination_port_local);
return __PO_HI_ERROR_QUEUE_FULL;
}
}
request->port = destination_port;
......@@ -175,8 +181,9 @@ int __po_hi_transport_send (__po_hi_task_id id, __po_hi_port_t port)
if (ret < 0) {
__PO_HI_DEBUG_CRITICAL
("[GQUEUE] Error delivering using inter-partitions ports, %d\n",
ret);
("[GQUEUE] Error delivering using inter-partitions ports, port=%d, ret=%d\n",
port, ret);
} else {
__PO_HI_DEBUG_DEBUG
("[GQUEUE] Data delivered using inter-partitions ports, %d\n",
......@@ -189,26 +196,34 @@ int __po_hi_transport_send (__po_hi_task_id id, __po_hi_port_t port)
__po_hi_port_kind_t pkind = __po_hi_transport_get_port_kind (port);
RETURN_CODE_TYPE ret;
__po_hi_mutex_lock (&__po_hi_c_send_mutex);
__po_hi_msg_reallocate (&__po_hi_c_send_msg);
__po_hi_marshall_request (request, &__po_hi_c_send_msg);
int size_to_write = __po_hi_msg_length ( &__po_hi_c_send_msg);
if (pkind == __PO_HI_OUT_DATA_INTER_PROCESS) {
WRITE_SAMPLING_MESSAGE
(__po_hi_air_port[port],
request, sizeof (__po_hi_request_t),
&__po_hi_c_send_msg, size_to_write,
&ret);
} else {
if (pkind == __PO_HI_OUT_EVENT_DATA_INTER_PROCESS) {
SEND_QUEUING_MESSAGE
(__po_hi_air_port[port],
&__po_hi_c_send_msg, size_to_write,
INFINITE_TIME_VALUE, &ret);
}
}
__po_hi_mutex_unlock (&__po_hi_c_send_mutex);
if (pkind == __PO_HI_OUT_EVENT_DATA_INTER_PROCESS) {
SEND_QUEUING_MESSAGE
(__po_hi_air_port[port],
request, sizeof (__po_hi_request_t),
INFINITE_TIME_VALUE, &ret);
}
if (ret != NO_ERROR) {
if (ret != NO_ERROR) {
__PO_HI_DEBUG_CRITICAL
("[GQUEUE] Error delivering using inter-partitions ports, %d\n",
ret);
("[GQUEUE] Error delivering using inter-partitions ports, air port=%d, ret=%d, size=%d\n",
__po_hi_air_port[port], ret, size_to_write);
} else {
__PO_HI_DEBUG_DEBUG
__PO_HI_DEBUG_DEBUG
("[GQUEUE] Data delivered using inter-partitions ports, %d\n",
ret);
}
......@@ -229,7 +244,7 @@ int __po_hi_transport_send (__po_hi_task_id id, __po_hi_port_t port)
#endif
}
request->port = __PO_HI_GQUEUE_INVALID_PORT;
request->port = __PO_HI_GQUEUE_INVALID_PORT; // XXX questionnable
#ifdef __PO_HI_DEBUG
__PO_HI_DEBUG_DEBUG ("\n");
......@@ -565,6 +580,12 @@ int __po_hi_transport_xtratum_get_port (const __po_hi_port_t portno)
#endif
#if defined(AIR_HYPERVISOR)
void __po_hi_transport_air_init (void)
{
__po_hi_mutex_init (&__po_hi_c_send_mutex, __PO_HI_MUTEX_REGULAR, 0);
}
void __po_hi_transport_air_port_init (const __po_hi_port_t portno, long int val)
{
__po_hi_air_port[portno] = val;
......
This diff is collapsed.