sched: Remove task_delete in case of CONFIG_BUILD_KERNEL

Deleting a task from another task's context will not do, so shut
this gate down for BUILD_KERNEL. In this case if a task wants another
task to terminate, it must ask the other task to politely kill itself.

Note: kthreads still need this, also, the kernel can delete a task
without asking.
This commit is contained in:
Ville Juven 2022-05-11 09:03:04 +03:00 committed by Xiang Xiao
parent c39d3fa9e4
commit b1d92159fa
4 changed files with 117 additions and 86 deletions

View file

@ -154,20 +154,19 @@ int kthread_create(FAR const char *name, int priority, int stack_size,
* function is equivalent to task_delete.c; the following definition
* simply reserves the name in the name space.
*
* Refer to comments with task_delete() for a more detailed description of
* the operation of this function.
* Refer to comments with nxtask_delete() for a more detailed description
* of the operation of this function.
*
* Input Parameters:
* pid - The task ID of the task to delete. A pid of zero
* signifies the calling task.
*
* Returned Value:
* OK on success; or ERROR on failure with the errno variable set
* appropriately.
* OK on success; or negated errno on failure.
*
****************************************************************************/
#define kthread_delete(p) task_delete(p)
#define kthread_delete(p) nxtask_delete(p)
#undef EXTERN
#ifdef __cplusplus

View file

@ -92,10 +92,11 @@ SYSCALL_LOOKUP(sem_wait, 1)
#ifndef CONFIG_BUILD_KERNEL
SYSCALL_LOOKUP(task_create, 5)
SYSCALL_LOOKUP(task_spawn, 6)
SYSCALL_LOOKUP(task_delete, 1)
#else
SYSCALL_LOOKUP(pgalloc, 2)
#endif
SYSCALL_LOOKUP(task_delete, 1)
SYSCALL_LOOKUP(task_restart, 1)
SYSCALL_LOOKUP(task_setcancelstate, 2)
SYSCALL_LOOKUP(up_assert, 2)

View file

@ -37,6 +37,110 @@
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nxtask_delete
*
* Description:
* This function causes a specified task to cease to exist. Its stack and
* TCB will be deallocated.
*
* The logic in this function only deletes non-running tasks. If the
* 'pid' parameter refers to the currently running task, then processing
* is redirected to exit(). This can only happen if a task calls
* nxtask_delete() in order to delete itself.
*
* This function obeys the semantics of pthread cancellation: task
* deletion is deferred if cancellation is disabled or if deferred
* cancellation is supported (with cancellation points enabled).
*
* Input Parameters:
* pid - The task ID of the task to delete. A pid of zero
* signifies the calling task.
*
* Returned Value:
* OK on success; or negated errno on failure
*
****************************************************************************/
int nxtask_delete(pid_t pid)
{
FAR struct tcb_s *dtcb;
FAR struct tcb_s *rtcb;
int ret;
/* Check if the task to delete is the calling task: PID=0 means to delete
* the calling task. In this case, task_delete() is much like exit()
* except that it obeys the cancellation semantics.
*/
rtcb = this_task();
if (pid == 0)
{
pid = rtcb->pid;
}
/* Get the TCB of the task to be deleted */
dtcb = (FAR struct tcb_s *)nxsched_get_tcb(pid);
if (dtcb == NULL)
{
/* The pid does not correspond to any known thread. The task
* has probably already exited.
*/
return -ESRCH;
}
/* Only tasks and kernel threads can be deleted with this interface
* (The semantics of the call should be sufficient to prohibit this).
*/
DEBUGASSERT((dtcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD);
/* Non-privileged tasks and pthreads may not delete privileged kernel
* threads.
*
* REVISIT: We will need to look at this again in the future if/when
* permissions are supported and a user task might also be privileged.
*/
if (((rtcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL) &&
((dtcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL))
{
return -EACCES;
}
/* Check if the task to delete is the calling task */
if (pid == rtcb->pid)
{
/* If it is, then what we really wanted to do was exit. Note that we
* don't bother to unlock the TCB since it will be going away.
*/
exit(EXIT_SUCCESS);
}
/* Notify the target if the non-cancelable or deferred cancellation set */
if (nxnotify_cancellation(dtcb))
{
return OK;
}
/* Otherwise, perform the asynchronous cancellation, letting
* nxtask_terminate() do all of the heavy lifting.
*/
ret = nxtask_terminate(pid, false);
if (ret < 0)
{
return ret;
}
return OK;
}
/****************************************************************************
* Name: task_delete
*
@ -66,89 +170,16 @@
*
****************************************************************************/
#ifndef CONFIG_BUILD_KERNEL
int task_delete(pid_t pid)
{
FAR struct tcb_s *dtcb;
FAR struct tcb_s *rtcb;
int errcode;
int ret;
/* Check if the task to delete is the calling task: PID=0 means to delete
* the calling task. In this case, task_delete() is much like exit()
* except that it obeys the cancellation semantics.
*/
rtcb = this_task();
if (pid == 0)
{
pid = rtcb->pid;
}
/* Get the TCB of the task to be deleted */
dtcb = (FAR struct tcb_s *)nxsched_get_tcb(pid);
if (dtcb == NULL)
{
/* The pid does not correspond to any known thread. The task
* has probably already exited.
*/
errcode = ESRCH;
goto errout;
}
/* Only tasks and kernel threads can be deleted with this interface
* (The semantics of the call should be sufficient to prohibit this).
*/
DEBUGASSERT((dtcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD);
/* Non-privileged tasks and pthreads may not delete privileged kernel
* threads.
*
* REVISIT: We will need to look at this again in the future if/when
* permissions are supported and a user task might also be privileged.
*/
if (((rtcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL) &&
((dtcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL))
{
errcode = EACCES;
goto errout;
}
/* Check if the task to delete is the calling task */
if (pid == rtcb->pid)
{
/* If it is, then what we really wanted to do was exit. Note that we
* don't bother to unlock the TCB since it will be going away.
*/
exit(EXIT_SUCCESS);
}
/* Notify the target if the non-cancelable or deferred cancellation set */
if (nxnotify_cancellation(dtcb))
{
return OK;
}
/* Otherwise, perform the asynchronous cancellation, letting
* nxtask_terminate() do all of the heavy lifting.
*/
ret = nxtask_terminate(pid, false);
int ret = nxtask_delete(pid);
if (ret < 0)
{
errcode = -ret;
goto errout;
set_errno(-ret);
ret = ERROR;
}
return OK;
errout:
set_errno(errcode);
return ERROR;
return ret;
}
#endif

View file

@ -172,7 +172,7 @@
"symlink","unistd.h","defined(CONFIG_PSEUDOFS_SOFTLINKS)","int","FAR const char *","FAR const char *"
"sysinfo","sys/sysinfo.h","","int","FAR struct sysinfo *"
"task_create","sched.h","!defined(CONFIG_BUILD_KERNEL)", "int","FAR const char *","int","int","main_t","FAR char * const []|FAR char * const *"
"task_delete","sched.h","","int","pid_t"
"task_delete","sched.h","!defined(CONFIG_BUILD_KERNEL)","int","pid_t"
"task_restart","sched.h","","int","pid_t"
"task_setcancelstate","sched.h","","int","int","FAR int *"
"task_setcanceltype","sched.h","defined(CONFIG_CANCELLATION_POINTS)","int","int","FAR int *"

Can't render this file because it has a wrong number of fields in line 2.