Commit da540890 authored by Cedric Roux's avatar Cedric Roux

itti: test an assumption that the new ITTI implementation is broken

The previous implementation has the notion of 'task ready' that is
removed from the new implementation.

When a task is created, it initializes some data structures and whatever
and then marks itself ready. Then it waits for all the other tasks to
be also ready. Then it does what it has to do.

The task creator creates all the tasks, then waits for each of them to
be ready then it sets a global variable to signal all the tasks that
all the other tasks are ready and that they can start their work.

The new ITTI implementation wants to be API-compatible with the previous
implementation but completely fails to respect this initialization
mechanism, leading to various random crashes.

We already observe some failures in the CI testbench with the basic
simulator.

This commit is not to be integrated into the develop branch but is done
to check if the analysis above is correct.

If it is then the basic simulator should work properly in the CI, as it
more or less used to do with the previous IITI implementation.

And then we need a proper fix. What is done here is not really satisfying.
(But can go into develop if no cleaner solution is found.)

Let's see...
parent 957bd567
...@@ -29,8 +29,13 @@ typedef struct task_list_s { ...@@ -29,8 +29,13 @@ typedef struct task_list_s {
int nb_events=0; int nb_events=0;
int epoll_fd=-1; int epoll_fd=-1;
int sem_fd=-1; int sem_fd=-1;
int created = 0;
volatile int ready = 0;
} task_list_t; } task_list_t;
static volatile int init_done = 0;
static volatile int all_created = 0;
int timer_expired(int fd); int timer_expired(int fd);
task_list_t tasks[TASK_MAX]; task_list_t tasks[TASK_MAX];
...@@ -273,7 +278,13 @@ extern "C" { ...@@ -273,7 +278,13 @@ extern "C" {
} }
int itti_create_task(task_id_t task_id, void *(*start_routine)(void *), void *args_p) { int itti_create_task(task_id_t task_id, void *(*start_routine)(void *), void *args_p) {
if (all_created) {
printf("ITTI: task %d cannot be created at this point\n", task_id);
abort();
}
task_list_t *t=&tasks[task_id]; task_list_t *t=&tasks[task_id];
printf("ITTI: thread %d created\n", task_id);
t->created = 1;
AssertFatal ( pthread_create (&t->thread, NULL, start_routine, args_p) ==0, AssertFatal ( pthread_create (&t->thread, NULL, start_routine, args_p) ==0,
"Thread creation for task %d failed!\n", task_id); "Thread creation for task %d failed!\n", task_id);
pthread_setname_np( t->thread, itti_get_task_name(task_id) ); pthread_setname_np( t->thread, itti_get_task_name(task_id) );
...@@ -385,12 +396,25 @@ extern "C" { ...@@ -385,12 +396,25 @@ extern "C" {
void itti_update_lte_time(uint32_t frame, uint8_t slot) {} void itti_update_lte_time(uint32_t frame, uint8_t slot) {}
void itti_set_task_real_time(task_id_t task_id) {} void itti_set_task_real_time(task_id_t task_id) {}
void itti_mark_task_ready(task_id_t task_id) { void itti_mark_task_ready(task_id_t task_id) {
// Function meaning is clear, but legacy implementation is wrong tasks[task_id].ready = 1;
// keep it void is fine: today implementation accepts messages in the queue before task is ready while (init_done == 0) usleep(1000);
} }
void itti_wait_ready(int wait_tasks) { void itti_wait_ready(int wait_tasks) {
// Stupid function, kept for compatibility (the parameter is meaningless!!!) int i;
if (wait_tasks) return;
all_created = 1;
for (i = 0; i < TASK_MAX; i++) {
if (!tasks[i].created) continue;
printf("ITTI: task %d created, wait for it to be ready\n", i);
while (!tasks[i].ready) usleep(1000);
printf("ITTI: task %d is ready\n", i);
}
init_done = 1;
printf("ITTI: all tasks should be created from now on\n");
} }
int signal_mask(void) { return 0;} int signal_mask(void) { return 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