From 701dd96f598bd58a41884795ba5bf0b5da337d78 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 12 Jun 2014 14:37:57 +0200 Subject: score: PR2181: Add _Thread_Yield() The _Scheduler_Yield() was called by the executing thread with thread dispatching disabled and interrupts enabled. The rtems_task_suspend() is explicitly allowed in ISRs: http://rtems.org/onlinedocs/doc-current/share/rtems/html/c_user/Interrupt-Manager-Directives-Allowed-from-an-ISR.html#Interrupt-Manager-Directives-Allowed-from-an-ISR Unlike the other scheduler operations the locking was performed inside the operation. This lead to the following race condition. Suppose a ISR suspends the executing thread right before the yield scheduler operation. Now the executing thread is not longer in the set of ready threads. The typical scheduler operations did not check the thread state and will now extract the thread again and enqueue it. This corrupted data structures. Add _Thread_Yield() and do the scheduler yield operation with interrupts disabled. This has a negligible effect on the interrupt latency. --- cpukit/score/src/threadyield.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 cpukit/score/src/threadyield.c (limited to 'cpukit/score/src/threadyield.c') diff --git a/cpukit/score/src/threadyield.c b/cpukit/score/src/threadyield.c new file mode 100644 index 0000000000..b49e2b30ba --- /dev/null +++ b/cpukit/score/src/threadyield.c @@ -0,0 +1,41 @@ +/** + * @file + * + * @brief Thread Yield + * + * @ingroup ScoreThread + */ + +/* + * Copyright (c) 2014 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#if HAVE_CONFIG_H + #include "config.h" +#endif + +#include +#include + +void _Thread_Yield( Thread_Control *executing ) +{ + ISR_Level level; + + _ISR_Disable( level ); + + if ( _States_Is_ready( executing->current_state ) ) { + _Scheduler_Yield( _Scheduler_Get( executing ), executing ); + } + + _ISR_Enable( level ); +} -- cgit v1.2.3