Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training




Loading

Thread End

Posted by Nobody/Anonymous on December 29, 2004
Hi Everybody!
I've just read FreeRTOS documentation, and there is one thing that surprised me.
Thread is implemented as infinite loop (this of course is not surprisnig :) ), but when parent thread want to finish it, it calls vTaskDelete(). After reading documentation I understand, that it immediately finishes loop execution (by removing thread from scheduler), and idle thread will free memory allocated while thread creation. But some memory leaks will occur if thread dinamicaly allocate memory.
Shouldn't be finishing thread done by singnalig thread to leave infinite loop, dealocate all resources and leave thread execution routine?

RE: Thread End

Posted by Richard on December 29, 2004
This functionality is not easy to implement without increasing the complexity and code size of the kernel. This is because the task could be in any state when it is deleted. For example, if the task is blocked on a queue then when it unblocks it has to know was this because it timed out, because something arrived on the queue, or because it was deleted. Checking for a delete signal every time the task executes generates a large overhead.

There is however an easy to implement alternative.

Each task can have an AboutToDelete function – like a callback. When the idle task deletes the task it first calls the AboutToDelete function for the task. This would do nothing but free up any resources the task had dynamically allocated itself (resources allocated by the kernel are automatically de-allocated). A pointer to such a function could be stored within the TCB.

Regards.

RE: Thread End

Posted by Nobody/Anonymous on December 29, 2004
OK. But I think that nobody can say: 'Let's kill this thread now!', because it may be just after activity A and after A it has to perform activity B (it doesn't mean that it should be done in critical section). What if after A parent call vTaskDelete()? OK. You can register AboutToDelete callback, but You have to check at what stage thread has been interrupted. This exaple is quite simple, but it may be more complex in real system.
I think the best sollution for finishing threads is signaling by parent-thread to child-thread to self-finish:

static void threadFn(void *pParam)
{
message msg;
while(1)
{
queueReceive(queue, &msg)
switch(msg){
case LEAVE_THREAD:
dealocate_memory;
free_resources;
return;
case PERFORM_ACTION_A_AND_B:
do_action_A();
do_action_B();
break;
default:
break;
}
}
}


void parentTaskFn(void *pParam)
{
message msg;
thread hThread;
hThread = createThread(threadFn, ...);
....
....
msg = LEAVE_THREAD;
queueSend(queue, msg);
waitThread(hThread); //wait for thread termination
//when thread returns its routine it is removing from scheduler by kernel
}

Am I wrong?
Regards.

RE: Thread End

Posted by Nobody/Anonymous on December 29, 2004
Unfortunately no tabulatros :(

RE: Thread End

Posted by Richard on December 29, 2004
If your tasks can all take this form then this is fine. It places a lot of limitations on the task implementation, there is not always a parent thread for example.

In a small embedded system dynamic memory allocation is likely to be less of an issue than, for example, a task being deleted while it has a peripheral locked for access. The application design must of coarse take into account any actions necessary.

RE: Thread End

Posted by Nobody/Anonymous on December 29, 2004
Is more like Windoze style thread than RTOS task.

RE: Thread End

Posted by Nobody/Anonymous on December 30, 2004
>>Is more like Windoze style thread than RTOS task

Do You think about WinAPI TerminateThread()?
Do not ever use it to terminate thread if You want your application to run for a long time :) !!! It breaks thread at the current point of execution and removes it from scheduler freeing thread stack. It's lieke vTaskDelete in FreeRTOS.

Richard: of course. You have right if You are talking about small complexity systems. In most cases in embeded systems there are not thread termination at all!
>>there is not always a parent thread for example - NO! There is always parent thread :) It may be Root thread (main function is called from its context). Someone creates thread of course - so it is parent.
Of course thread can be signaled to terminate by different thread than parent.
If your design is very complex you will be not able to control all of resources disposing or memory freeing if You will manage it from different contexts.
I think the best sollution is to free resource by this one who allocated it.
Of course this scheme of thread termination will work, but i think it is very unsafe (more unsafe if system is more complex).

>>If your tasks can all take this form then this is fine
Which another form could them take?
Of course there may be not massage queue and signaling to terminate could look like this:

static volatiole boolean bTerminate = false;
static void threadFn(void *pParam)
{
while(1)
{
if(bTerminate == true)
break;
do_action_A();
do_action_B();
}
}
}

May I have a question? What kind of embeded systems are You designing?

PS. My name is Kamil -> I think i should register soon to be visible at forum not as Nobody :)

RE: Thread End

Posted by Richard on December 30, 2004
> >>Is more like Windoze style thread than RTOS task
>
> Do You think about WinAPI TerminateThread()?
> Do not ever use it to terminate thread if You want your application to run for
> a long time :) !!! It breaks thread at the current point of execution and removes
> it from scheduler freeing thread stack. It's lieke vTaskDelete in FreeRTOS.
>

Sorry can’t comment on WinAPI as its out of my realm.

> Richard: of course. You have right if You are talking about small complexity
> systems. In most cases in embeded systems there are not thread termination at
> all!



> >>there is not always a parent thread for example - NO! There is always parent
> thread :) It may be Root thread (main function is called from its context).


Ok, a question of semantics I suppose.

