summaryrefslogtreecommitdiffstats
path: root/cpukit/score/include
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 /cpukit/score/include
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.
Diffstat (limited to 'cpukit/score/include')
-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
6 files changed, 132 insertions, 35 deletions
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