mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 10:58:49 +08:00
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:
parent
c39d3fa9e4
commit
b1d92159fa
4 changed files with 117 additions and 86 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
Loading…
Reference in a new issue