There are of coarse occasions when one task may create another. There are also those tasks that are created before the kernel has started. These are effectively started from main() – and once the kernel has started the context of main() effectively does not exist. It never runs again unless the vPortEndScheduler() is called. I have only vPortEndScheduler() for the ports that run over DOS, because in other cases there is nothing to return to.

> Someone creates thread of course - so it is parent.
> Of course thread can be signaled to terminate by different thread than parent.

There is no super process running in the middle of the kernel that has knowledge of all the message queues. It is up to the application design to say which tasks have knowledge of which threads – and how to talk to which threads. There is no automatic way of communicating with a thread unless the threads generates a queue/semaphore/… and gives the rest of the system knowledge of it.

>
> >>If your tasks can all take this form then this is fine
> Which another form could them take?

A task may never block (like the idle task) but just run continuously in the background.

A task may block on a semaphore. A task may block on a queue. A task may run periodically (very common).

Most of these forms of execution do not require a central messaging system. Of coarse you could create a queue which is checked for signals without blocking every iteration – but this will take up a lot of resources and severely limit the amount of tasks that can be created (remember the FreeRTOS is running on 8bit systems with as little as 1.5KBytes of RAM).

> Of course there may be not massage queue and signaling to terminate could look
> like this:
>
> static volatiole boolean bTerminate = false;
> static void threadFn(void *pParam)
> {
> while(1)
> {
> if(bTerminate == true)
> break;
> do_action_A();
> do_action_B();
> }
> }
> }
>

> May I have a question?

Of coarse :-)

> What kind of embeded systems are You designing?

How long have you got? Industrial automation, consumer electronics, motor control, hobby projects, automotive, …. a rather general answer I know.

>
> PS. My name is Kamil -> I think i should register soon to be visible at forum
> not as Nobody :)
>


Thanks for your interesting comments.

Best regards.

RE: Thread End

Posted by Nobody/Anonymous on December 30, 2004
OK! But I think that my approach gives better control over what is going on in our system. Code is more compact and therfore more portable to other systems. (Some parts of code may be used in other systems, employing other OSs) And this is my second question:
What will happen if I finish thread by exiting its routine? (under FreeRTOS of course) Would it be hard to implement to finish thread as I described in my 2nd post?
(After quick review of source code I think it wouldn't be very hard).
Kamil

RE: Thread End

Posted by Nobody/Anonymous on December 30, 2004
O! And one another question. A lot of RTOS implements both ways of thread termination. One - soft - which I proposed to normal thread termination, and another one - hard - like implemented in FreeRTOS(it is sometimes called "thread kill" and can be used to kill threads that don't answer).
Maybe it will be good to implement it in FreeRTOS?

RE: Thread End

Posted by Richard on December 30, 2004
> What will happen if I finish thread by exiting its routine? (under FreeRTOS
> of course) Would it be hard to implement to finish thread as I described in
> my 2nd post?

If the thread leaves it's routine a return from subroutine instruction will be called. Where this jumps to depends on how the initial task stack was created (when the task was created in the port.c file).

If this is required functionality then I would suggest an approach such as:

void vATask( void * pvParameters )
{
for(;;)
{
// perform operation here.

if( WhatToDie() )
{
break;
}
}

// delete any resources we have used here.

// Left the normal operation - make sure
// we leave the kernel in a clean state.
vTaskDelete( NULL );

// Will never get here!
}


RE: Thread End

Posted by Richard on December 30, 2004
> O! And one another question. A lot of RTOS implements both ways of thread
> termination. One - soft - which I proposed to normal thread termination, and
> another one - hard - like implemented in FreeRTOS(it is sometimes called "thread
> kill" and can be used to kill threads that don't answer).
> Maybe it will be good to implement it in FreeRTOS?

It is the stated goal of FreeRTOS to be a minimal implementation - which is (hopefully) easy to understand and therefore extend to fit your requirements.

There are a lot of features that could be added, but would only be suitable for a small proportion of applications. The functionality will grow over time, but this comes at the cost of complexity. To keep the code size down it will also require greater use of conditional compilation which I have always tried to keep to a minimum to ease code readability. Linux and eCOS provide open source alternatives if your application requires a more heavy weight OS.

RE: Thread End

Posted by Nobody/Anonymous on December 30, 2004
:)
Let's consider:
portSHORT sTaskCreate( pdTASK_CODE pvTaskCode, const signed portCHAR * const pcName, unsigned portSHORT usStackDepth, void *pvParameters, unsigned portCHAR ucPriority, xTaskHandle *pxCreatedTask )
function
Enter condition:
usCurrentNumberOfTasks > 1
cSchedulerRunning == TRUE
pxCreatedTask == NULL
pxCurrentTCB->ucPriority < ucPriority

So preemption (taskYIELD() ) is not performed.
WHY? It all depends of argument passed pxCreatedTask but if it is NULL it means that I don't need just created thread handle but if its priority is higher than actual there should be context switching performed.

Kamil

RE: Thread End

Posted by Richard on December 30, 2004
Not sure about that one...I will have to look back through the older versions to see if it is always thus. Maybe the YIELD choice should be outside the if().

RE: Thread End

Posted by Richard on January 3, 2005
I have changed this for V2.5.5.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.


Free TCP/IP and file system demos for the RTOS


Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists