| 183 | ****************************************************************************/ |
| 184 | |
| 185 | static int nxtask_restart(pid_t pid) |
| 186 | { |
| 187 | FAR struct tcb_s *rtcb; |
| 188 | FAR struct tcb_s *tcb; |
| 189 | irqstate_t flags; |
| 190 | int ret; |
| 191 | |
| 192 | /* We are restarting some other task than ourselves. Make sure that the |
| 193 | * task does not change its state while we are executing. In the single |
| 194 | * CPU state this could be done by disabling pre-emption. But we will |
| 195 | * a little stronger medicine on the SMP case: The task make be running |
| 196 | * on another CPU. |
| 197 | */ |
| 198 | |
| 199 | flags = enter_critical_section(); |
| 200 | |
| 201 | /* Check if the task to restart is the calling task */ |
| 202 | |
| 203 | rtcb = this_task(); |
| 204 | if (pid == 0 || pid == rtcb->pid) |
| 205 | { |
| 206 | /* Not implemented */ |
| 207 | |
| 208 | ret = -ENOSYS; |
| 209 | goto errout_with_lock; |
| 210 | } |
| 211 | |
| 212 | /* Find for the TCB associated with matching pid */ |
| 213 | |
| 214 | tcb = nxsched_get_tcb(pid); |
| 215 | #ifndef CONFIG_DISABLE_PTHREAD |
| 216 | if (!tcb || (tcb->flags & TCB_FLAG_TTYPE_MASK) == |
| 217 | TCB_FLAG_TTYPE_PTHREAD) |
| 218 | #else |
| 219 | if (!tcb) |
| 220 | #endif |
| 221 | { |
| 222 | /* There is no TCB with this pid or, if there is, it is not a task. */ |
| 223 | |
| 224 | ret = -ESRCH; |
| 225 | goto errout_with_lock; |
| 226 | } |
| 227 | |
| 228 | #ifdef CONFIG_SMP |
| 229 | if (tcb->task_state == TSTATE_TASK_RUNNING && |
| 230 | tcb->cpu != this_cpu()) |
| 231 | { |
| 232 | struct restart_arg_s arg; |
| 233 | |
| 234 | if ((tcb->flags & TCB_FLAG_CPU_LOCKED) != 0) |
| 235 | { |
| 236 | arg.pid = tcb->pid; |
| 237 | arg.need_restore = false; |
| 238 | } |
| 239 | else |
| 240 | { |
| 241 | arg.pid = tcb->pid; |
| 242 | arg.need_restore = true; |
no test coverage detected