From f00c0363674c200a15722fb41c95281f2bc4ce93 Mon Sep 17 00:00:00 2001 From: winckel <winckel@eurecom.fr> Date: Wed, 23 Oct 2013 14:08:42 +0000 Subject: [PATCH] added "itti_exit_task" to terminate current task when a MESSAGE_TERMINATE is received. Modified "itti_wait_tasks_end" to exit when some threads are not terminated after a 1 second time-out. modified "SIGINT" handling, exit is done after tring to join all threads like for "SIGUSR1". Added message reception for TASK_L2L1 and handling of TEST and TERMINATE messages in oaisim. git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4269 818b1a75-f10b-46b9-bf7c-635c3b92a50f --- common/utils/itti/intertask_interface.c | 41 +++++++++++++++++++++---- common/utils/itti/intertask_interface.h | 4 +++ common/utils/itti/signals.c | 8 +++-- targets/SIMU/USER/oaisim.c | 28 +++++++++++++++-- 4 files changed, 70 insertions(+), 11 deletions(-) diff --git a/common/utils/itti/intertask_interface.c b/common/utils/itti/intertask_interface.c index 53b8101dbb..1780a9b967 100644 --- a/common/utils/itti/intertask_interface.c +++ b/common/utils/itti/intertask_interface.c @@ -28,6 +28,7 @@ *******************************************************************************/ +#define _GNU_SOURCE #include <pthread.h> #include <stdio.h> #include <stdlib.h> @@ -394,6 +395,10 @@ void itti_mark_task_ready(task_id_t task_id) { pthread_mutex_unlock (&itti_desc.tasks[thread_id].message_queue_mutex); } +void itti_exit_task(void) { + pthread_exit (NULL); +} + void itti_terminate_tasks(task_id_t task_id) { // Sends Terminate signals to all tasks. itti_send_terminate_message (task_id); @@ -442,6 +447,9 @@ int itti_init(thread_id_t thread_max, MessagesIds messages_id_max, const char * void itti_wait_tasks_end(void) { int end = 0; int i; + int ready_tasks; + int result; + int retries = 10; itti_desc.thread_handling_signals = pthread_self (); @@ -450,14 +458,35 @@ void itti_wait_tasks_end(void) { signal_handle (&end); } - for (i = THREAD_FIRST; i < itti_desc.thread_max; i++) { - /* Skip tasks which are not running */ - if (itti_desc.tasks[i].task_state == TASK_STATE_READY) { - ITTI_DEBUG("Waiting end of thread %s\n", itti_desc.threads_name[i]); + do { + ready_tasks = 0; + + for (i = THREAD_FIRST; i < itti_desc.thread_max; i++) { + /* Skip tasks which are not running */ + if (itti_desc.tasks[i].task_state == TASK_STATE_READY) { - pthread_join (itti_desc.tasks[i].task_thread, NULL); - itti_desc.tasks[i].task_state = TASK_STATE_ENDED; + result = pthread_tryjoin_np (itti_desc.tasks[i].task_thread, NULL); + + ITTI_DEBUG("Thread %s join status %d\n", itti_desc.threads_name[i], result); + + if (result == 0) { + /* Thread has terminated */ + itti_desc.tasks[i].task_state = TASK_STATE_ENDED; + } + else { + /* Thread is still running, count it */ + ready_tasks++; + } + } + } + if (ready_tasks > 0) { + usleep (100 * 1000); } + } while ((ready_tasks > 0) && (retries--)); + + if (ready_tasks > 0) { + ITTI_DEBUG("Some threads are still running, force exit\n"); + exit (0); } } diff --git a/common/utils/itti/intertask_interface.h b/common/utils/itti/intertask_interface.h index 9b1ac0851a..7856cee9ef 100644 --- a/common/utils/itti/intertask_interface.h +++ b/common/utils/itti/intertask_interface.h @@ -120,6 +120,10 @@ int itti_create_task(task_id_t task_id, **/ void itti_mark_task_ready(task_id_t task_id); +/** \brief Exit the current task. + **/ +void itti_exit_task(void); + /** \brief Indicate that the task is completed and initiate termination of all tasks. * \param task_id task that is completed **/ diff --git a/common/utils/itti/signals.c b/common/utils/itti/signals.c index 1fc62fc0a4..0f5c4e7415 100644 --- a/common/utils/itti/signals.c +++ b/common/utils/itti/signals.c @@ -60,6 +60,7 @@ int signal_init(void) sigemptyset(&set); sigaddset (&set, SIGTIMER); + sigaddset (&set, SIGUSR1); sigaddset (&set, SIGABRT); sigaddset (&set, SIGSEGV); sigaddset (&set, SIGINT); @@ -115,18 +116,19 @@ int signal_handle(int *end) printf("Received SIGUSR1\n"); *end = 1; break; + case SIGSEGV: /* Fall through */ case SIGABRT: printf("Received SIGABORT\n"); backtrace_handle_signal(&info); break; - case SIGQUIT: + case SIGINT: printf("Received SIGINT\n"); itti_send_terminate_message(TASK_UNKNOWN); - printf("All tasks terminated -> exiting '"PACKAGE_NAME"'\n"); - exit(0); + *end = 1; break; + default: printf("Received unknown signal %d\n", info.si_signo); break; diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index f96bed6f78..73cdf67bee 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -376,14 +376,13 @@ void *l2l1_task(void *args_p) { char fname[64], vname[64]; #if defined(ENABLE_ITTI) + MessageDef *message_p; long timer_id; itti_mark_task_ready(TASK_L2L1); /* Test code */ { - MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_L2L1, MESSAGE_TEST); itti_send_msg_to_task(TASK_L2L1, INSTANCE_DEFAULT, message_p); @@ -400,6 +399,31 @@ void *l2l1_task(void *args_p) { #endif for (frame = 0; frame < oai_emulation.info.n_frames; frame++) { +#if defined(ENABLE_ITTI) + // Checks if a message has been sent to L2L1 task + itti_poll_msg(TASK_L2L1, INSTANCE_ALL, &message_p); + + if(message_p != NULL) + { + switch(message_p->header.messageId) + { + case TERMINATE_MESSAGE: + itti_exit_task(); + break; + + case MESSAGE_TEST: + LOG_D(EMU, "Received %s\n", itti_get_message_name(message_p->header.messageId)); + break; + + default: + LOG_E(EMU, "Received unexpected message %s\n", itti_get_message_name(message_p->header.messageId)); + break; + } + + free(message_p); + } +#endif + /* // Handling the cooperation Flag if (cooperation_flag == 2) -- GitLab