On 12/1/18 9:52 PM, Matheus Pinto via Xenomai wrote: > Hi, > > I want use the Xenomai library as underlayer for objects classes in C++. > For that, I am using the follow system: > > -Ubuntu Mate 16.04.2 (Xenial) > -Xenomai/cobalt v3.0.6 > -Raspberry Pi 3 with Broadcom BCM2837 > > This prototype code is in a .cpp main file: > > #include "test_led.hpp" > #include <stdio.h> > #include <stdlib.h> > #include <iostream> > #include <signal.h> > #include <unistd.h> > #include <sys/mman.h> > #include <alchemy/task.h> > #include <alchemy/timer.h> > #include <alchemy/heap.h> > > using namespace std; > > /*******************TASKS PROTOTYPES*********************/ > > void PubFunc(void * arg); > > void ManFunc(void* arg); > > void TopicTaskFunc(void * args); > > /*******************************************************/ > > > class Topic > { > private: > RT_TASK task; > public: > > Topic(void) > { > rt_task_create(&task, "", 100000, 20, 0); > } > > ~Topic(void) > { > rt_task_delete(&task); > } > > RT_TASK* GetTask(void) > { > return &task; > } > > private: > friend void TopicTaskFunc(void* args); > }; > > > class Communic{ > private: > Topic *top; > RT_HEAP heap; > public: > > Communic(): > top(NULL) > { > /*******************Create heap to allocate dynamically the > objects*********************/ > if(rt_heap_create(&(this->heap), "commHeap", 83886080, H_PRIO) != 0) > { > rt_printf("Impossible create heap.\n"); > exit(1); > } > } > > void InitComm() > { > void *temp; > > > /*******************Allocate memory for Topic object and call > constructor****************/ > if(rt_heap_alloc(&(this->heap), > sizeof(Topic), > TM_INFINITE, > (void**)&(temp)) > != 0) > { > rt_printf("Problem to create topic: impossible allocate heap > for topic.\n"); > exit(1); > } > > this->top = new(temp) Topic(); > > /*****************Initiate the topic task, that will start after > management task sleep***/ > rt_task_start(this->top->GetTask(), > TopicTaskFunc, > (void*)this->top); > } > > void DeinitComm(void) > { > this->top->~Topic(); > led_TurnOn(9); // This led never is ON. > rt_heap_free(&(this->heap), this->top); > } > > }; > > /*******************TASKS IMPLEMENTATIONS*********************/ > > void PubFunc(void * arg) > { > uint16_t id = *((uint16_t*)arg); > size_t execNum = 0; > > RT_TASK_INFO info; > > rt_task_inquire(rt_task_self(), &info); > > rt_printf("Start Task with PID: %d.\n", info.pid); > > /*Sleep for 1 second and show the current execution number*/ > for(;;) > { > execNum++; > rt_printf("Task %d -> Execution %d.\n", id, execNum); > rt_task_sleep(1000000000); > } > } > > void ManFunc(void* arg) > { > RT_TASK taskHand; > Communic comm; > size_t id = 1; > > /* Create the task for "PubFunc above" and init the comm object. > * After 5 seconds, sleep for "Pub Func execute and delete it and > * deinitialize comm object (with its own task )"*/ > for(;;) > { > rt_task_create(&taskHand, "", 500, 5, 0); > rt_task_start(&taskHand, > PubFunc, > (void*)&id); > > comm.InitComm(); > rt_task_sleep((uint64_t)(((uint64_t)1000000000)*5)); > comm.DeinitComm(); > > rt_task_delete(&taskHand); > rt_task_sleep(1000000000); > } > } > > void TopicTaskFunc(void * args) > { > RT_TASK_INFO info; > > rt_task_inquire(rt_task_self(), &info); > > rt_printf("topic task PID = %d.\n",info.pid); > > /* Just stay suspend and wait be deleted. > * HINT: the task is awaken when management task call delete > * through "comm.Deinit()", The led being ON confirmed that, > * besides that the program is freeze when led is ON.*/ > for(;;) > { > rt_task_suspend(rt_task_self()); > led_TurnOn(8); > } > } > > /*************************************************************************/ > > int main(int argc, char* argv[]) > { > RT_TASK taskHand; > > // Lock memory : avoid memory swapping for this program > mlockall(MCL_CURRENT|MCL_FUTURE); > > led_Init(8); > led_Init(9); > led_TurnOff(8); > led_TurnOff(9); > > rt_task_create(&taskHand, "", 500, 40, 0); > rt_task_start(&taskHand, > ManFunc, > NULL); > > for(;;) > { > > getchar(); > } > } > > The first thing I do was create a management task (ManFunc) in main with > the higher priority (40). Inside this task another task (PubFunc) is create > directly with priority 5, and other is create indirectly (TopicTaskFunc) > with the call oh method "comm.InitComm" with priority 20. > > After creation, ManFunc sleep for 5 seconds, to PubFunc execute is > workload (Just print). The TopicTaskFunc do nothing, because is stuck in a > "rt_task_suspend" inside a loop. > > Passed the 5 seconds, the PubFunc stop its execution because its lower > priority. However, in call of "comm.DeinitComm" the program freeze. It was > confirmed that the reason is because in the call of "rt_task_delete" > for TopicTaskFunc, > it is awaken from its blocked state and get stuck in its own loop. > > This is a weird behavior, because: > - rt_task_delete resumes the TopicTaskFunc, instead just removing it from > schedule and:
Technically speaking, Linux threads cannot be "removed from schedule" by other threads: they do block or exit, possibly as a result of a remote action or event, typically signals. So the question would rather be: why doesn't your thread receive the cancellation request sent on behalf of rt_task_delete()? > - TopicTaskFunc have a lower priority than ManFunc, but execute instead > that. > > Any tip for this problem? > Try --enable-async-cancel when configuring. -- Philippe.