Unverified Commit 3969bbee authored by Jerome Hugues's avatar Jerome Hugues Committed by GitHub

Merge pull request #35 from bouazizrahma/master

Improve the generation of the vcd trace.
For openaadl/ocarina#244
parents c803b3d3 5be4ff61
......@@ -129,6 +129,16 @@ typedef struct
} __po_hi_ba_automata_state_t;
/* __po_hi_vcd_event_kind_t : this type enumerates the different
* kinds of events caught in the vcd trace */
typedef enum
{
__po_hi_task_wait_dispatch,
__po_hi_task_dispatched,
__po_hi_store_in_port_queue,
__po_hi_next_value_port_queue,
} __po_hi_vcd_event_kind_t;
void __po_hi_copy_array (void* dst, void* src, __po_hi_uint32_t size);
#endif /* __PO_HI_TYPES_H_ */
......@@ -25,6 +25,66 @@ unsigned long __po_hi_swap_byte (unsigned long value);
#include <pthread.h>
#include <string.h>
#include <deployment.h>
/* Types used to store the vcd trace */
typedef struct
{
__po_hi_vcd_event_kind_t vcd_event_kind;
uint64_t __po_hi_vcd_trace_timestamp;
__po_hi_task_id task_id;
__po_hi_local_port_t port_id;
__po_hi_port_id_t port_queue_used_size;
} __po_hi_vcd_trace_element_t;
/* __po_hi_vcd_trace_max_nb_events used to reallocate the array
* of the vcd trace */
__po_hi_int32_t __po_hi_vcd_trace_max_nb_events;
/* __po_hi_vcd_trace_array an array containing the vcd trace
* as elements with type __po_hi_vcd_trace_element_t */
__po_hi_vcd_trace_element_t* __po_hi_vcd_trace_array;
/* __po_hi_vcd_trace_array_index is the index of __po_hi_vcd_trace_array
* it should be protected as it is shared between tasks used to
* save a new element in the array*/
__po_hi_int32_t __po_hi_vcd_trace_array_index;
/* mutex used to protect the index __po_hi_vcd_trace_array_index */
pthread_mutex_t __po_hi_vcd_trace_mutex;
/* __po_hi_get_larger_array_for_vcd_trace allows to reallocate a larger
* array to save the vcd trace */
void __po_hi_get_larger_array_for_vcd_trace (void);
/* __po_hi_save_event_in_vcd_trace allows to save an element in
* __po_hi_vcd_trace_array */
void __po_hi_save_event_in_vcd_trace (uint64_t timestamp, __po_hi_vcd_event_kind_t event_kind, __po_hi_task_id task, __po_hi_local_port_t port, __po_hi_port_id_t queue_size);
/* __po_hi_compute_timestamp : returns the actual instant
* based on the __po_hi_vcd_start_t instant. The returned
* value is in (ms) */
uint64_t __po_hi_compute_timestamp (void);
/* __po_hi_vcd_start_t is the start time and it is
* set in the procedure __po_hi_initialize_vcd_trace */
__po_hi_time_t __po_hi_vcd_start_t;
/* __po_hi_signalHandler is a SIGINT signal handler : it is invoked when
* Ctrl-c is pressed in the keyboard to interrupt the execution
* of the application. This handler allows a normal exit
* of the program which enables the invocation
* of the atexit function */
void __po_hi_signalHandler(int signo);
/* __po_hi_signalHandler create the vcd file and fill it
* with the vcd trace saved in __po_hi_vcd_trace_array */
void __po_hi_create_vcd_file(void);
/* __po_hi_initialize_vcd_trace initializes some variables and catches
* the SIGINT signal*/
void __po_hi_initialize_vcd_trace (void);
/* Variable keeping track of whether VCD tracing is enabled or not */
enum tagVCD {
......@@ -35,45 +95,9 @@ enum tagVCD {
void __po_hi_instrumentation_vcd_init (void);
#define __PO_HI_INSTRUMENTATION_VCD_INIT __po_hi_instrumentation_vcd_init ();
#define __PO_HI_INSTRUMENTATION_VCD_WRITE(s, args...) \
{ \
extern enum tagVCD VCD_state; \
if (VCD_state == VCD_ENABLED) { \
extern int __po_hi_vcd_file; \
extern __po_hi_time_t __po_hi_vcd_start_time; \
extern pthread_mutex_t __po_hi_vcd_mutex; \
__po_hi_time_t __po_hi_vcd_current_time; \
char buf[1024]; \
int size_to_write = 0; \
uint64_t st,ct,et = 0; \
\
pthread_mutex_lock (&__po_hi_vcd_mutex); \
\
if (__po_hi_get_time(&__po_hi_vcd_current_time) != __PO_HI_SUCCESS) \
{ \
__DEBUGMSG("[POHIC-INSTRUMENTATION] Could not retrieve time\n"); \
} \
else \
{ \
st = __PO_HI_TIME_TO_US(__po_hi_vcd_start_time); \
ct = __PO_HI_TIME_TO_US(__po_hi_vcd_current_time); \
et = ct - st ; \
memset (buf, '\0', 1024); \
size_to_write = sprintf (buf, "#%llu\n", et); \
write (__po_hi_vcd_file, buf, size_to_write); \
\
memset (buf, '\0', 1024); \
size_to_write = sprintf (buf, s, ##args); \
write (__po_hi_vcd_file, buf, size_to_write); \
} \
pthread_mutex_unlock (&__po_hi_vcd_mutex); \
} \
}
#define __PO_HI_INITIALIZE_VCD_TRACE __po_hi_initialize_vcd_trace ();
#else
#define __PO_HI_INSTRUMENTATION_VCD_WRITE(s, args...)
#define __PO_HI_INSTRUMENTATION_VCD_INIT
#define __PO_HI_INITIALIZE_VCD_TRACE
#endif
#endif /* __PO_HI_UTILS_H__ */
......@@ -367,8 +367,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]);
__PO_HI_INSTRUMENTATION_VCD_WRITE("r%d p%d.%d\n", __po_hi_gqueue_used_size(id,port), 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
/* 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];
......@@ -476,21 +478,21 @@ void __po_hi_gqueue_wait_for_specific_incoming_events (__po_hi_task_id id,
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))
{
__PO_HI_INSTRUMENTATION_VCD_WRITE("0t%d\n", id);
/* 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);
__DEBUGMSG("GQUEUE_SEM_WAIT %d %d\n", id, res_sem);
assert(res_sem == __PO_HI_SUCCESS);
__PO_HI_INSTRUMENTATION_VCD_WRITE("1t%d\n", id);
}
#if defined (MONITORING)
record_event(SPORADIC, WAIT_FOR, id, invalid_port_t, invalid_port_t, *port, invalid_local_port_t, NULL);
#endif
#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
/** 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);
......@@ -504,6 +506,9 @@ void __po_hi_gqueue_wait_for_specific_incoming_events (__po_hi_task_id id,
void __po_hi_gqueue_wait_for_incoming_event (__po_hi_task_id id,
__po_hi_local_port_t* port)
{
#if defined(__PO_HI_USE_VCD) && defined(__unix__)
__po_hi_save_event_in_vcd_trace(__po_hi_compute_timestamp(), __po_hi_task_wait_dispatch, id, invalid_local_port_t, -1);
#endif
/* Locking only the mutex of the semaphore */
int result = __po_hi_sem_mutex_wait_gqueue(__po_hi_gqueues_semaphores,id);
__DEBUGMSG("GQUEUE_SEM_MUTEX_WAIT %d %d\n", id, result);
......@@ -511,13 +516,10 @@ void __po_hi_gqueue_wait_for_incoming_event (__po_hi_task_id id,
while(po_hi_gqueues_queue_is_empty(id) == 1)
{
__PO_HI_INSTRUMENTATION_VCD_WRITE("0t%d\n", id);
/* 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);
__DEBUGMSG("GQUEUE_SEM_WAIT %d %d\n", id, res_sem);
assert(res_sem == __PO_HI_SUCCESS);
__PO_HI_INSTRUMENTATION_VCD_WRITE("1t%d\n", id);
}
*port = __po_hi_gqueues_global_history[id][__po_hi_gqueues_global_history_offset[id]];
......@@ -526,8 +528,11 @@ void __po_hi_gqueue_wait_for_incoming_event (__po_hi_task_id id,
record_event(SPORADIC, WAIT_FOR, id, invalid_port_t, invalid_port_t, *port, invalid_local_port_t, NULL);
#endif
#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
/** 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);
......@@ -663,7 +668,10 @@ int __po_hi_gqueue_next_value (__po_hi_task_id id, __po_hi_local_port_t port)
__PO_HI_DEBUG_DEBUG ("\nBefore -- on size, Next_value for task id = %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 -- on size , Next_value for task id = %d, __po_hi_gqueues_used_size[id][port] = %d\n",id, __po_hi_gqueues_used_size[id][port]);
__PO_HI_INSTRUMENTATION_VCD_WRITE("r%d p%d.%d\n", __po_hi_gqueue_used_size(id,port), id, port);
#if defined(__PO_HI_USE_VCD) && defined(__unix__)
__po_hi_save_event_in_vcd_trace(__po_hi_compute_timestamp(), __po_hi_next_value_port_queue, id, port, __po_hi_gqueue_used_size(id,port));
#endif
if (__po_hi_gqueue_used_size(id,port) == 0)
{
......
......@@ -479,7 +479,10 @@ int __po_hi_wait_initialization (void)
pthread_mutex_unlock (&mutex_init);
__PO_HI_INSTRUMENTATION_VCD_INIT
#if defined(__PO_HI_USE_VCD) && defined(__unix__)
/* initialize parameters used to save the vcd trace */
__PO_HI_INITIALIZE_VCD_TRACE
#endif
return (__PO_HI_SUCCESS);
......
......@@ -62,15 +62,15 @@ int __po_hi_protected_init ()
int __po_hi_protected_lock (__po_hi_protected_t protected_id)
{
__PO_HI_INSTRUMENTATION_VCD_WRITE("1w%d\n", protected_id);
//__PO_HI_INSTRUMENTATION_VCD_WRITE("1w%d\n", protected_id);
if (__po_hi_mutex_lock (&__po_hi_protected_mutexes[protected_id]) != __PO_HI_SUCCESS )
{
__PO_HI_INSTRUMENTATION_VCD_WRITE("0w%d\n", protected_id);
//__PO_HI_INSTRUMENTATION_VCD_WRITE("0w%d\n", protected_id);
__PO_HI_DEBUG_CRITICAL ("[PROTECTED] Error when lock protected resource %d\n", protected_id);
return __PO_HI_ERROR_PROTECTED_LOCK;
}
__PO_HI_INSTRUMENTATION_VCD_WRITE("0w%d\n", protected_id);
__PO_HI_INSTRUMENTATION_VCD_WRITE("1l%d\n", protected_id);
//__PO_HI_INSTRUMENTATION_VCD_WRITE("0w%d\n", protected_id);
//__PO_HI_INSTRUMENTATION_VCD_WRITE("1l%d\n", protected_id);
return __PO_HI_SUCCESS;
}
......
......@@ -167,13 +167,31 @@ void __po_hi_wait_for_tasks ()
#if defined (RTEMS_POSIX) || defined (POSIX) || defined (XENO_POSIX)
#if defined(__PO_HI_USE_VCD) && defined(__unix__)
/* the atexit function allows the call of the function
* __po_hi_create_vcd_file when the program terminates
* normally */
atexit(__po_hi_create_vcd_file);
#endif
int i;
for (i = 0; i < __PO_HI_NB_TASKS; i++)
{
pthread_join( tasks[i].tid , NULL );
}
#if defined(__PO_HI_USE_VCD) && defined(__unix__)
/* initialize the index of the vcd trace array
* and its maximum size*/
__po_hi_vcd_trace_array_index = 0;
__po_hi_vcd_trace_max_nb_events = 0;
if (__po_hi_vcd_trace_array_index == __po_hi_vcd_trace_max_nb_events)
__po_hi_get_larger_array_for_vcd_trace ();
#endif
#elif defined (__PO_HI_RTEMS_CLASSIC_API)
rtems_task_suspend(RTEMS_SELF);
......@@ -274,7 +292,6 @@ int __po_hi_compute_next_period (__po_hi_task_id task)
#endif
}
int __po_hi_wait_for_next_period (__po_hi_task_id task)
{
......@@ -286,8 +303,20 @@ int __po_hi_wait_for_next_period (__po_hi_task_id task)
#endif
#if defined (POSIX) || defined (RTEMS_POSIX) || defined (XENO_POSIX)
#if defined(__PO_HI_USE_VCD) && defined(__unix__)
uint64_t current_timestamp = __po_hi_compute_timestamp();
#endif
int ret;
__PO_HI_INSTRUMENTATION_VCD_WRITE("0t%d\n", task);
#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
__po_hi_task_delay_until (&(tasks[task].timer), task);
if ( (ret = __po_hi_compute_next_period (task)) != 1)
......@@ -295,8 +324,14 @@ int __po_hi_wait_for_next_period (__po_hi_task_id task)
return (__PO_HI_ERROR_CLOCK);
}
__PO_HI_INSTRUMENTATION_VCD_WRITE("1t%d\n", 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);
#elif defined (_WIN32)
......
This diff is collapsed.
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