diff --git a/arch/sim/src/nuttx-names.dat b/arch/sim/src/nuttx-names.dat index 759743be534..f1373f1d9c1 100644 --- a/arch/sim/src/nuttx-names.dat +++ b/arch/sim/src/nuttx-names.dat @@ -62,7 +62,10 @@ pthread_mutex_init NXpthread_mutex_init pthread_mutex_lock NXpthread_mutex_lock pthread_mutex_unlock NXpthread_mutex_unlock pthread_setspecific NXpthread_setspecific +pthread_setcancelstate NXpthread_setcancelstate +pthread_setcanceltype NXpthread_setcanceltype pthread_sigmask NXpthread_sigmask +pthread_testcancel NXpthread_testcancel pthread_yield NXpthread_yield ptsname NXptsname ptsname_r NXptsname_r diff --git a/sched/init/os_smpstart.c b/sched/init/os_smpstart.c index ba8afac2ded..17316e5b616 100644 --- a/sched/init/os_smpstart.c +++ b/sched/init/os_smpstart.c @@ -218,6 +218,13 @@ int os_smp_start(void) */ up_initial_state(tcb); + + /* Set the task flags to indicate that this is a kernel thread and that + * this task is locked to this CPU. + */ + + tcb->flags = (TCB_FLAG_TTYPE_KERNEL | TCB_FLAG_NONCANCELABLE | TCB_FLAG_CPU_LOCKED); + tcb->cpu = cpu; } /* Then start all of the other CPUs after we have completed the memory diff --git a/sched/init/os_start.c b/sched/init/os_start.c index 17e1f40cde9..5b8236b56ac 100644 --- a/sched/init/os_start.c +++ b/sched/init/os_start.c @@ -470,10 +470,11 @@ void os_start(void) */ #ifdef CONFIG_SMP - g_idletcb[cpu].cmn.flags = (TCB_FLAG_TTYPE_KERNEL | TCB_FLAG_CPU_LOCKED); + g_idletcb[cpu].cmn.flags = (TCB_FLAG_TTYPE_KERNEL TCB_FLAG_NONCANCELABLE | + TCB_FLAG_CPU_LOCKED); g_idletcb[cpu].cmn.cpu = cpu; #else - g_idletcb[cpu].cmn.flags = TCB_FLAG_TTYPE_KERNEL; + g_idletcb[cpu].cmn.flags = (TCB_FLAG_TTYPE_KERNEL | TCB_FLAG_NONCANCELABLE); #endif #ifdef CONFIG_SMP diff --git a/sched/pthread/pthread_testcancel.c b/sched/pthread/pthread_testcancel.c index 0e6186dec2e..c58d9344e10 100644 --- a/sched/pthread/pthread_testcancel.c +++ b/sched/pthread/pthread_testcancel.c @@ -42,6 +42,8 @@ #include #include +#include + #include "sched/sched.h" /**************************************************************************** @@ -60,7 +62,6 @@ void pthread_testcancel(void) { -#ifdef CONFIG_CANCELLATION_POINTS -# warning Missing Logic -#endif + enter_cancellation_point(); + leave_cancellation_point(); } diff --git a/sched/sched/sched_wait.c b/sched/sched/sched_wait.c index d1547e07cfa..6a50403d54e 100644 --- a/sched/sched/sched_wait.c +++ b/sched/sched/sched_wait.c @@ -44,6 +44,7 @@ #include #include +#include #include "sched/sched.h" @@ -84,4 +85,3 @@ pid_t wait(FAR int *stat_loc) } #endif /* CONFIG_SCHED_WAITPID && CONFIG_SCHED_HAVE_PARENT */ - diff --git a/sched/sched/sched_waitid.c b/sched/sched/sched_waitid.c index f4e48d5f649..3fb3a329a21 100644 --- a/sched/sched/sched_waitid.c +++ b/sched/sched/sched_waitid.c @@ -164,6 +164,10 @@ int waitid(idtype_t idtype, id_t id, FAR siginfo_t *info, int options) int errcode; int ret; + /* waitid() is a cancellation point */ + + enter_cancellation_point(); + /* MISSING LOGIC: If WNOHANG is provided in the options, then this function * should returned immediately. However, there is no mechanism available now * know if the thread has child: The children remember their parents (if @@ -404,12 +408,14 @@ int waitid(idtype_t idtype, id_t id, FAR siginfo_t *info, int options) } } + leave_cancellation_point(); sched_unlock(); return OK; errout_with_errno: set_errno(errcode); errout: + leave_cancellation_point(); sched_unlock(); return ERROR; } diff --git a/sched/sched/sched_waitpid.c b/sched/sched/sched_waitpid.c index a3ef50674f1..d386d153087 100644 --- a/sched/sched/sched_waitpid.c +++ b/sched/sched/sched_waitpid.c @@ -45,6 +45,7 @@ #include #include +#include #include "sched/sched.h" #include "group/group.h" @@ -185,12 +186,17 @@ pid_t waitpid(pid_t pid, int *stat_loc, int options) DEBUGASSERT(stat_loc); + /* waitpid() is a cancellation point */ + + enter_cancellation_point(); + /* None of the options are supported */ #ifdef CONFIG_DEBUG_FEATURES if (options != 0) { set_errno(ENOSYS); + leave_cancellation_point(); return ERROR; } #endif @@ -268,12 +274,14 @@ pid_t waitpid(pid_t pid, int *stat_loc, int options) /* On success, return the PID */ + leave_cancellation_point(); sched_unlock(); return pid; errout_with_errno: set_errno(errcode); errout: + leave_cancellation_point(); sched_unlock(); return ERROR; } @@ -307,12 +315,17 @@ pid_t waitpid(pid_t pid, int *stat_loc, int options) DEBUGASSERT(stat_loc); + /* waitpid() is a cancellation point */ + + enter_cancellation_point(); + /* None of the options are supported */ #ifdef CONFIG_DEBUG_FEATURES if (options != 0) { set_errno(ENOSYS); + leave_cancellation_point(); return ERROR; } #endif @@ -528,6 +541,7 @@ pid_t waitpid(pid_t pid, int *stat_loc, int options) } } + leave_cancellation_point(); sched_unlock(); return (int)pid; @@ -535,6 +549,7 @@ errout_with_errno: set_errno(errcode); errout_with_lock: + leave_cancellation_point(); sched_unlock(); return ERROR; } diff --git a/sched/semaphore/sem_wait.c b/sched/semaphore/sem_wait.c index da855bc70c0..d0b6c8661a3 100644 --- a/sched/semaphore/sem_wait.c +++ b/sched/semaphore/sem_wait.c @@ -86,6 +86,10 @@ int sem_wait(FAR sem_t *sem) DEBUGASSERT(sem != NULL && up_interrupt_context() == false); + /* sem_wait is a cancellation point */ + + enter_cancellation_point(); + /* Make sure we were supplied with a valid semaphore. */ if (sem != NULL) @@ -196,5 +200,6 @@ int sem_wait(FAR sem_t *sem) set_errno(EINVAL); } + leave_cancellation_point(); return ret; }