Closed thesamprice closed 2 years ago
Yes, there have been other observed corner cases when deleting a task. In the pthread implementation, this uses condition variables, and pthread_cond_wait
is a cancellation point. There is a handler installed via "pthread_cleanup_push" that releases the mutex in the event that the task is deleted while pending on the sem. Sounds like in your Qt port this isn't working the same way.
Make sure you are using something equivalent to "pthread_cleanup_push" ... this is actually part of the POSIX spec that says the mutex is re-locked if a task is canceled during the call to pthread_cond_wait, that this is intended behavior that the mutex will be left in a locked state after task deletion. One must use a cleanup handler to unlock it.
That being said, this is just one example. There are other cases where it is unclear if/when a resource is held by a task and whether that resource (count sem, mutex, etc) should be returned/reset when the task is deleted. There just isn't one right answer, and any answer is subject to possible race conditions.
It may be that this test is checking something that won't work on Qt port if it doesn't have a proper underlying mechanism to handle it. Might have to disable this test with that caveat.
In short, suffice to say that deleting tasks is hard ... better to design the software to have the task self-exit when done, or better yet just "park" idle worker tasks and not delete them. Most FSW does not delete tasks for this reason, so it might not be that big of a deal to ignore this failure.
@jphickey Thanks for the info.
For disabling the test I added a test_1_running volatile flag, and the following logic. Is there an appropriate config file to specify if the OS can handle doing cleanup on task deletions? and then add appropriate logic if the OS cleans up on task deletes. A desired name for this?
Something like this lets my test work.
/* Delete the task, which should be pending in OS_BinSemTake() */
if(OS_TASK_DELETE_SELFCLEANS == 0){
task_1_running = 0;
OS_TaskDelay(100); /* Allow task_1 to gracefully stop */
}
status = OS_TaskDelete(task_1_id);
UtAssert_True(status == OS_SUCCESS, "OS_TaskDelete Rc=%d", (int)status);
status = OS_TimerDelete(timer_id);
UtAssert_True(status == OS_SUCCESS, "OS_TimerDelete Rc=%d", (int)status);
OS_TaskDelay(100);
status = OS_BinSemGetInfo(bin_sem_id, &bin_sem_prop);
UtAssert_True(status == OS_SUCCESS, "BinSem value=%d Rc=%d", (int)bin_sem_prop.value, (int)status);
/* if failures occur, do not loop endlessly */
while (task_1_failures < 20 && task_1_running == 1)
{
status = OS_BinSemTake(bin_sem_id);
if (status != OS_SUCCESS)
{
Not sure, this seems to be an oddball case because the 3 supported OS's (POSIX, RTEMS, VxWorks) all pass this test. If the Qt cannot pass it, then any such workaround to the functional test should probably be limited to that port. In a way this also helps to document what is not working correctly in the port.
If Qt does not offer something akin to pthread_cleanup_push, then maybe disable cancellation during the mutex operation and re-enable cancellation once it has released the mutex normally? That would at least ensure it doesn't get canceled in the middle.
Under the hood Qt calls pthread_cleanup_push when starting a thread, but I dont see this callback when taking a semaphore.
Ill go ahead and just add it to the osal_config.ini / osal_config.h
Describe the bug Working through the unit tests for a qt port. I hit a stumbling block on bin-sem-test.c function
BinSemCheck
.When a task is deleted it may have registered callbacks with resources. In case of qt the task with a binary semaphore (QSemaphore) in a waiting state that gets deleted. Ends up stalling the system when that QSemaphore is written to.
From what i gather free-rtos has a similar issue.
https://www.freertos.org/FreeRTOS_Support_Forum_Archive/August_2016/freertos_Releasing_Resources_on_Task_Exit_Delete_b113e7a9j.html
A ctrl+c shows backtrace as follows.
System observed on:
Additional context I subclassed my qt thread from the qt class, and have been using the terminate call. I'll try a different method to see if that allows qt to cleanup semaphores from deleted tasks.
Reporter Info Full name and company/organization if applicable