Commit a1982390 authored by Laurent THOMAS's avatar Laurent THOMAS Committed by Robert Schmidt

Introduce no-thread mode in ITTI

Introduce a --no-itti-threads command line option to disable threading
in ITTI, and call message handlers in the current thread. This is being
introduced in order to increase repeatability when testing the nrUE with
the IQPlayer. Without this feature, runs with the IQPlayer will end up
differently, depending on the timing of ITTI threads, mostly when
sending messages to RRC and NAS.
parent 724c8c01
...@@ -30,17 +30,19 @@ ...@@ -30,17 +30,19 @@
extern "C" { extern "C" {
#include <intertask_interface.h> #include <intertask_interface.h>
#include <common/utils/system.h> #include <common/utils/system.h>
#include "executables/softmodem-common.h"
typedef struct timer_elm_s { typedef struct timer_elm_s {
timer_type_t type; ///< Timer type timer_type_t type; ///< Timer type
long instance; long instance;
long duration; long duration;
uint64_t timeout; uint64_t timeout;
void *timer_arg; ///< Optional argument that will be passed when timer expires void *timer_arg; ///< Optional argument that will be passed when timer expires
} timer_elm_t ; } timer_elm_t;
typedef struct task_list_s { typedef struct task_list_s {
task_info_t admin; task_info_t admin;
ittiTask_parms_t task_parms;
pthread_t thread; pthread_t thread;
pthread_mutex_t queue_cond_lock; pthread_mutex_t queue_cond_lock;
std::vector<MessageDef *> message_queue; std::vector<MessageDef *> message_queue;
...@@ -162,12 +164,12 @@ extern "C" { ...@@ -162,12 +164,12 @@ extern "C" {
pthread_mutex_lock (&t->queue_cond_lock); pthread_mutex_lock (&t->queue_cond_lock);
int ret=itti_send_msg_to_task_locked(destination_task_id, destinationInstance, message); int ret=itti_send_msg_to_task_locked(destination_task_id, destinationInstance, message);
while ( t->message_queue.size()>0 && t->admin.func != NULL ) { while (t->message_queue.size() > 0 && t->task_parms.shortcut_func != NULL) {
if (t->message_queue.size()>1) if (t->message_queue.size()>1)
LOG_W(ITTI,"queue in no thread mode is %ld\n", t->message_queue.size()); LOG_W(ITTI,"queue in no thread mode is %ld\n", t->message_queue.size());
pthread_mutex_unlock (&t->queue_cond_lock); pthread_mutex_unlock (&t->queue_cond_lock);
t->admin.func(NULL); t->task_parms.shortcut_func(NULL);
pthread_mutex_lock (&t->queue_cond_lock); pthread_mutex_lock (&t->queue_cond_lock);
} }
...@@ -327,11 +329,20 @@ extern "C" { ...@@ -327,11 +329,20 @@ extern "C" {
pthread_mutex_unlock (&t->queue_cond_lock); pthread_mutex_unlock (&t->queue_cond_lock);
} }
int itti_create_task(task_id_t task_id, int itti_create_task(const task_id_t task_id, void *(*start_routine)(void *), const ittiTask_parms_t *parms)
void *(*start_routine)(void *), {
void *args_p) {
task_list_t *t=tasks[task_id]; task_list_t *t=tasks[task_id];
threadCreate (&t->thread, start_routine, args_p, (char *)itti_get_task_name(task_id),-1,OAI_PRIORITY_RT); if (get_softmodem_params()->no_itti && task_id < sizeofArray(tasks_info) && parms && parms->shortcut_func) {
LOG_W(ITTI, "not starting the thread for %s, the msg processing will be done in place\n", tasks_info[task_id].name);
t->task_parms.shortcut_func = parms->shortcut_func;
return 0;
}
threadCreate(&t->thread,
start_routine,
parms ? parms->args_to_start_routine : NULL,
(char *)itti_get_task_name(task_id),
-1,
OAI_PRIORITY_RT);
LOG_I(ITTI,"Created Posix thread %s\n", itti_get_task_name(task_id) ); LOG_I(ITTI,"Created Posix thread %s\n", itti_get_task_name(task_id) );
return 0; return 0;
} }
...@@ -353,6 +364,7 @@ extern "C" { ...@@ -353,6 +364,7 @@ extern "C" {
AssertFatal(new_tasks != NULL, "could not realloc() tasks list"); AssertFatal(new_tasks != NULL, "could not realloc() tasks list");
tasks = new_tasks; tasks = new_tasks;
tasks[newQueue]= new task_list_t; tasks[newQueue]= new task_list_t;
tasks[newQueue]->task_parms = {0};
pthread_mutex_unlock (&lock_nb_queues); pthread_mutex_unlock (&lock_nb_queues);
LOG_I(ITTI,"Starting itti queue: %s as task %d\n", taskInfo->name, newQueue); LOG_I(ITTI,"Starting itti queue: %s as task %d\n", taskInfo->name, newQueue);
pthread_mutex_init(&tasks[newQueue]->queue_cond_lock, NULL); pthread_mutex_init(&tasks[newQueue]->queue_cond_lock, NULL);
...@@ -361,9 +373,6 @@ extern "C" { ...@@ -361,9 +373,6 @@ extern "C" {
AssertFatal( ( tasks[newQueue]->sem_fd = eventfd(0, EFD_SEMAPHORE) ) >=0, ""); AssertFatal( ( tasks[newQueue]->sem_fd = eventfd(0, EFD_SEMAPHORE) ) >=0, "");
itti_subscribe_event_fd((task_id_t)newQueue, tasks[newQueue]->sem_fd); itti_subscribe_event_fd((task_id_t)newQueue, tasks[newQueue]->sem_fd);
if (tasks[newQueue]->admin.threadFunc != NULL)
itti_create_task((task_id_t)newQueue, tasks[newQueue]->admin.threadFunc, NULL);
return newQueue; return newQueue;
} }
......
...@@ -484,9 +484,11 @@ void itti_poll_msg(task_id_t task_id, MessageDef **received_msg); ...@@ -484,9 +484,11 @@ void itti_poll_msg(task_id_t task_id, MessageDef **received_msg);
\param args_p Optional argument to pass to the start routine \param args_p Optional argument to pass to the start routine
@returns -1 on failure, 0 otherwise @returns -1 on failure, 0 otherwise
**/ **/
int itti_create_task(task_id_t task_id, typedef struct {
void *(*start_routine) (void *), void *args_to_start_routine;
void *args_p); void *(*shortcut_func)(void *);
} ittiTask_parms_t;
int itti_create_task(const task_id_t task_id, void *(*start_routine)(void *), const ittiTask_parms_t *args_p);
int itti_create_queue(const task_info_t *task_info); int itti_create_queue(const task_info_t *task_info);
......
...@@ -47,8 +47,8 @@ int create_tasks_ue(uint32_t ue_nb) { ...@@ -47,8 +47,8 @@ int create_tasks_ue(uint32_t ue_nb) {
if (users == NULL) abort(); if (users == NULL) abort();
users->count = ue_nb; users->count = ue_nb;
ittiTask_parms_t parms = {users, NULL};
if (itti_create_task (TASK_NAS_UE, nas_ue_task, users) < 0) { if (itti_create_task(TASK_NAS_UE, nas_ue_task, &parms) < 0) {
LOG_E(NAS, "Create task for NAS UE failed\n"); LOG_E(NAS, "Create task for NAS UE failed\n");
return -1; return -1;
} }
......
...@@ -197,7 +197,8 @@ int create_tasks_nrue(uint32_t ue_nb) { ...@@ -197,7 +197,8 @@ int create_tasks_nrue(uint32_t ue_nb) {
if (ue_nb > 0) { if (ue_nb > 0) {
LOG_I(NR_RRC,"create TASK_RRC_NRUE \n"); LOG_I(NR_RRC,"create TASK_RRC_NRUE \n");
if (itti_create_task (TASK_RRC_NRUE, rrc_nrue_task, NULL) < 0) { const ittiTask_parms_t parmsRRC = {NULL, rrc_nrue};
if (itti_create_task(TASK_RRC_NRUE, rrc_nrue_task, &parmsRRC) < 0) {
LOG_E(NR_RRC, "Create task for RRC UE failed\n"); LOG_E(NR_RRC, "Create task for RRC UE failed\n");
return -1; return -1;
} }
...@@ -208,7 +209,8 @@ int create_tasks_nrue(uint32_t ue_nb) { ...@@ -208,7 +209,8 @@ int create_tasks_nrue(uint32_t ue_nb) {
return -1; return -1;
} }
} }
if (itti_create_task (TASK_NAS_NRUE, nas_nrue_task, NULL) < 0) { const ittiTask_parms_t parmsNAS = {NULL, nas_nrue};
if (itti_create_task(TASK_NAS_NRUE, nas_nrue_task, &parmsNAS) < 0) {
LOG_E(NR_RRC, "Create task for NAS UE failed\n"); LOG_E(NR_RRC, "Create task for NAS UE failed\n");
return -1; return -1;
} }
......
...@@ -109,6 +109,7 @@ extern "C" ...@@ -109,6 +109,7 @@ extern "C"
#define CONFIG_HLP_SYNC_REF "Sync Reference in Sidelink\n" #define CONFIG_HLP_SYNC_REF "Sync Reference in Sidelink\n"
#define CONFIG_HLP_NID1 "Set NID1 value in Sidelink\n" #define CONFIG_HLP_NID1 "Set NID1 value in Sidelink\n"
#define CONFIG_HLP_NID2 "Set NID2 value in Sidelink\n" #define CONFIG_HLP_NID2 "Set NID2 value in Sidelink\n"
#define CONFIG_HLP_NOITTI "Do not start itti threads, call queue processing in place, inside the caller thread"
/*-----------------------------------------------------------------------------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters common to eNodeB and UE */ /* command line parameters common to eNodeB and UE */
...@@ -190,6 +191,7 @@ extern int usrp_tx_thread; ...@@ -190,6 +191,7 @@ extern int usrp_tx_thread;
{"disable-stats", CONFIG_HLP_STATS_DISABLE, PARAMFLAG_BOOL, .iptr=&stats_disabled, .defintval=0, TYPE_INT, 0}, \ {"disable-stats", CONFIG_HLP_STATS_DISABLE, PARAMFLAG_BOOL, .iptr=&stats_disabled, .defintval=0, TYPE_INT, 0}, \
{"nid1", CONFIG_HLP_NID1, 0, .iptr=&NID1, .defintval=10, TYPE_INT, 0}, \ {"nid1", CONFIG_HLP_NID1, 0, .iptr=&NID1, .defintval=10, TYPE_INT, 0}, \
{"nid2", CONFIG_HLP_NID2, 0, .iptr=&NID2, .defintval=1, TYPE_INT, 0}, \ {"nid2", CONFIG_HLP_NID2, 0, .iptr=&NID2, .defintval=1, TYPE_INT, 0}, \
{"no-itti-threads", CONFIG_HLP_NOITTI, PARAMFLAG_BOOL, .iptr=&softmodem_params.no_itti, .defintval=0, TYPE_INT, 0}, \
} }
// clang-format on // clang-format on
...@@ -238,6 +240,7 @@ extern int usrp_tx_thread; ...@@ -238,6 +240,7 @@ extern int usrp_tx_thread;
{ .s5 = { NULL } }, \ { .s5 = { NULL } }, \
{ .s5 = { NULL } }, \ { .s5 = { NULL } }, \
{ .s5 = { NULL } }, \ { .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
} }
// clang-format on // clang-format on
...@@ -349,6 +352,7 @@ typedef struct { ...@@ -349,6 +352,7 @@ typedef struct {
int sync_ref; int sync_ref;
int nid1; int nid1;
int nid2; int nid2;
int no_itti;
} softmodem_params_t; } softmodem_params_t;
extern uint64_t get_softmodem_optmask(void); extern uint64_t get_softmodem_optmask(void);
......
...@@ -51,3 +51,7 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, ...@@ -51,3 +51,7 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id,
const channel_t channel, const channel_t channel,
const uint8_t* pduP, const uint8_t* pduP,
const sdu_size_t pdu_len) { return 0; } const sdu_size_t pdu_len) { return 0; }
void *rrc_nrue(void *notUsed)
{
return NULL;
}
This diff is collapsed.
...@@ -114,6 +114,7 @@ int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index); ...@@ -114,6 +114,7 @@ int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index);
/**\brief RRC UE task. /**\brief RRC UE task.
\param void *args_p Pointer on arguments to start the task. */ \param void *args_p Pointer on arguments to start the task. */
void *rrc_nrue_task(void *args_p); void *rrc_nrue_task(void *args_p);
void *rrc_nrue(void *args_p);
void nr_rrc_handle_timers(NR_UE_Timers_Constants_t *timers); void nr_rrc_handle_timers(NR_UE_Timers_Constants_t *timers);
......
This diff is collapsed.
...@@ -174,6 +174,7 @@ typedef struct { ...@@ -174,6 +174,7 @@ typedef struct {
nr_ue_nas_t *get_ue_nas_info(module_id_t module_id); nr_ue_nas_t *get_ue_nas_info(module_id_t module_id);
void generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas); void generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas);
void *nas_nrue_task(void *args_p); void *nas_nrue_task(void *args_p);
void *nas_nrue(void *args_p);
#endif /* __NR_NAS_MSG_SIM_H__*/ #endif /* __NR_NAS_MSG_SIM_H__*/
......
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