summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2015-04-23 10:01:22 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2015-05-19 12:00:45 +0200
commit02c4c441a51b43b55608893efa4a80a62bb9d4d5 (patch)
tree709655b1c53afc3ff981890989a5290d1c400ad2
parentscore: Generalize _Event_Timeout() (diff)
downloadrtems-02c4c441a51b43b55608893efa4a80a62bb9d4d5.tar.bz2
score: Add Thread_queue_Control::Lock
Move the complete thread queue enqueue procedure into _Thread_queue_Enqueue_critical(). It is possible to use the thread queue lock to protect state of the object embedding the thread queue. This enables per object fine grained locking in the future. Delete _Thread_queue_Enter_critical_section(). Update #2273.
-rw-r--r--cpukit/posix/include/rtems/posix/barrierimpl.h1
-rw-r--r--cpukit/posix/include/rtems/posix/condimpl.h2
-rw-r--r--cpukit/posix/include/rtems/posix/muteximpl.h1
-rw-r--r--cpukit/posix/include/rtems/posix/psignalimpl.h8
-rw-r--r--cpukit/posix/include/rtems/posix/rwlockimpl.h1
-rw-r--r--cpukit/posix/include/rtems/posix/semaphoreimpl.h1
-rw-r--r--cpukit/posix/src/condwaitsupp.c2
-rw-r--r--cpukit/posix/src/psignal.c2
-rw-r--r--cpukit/posix/src/pthread.c2
-rw-r--r--cpukit/posix/src/pthreadjoin.c1
-rw-r--r--cpukit/posix/src/sigtimedwait.c8
-rw-r--r--cpukit/rtems/include/rtems/rtems/barrierimpl.h1
-rw-r--r--cpukit/rtems/include/rtems/rtems/messageimpl.h1
-rw-r--r--cpukit/rtems/include/rtems/rtems/regionimpl.h2
-rw-r--r--cpukit/rtems/src/regioncreate.c18
-rw-r--r--cpukit/rtems/src/regiongetsegment.c3
-rw-r--r--cpukit/rtems/src/semdelete.c2
-rw-r--r--cpukit/score/include/rtems/score/corebarrierimpl.h8
-rw-r--r--cpukit/score/include/rtems/score/coremuteximpl.h5
-rw-r--r--cpukit/score/include/rtems/score/corerwlockimpl.h8
-rw-r--r--cpukit/score/include/rtems/score/coresemimpl.h19
-rw-r--r--cpukit/score/include/rtems/score/threadq.h13
-rw-r--r--cpukit/score/include/rtems/score/threadqimpl.h114
-rw-r--r--cpukit/score/src/corebarrierwait.c16
-rw-r--r--cpukit/score/src/coremsgclose.c1
-rw-r--r--cpukit/score/src/coremsgseize.c16
-rw-r--r--cpukit/score/src/coremsgsubmit.c6
-rw-r--r--cpukit/score/src/coremutexseize.c18
-rw-r--r--cpukit/score/src/corerwlockobtainread.c20
-rw-r--r--cpukit/score/src/corerwlockobtainwrite.c22
-rw-r--r--cpukit/score/src/coresemseize.c18
-rw-r--r--cpukit/score/src/mpci.c2
-rw-r--r--cpukit/score/src/threadq.c3
-rw-r--r--cpukit/score/src/threadqenqueue.c63
-rw-r--r--cpukit/score/src/threadqfirst.c22
35 files changed, 261 insertions, 169 deletions
diff --git a/cpukit/posix/include/rtems/posix/barrierimpl.h b/cpukit/posix/include/rtems/posix/barrierimpl.h
index 240abad45d..22be1c0d6e 100644
--- a/cpukit/posix/include/rtems/posix/barrierimpl.h
+++ b/cpukit/posix/include/rtems/posix/barrierimpl.h
@@ -80,6 +80,7 @@ RTEMS_INLINE_ROUTINE void _POSIX_Barrier_Free (
POSIX_Barrier_Control *the_barrier
)
{
+ _CORE_barrier_Destroy( &the_barrier->Barrier );
_Objects_Free( &_POSIX_Barrier_Information, &the_barrier->Object );
}
diff --git a/cpukit/posix/include/rtems/posix/condimpl.h b/cpukit/posix/include/rtems/posix/condimpl.h
index 435127ee3c..7def0f852a 100644
--- a/cpukit/posix/include/rtems/posix/condimpl.h
+++ b/cpukit/posix/include/rtems/posix/condimpl.h
@@ -19,6 +19,7 @@
#include <rtems/posix/cond.h>
#include <rtems/score/objectimpl.h>
+#include <rtems/score/threadqimpl.h>
#include <rtems/score/watchdog.h>
#ifdef __cplusplus
@@ -72,6 +73,7 @@ RTEMS_INLINE_ROUTINE void _POSIX_Condition_variables_Free (
POSIX_Condition_variables_Control *the_condition_variable
)
{
+ _Thread_queue_Destroy( &the_condition_variable->Wait_queue );
_Objects_Free(
&_POSIX_Condition_variables_Information,
&the_condition_variable->Object
diff --git a/cpukit/posix/include/rtems/posix/muteximpl.h b/cpukit/posix/include/rtems/posix/muteximpl.h
index 821961c0f4..f4c6c686aa 100644
--- a/cpukit/posix/include/rtems/posix/muteximpl.h
+++ b/cpukit/posix/include/rtems/posix/muteximpl.h
@@ -72,6 +72,7 @@ RTEMS_INLINE_ROUTINE void _POSIX_Mutex_Free(
POSIX_Mutex_Control *the_mutex
)
{
+ _CORE_mutex_Destroy( &the_mutex->Mutex );
_Objects_Free( &_POSIX_Mutex_Information, &the_mutex->Object );
}
diff --git a/cpukit/posix/include/rtems/posix/psignalimpl.h b/cpukit/posix/include/rtems/posix/psignalimpl.h
index 81561e2539..166705b37b 100644
--- a/cpukit/posix/include/rtems/posix/psignalimpl.h
+++ b/cpukit/posix/include/rtems/posix/psignalimpl.h
@@ -33,7 +33,7 @@
#include <rtems/posix/sigset.h>
#include <rtems/score/apiext.h>
#include <rtems/score/isrlock.h>
-#include <rtems/score/threadq.h>
+#include <rtems/score/threadqimpl.h>
#define _States_Is_interruptible_signal( _states ) \
( ((_states) & \
@@ -55,8 +55,6 @@
* Variables
*/
-extern ISR_lock_Control _POSIX_signals_Lock;
-
extern sigset_t _POSIX_signals_Pending;
extern const struct sigaction _POSIX_signals_Default_vectors[ SIG_ARRAY_MAX ];
@@ -79,10 +77,10 @@ extern Chain_Control _POSIX_signals_Siginfo[ SIG_ARRAY_MAX ];
void _POSIX_signals_Manager_Initialization(void);
#define _POSIX_signals_Acquire( lock_context ) \
- _ISR_lock_ISR_disable_and_acquire( &_POSIX_signals_Lock, lock_context )
+ _Thread_queue_Acquire( &_POSIX_signals_Wait_queue, lock_context )
#define _POSIX_signals_Release( lock_context ) \
- _ISR_lock_Release_and_ISR_enable( &_POSIX_signals_Lock, lock_context )
+ _Thread_queue_Release( &_POSIX_signals_Wait_queue, lock_context )
void _POSIX_signals_Action_handler(
Thread_Control *executing,
diff --git a/cpukit/posix/include/rtems/posix/rwlockimpl.h b/cpukit/posix/include/rtems/posix/rwlockimpl.h
index 48e0a17366..46e33904dc 100644
--- a/cpukit/posix/include/rtems/posix/rwlockimpl.h
+++ b/cpukit/posix/include/rtems/posix/rwlockimpl.h
@@ -89,6 +89,7 @@ RTEMS_INLINE_ROUTINE void _POSIX_RWLock_Free (
POSIX_RWLock_Control *the_RWLock
)
{
+ _CORE_RWLock_Destroy( &the_RWLock->RWLock );
_Objects_Free( &_POSIX_RWLock_Information, &the_RWLock->Object );
}
diff --git a/cpukit/posix/include/rtems/posix/semaphoreimpl.h b/cpukit/posix/include/rtems/posix/semaphoreimpl.h
index df5e5238de..783289aa44 100644
--- a/cpukit/posix/include/rtems/posix/semaphoreimpl.h
+++ b/cpukit/posix/include/rtems/posix/semaphoreimpl.h
@@ -65,6 +65,7 @@ RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Free (
POSIX_Semaphore_Control *the_semaphore
)
{
+ _CORE_semaphore_Destroy( &the_semaphore->Semaphore );
_Objects_Free( &_POSIX_Semaphore_Information, &the_semaphore->Object );
}
diff --git a/cpukit/posix/src/condwaitsupp.c b/cpukit/posix/src/condwaitsupp.c
index 1abdc426fc..8a9e23540c 100644
--- a/cpukit/posix/src/condwaitsupp.c
+++ b/cpukit/posix/src/condwaitsupp.c
@@ -74,10 +74,8 @@ int _POSIX_Condition_variables_Wait_support(
if ( !already_timedout ) {
the_cond->Mutex = *mutex;
- _Thread_queue_Enter_critical_section( &the_cond->Wait_queue );
executing = _Thread_Executing;
executing->Wait.return_code = 0;
- executing->Wait.queue = &the_cond->Wait_queue;
executing->Wait.id = *cond;
_Thread_queue_Enqueue(
diff --git a/cpukit/posix/src/psignal.c b/cpukit/posix/src/psignal.c
index eec4d95fb5..543b558eac 100644
--- a/cpukit/posix/src/psignal.c
+++ b/cpukit/posix/src/psignal.c
@@ -45,8 +45,6 @@ RTEMS_STATIC_ASSERT(
/*** PROCESS WIDE STUFF ****/
-ISR_lock_Control _POSIX_signals_Lock = ISR_LOCK_INITIALIZER("POSIX signals");
-
sigset_t _POSIX_signals_Pending;
void _POSIX_signals_Abnormal_termination_handler(
diff --git a/cpukit/posix/src/pthread.c b/cpukit/posix/src/pthread.c
index 97882bf4cb..2817891ac5 100644
--- a/cpukit/posix/src/pthread.c
+++ b/cpukit/posix/src/pthread.c
@@ -288,6 +288,8 @@ static void _POSIX_Threads_Terminate_extension(
if ( api->schedpolicy == SCHED_SPORADIC )
_Watchdog_Remove_ticks( &api->Sporadic_timer );
+ _Thread_queue_Destroy( &api->Join_List );
+
_Thread_Enable_dispatch();
}
diff --git a/cpukit/posix/src/pthreadjoin.c b/cpukit/posix/src/pthreadjoin.c
index e2b1664b0b..48fb7d58df 100644
--- a/cpukit/posix/src/pthreadjoin.c
+++ b/cpukit/posix/src/pthreadjoin.c
@@ -67,7 +67,6 @@ on_EINTR:
_Thread_Clear_state( the_thread, STATES_WAITING_FOR_JOIN_AT_EXIT );
} else {
executing->Wait.return_argument = &return_pointer;
- _Thread_queue_Enter_critical_section( &api->Join_List );
_Thread_queue_Enqueue(
&api->Join_List,
executing,
diff --git a/cpukit/posix/src/sigtimedwait.c b/cpukit/posix/src/sigtimedwait.c
index 8d86ba72a9..e988761453 100644
--- a/cpukit/posix/src/sigtimedwait.c
+++ b/cpukit/posix/src/sigtimedwait.c
@@ -152,17 +152,15 @@ int sigtimedwait(
the_info->si_signo = -1;
_Thread_Disable_dispatch();
- executing->Wait.queue = &_POSIX_signals_Wait_queue;
executing->Wait.return_code = EINTR;
executing->Wait.option = *set;
executing->Wait.return_argument = the_info;
- _Thread_queue_Enter_critical_section( &_POSIX_signals_Wait_queue );
- _POSIX_signals_Release( &lock_context );
- _Thread_queue_Enqueue(
+ _Thread_queue_Enqueue_critical(
&_POSIX_signals_Wait_queue,
executing,
STATES_WAITING_FOR_SIGNAL | STATES_INTERRUPTIBLE_BY_SIGNAL,
- interval
+ interval,
+ &lock_context
);
_Thread_Enable_dispatch();
diff --git a/cpukit/rtems/include/rtems/rtems/barrierimpl.h b/cpukit/rtems/include/rtems/rtems/barrierimpl.h
index 963ebd93da..e718028715 100644
--- a/cpukit/rtems/include/rtems/rtems/barrierimpl.h
+++ b/cpukit/rtems/include/rtems/rtems/barrierimpl.h
@@ -86,6 +86,7 @@ RTEMS_INLINE_ROUTINE void _Barrier_Free (
Barrier_Control *the_barrier
)
{
+ _CORE_barrier_Destroy( &the_barrier->Barrier );
_Objects_Free( &_Barrier_Information, &the_barrier->Object );
}
diff --git a/cpukit/rtems/include/rtems/rtems/messageimpl.h b/cpukit/rtems/include/rtems/rtems/messageimpl.h
index e2bc88d0db..fa9e573892 100644
--- a/cpukit/rtems/include/rtems/rtems/messageimpl.h
+++ b/cpukit/rtems/include/rtems/rtems/messageimpl.h
@@ -18,6 +18,7 @@
#include <rtems/rtems/message.h>
#include <rtems/score/objectimpl.h>
+#include <rtems/score/coremsgimpl.h>
#ifdef __cplusplus
extern "C" {
diff --git a/cpukit/rtems/include/rtems/rtems/regionimpl.h b/cpukit/rtems/include/rtems/rtems/regionimpl.h
index 9ff7b966ca..ae1a50d208 100644
--- a/cpukit/rtems/include/rtems/rtems/regionimpl.h
+++ b/cpukit/rtems/include/rtems/rtems/regionimpl.h
@@ -20,6 +20,7 @@
#include <rtems/rtems/region.h>
#include <rtems/score/heapimpl.h>
#include <rtems/score/objectimpl.h>
+#include <rtems/score/threadqimpl.h>
#include <rtems/debug.h>
#ifdef __cplusplus
@@ -84,6 +85,7 @@ RTEMS_INLINE_ROUTINE void _Region_Free (
Region_Control *the_region
)
{
+ _Thread_queue_Destroy( &the_region->Wait_queue );
_Objects_Free( &_Region_Information, &the_region->Object );
}
diff --git a/cpukit/rtems/src/regioncreate.c b/cpukit/rtems/src/regioncreate.c
index 0daf644ce3..aa95f3231b 100644
--- a/cpukit/rtems/src/regioncreate.c
+++ b/cpukit/rtems/src/regioncreate.c
@@ -71,6 +71,12 @@ rtems_status_code rtems_region_create(
return_status = RTEMS_TOO_MANY;
else {
+ _Thread_queue_Initialize(
+ &the_region->Wait_queue,
+ _Attributes_Is_priority( attribute_set ) ?
+ THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO,
+ RTEMS_TIMEOUT
+ );
the_region->maximum_segment_size = _Heap_Initialize(
&the_region->Memory, starting_address, length, page_size
@@ -79,23 +85,13 @@ rtems_status_code rtems_region_create(
if ( !the_region->maximum_segment_size ) {
_Region_Free( the_region );
return_status = RTEMS_INVALID_SIZE;
- }
-
- else {
-
+ } else {
the_region->starting_address = starting_address;
the_region->length = length;
the_region->page_size = page_size;
the_region->attribute_set = attribute_set;
the_region->number_of_used_blocks = 0;
- _Thread_queue_Initialize(
- &the_region->Wait_queue,
- _Attributes_Is_priority( attribute_set ) ?
- THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO,
- RTEMS_TIMEOUT
- );
-
_Objects_Open(
&_Region_Information,
&the_region->Object,
diff --git a/cpukit/rtems/src/regiongetsegment.c b/cpukit/rtems/src/regiongetsegment.c
index 1a52bc1d59..cef90e79f3 100644
--- a/cpukit/rtems/src/regiongetsegment.c
+++ b/cpukit/rtems/src/regiongetsegment.c
@@ -79,13 +79,10 @@ rtems_status_code rtems_region_get_segment(
_Thread_Disable_dispatch();
_RTEMS_Unlock_allocator();
- executing->Wait.queue = &the_region->Wait_queue;
executing->Wait.id = id;
executing->Wait.count = size;
executing->Wait.return_argument = segment;
- _Thread_queue_Enter_critical_section( &the_region->Wait_queue );
-
_Thread_queue_Enqueue(
&the_region->Wait_queue,
executing,
diff --git a/cpukit/rtems/src/semdelete.c b/cpukit/rtems/src/semdelete.c
index a805ac61de..e9c3ad21e9 100644
--- a/cpukit/rtems/src/semdelete.c
+++ b/cpukit/rtems/src/semdelete.c
@@ -76,12 +76,14 @@ rtems_status_code rtems_semaphore_delete(
SEMAPHORE_MP_OBJECT_WAS_DELETED,
CORE_MUTEX_WAS_DELETED
);
+ _CORE_mutex_Destroy( &the_semaphore->Core_control.mutex );
} else {
_CORE_semaphore_Flush(
&the_semaphore->Core_control.semaphore,
SEMAPHORE_MP_OBJECT_WAS_DELETED,
CORE_SEMAPHORE_WAS_DELETED
);
+ _CORE_semaphore_Destroy( &the_semaphore->Core_control.semaphore );
}
_Objects_Close( &_Semaphore_Information, &the_semaphore->Object );
diff --git a/cpukit/score/include/rtems/score/corebarrierimpl.h b/cpukit/score/include/rtems/score/corebarrierimpl.h
index 124ecabf05..e8b330dcb6 100644
--- a/cpukit/score/include/rtems/score/corebarrierimpl.h
+++ b/cpukit/score/include/rtems/score/corebarrierimpl.h
@@ -21,6 +21,7 @@
#include <rtems/score/corebarrier.h>
#include <rtems/score/thread.h>
+#include <rtems/score/threadqimpl.h>
#include <rtems/score/watchdog.h>
#ifdef __cplusplus
@@ -83,6 +84,13 @@ void _CORE_barrier_Initialize(
CORE_barrier_Attributes *the_barrier_attributes
);
+RTEMS_INLINE_ROUTINE void _CORE_barrier_Destroy(
+ CORE_barrier_Control *the_barrier
+)
+{
+ _Thread_queue_Destroy( &the_barrier->Wait_queue );
+}
+
/**
* @brief Wait for the barrier.
*
diff --git a/cpukit/score/include/rtems/score/coremuteximpl.h b/cpukit/score/include/rtems/score/coremuteximpl.h
index e019b0abab..a6811680ff 100644
--- a/cpukit/score/include/rtems/score/coremuteximpl.h
+++ b/cpukit/score/include/rtems/score/coremuteximpl.h
@@ -119,6 +119,11 @@ CORE_mutex_Status _CORE_mutex_Initialize(
bool initially_locked
);
+RTEMS_INLINE_ROUTINE void _CORE_mutex_Destroy( CORE_mutex_Control *the_mutex )
+{
+ _Thread_queue_Destroy( &the_mutex->Wait_queue );
+}
+
/**
* @brief Attempt to receive a unit from the_mutex.
*
diff --git a/cpukit/score/include/rtems/score/corerwlockimpl.h b/cpukit/score/include/rtems/score/corerwlockimpl.h
index 331510ba02..e619574d89 100644
--- a/cpukit/score/include/rtems/score/corerwlockimpl.h
+++ b/cpukit/score/include/rtems/score/corerwlockimpl.h
@@ -21,6 +21,7 @@
#include <rtems/score/corerwlock.h>
#include <rtems/score/thread.h>
+#include <rtems/score/threadqimpl.h>
#include <rtems/score/watchdog.h>
#ifdef __cplusplus
@@ -87,6 +88,13 @@ void _CORE_RWLock_Initialize(
CORE_RWLock_Attributes *the_rwlock_attributes
);
+RTEMS_INLINE_ROUTINE void _CORE_RWLock_Destroy(
+ CORE_RWLock_Control *the_rwlock
+)
+{
+ _Thread_queue_Destroy( &the_rwlock->Wait_queue );
+}
+
/**
* @brief Obtain RWLock for reading.
*
diff --git a/cpukit/score/include/rtems/score/coresemimpl.h b/cpukit/score/include/rtems/score/coresemimpl.h
index 6a3a212f34..fac9f689e4 100644
--- a/cpukit/score/include/rtems/score/coresemimpl.h
+++ b/cpukit/score/include/rtems/score/coresemimpl.h
@@ -98,6 +98,13 @@ void _CORE_semaphore_Initialize(
uint32_t initial_value
);
+RTEMS_INLINE_ROUTINE void _CORE_semaphore_Destroy(
+ CORE_semaphore_Control *the_semaphore
+)
+{
+ _Thread_queue_Destroy( &the_semaphore->Wait_queue );
+}
+
#if defined(RTEMS_SCORE_CORESEM_ENABLE_SEIZE_BODY)
/**
* This routine attempts to receive a unit from @a the_semaphore.
@@ -234,16 +241,14 @@ RTEMS_INLINE_ROUTINE void _CORE_semaphore_Seize_isr_disable(
}
_Thread_Disable_dispatch();
- _Thread_queue_Enter_critical_section( &the_semaphore->Wait_queue );
- executing->Wait.queue = &the_semaphore->Wait_queue;
- executing->Wait.id = id;
- _ISR_lock_ISR_enable( lock_context );
-
- _Thread_queue_Enqueue(
+ executing->Wait.id = id;
+ _Thread_queue_Acquire_critical( &the_semaphore->Wait_queue, lock_context );
+ _Thread_queue_Enqueue_critical(
&the_semaphore->Wait_queue,
executing,
STATES_WAITING_FOR_SEMAPHORE,
- timeout
+ timeout,
+ lock_context
);
_Thread_Enable_dispatch();
}
diff --git a/cpukit/score/include/rtems/score/threadq.h b/cpukit/score/include/rtems/score/threadq.h
index 00b9221356..1f99ffde04 100644
--- a/cpukit/score/include/rtems/score/threadq.h
+++ b/cpukit/score/include/rtems/score/threadq.h
@@ -20,6 +20,7 @@
#define _RTEMS_SCORE_THREADQ_H
#include <rtems/score/chain.h>
+#include <rtems/score/isrlock.h>
#include <rtems/score/states.h>
#include <rtems/score/threadsync.h>
#include <rtems/score/rbtree.h>
@@ -62,6 +63,18 @@ typedef struct {
/** This is the set of threads for priority discipline waiting. */
RBTree_Control Priority;
} Queues;
+
+ /**
+ * @brief Lock to protect this thread queue.
+ *
+ * It may be used to protect additional state of the object embedding this
+ * thread queue.
+ *
+ * @see _Thread_queue_Acquire(), _Thread_queue_Acquire_critical() and
+ * _Thread_queue_Release().
+ */
+ ISR_LOCK_MEMBER( Lock )
+
/** This field is used to manage the critical section. */
Thread_blocking_operation_States sync_state;
/** This field indicates the thread queue's blocking discipline. */
diff --git a/cpukit/score/include/rtems/score/threadqimpl.h b/cpukit/score/include/rtems/score/threadqimpl.h
index 6fc38cfa5b..3595dc5d85 100644
--- a/cpukit/score/include/rtems/score/threadqimpl.h
+++ b/cpukit/score/include/rtems/score/threadqimpl.h
@@ -31,6 +31,31 @@ extern "C" {
*/
/**@{*/
+RTEMS_INLINE_ROUTINE void _Thread_queue_Acquire_critical(
+ Thread_queue_Control *the_thread_queue,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_Acquire( &the_thread_queue->Lock, lock_context );
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_queue_Acquire(
+ Thread_queue_Control *the_thread_queue,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_ISR_disable( lock_context );
+ _Thread_queue_Acquire_critical( the_thread_queue, lock_context );
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_queue_Release(
+ Thread_queue_Control *the_thread_queue,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_Release_and_ISR_enable( &the_thread_queue->Lock, lock_context );
+}
+
/**
* The following type defines the callout used when a remote task
* is extracted from a local thread queue.
@@ -55,26 +80,48 @@ Thread_Control *_Thread_queue_Dequeue(
);
/**
- * @brief Blocks a thread and places it on a thread.
+ * @brief Blocks a thread and places it on a thread queue.
*
- * This routine blocks a thread, places it on a thread, and optionally
- * starts a timeout timer.
+ * This routine blocks a thread, places it on a thread queue, and optionally
+ * starts a watchdog in case the timeout interval is not WATCHDOG_NO_TIMEOUT.
*
- * @param[in] the_thread_queue pointer to threadq
- * @param[in] the_thread the thread to enqueue
- * @param[in] state is the new state of the thread
- * @param[in] timeout interval to wait
+ * The caller must be the owner of the thread queue lock. This function will
+ * release the thread queue lock and register it as the new thread lock.
*
- * - INTERRUPT LATENCY:
- * + single case
+ * @param[in] the_thread_queue The thread queue.
+ * @param[in] the_thread The thread to enqueue.
+ * @param[in] state The new state of the thread.
+ * @param[in] timeout Interval to wait. Use WATCHDOG_NO_TIMEOUT to block
+ * potentially forever.
+ * @param[in] lock_context The lock context of the lock acquire.
*/
-void _Thread_queue_Enqueue(
+void _Thread_queue_Enqueue_critical(
Thread_queue_Control *the_thread_queue,
Thread_Control *the_thread,
States_Control state,
- Watchdog_Interval timeout
+ Watchdog_Interval timeout,
+ ISR_lock_Context *lock_context
);
+RTEMS_INLINE_ROUTINE void _Thread_queue_Enqueue(
+ Thread_queue_Control *the_thread_queue,
+ Thread_Control *the_thread,
+ States_Control state,
+ Watchdog_Interval timeout
+)
+{
+ ISR_lock_Context lock_context;
+
+ _Thread_queue_Acquire( the_thread_queue, &lock_context );
+ _Thread_queue_Enqueue_critical(
+ the_thread_queue,
+ the_thread,
+ state,
+ timeout,
+ &lock_context
+ );
+}
+
/**
* @brief Extracts thread from thread queue.
*
@@ -116,15 +163,30 @@ void _Thread_queue_Extract_with_proxy(
);
/**
- * @brief Gets a pointer to the "first" thread on the_thread_queue.
+ * @brief Returns the first thread on the thread queue if it exists, otherwise
+ * @c NULL (locked).
+ *
+ * The caller must be the owner of the thread queue lock.
+ *
+ * @param[in] the_thread_queue The thread queue.
*
- * This function returns a pointer to the "first" thread
- * on the_thread_queue. The "first" thread is selected
- * based on the discipline of the_thread_queue.
+ * @retval NULL No thread is present on the thread queue.
+ * @retval first The first thread on the thread queue according to the enqueue
+ * order.
+ */
+Thread_Control *_Thread_queue_First_locked(
+ Thread_queue_Control *the_thread_queue
+);
+
+/**
+ * @brief Returns the first thread on the thread queue if it exists, otherwise
+ * @c NULL.
*
- * @param[in] the_thread_queue pointer to thread queue
+ * @param[in] the_thread_queue The thread queue.
*
- * @retval first thread or NULL
+ * @retval NULL No thread is present on the thread queue.
+ * @retval first The first thread on the thread queue according to the enqueue
+ * order.
*/
Thread_Control *_Thread_queue_First(
Thread_queue_Control *the_thread_queue
@@ -165,6 +227,13 @@ void _Thread_queue_Initialize(
uint32_t timeout_status
);
+RTEMS_INLINE_ROUTINE void _Thread_queue_Destroy(
+ Thread_queue_Control *the_thread_queue
+)
+{
+ _ISR_lock_Destroy( &the_thread_queue->Lock );
+}
+
/**
* @brief Thread queue timeout.
*
@@ -212,17 +281,6 @@ RBTree_Compare_result _Thread_queue_Compare_priority(
const RBTree_Node *right
);
-/**
- * This routine is invoked to indicate that the specified thread queue is
- * entering a critical section.
- */
-RTEMS_INLINE_ROUTINE void _Thread_queue_Enter_critical_section (
- Thread_queue_Control *the_thread_queue
-)
-{
- the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
-}
-
/**@}*/
#ifdef __cplusplus
diff --git a/cpukit/score/src/corebarrierwait.c b/cpukit/score/src/corebarrierwait.c
index 6267ae67c0..30abf0c17a 100644
--- a/cpukit/score/src/corebarrierwait.c
+++ b/cpukit/score/src/corebarrierwait.c
@@ -32,30 +32,28 @@ void _CORE_barrier_Wait(
CORE_barrier_API_mp_support_callout api_barrier_mp_support
)
{
- ISR_Level level;
+ ISR_lock_Context lock_context;
executing->Wait.return_code = CORE_BARRIER_STATUS_SUCCESSFUL;
- _ISR_Disable( level );
+ _Thread_queue_Acquire( &the_barrier->Wait_queue, &lock_context );
the_barrier->number_of_waiting_threads++;
if ( _CORE_barrier_Is_automatic( &the_barrier->Attributes ) ) {
if ( the_barrier->number_of_waiting_threads ==
the_barrier->Attributes.maximum_count) {
executing->Wait.return_code = CORE_BARRIER_STATUS_AUTOMATICALLY_RELEASED;
- _ISR_Enable( level );
+ _Thread_queue_Release( &the_barrier->Wait_queue, &lock_context );
_CORE_barrier_Release( the_barrier, id, api_barrier_mp_support );
return;
}
}
- _Thread_queue_Enter_critical_section( &the_barrier->Wait_queue );
- executing->Wait.queue = &the_barrier->Wait_queue;
- executing->Wait.id = id;
- _ISR_Enable( level );
+ executing->Wait.id = id;
- _Thread_queue_Enqueue(
+ _Thread_queue_Enqueue_critical(
&the_barrier->Wait_queue,
executing,
STATES_WAITING_FOR_BARRIER,
- timeout
+ timeout,
+ &lock_context
);
}
diff --git a/cpukit/score/src/coremsgclose.c b/cpukit/score/src/coremsgclose.c
index 987f038cb3..17ecc4428e 100644
--- a/cpukit/score/src/coremsgclose.c
+++ b/cpukit/score/src/coremsgclose.c
@@ -54,4 +54,5 @@ void _CORE_message_queue_Close(
(void) _Workspace_Free( the_message_queue->message_buffers );
+ _Thread_queue_Destroy( &the_message_queue->Wait_queue );
}
diff --git a/cpukit/score/src/coremsgseize.c b/cpukit/score/src/coremsgseize.c
index db8d558ca6..45105ca19b 100644
--- a/cpukit/score/src/coremsgseize.c
+++ b/cpukit/score/src/coremsgseize.c
@@ -36,15 +36,15 @@ void _CORE_message_queue_Seize(
Watchdog_Interval timeout
)
{
- ISR_Level level;
+ ISR_lock_Context lock_context;
CORE_message_queue_Buffer_control *the_message;
executing->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
- _ISR_Disable( level );
+ _Thread_queue_Acquire( &the_message_queue->Wait_queue, &lock_context );
the_message = _CORE_message_queue_Get_pending_message( the_message_queue );
if ( the_message != NULL ) {
the_message_queue->number_of_pending_messages -= 1;
- _ISR_Enable( level );
+ _Thread_queue_Release( &the_message_queue->Wait_queue, &lock_context );
*size_p = the_message->Contents.size;
executing->Wait.count =
@@ -109,23 +109,21 @@ void _CORE_message_queue_Seize(
}
if ( !wait ) {
- _ISR_Enable( level );
+ _Thread_queue_Release( &the_message_queue->Wait_queue, &lock_context );
executing->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_NOWAIT;
return;
}
- _Thread_queue_Enter_critical_section( &the_message_queue->Wait_queue );
- executing->Wait.queue = &the_message_queue->Wait_queue;
executing->Wait.id = id;
executing->Wait.return_argument_second.mutable_object = buffer;
executing->Wait.return_argument = size_p;
/* Wait.count will be filled in with the message priority */
- _ISR_Enable( level );
- _Thread_queue_Enqueue(
+ _Thread_queue_Enqueue_critical(
&the_message_queue->Wait_queue,
executing,
STATES_WAITING_FOR_MESSAGE,
- timeout
+ timeout,
+ &lock_context
);
}
diff --git a/cpukit/score/src/coremsgsubmit.c b/cpukit/score/src/coremsgsubmit.c
index 4437856b17..0bcebe04af 100644
--- a/cpukit/score/src/coremsgsubmit.c
+++ b/cpukit/score/src/coremsgsubmit.c
@@ -120,16 +120,10 @@ CORE_message_queue_Status _CORE_message_queue_Submit(
* would be to use this variable prior to here.
*/
{
- ISR_Level level;
-
- _ISR_Disable( level );
- _Thread_queue_Enter_critical_section( &the_message_queue->Wait_queue );
- executing->Wait.queue = &the_message_queue->Wait_queue;
executing->Wait.id = id;
executing->Wait.return_argument_second.immutable_object = buffer;
executing->Wait.option = (uint32_t) size;
executing->Wait.count = submit_type;
- _ISR_Enable( level );
_Thread_queue_Enqueue(
&the_message_queue->Wait_queue,
diff --git a/cpukit/score/src/coremutexseize.c b/cpukit/score/src/coremutexseize.c
index 3fc3765ef4..67954b697b 100644
--- a/cpukit/score/src/coremutexseize.c
+++ b/cpukit/score/src/coremutexseize.c
@@ -53,27 +53,35 @@ void _CORE_mutex_Seize_interrupt_blocking(
ISR_lock_Context *lock_context
)
{
- _Thread_queue_Enter_critical_section( &the_mutex->Wait_queue );
- executing->Wait.queue = &the_mutex->Wait_queue;
_Thread_Disable_dispatch();
- _ISR_lock_ISR_enable( lock_context );
if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ) {
Thread_Control *holder = the_mutex->holder;
+ /*
+ * To enable interrupts here works only since we own the Giant lock and
+ * only threads are allowed to seize and surrender mutexes with the
+ * priority inheritance protocol.
+ */
+ _ISR_lock_ISR_enable( lock_context );
+
_Scheduler_Change_priority_if_higher(
_Scheduler_Get( holder ),
holder,
executing->current_priority,
false
);
+
+ _ISR_lock_ISR_disable( lock_context );
}
- _Thread_queue_Enqueue(
+ _Thread_queue_Acquire_critical( &the_mutex->Wait_queue, lock_context );
+ _Thread_queue_Enqueue_critical(
&the_mutex->Wait_queue,
executing,
STATES_WAITING_FOR_MUTEX,
- timeout
+ timeout,
+ lock_context
);
_Thread_Enable_dispatch();
diff --git a/cpukit/score/src/corerwlockobtainread.c b/cpukit/score/src/corerwlockobtainread.c
index 203680f6dc..59c1097354 100644
--- a/cpukit/score/src/corerwlockobtainread.c
+++ b/cpukit/score/src/corerwlockobtainread.c
@@ -32,7 +32,7 @@ void _CORE_RWLock_Obtain_for_reading(
CORE_RWLock_API_mp_support_callout api_rwlock_mp_support
)
{
- ISR_Level level;
+ ISR_lock_Context lock_context;
/*
* If unlocked, then OK to read.
@@ -40,21 +40,21 @@ void _CORE_RWLock_Obtain_for_reading(
* If any thread is waiting, then we wait.
*/
- _ISR_Disable( level );
+ _Thread_queue_Acquire( &the_rwlock->Wait_queue, &lock_context );
switch ( the_rwlock->current_state ) {
case CORE_RWLOCK_UNLOCKED:
the_rwlock->current_state = CORE_RWLOCK_LOCKED_FOR_READING;
the_rwlock->number_of_readers += 1;
- _ISR_Enable( level );
+ _Thread_queue_Release( &the_rwlock->Wait_queue, &lock_context );
executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
return;
case CORE_RWLOCK_LOCKED_FOR_READING: {
Thread_Control *waiter;
- waiter = _Thread_queue_First( &the_rwlock->Wait_queue );
+ waiter = _Thread_queue_First_locked( &the_rwlock->Wait_queue );
if ( !waiter ) {
the_rwlock->number_of_readers += 1;
- _ISR_Enable( level );
+ _Thread_queue_Release( &the_rwlock->Wait_queue, &lock_context );
executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
return;
}
@@ -69,7 +69,7 @@ void _CORE_RWLock_Obtain_for_reading(
*/
if ( !wait ) {
- _ISR_Enable( level );
+ _Thread_queue_Release( &the_rwlock->Wait_queue, &lock_context );
executing->Wait.return_code = CORE_RWLOCK_UNAVAILABLE;
return;
}
@@ -78,18 +78,16 @@ void _CORE_RWLock_Obtain_for_reading(
* We need to wait to enter this critical section
*/
- _Thread_queue_Enter_critical_section( &the_rwlock->Wait_queue );
- executing->Wait.queue = &the_rwlock->Wait_queue;
executing->Wait.id = id;
executing->Wait.option = CORE_RWLOCK_THREAD_WAITING_FOR_READ;
executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
- _ISR_Enable( level );
- _Thread_queue_Enqueue(
+ _Thread_queue_Enqueue_critical(
&the_rwlock->Wait_queue,
executing,
STATES_WAITING_FOR_RWLOCK,
- timeout
+ timeout,
+ &lock_context
);
/* return to API level so it can dispatch and we block */
diff --git a/cpukit/score/src/corerwlockobtainwrite.c b/cpukit/score/src/corerwlockobtainwrite.c
index 3499bcd4c8..409d31aeec 100644
--- a/cpukit/score/src/corerwlockobtainwrite.c
+++ b/cpukit/score/src/corerwlockobtainwrite.c
@@ -32,7 +32,7 @@ void _CORE_RWLock_Obtain_for_writing(
CORE_RWLock_API_mp_support_callout api_rwlock_mp_support
)
{
- ISR_Level level;
+ ISR_lock_Context lock_context;
/*
* If unlocked, then OK to read.
@@ -41,13 +41,13 @@ void _CORE_RWLock_Obtain_for_writing(
* If any thread is waiting, then we wait.
*/
- _ISR_Disable( level );
+ _Thread_queue_Acquire( &the_rwlock->Wait_queue, &lock_context );
switch ( the_rwlock->current_state ) {
case CORE_RWLOCK_UNLOCKED:
- the_rwlock->current_state = CORE_RWLOCK_LOCKED_FOR_WRITING;
- _ISR_Enable( level );
- executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
- return;
+ the_rwlock->current_state = CORE_RWLOCK_LOCKED_FOR_WRITING;
+ _Thread_queue_Release( &the_rwlock->Wait_queue, &lock_context );
+ executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
+ return;
case CORE_RWLOCK_LOCKED_FOR_READING:
case CORE_RWLOCK_LOCKED_FOR_WRITING:
@@ -59,7 +59,7 @@ void _CORE_RWLock_Obtain_for_writing(
*/
if ( !wait ) {
- _ISR_Enable( level );
+ _Thread_queue_Release( &the_rwlock->Wait_queue, &lock_context );
executing->Wait.return_code = CORE_RWLOCK_UNAVAILABLE;
return;
}
@@ -68,18 +68,16 @@ void _CORE_RWLock_Obtain_for_writing(
* We need to wait to enter this critical section
*/
- _Thread_queue_Enter_critical_section( &the_rwlock->Wait_queue );
- executing->Wait.queue = &the_rwlock->Wait_queue;
executing->Wait.id = id;
executing->Wait.option = CORE_RWLOCK_THREAD_WAITING_FOR_WRITE;
executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
- _ISR_Enable( level );
- _Thread_queue_Enqueue(
+ _Thread_queue_Enqueue_critical(
&the_rwlock->Wait_queue,
executing,
STATES_WAITING_FOR_RWLOCK,
- timeout
+ timeout,
+ &lock_context
);
/* return to API level so it can dispatch and we block */
diff --git a/cpukit/score/src/coresemseize.c b/cpukit/score/src/coresemseize.c
index 9c0db96204..d7ab28e779 100644
--- a/cpukit/score/src/coresemseize.c
+++ b/cpukit/score/src/coresemseize.c
@@ -34,13 +34,13 @@ void _CORE_semaphore_Seize(
Watchdog_Interval timeout
)
{
- ISR_Level level;
+ ISR_lock_Context lock_context;
executing->Wait.return_code = CORE_SEMAPHORE_STATUS_SUCCESSFUL;
- _ISR_Disable( level );
+ _Thread_queue_Acquire( &the_semaphore->Wait_queue, &lock_context );
if ( the_semaphore->count != 0 ) {
the_semaphore->count -= 1;
- _ISR_Enable( level );
+ _Thread_queue_Release( &the_semaphore->Wait_queue, &lock_context );
return;
}
@@ -50,7 +50,7 @@ void _CORE_semaphore_Seize(
* the semaphore was not available and the caller never blocked.
*/
if ( !wait ) {
- _ISR_Enable( level );
+ _Thread_queue_Release( &the_semaphore->Wait_queue, &lock_context );
executing->Wait.return_code = CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT;
return;
}
@@ -59,15 +59,13 @@ void _CORE_semaphore_Seize(
* If the semaphore is not available and the caller is willing to
* block, then we now block the caller with optional timeout.
*/
- _Thread_queue_Enter_critical_section( &the_semaphore->Wait_queue );
- executing->Wait.queue = &the_semaphore->Wait_queue;
- executing->Wait.id = id;
- _ISR_Enable( level );
- _Thread_queue_Enqueue(
+ executing->Wait.id = id;
+ _Thread_queue_Enqueue_critical(
&the_semaphore->Wait_queue,
executing,
STATES_WAITING_FOR_SEMAPHORE,
- timeout
+ timeout,
+ &lock_context
);
}
#endif
diff --git a/cpukit/score/src/mpci.c b/cpukit/score/src/mpci.c
index 424bcb4d33..9915aa2d12 100644
--- a/cpukit/score/src/mpci.c
+++ b/cpukit/score/src/mpci.c
@@ -206,8 +206,6 @@ uint32_t _MPCI_Send_request_packet (
(*_MPCI_table->send_packet)( destination, the_packet );
- _Thread_queue_Enter_critical_section( &_MPCI_Remote_blocked_threads );
-
/*
* See if we need a default timeout
*/
diff --git a/cpukit/score/src/threadq.c b/cpukit/score/src/threadq.c
index 0ea0c82d83..47c294e968 100644
--- a/cpukit/score/src/threadq.c
+++ b/cpukit/score/src/threadq.c
@@ -55,10 +55,11 @@ void _Thread_queue_Initialize(
the_thread_queue->timeout_status = timeout_status;
the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
+ _ISR_lock_Initialize( &the_thread_queue->Lock, "Thread Queue" );
+
if ( the_discipline == THREAD_QUEUE_DISCIPLINE_PRIORITY ) {
_RBTree_Initialize_empty( &the_thread_queue->Queues.Priority );
} else { /* must be THREAD_QUEUE_DISCIPLINE_FIFO */
_Chain_Initialize_empty( &the_thread_queue->Queues.Fifo );
}
-
}
diff --git a/cpukit/score/src/threadqenqueue.c b/cpukit/score/src/threadqenqueue.c
index 590865d8dd..76eaa30dde 100644
--- a/cpukit/score/src/threadqenqueue.c
+++ b/cpukit/score/src/threadqenqueue.c
@@ -24,18 +24,6 @@
#include <rtems/score/threadimpl.h>
#include <rtems/score/watchdogimpl.h>
-ISR_LOCK_DEFINE( static, _Thread_queue_Lock, "Thread Queue" )
-
-static void _Thread_queue_Acquire( ISR_lock_Context *lock_context )
-{
- _ISR_lock_ISR_disable_and_acquire( &_Thread_queue_Lock, lock_context );
-}
-
-static void _Thread_queue_Release( ISR_lock_Context *lock_context )
-{
- _ISR_lock_Release_and_ISR_enable( &_Thread_queue_Lock, lock_context );
-}
-
/**
* @brief Finalize a blocking operation.
*
@@ -50,8 +38,9 @@ static void _Thread_queue_Release( ISR_lock_Context *lock_context )
* @param[in] lock_context is the previous ISR disable level
*/
static void _Thread_blocking_operation_Finalize(
- Thread_Control *the_thread,
- ISR_lock_Context *lock_context
+ Thread_queue_Control *the_thread_queue,
+ Thread_Control *the_thread,
+ ISR_lock_Context *lock_context
)
{
/*
@@ -59,16 +48,18 @@ static void _Thread_blocking_operation_Finalize(
*/
the_thread->Wait.queue = NULL;
+ _Thread_Lock_restore_default( the_thread );
+
/*
* If the sync state is timed out, this is very likely not needed.
* But better safe than sorry when it comes to critical sections.
*/
if ( _Watchdog_Is_active( &the_thread->Timer ) ) {
_Watchdog_Deactivate( &the_thread->Timer );
- _Thread_queue_Release( lock_context );
+ _Thread_queue_Release( the_thread_queue, lock_context );
_Watchdog_Remove_ticks( &the_thread->Timer );
} else
- _Thread_queue_Release( lock_context );
+ _Thread_queue_Release( the_thread_queue, lock_context );
/*
* Global objects with thread queue's should not be operated on from an
@@ -101,16 +92,23 @@ static void _Thread_queue_Requeue_priority(
);
}
-void _Thread_queue_Enqueue(
+void _Thread_queue_Enqueue_critical(
Thread_queue_Control *the_thread_queue,
Thread_Control *the_thread,
States_Control state,
- Watchdog_Interval timeout
+ Watchdog_Interval timeout,
+ ISR_lock_Context *lock_context
)
{
- ISR_lock_Context lock_context;
Thread_blocking_operation_States sync_state;
+ _Thread_Lock_set( the_thread, &the_thread_queue->Lock );
+
+ the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
+ the_thread->Wait.queue = the_thread_queue;
+
+ _Thread_queue_Release( the_thread_queue, lock_context );
+
#if defined(RTEMS_MULTIPROCESSING)
if ( _Thread_MP_Is_receive( the_thread ) && the_thread->receive_packet )
the_thread = _Thread_MP_Allocate_proxy( state );
@@ -140,7 +138,7 @@ void _Thread_queue_Enqueue(
* should be completed or the thread has had its blocking condition
* satisfied before we got here.
*/
- _Thread_queue_Acquire( &lock_context );
+ _Thread_queue_Acquire( the_thread_queue, lock_context );
sync_state = the_thread_queue->sync_state;
the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
@@ -155,7 +153,6 @@ void _Thread_queue_Enqueue(
&the_thread->Object.Node
);
} else { /* must be THREAD_QUEUE_DISCIPLINE_PRIORITY */
- _Thread_Lock_set( the_thread, &_Thread_queue_Lock );
_Thread_Priority_set_change_handler(
the_thread,
_Thread_queue_Requeue_priority,
@@ -169,9 +166,8 @@ void _Thread_queue_Enqueue(
);
}
- the_thread->Wait.queue = the_thread_queue;
the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
- _Thread_queue_Release( &lock_context );
+ _Thread_queue_Release( the_thread_queue, lock_context );
} else {
/* Cancel a blocking operation due to ISR */
@@ -180,7 +176,7 @@ void _Thread_queue_Enqueue(
sync_state == THREAD_BLOCKING_OPERATION_SATISFIED
);
- _Thread_blocking_operation_Finalize( the_thread, &lock_context );
+ _Thread_blocking_operation_Finalize( the_thread_queue, the_thread, lock_context );
}
}
@@ -190,16 +186,19 @@ void _Thread_queue_Extract_with_return_code(
)
{
Thread_queue_Control *the_thread_queue;
- ISR_lock_Context lock_context;
+ ISR_lock_Control *lock;
+ ISR_lock_Context lock_context;
- _Thread_queue_Acquire( &lock_context );
+ lock = _Thread_Lock_acquire( the_thread, &lock_context );
the_thread_queue = the_thread->Wait.queue;
if ( the_thread_queue == NULL ) {
- _Thread_queue_Release( &lock_context );
+ _Thread_Lock_release( lock, &lock_context );
return;
}
+ _SMP_Assert( lock == &the_thread_queue->Lock );
+
if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_FIFO ) {
_Chain_Extract_unprotected( &the_thread->Object.Node );
} else { /* must be THREAD_QUEUE_DISCIPLINE_PRIORITY */
@@ -208,7 +207,6 @@ void _Thread_queue_Extract_with_return_code(
&the_thread->RBNode
);
_Thread_Priority_restore_default_change_handler( the_thread );
- _Thread_Lock_restore_default( the_thread );
}
the_thread->Wait.return_code = return_code;
@@ -218,7 +216,7 @@ void _Thread_queue_Extract_with_return_code(
*
* NOTE: This is invoked with interrupts still disabled.
*/
- _Thread_blocking_operation_Finalize( the_thread, &lock_context );
+ _Thread_blocking_operation_Finalize( the_thread_queue, the_thread, &lock_context );
}
void _Thread_queue_Extract( Thread_Control *the_thread )
@@ -238,7 +236,7 @@ Thread_Control *_Thread_queue_Dequeue(
Thread_blocking_operation_States sync_state;
the_thread = NULL;
- _Thread_queue_Acquire( &lock_context );
+ _Thread_queue_Acquire( the_thread_queue, &lock_context );
/*
* Invoke the discipline specific dequeue method.
@@ -255,7 +253,6 @@ Thread_Control *_Thread_queue_Dequeue(
if ( first ) {
the_thread = THREAD_RBTREE_NODE_TO_THREAD( first );
_Thread_Priority_restore_default_change_handler( the_thread );
- _Thread_Lock_restore_default( the_thread );
}
}
@@ -270,7 +267,7 @@ Thread_Control *_Thread_queue_Dequeue(
the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SATISFIED;
the_thread = _Thread_Executing;
} else {
- _Thread_queue_Release( &lock_context );
+ _Thread_queue_Release( the_thread_queue, &lock_context );
return NULL;
}
}
@@ -280,7 +277,7 @@ Thread_Control *_Thread_queue_Dequeue(
*
* NOTE: This is invoked with interrupts still disabled.
*/
- _Thread_blocking_operation_Finalize( the_thread, &lock_context );
+ _Thread_blocking_operation_Finalize( the_thread_queue, the_thread, &lock_context );
return the_thread;
}
diff --git a/cpukit/score/src/threadqfirst.c b/cpukit/score/src/threadqfirst.c
index 5d97ae156d..f43b9abbd0 100644
--- a/cpukit/score/src/threadqfirst.c
+++ b/cpukit/score/src/threadqfirst.c
@@ -20,20 +20,16 @@
#include <rtems/score/threadqimpl.h>
#include <rtems/score/chainimpl.h>
-#include <rtems/score/isrlevel.h>
#include <rtems/score/threadimpl.h>
-Thread_Control *_Thread_queue_First(
+Thread_Control *_Thread_queue_First_locked(
Thread_queue_Control *the_thread_queue
)
{
- ISR_Level level;
Thread_Control *thread;
thread = NULL;
- _ISR_Disable( level );
-
if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_FIFO ) {
if ( !_Chain_Is_empty( &the_thread_queue->Queues.Fifo ) )
thread = (Thread_Control *) _Chain_First(&the_thread_queue->Queues.Fifo);
@@ -45,7 +41,19 @@ Thread_Control *_Thread_queue_First(
thread = THREAD_RBTREE_NODE_TO_THREAD( first );
}
- _ISR_Enable( level );
-
return thread;
}
+
+Thread_Control *_Thread_queue_First(
+ Thread_queue_Control *the_thread_queue
+)
+{
+ Thread_Control *the_thread;
+ ISR_lock_Context lock_context;
+
+ _Thread_queue_Acquire( the_thread_queue, &lock_context );
+ the_thread = _Thread_queue_First_locked( the_thread_queue );
+ _Thread_queue_Release( the_thread_queue, &lock_context );
+
+ return the_thread;
+}