cancellation points are basically function. More tested is needed and additional cancellation points must be implemented before this can be merged back to master.

This commit is contained in:
Gregory Nutt
2016-12-09 12:01:18 -06:00
parent 018db84567
commit c9ca97b4b5
9 changed files with 103 additions and 3 deletions
+6 -2
View File
@@ -108,6 +108,8 @@ void enter_cancellation_point(void)
/* Disabling pre-emption should provide sufficient protection. We only
* need the TCB to be stationary (no interrupt level modification is
* anticipated).
*
* REVISIT: is locking the scheduler sufficent in SMP mode?
*/
sched_lock();
@@ -135,7 +137,7 @@ void enter_cancellation_point(void)
#ifndef CONFIG_DISABLE_PTHREAD
if ((tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD)
{
pthread_exit(NULL);
pthread_exit(PTHREAD_CANCELED);
}
else
#endif
@@ -180,6 +182,8 @@ void leave_cancellation_point(void)
/* Disabling pre-emption should provide sufficient protection. We only
* need the TCB to be stationary (no interrupt level modification is
* anticipated).
*
* REVISIT: is locking the scheduler sufficent in SMP mode?
*/
sched_lock();
@@ -211,7 +215,7 @@ void leave_cancellation_point(void)
#ifndef CONFIG_DISABLE_PTHREAD
if ((tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD)
{
pthread_exit(NULL);
pthread_exit(PTHREAD_CANCELED);
}
else
#endif
+31 -1
View File
@@ -103,7 +103,37 @@ int task_delete(pid_t pid)
exit(EXIT_SUCCESS);
}
/* Then let task_terminate do the heavy lifting */
#ifdef CONFIG_CANCELLATION_POINTS
/* Check if this task supports deferred cancellation */
sched_lock();
if ((rtcb->flags & TCB_FLAG_CANCEL_DEFERRED) != 0)
{
/* Then we cannot cancel the task asynchronoulsy. Mark the cancellation
* as pending.
*/
rtcb->flags |= TCB_FLAG_CANCEL_PENDING;
/* If the task is waiting at a cancellation point, then notify of the
* cancellation thereby waking the task up with an ECANCELED error.
*
* REVISIT: is locking the scheduler sufficent in SMP mode?
*/
if (rtcb->cpcount > 0)
{
notify_cancellation(rtcb);
}
sched_unlock();
return OK;
}
#endif
/* Otherwise, perform the asynchronous cancellation, letting
* task_terminate() do all of the heavy lifting.
*/
return task_terminate(pid, false);
}
+11
View File
@@ -612,6 +612,17 @@ void task_exithook(FAR struct tcb_s *tcb, int status, bool nonblocking)
return;
}
#ifdef CONFIG_CANCELLATION_POINTS
/* Mark the task as non-cancelable to avoid additional calls to exit()
* due to any cancellation point logic that might get kicked off by
* actions taken during exit processing.
*/
tcb->flags |= TCB_FLAG_NONCANCELABLE;
tcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
tcb->cpcount = 0;
#endif
#if defined(CONFIG_SCHED_ATEXIT) || defined(CONFIG_SCHED_ONEXIT)
/* If exit function(s) were registered, call them now before we do any un-
* initialization.