Forum Discussion
Crash and semaphores
Hi,
when I make three tasks synchronized by semaphores (the tasks do nothing, they only make a Post and then a Pend to pass the control each other), after a number of iterations (this number is ever the same) the program is blocked. If I put a delay after the Pend, the number of iterations grew, but after this number of iterations the program crash. Why?? Thanks15 Replies
- Altera_Forum
Honored Contributor
Nobody had the same problem? I don't understand why the program crashes, it make nothing, there are only three tasks and each launches the other between semaphores: task A launches task B that launches task C that launches task A, and so on. After 107 iterations, the program crashes!
- Altera_Forum
Honored Contributor
could you post your code?
- Altera_Forum
Honored Contributor
Thank you for the interesting.
The code is: #include "includes.h" #include <iostream> using namespace std; #define OS_TASK_STAT_EN 1 #define OS_MAX_TASKS 8 #define TASK_STK_SIZE 1024 OS_STK TaskStartStk[TASK_STK_SIZE]; OS_STK TaskStartStk1[TASK_STK_SIZE]; OS_STK TaskStartStk2[TASK_STK_SIZE]; OS_STK TaskStartStk3[TASK_STK_SIZE]; OS_EVENT* sem_sync0; OS_EVENT* sem_sync1; OS_EVENT* sem_sync2; OS_EVENT* sem_sync3; void handle_sync(void* pdata) { INT8U err_sync3; pdata = pdata; for(;;) { cout << "I'm in handle_sync" << endl; fflush(0); OSSemPost(sem_sync1); OSSemPend(sem_sync3, 0, &err_sync3); } } void processing(void* pdata) { INT8U err_sync1; pdata = pdata; for(;;) { cout << "I'm in processing" << endl; fflush(0); OSSemPost(sem_sync2); OSSemPend(sem_sync1, 0, &err_sync1); } } void monitoring(void* pdata) { INT8U err_sync2; pdata = pdata; for(;;) { cout << "I'm in monitoring" << endl; fflush(0); OSSemPost(sem_sync3); OSSemPend(sem_sync2, 0, &err_sync2); } } static void TaskStartCreateTask(void) { cout << "I'm in TaskStartCreateTask" << endl; fflush(0); OSTaskCreate(handle_sync, (void*) 0, &TaskStartStk1 [TASK_STK_SIZE - 1], 11); OSTaskCreate(processing, (void*) 0, &TaskStartStk2[TASK_STK_SIZE - 1], 12); OSTaskCreate(monitoring, (void*) 0, &TaskStartStk3[TASK_STK_SIZE - 1], 15); } void TaskStart(void* pdata) { INT8U err_sync0; cout << "I'm in TaskStart" << endl; fflush(0); pdata = pdata; OSStatInit(); OSTaskCreate(handle_sync, (void*) 0, &TaskStartStk1[TASK_STK_SIZE - 1], 11); OSTaskCreate(processing, (void*) 0, &TaskStartStk2[TASK_STK_SIZE - 1], 6); OSTaskCreate(monitoring, (void*) 0, &TaskStartStk3[TASK_STK_SIZE - 1], 15); for(;;) { OSSemPost(sem_sync3); OSSemPend(sem_sync0, 0, &err_sync0); } } int main() { OSInit(); sem_sync0 = OSSemCreate(0); sem_sync1 = OSSemCreate(0); sem_sync2 = OSSemCreate(0); sem_sync3 = OSSemCreate(0); cout << "I'm in the main" << endl; fflush(0); OSTaskCreate(TaskStart, (void*) 0, &TaskStartStk[TASK_STK_SIZE - 1], 18); OSStart(); } - Altera_Forum
Honored Contributor
I'm pretty sure the standard output drivers aren't thread safe, so if you write from several threads at the same time you can crash. It's better either to only print out from one task, or use something else, such as leds, to monitor the threads activities.
- Altera_Forum
Honored Contributor
Thanks for the answer, but now, because hardware's problems, I can't verify if your idea is right.
- Altera_Forum
Honored Contributor
If I put the semaphore in this way:
OSSemPend(sem); cout << "Hello world" << endl; OSSemPost(sem, 0, err); does it become thread safe? Thanks - Altera_Forum
Honored Contributor
Yes, as long as you do that in every thread that uses the standard output, and that you use the same semaphore on each, obviously.
I re-read your code and I'm wondering something... where do you post your semaphore sem_sync0 ? What are you trying to achieve in this code? - Altera_Forum
Honored Contributor
I don't post sem_sync0 because I want that TaskStart creates the other tasks and stops: sem_sync0 never becomes 1, then TaskStart never runs, only at the beginning. But I don' think that this is the problem, because the same problem is verified when the three tasks are created in the main and not in TaskStart, i.e. when there isn't the thread TaskStart.
Thanks - Altera_Forum
Honored Contributor
A task can kill itself with OsTaskDel(OS_PRIO_SELF);
After this call the task will be deleted. Did you see any improvement by using this semaphore to make the standard output thread safe? - Altera_Forum
Honored Contributor
Unfortunately now I've not the hardware, and then I can't try if it runs. According to you, with the semaphores to make the cout thread safe, must it function?