| /**************************************************************************** |
| * sched/task/task_delete.c |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. The |
| * ASF licenses this file to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance with the |
| * License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations |
| * under the License. |
| * |
| ****************************************************************************/ |
| |
| /**************************************************************************** |
| * Included Files |
| ****************************************************************************/ |
| |
| #include <nuttx/config.h> |
| |
| #include <stdlib.h> |
| #include <assert.h> |
| #include <errno.h> |
| |
| #include <nuttx/sched.h> |
| |
| #include "sched/sched.h" |
| #include "task/task.h" |
| |
| /**************************************************************************** |
| * 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; |
| |
| /* 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 = 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. |
| */ |
| |
| return nxtask_terminate(pid); |
| } |
| |
| /**************************************************************************** |
| * Name: task_delete |
| * |
| * Description: |
| * This function causes a specified task to cease to exist. Its stack and |
| * TCB will be deallocated. This function is the companion to |
| * task_create(). This is the version of the function exposed to the |
| * user; it is simply a wrapper around the internal, nxtask_terminate |
| * function. |
| * |
| * 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 |
| * task_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 ERROR on failure with the errno variable set |
| * appropriately. |
| * |
| ****************************************************************************/ |
| |
| #ifndef CONFIG_BUILD_KERNEL |
| int task_delete(pid_t pid) |
| { |
| int ret = nxtask_delete(pid); |
| if (ret < 0) |
| { |
| set_errno(-ret); |
| ret = ERROR; |
| } |
| |
| return ret; |
| } |
| #endif |