diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index b19cf6898e9..54e11b7c930 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -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() diff --git a/sched/sched/sched_releasetcb.c b/sched/sched/sched_releasetcb.c index 5cf57b62828..00e6355642c 100644 --- a/sched/sched/sched_releasetcb.c +++ b/sched/sched/sched_releasetcb.c @@ -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 diff --git a/sched/task/task_init.c b/sched/task/task_init.c index 315e6b6f6d0..91c7904b138 100644 --- a/sched/task/task_init.c +++ b/sched/task/task_init.c @@ -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()