[PATCH 25/45] score: Fine grained locking for semaphores
Sebastian Huber
sebastian.huber at embedded-brains.de
Fri May 15 11:41:25 UTC 2015
Update #2273.
---
cpukit/posix/include/rtems/posix/semaphoreimpl.h | 14 ++++++++++
cpukit/posix/src/sempost.c | 13 ++++++---
cpukit/rtems/src/semobtain.c | 9 +++----
cpukit/rtems/src/semrelease.c | 19 +++++++++----
cpukit/score/include/rtems/score/coresemimpl.h | 13 ++++-----
cpukit/score/src/coresemsurrender.c | 34 ++++++++++++++++--------
cpukit/score/src/mpci.c | 7 ++---
7 files changed, 75 insertions(+), 34 deletions(-)
diff --git a/cpukit/posix/include/rtems/posix/semaphoreimpl.h b/cpukit/posix/include/rtems/posix/semaphoreimpl.h
index 783289a..eeea51c 100644
--- a/cpukit/posix/include/rtems/posix/semaphoreimpl.h
+++ b/cpukit/posix/include/rtems/posix/semaphoreimpl.h
@@ -89,6 +89,20 @@ RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *_POSIX_Semaphore_Get (
_Objects_Get( &_POSIX_Semaphore_Information, (Objects_Id)*id, location );
}
+RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *
+_POSIX_Semaphore_Get_interrupt_disable(
+ sem_t *id,
+ Objects_Locations *location,
+ ISR_lock_Context *lock_context
+)
+{
+ return (POSIX_Semaphore_Control *) _Objects_Get_isr_disable(
+ &_POSIX_Semaphore_Information,
+ (Objects_Id)*id,
+ location,
+ lock_context
+ );
+}
/**
* @brief POSIX Semaphore Create Support
diff --git a/cpukit/posix/src/sempost.c b/cpukit/posix/src/sempost.c
index f139c9a..9c8c673 100644
--- a/cpukit/posix/src/sempost.c
+++ b/cpukit/posix/src/sempost.c
@@ -37,8 +37,13 @@ int sem_post(
{
POSIX_Semaphore_Control *the_semaphore;
Objects_Locations location;
+ ISR_lock_Context lock_context;
- the_semaphore = _POSIX_Semaphore_Get( sem, &location );
+ the_semaphore = _POSIX_Semaphore_Get_interrupt_disable(
+ sem,
+ &location,
+ &lock_context
+ );
switch ( location ) {
case OBJECTS_LOCAL:
@@ -46,12 +51,12 @@ int sem_post(
&the_semaphore->Semaphore,
the_semaphore->Object.id,
#if defined(RTEMS_MULTIPROCESSING)
- NULL /* POSIX Semaphores are local only */
+ NULL, /* POSIX Semaphores are local only */
#else
- NULL
+ NULL,
#endif
+ &lock_context
);
- _Objects_Put( &the_semaphore->Object );
return 0;
#if defined(RTEMS_MULTIPROCESSING)
diff --git a/cpukit/rtems/src/semobtain.c b/cpukit/rtems/src/semobtain.c
index 0edac96..ca13bea 100644
--- a/cpukit/rtems/src/semobtain.c
+++ b/cpukit/rtems/src/semobtain.c
@@ -56,10 +56,10 @@ rtems_status_code rtems_semaphore_obtain(
attribute_set = the_semaphore->attribute_set;
wait = !_Options_Is_no_wait( option_set );
#if defined(RTEMS_SMP)
- _Thread_Disable_dispatch();
if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) {
MRSP_Status mrsp_status;
+ _Thread_Disable_dispatch();
_ISR_lock_ISR_enable( &lock_context );
mrsp_status = _MRSP_Obtain(
&the_semaphore->Core_control.mrsp,
@@ -73,6 +73,9 @@ rtems_status_code rtems_semaphore_obtain(
} else
#endif
if ( !_Attributes_Is_counting_semaphore( attribute_set ) ) {
+#if defined(RTEMS_SMP)
+ _Thread_Disable_dispatch();
+#endif
_CORE_mutex_Seize(
&the_semaphore->Core_control.mutex,
executing,
@@ -98,10 +101,6 @@ rtems_status_code rtems_semaphore_obtain(
timeout,
&lock_context
);
-#if defined(RTEMS_SMP)
- _Thread_Enable_dispatch();
-#endif
- _Objects_Put_for_get_isr_disable( &the_semaphore->Object );
return _Semaphore_Translate_core_semaphore_return_code(
executing->Wait.return_code );
diff --git a/cpukit/rtems/src/semrelease.c b/cpukit/rtems/src/semrelease.c
index 37a05b2..1f0581e 100644
--- a/cpukit/rtems/src/semrelease.c
+++ b/cpukit/rtems/src/semrelease.c
@@ -62,37 +62,46 @@ rtems_status_code rtems_semaphore_release(
CORE_mutex_Status mutex_status;
CORE_semaphore_Status semaphore_status;
rtems_attribute attribute_set;
+ ISR_lock_Context lock_context;
- the_semaphore = _Semaphore_Get( id, &location );
+ the_semaphore = _Semaphore_Get_interrupt_disable(
+ id,
+ &location,
+ &lock_context
+ );
switch ( location ) {
case OBJECTS_LOCAL:
attribute_set = the_semaphore->attribute_set;
#if defined(RTEMS_SMP)
if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) {
+ _Thread_Disable_dispatch();
+ _ISR_lock_ISR_enable( &lock_context );
MRSP_Status mrsp_status = _MRSP_Release(
&the_semaphore->Core_control.mrsp,
_Thread_Get_executing()
);
- _Objects_Put( &the_semaphore->Object );
+ _Thread_Enable_dispatch();
return _Semaphore_Translate_MRSP_status_code( mrsp_status );
} else
#endif
if ( !_Attributes_Is_counting_semaphore( attribute_set ) ) {
+ _Thread_Disable_dispatch();
+ _ISR_lock_ISR_enable( &lock_context );
mutex_status = _CORE_mutex_Surrender(
&the_semaphore->Core_control.mutex,
id,
MUTEX_MP_SUPPORT
);
- _Objects_Put( &the_semaphore->Object );
+ _Thread_Enable_dispatch();
return _Semaphore_Translate_core_mutex_return_code( mutex_status );
} else {
semaphore_status = _CORE_semaphore_Surrender(
&the_semaphore->Core_control.semaphore,
id,
- MUTEX_MP_SUPPORT
+ MUTEX_MP_SUPPORT,
+ &lock_context
);
- _Objects_Put( &the_semaphore->Object );
return
_Semaphore_Translate_core_semaphore_return_code( semaphore_status );
}
diff --git a/cpukit/score/include/rtems/score/coresemimpl.h b/cpukit/score/include/rtems/score/coresemimpl.h
index 3fdb4d1..6080766 100644
--- a/cpukit/score/include/rtems/score/coresemimpl.h
+++ b/cpukit/score/include/rtems/score/coresemimpl.h
@@ -141,13 +141,16 @@ RTEMS_INLINE_ROUTINE void _CORE_semaphore_Destroy(
* with this instance of a SuperCore Semaphore
* @param[in] api_semaphore_mp_support is the routine to invoke if the
* thread unblocked is remote
+ * @param[in] lock_context is a temporary variable used to contain the ISR
+ * disable level cookie
*
* @retval an indication of whether the routine succeeded or failed
*/
CORE_semaphore_Status _CORE_semaphore_Surrender(
CORE_semaphore_Control *the_semaphore,
Objects_Id id,
- CORE_semaphore_API_mp_support_callout api_semaphore_mp_support
+ CORE_semaphore_API_mp_support_callout api_semaphore_mp_support,
+ ISR_lock_Context *lock_context
);
/**
@@ -228,21 +231,20 @@ RTEMS_INLINE_ROUTINE void _CORE_semaphore_Seize_isr_disable(
/* disabled when you get here */
executing->Wait.return_code = CORE_SEMAPHORE_STATUS_SUCCESSFUL;
+ _Thread_queue_Acquire_critical( &the_semaphore->Wait_queue, lock_context );
if ( the_semaphore->count != 0 ) {
the_semaphore->count -= 1;
- _ISR_lock_ISR_enable( lock_context );
+ _Thread_queue_Release( &the_semaphore->Wait_queue, lock_context );
return;
}
if ( !wait ) {
- _ISR_lock_ISR_enable( lock_context );
+ _Thread_queue_Release( &the_semaphore->Wait_queue, lock_context );
executing->Wait.return_code = CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT;
return;
}
- _Thread_Disable_dispatch();
executing->Wait.id = id;
- _Thread_queue_Acquire_critical( &the_semaphore->Wait_queue, lock_context );
_Thread_queue_Enqueue_critical(
&the_semaphore->Wait_queue,
executing,
@@ -251,7 +253,6 @@ RTEMS_INLINE_ROUTINE void _CORE_semaphore_Seize_isr_disable(
CORE_SEMAPHORE_TIMEOUT,
lock_context
);
- _Thread_Enable_dispatch();
}
/** @} */
diff --git a/cpukit/score/src/coresemsurrender.c b/cpukit/score/src/coresemsurrender.c
index 58ba6a3..fbc088f 100644
--- a/cpukit/score/src/coresemsurrender.c
+++ b/cpukit/score/src/coresemsurrender.c
@@ -20,34 +20,46 @@
#endif
#include <rtems/score/coresemimpl.h>
-#include <rtems/score/objectimpl.h>
CORE_semaphore_Status _CORE_semaphore_Surrender(
CORE_semaphore_Control *the_semaphore,
Objects_Id id,
- CORE_semaphore_API_mp_support_callout api_semaphore_mp_support
+ CORE_semaphore_API_mp_support_callout api_semaphore_mp_support,
+ ISR_lock_Context *lock_context
)
{
Thread_Control *the_thread;
- ISR_Level level;
CORE_semaphore_Status status;
status = CORE_SEMAPHORE_STATUS_SUCCESSFUL;
- if ( (the_thread = _Thread_queue_Dequeue(&the_semaphore->Wait_queue)) ) {
+ _Thread_queue_Acquire_critical( &the_semaphore->Wait_queue, lock_context );
+
+ the_thread = _Thread_queue_First_locked( &the_semaphore->Wait_queue );
+ if ( the_thread != NULL ) {
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Dispatch_disable_critical();
+#endif
+
+ _Thread_queue_Extract_critical(
+ &the_semaphore->Wait_queue,
+ the_thread,
+ lock_context
+ );
#if defined(RTEMS_MULTIPROCESSING)
if ( !_Objects_Is_local_id( the_thread->Object.id ) )
(*api_semaphore_mp_support) ( the_thread, id );
-#endif
+ _Thread_Dispatch_enable( _Per_CPU_Get() );
+#endif
} else {
- _ISR_Disable( level );
- if ( the_semaphore->count < the_semaphore->Attributes.maximum_count )
- the_semaphore->count += 1;
- else
- status = CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED;
- _ISR_Enable( level );
+ if ( the_semaphore->count < the_semaphore->Attributes.maximum_count )
+ the_semaphore->count += 1;
+ else
+ status = CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED;
+
+ _Thread_queue_Release( &the_semaphore->Wait_queue, lock_context );
}
return status;
diff --git a/cpukit/score/src/mpci.c b/cpukit/score/src/mpci.c
index 7fd77f7..6b3bc7f 100644
--- a/cpukit/score/src/mpci.c
+++ b/cpukit/score/src/mpci.c
@@ -329,9 +329,10 @@ Thread _MPCI_Receive_server(
void _MPCI_Announce ( void )
{
- _Thread_Disable_dispatch();
- (void) _CORE_semaphore_Surrender( &_MPCI_Semaphore, 0, 0 );
- _Thread_Enable_dispatch();
+ ISR_lock_Context lock_context;
+
+ _ISR_lock_ISR_disable( &lock_context );
+ (void) _CORE_semaphore_Surrender( &_MPCI_Semaphore, 0, 0, &lock_context );
}
void _MPCI_Internal_packets_Send_process_packet (
--
1.8.4.5
More information about the devel
mailing list