sched/sched/sched_releasetcb.c: Handle custom stack allocations.

sched_releasetcb() will normally free the stack allocated for a task.  However, a task with a custom, user-managed stack may be created using nxtask_init() followed by nxtask_activer.  If such a custom stack is used then it must not be free in this many or a crash will most likely result.

This chagne addes a flag call TCB_FLAG_CUSTOM_STACK that may be passed in the the pre-allocted TCB to nxtask_init().  This flag is not used internally anywhere in the OS except that if set, it will prevent sched_releasetcb() from freeing that custom stack.
This commit is contained in:
Gregory Nutt 2020-05-27 11:33:20 -06:00 committed by Abdelatif Guettouche
parent b9042f5900
commit 124e6ee53d
3 changed files with 29 additions and 5 deletions

View File

@ -103,9 +103,10 @@
# define TCB_FLAG_SCHED_SPORADIC (2 << TCB_FLAG_POLICY_SHIFT) /* Sporadic scheding policy */
# define TCB_FLAG_SCHED_OTHER (3 << TCB_FLAG_POLICY_SHIFT) /* Other scheding policy */
#define TCB_FLAG_CPU_LOCKED (1 << 7) /* Bit 7: Locked to this CPU */
#define TCB_FLAG_SIGNAL_ACTION (1 << 8) /* Bit 8: In a signal handler */
#define TCB_FLAG_SYSCALL (1 << 9) /* Bit 9: In a system call */
#define TCB_FLAG_EXIT_PROCESSING (1 << 10) /* Bit 10: Exitting */
#define TCB_FLAG_CUSTOM_STACK (1 << 8) /* Bit 8: Thread uses a custom stack */
#define TCB_FLAG_SIGNAL_ACTION (1 << 9) /* Bit 9: In a signal handler */
#define TCB_FLAG_SYSCALL (1 << 10) /* Bit 10: In a system call */
#define TCB_FLAG_EXIT_PROCESSING (1 << 11) /* Bit 11: Exitting */
/* Bits 11-15: Available */
/* Values for struct task_group tg_flags */
@ -920,6 +921,14 @@ FAR struct socketlist *nxsched_get_sockets(void);
* 2. Allocate the stack. The pre-allocated stack is passed in argv.
* 3. Activate the task. This must be done by calling nxtask_activate().
*
* Certain fields of the pre-allocated TCB may be set to change the
* nature of the created task. For example:
*
* - Task type may be set in the TCB flags to create kernel thread
* - If a custom stack is used, i.e., one allocated, managed, and freed
* by the caller, then TCB_FLAG_CUSTOM_STACK should be set in the
* TCB flags.
*
* Input Parameters:
* tcb - Address of the new task's TCB
* name - Name of the new task (not used)
@ -954,6 +963,8 @@ int nxtask_init(FAR struct tcb_s *tcb, const char *name, int priority,
* was when a subsequent call to task_activate fails.
*
* Caution: Freeing of the TCB itself might be an unexpected side-effect.
* The stack will also be freed UNLESS TCB_FLAG_CUSTOM_STACK was set in
* in the tcb->flags field when nxtask_init() was called.
*
* Input Parameters:
* tcb - Address of the TCB initialized by task_init()

View File

@ -127,9 +127,12 @@ int nxsched_release_tcb(FAR struct tcb_s *tcb, uint8_t ttype)
nxsched_releasepid(tcb->pid);
}
/* Delete the thread's stack if one has been allocated */
/* Delete the thread's stack if one has been allocated and it is
* not some custom stack managed by the caller.
*/
if (tcb->stack_alloc_ptr)
if (tcb->stack_alloc_ptr &&
(tcb->flags & TCB_FLAG_CUSTOM_STACK) == 0)
{
#ifdef CONFIG_BUILD_KERNEL
/* If the exiting thread is not a kernel thread, then it has an

View File

@ -54,6 +54,14 @@
* 2. Allocate the stack. The pre-allocated stack is passed in argv.
* 3. Activate the task. This must be done by calling nxtask_activate().
*
* Certain fields of the pre-allocated TCB may be set to change the
* nature of the created task. For example:
*
* - Task type may be set in the TCB flags to create kernel thread
* - If a custom stack is used, i.e., one allocated, managed, and freed
* by the caller, then TCB_FLAG_CUSTOM_STACK should be set in the
* TCB flags.
*
* Input Parameters:
* tcb - Address of the new task's TCB
* name - Name of the new task (not used)
@ -148,6 +156,8 @@ errout:
* was when a subsequent call to task_activate fails.
*
* Caution: Freeing of the TCB itself might be an unexpected side-effect.
* The stack will also be freed UNLESS TCB_FLAG_CUSTOM_STACK was set in
* in the tcb->flags field when nxtask_init() was called.
*
* Input Parameters:
* tcb - Address of the TCB initialized by task_init()