summaryrefslogtreecommitdiffstats
path: root/c/src/exec/rtems/src/sem.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/exec/rtems/src/sem.c')
-rw-r--r--c/src/exec/rtems/src/sem.c451
1 files changed, 265 insertions, 186 deletions
diff --git a/c/src/exec/rtems/src/sem.c b/c/src/exec/rtems/src/sem.c
index 9e87550c31..9ba1634164 100644
--- a/c/src/exec/rtems/src/sem.c
+++ b/c/src/exec/rtems/src/sem.c
@@ -27,17 +27,22 @@
*/
#include <rtems/system.h>
-#include <rtems/support.h>
-#include <rtems/attr.h>
-#include <rtems/config.h>
-#include <rtems/isr.h>
-#include <rtems/object.h>
-#include <rtems/options.h>
-#include <rtems/sem.h>
-#include <rtems/states.h>
-#include <rtems/thread.h>
-#include <rtems/threadq.h>
-#include <rtems/mpci.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/core/isr.h>
+#include <rtems/core/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/sem.h>
+#include <rtems/core/coremutex.h>
+#include <rtems/core/coresem.h>
+#include <rtems/core/states.h>
+#include <rtems/core/thread.h>
+#include <rtems/core/threadq.h>
+#include <rtems/core/mpci.h>
+#include <rtems/sysstate.h>
+
+#include <rtems/core/interr.h>
/*PAGE
*
@@ -65,6 +70,16 @@ void _Semaphore_Manager_initialization(
RTEMS_MAXIMUM_NAME_LENGTH,
FALSE
);
+
+ /*
+ * Register the MP Process Packet routine.
+ */
+
+ _MPCI_Register_packet_processor(
+ MP_PACKET_SEMAPHORE,
+ _Semaphore_MP_Process_packet
+ );
+
}
/*PAGE
@@ -75,10 +90,11 @@ void _Semaphore_Manager_initialization(
* on the given count. A semaphore id is returned.
*
* Input parameters:
- * name - user defined semaphore name
- * count - initial count of semaphore
- * attribute_set - semaphore attributes
- * id - pointer to semaphore id
+ * name - user defined semaphore name
+ * count - initial count of semaphore
+ * attribute_set - semaphore attributes
+ * priority_ceiling - semaphore's ceiling priority
+ * id - pointer to semaphore id
*
* Output parameters:
* id - semaphore id
@@ -87,21 +103,24 @@ void _Semaphore_Manager_initialization(
*/
rtems_status_code rtems_semaphore_create(
- rtems_name name,
- unsigned32 count,
- rtems_attribute attribute_set,
- rtems_task_priority priority_ceiling,
- Objects_Id *id
+ rtems_name name,
+ unsigned32 count,
+ rtems_attribute attribute_set,
+ rtems_task_priority priority_ceiling,
+ Objects_Id *id
)
{
register Semaphore_Control *the_semaphore;
+ CORE_mutex_Attributes the_mutex_attributes;
+ CORE_semaphore_Attributes the_semaphore_attributes;
+ unsigned32 lock;
if ( !rtems_is_name_valid( name ) )
return ( RTEMS_INVALID_NAME );
if ( _Attributes_Is_global( attribute_set ) ) {
- if ( !_Configuration_Is_multiprocessing() )
+ if ( !_System_state_Is_multiprocessing )
return( RTEMS_MP_NOT_CONFIGURED );
if ( _Attributes_Is_inherit_priority( attribute_set ) )
@@ -128,7 +147,7 @@ rtems_status_code rtems_semaphore_create(
}
if ( _Attributes_Is_global( attribute_set ) &&
- !( _Objects_MP_Allocate_and_open( &_Semaphore_Information, name,
+ ! ( _Objects_MP_Allocate_and_open( &_Semaphore_Information, name,
the_semaphore->Object.id, FALSE ) ) ) {
_Semaphore_Free( the_semaphore );
_Thread_Enable_dispatch();
@@ -136,27 +155,48 @@ rtems_status_code rtems_semaphore_create(
}
the_semaphore->attribute_set = attribute_set;
- the_semaphore->count = count;
-
- if ( _Attributes_Is_binary_semaphore( attribute_set ) && count == 0 ) {
- the_semaphore->nest_count = 1;
- the_semaphore->holder = _Thread_Executing;
- the_semaphore->holder_id = _Thread_Executing->Object.id;
- _Thread_Executing->resource_count++;
- } else {
- the_semaphore->nest_count = 0;
- the_semaphore->holder = NULL;
- the_semaphore->holder_id = 0;
- }
- _Thread_queue_Initialize(
- &the_semaphore->Wait_queue,
- OBJECTS_RTEMS_SEMAPHORES,
- _Attributes_Is_priority( attribute_set ) ?
- THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO,
- STATES_WAITING_FOR_SEMAPHORE,
- _Semaphore_MP_Send_extract_proxy
- );
+ if ( _Attributes_Is_binary_semaphore( attribute_set ) ) {
+ if ( _Attributes_Is_inherit_priority( attribute_set ) )
+ the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
+ else if (_Attributes_Is_priority_ceiling( attribute_set ) )
+ the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
+ else if (_Attributes_Is_priority( attribute_set ) )
+ the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY;
+ else
+ the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_FIFO;
+
+ the_mutex_attributes.allow_nesting = TRUE;
+
+ /* Add priority ceiling code here ????? */
+
+ if ( count == 1 )
+ lock = CORE_MUTEX_UNLOCKED;
+ else
+ lock = CORE_MUTEX_LOCKED;
+
+ _CORE_mutex_Initialize(
+ &the_semaphore->Core_control.mutex,
+ OBJECTS_RTEMS_SEMAPHORES,
+ &the_mutex_attributes,
+ lock,
+ _Semaphore_MP_Send_extract_proxy
+ );
+ }
+ else {
+ if ( _Attributes_Is_priority( attribute_set ) )
+ the_semaphore_attributes.discipline = CORE_SEMAPHORE_DISCIPLINES_PRIORITY;
+ else
+ the_semaphore_attributes.discipline = CORE_SEMAPHORE_DISCIPLINES_FIFO;
+
+ _CORE_semaphore_Initialize(
+ &the_semaphore->Core_control.semaphore,
+ OBJECTS_RTEMS_SEMAPHORES,
+ &the_semaphore_attributes,
+ count,
+ _Semaphore_MP_Send_extract_proxy
+ );
+ }
_Objects_Open( &_Semaphore_Information, &the_semaphore->Object, &name );
@@ -192,12 +232,16 @@ rtems_status_code rtems_semaphore_create(
*/
rtems_status_code rtems_semaphore_ident(
- rtems_name name,
- unsigned32 node,
- Objects_Id *id
+ rtems_name name,
+ unsigned32 node,
+ Objects_Id *id
)
{
- return( _Objects_Name_to_id( &_Semaphore_Information, &name, node, id ) );
+ Objects_Name_to_id_errors status;
+
+ status = _Objects_Name_to_id( &_Semaphore_Information, &name, node, id );
+
+ return _Status_Object_name_errors_to_status[ status ];
}
/*PAGE
@@ -231,19 +275,27 @@ rtems_status_code rtems_semaphore_delete(
_Thread_Dispatch();
return( RTEMS_ILLEGAL_ON_REMOTE_OBJECT );
case OBJECTS_LOCAL:
- if ( _Attributes_Is_binary_semaphore( the_semaphore->attribute_set) &&
- ( the_semaphore->count == 0 ) ) {
- _Thread_Enable_dispatch();
- return( RTEMS_RESOURCE_IN_USE );
+ if ( _Attributes_Is_binary_semaphore( the_semaphore->attribute_set) ) {
+ if ( _CORE_mutex_Is_locked( &the_semaphore->Core_control.mutex ) ) {
+ _Thread_Enable_dispatch();
+ return( RTEMS_RESOURCE_IN_USE );
+ }
+ else
+ _CORE_mutex_Flush(
+ &the_semaphore->Core_control.mutex,
+ _Semaphore_MP_Send_object_was_deleted,
+ CORE_MUTEX_WAS_DELETED
+ );
}
+ else
+ _CORE_semaphore_Flush(
+ &the_semaphore->Core_control.semaphore,
+ _Semaphore_MP_Send_object_was_deleted,
+ CORE_SEMAPHORE_WAS_DELETED
+ );
_Objects_Close( &_Semaphore_Information, &the_semaphore->Object );
- _Thread_queue_Flush(
- &the_semaphore->Wait_queue,
- _Semaphore_MP_Send_object_was_deleted
- );
-
_Semaphore_Free( the_semaphore );
if ( _Attributes_Is_global( the_semaphore->attribute_set ) ) {
@@ -281,13 +333,14 @@ rtems_status_code rtems_semaphore_delete(
*/
rtems_status_code rtems_semaphore_obtain(
- Objects_Id id,
- unsigned32 option_set,
- rtems_interval timeout
+ Objects_Id id,
+ unsigned32 option_set,
+ rtems_interval timeout
)
{
register Semaphore_Control *the_semaphore;
Objects_Locations location;
+ boolean wait;
the_semaphore = _Semaphore_Get( id, &location );
switch ( location ) {
@@ -301,17 +354,32 @@ rtems_status_code rtems_semaphore_obtain(
timeout
);
case OBJECTS_LOCAL:
- if ( !_Semaphore_Seize( the_semaphore, option_set ) ) {
- if ( _Attributes_Is_inherit_priority( the_semaphore->attribute_set ) &&
- the_semaphore->holder->current_priority >
- _Thread_Executing->current_priority ) {
- _Thread_Change_priority(
- the_semaphore->holder, _Thread_Executing->current_priority );
- }
- _Thread_queue_Enqueue( &the_semaphore->Wait_queue, timeout );
+ if ( _Options_Is_no_wait( option_set ) )
+ wait = FALSE;
+ else
+ wait = TRUE;
+
+ if ( _Attributes_Is_binary_semaphore( the_semaphore->attribute_set ) ) {
+ _CORE_mutex_Seize(
+ &the_semaphore->Core_control.mutex,
+ id,
+ wait,
+ timeout
+ );
+ _Thread_Enable_dispatch();
+ return( _Semaphore_Translate_core_mutex_return_code(
+ _Thread_Executing->Wait.return_code ) );
+ } else {
+ _CORE_semaphore_Seize(
+ &the_semaphore->Core_control.semaphore,
+ id,
+ wait,
+ timeout
+ );
+ _Thread_Enable_dispatch();
+ return( _Semaphore_Translate_core_semaphore_return_code(
+ _Thread_Executing->Wait.return_code ) );
}
- _Thread_Enable_dispatch();
- return( _Thread_Executing->Wait.return_code );
}
return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */
@@ -337,7 +405,8 @@ rtems_status_code rtems_semaphore_release(
{
register Semaphore_Control *the_semaphore;
Objects_Locations location;
- Thread_Control *the_thread;
+ CORE_mutex_Status mutex_status;
+ CORE_semaphore_Status semaphore_status;
the_semaphore = _Semaphore_Get( id, &location );
switch ( location ) {
@@ -353,143 +422,153 @@ rtems_status_code rtems_semaphore_release(
)
);
case OBJECTS_LOCAL:
- if ( _Attributes_Is_binary_semaphore( the_semaphore->attribute_set)) {
-
- if ( !_Objects_Are_ids_equal(
- _Thread_Executing->Object.id, the_semaphore->holder_id ) ) {
- _Thread_Enable_dispatch();
- return( RTEMS_NOT_OWNER_OF_RESOURCE );
- }
-
- the_semaphore->nest_count--;
-
- if ( the_semaphore->nest_count != 0 ) {
- _Thread_Enable_dispatch();
- return( RTEMS_SUCCESSFUL );
- }
-
- _Thread_Executing->resource_count--;
- the_semaphore->holder = NULL;
- the_semaphore->holder_id = 0;
-
- /*
- * Whether or not someone is waiting for the semaphore, an
- * inherited priority must be lowered if this is the last
- * semaphore (i.e. resource) this task has.
- */
-
- if ( _Attributes_Is_inherit_priority(the_semaphore->attribute_set) &&
- _Thread_Executing->resource_count == 0 &&
- _Thread_Executing->real_priority !=
- _Thread_Executing->current_priority ) {
- _Thread_Change_priority(
- _Thread_Executing, _Thread_Executing->real_priority );
- }
-
+ if ( _Attributes_Is_binary_semaphore( the_semaphore->attribute_set ) ) {
+ mutex_status = _CORE_mutex_Surrender(
+ &the_semaphore->Core_control.mutex,
+ id,
+ _Semaphore_Core_mutex_mp_support
+ );
+ _Thread_Enable_dispatch();
+ return( _Semaphore_Translate_core_mutex_return_code( mutex_status ) );
}
+ else
+ semaphore_status = _CORE_semaphore_Surrender(
+ &the_semaphore->Core_control.semaphore,
+ id,
+ _Semaphore_Core_semaphore_mp_support
+ );
+ _Thread_Enable_dispatch();
+ return(
+ _Semaphore_Translate_core_semaphore_return_code( semaphore_status ) );
+ }
- if ( (the_thread = _Thread_queue_Dequeue(&the_semaphore->Wait_queue)) ) {
-
- if ( !_Objects_Is_local_id( the_thread->Object.id ) ) {
- the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL;
-
- if ( _Attributes_Is_binary_semaphore(the_semaphore->attribute_set) ) {
- the_semaphore->holder = NULL;
- the_semaphore->holder_id = the_thread->Object.id;
- the_semaphore->nest_count = 1;
- }
-
- _Semaphore_MP_Send_response_packet(
- SEMAPHORE_MP_OBTAIN_RESPONSE,
- id,
- the_thread
- );
- } else {
-
- if ( _Attributes_Is_binary_semaphore(the_semaphore->attribute_set) ) {
- the_semaphore->holder = the_thread;
- the_semaphore->holder_id = the_thread->Object.id;
- the_thread->resource_count++;
- the_semaphore->nest_count = 1;
- }
-
- /*
- * No special action for priority inheritance because the_thread
- * is guaranteed to be the highest priority thread waiting for
- * the semaphore.
- */
- }
- } else
- the_semaphore->count += 1;
+ return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */
+}
- _Thread_Enable_dispatch();
+/*PAGE
+ *
+ * _Semaphore_Translate_core_mutex_return_code
+ *
+ * Input parameters:
+ * the_mutex_status - mutex status code to translate
+ *
+ * Output parameters:
+ * rtems status code - translated RTEMS status code
+ *
+ */
+
+rtems_status_code _Semaphore_Translate_core_mutex_return_code (
+ unsigned32 the_mutex_status
+)
+{
+ switch ( the_mutex_status ) {
+ case CORE_MUTEX_STATUS_SUCCESSFUL:
return( RTEMS_SUCCESSFUL );
+ case CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT:
+ return( RTEMS_UNSATISFIED );
+ case CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED:
+ return( RTEMS_INTERNAL_ERROR );
+ case CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE:
+ return( RTEMS_NOT_OWNER_OF_RESOURCE );
+ case CORE_MUTEX_WAS_DELETED:
+ return( RTEMS_OBJECT_WAS_DELETED );
+ case CORE_MUTEX_TIMEOUT:
+ return( RTEMS_TIMEOUT );
+ case THREAD_STATUS_PROXY_BLOCKING:
+ return( THREAD_STATUS_PROXY_BLOCKING );
}
-
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_RTEMS_API,
+ TRUE,
+ the_mutex_status
+ );
return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */
}
/*PAGE
*
- * _Semaphore_Seize
- *
- * This routine attempts to allocate a semaphore to the calling thread.
+ * _Semaphore_Translate_core_semaphore_return_code
*
* Input parameters:
- * the_semaphore - pointer to semaphore control block
- * option_set - acquire semaphore options
+ * the_semaphore_status - semaphore status code to translate
*
* Output parameters:
- * TRUE - if semaphore allocated
- * FALSE - if semaphore NOT allocated
+ * rtems status code - translated RTEMS status code
*
- * INTERRUPT LATENCY:
- * available
- * wait
*/
-
-boolean _Semaphore_Seize(
- Semaphore_Control *the_semaphore,
- rtems_option option_set
+
+rtems_status_code _Semaphore_Translate_core_semaphore_return_code (
+ unsigned32 the_semaphore_status
)
{
- Thread_Control *executing;
- ISR_Level level;
-
- executing = _Thread_Executing;
- executing->Wait.return_code = RTEMS_SUCCESSFUL;
- _ISR_Disable( level );
- if ( the_semaphore->count != 0 ) {
- the_semaphore->count -= 1;
- if ( _Attributes_Is_binary_semaphore( the_semaphore->attribute_set ) ) {
- the_semaphore->holder = executing;
- the_semaphore->holder_id = executing->Object.id;
- the_semaphore->nest_count = 1;
- executing->resource_count++;
- }
- _ISR_Enable( level );
- return( TRUE );
+ switch ( the_semaphore_status ) {
+ case CORE_SEMAPHORE_STATUS_SUCCESSFUL:
+ return( RTEMS_SUCCESSFUL );
+ case CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT:
+ return( RTEMS_UNSATISFIED );
+ case CORE_SEMAPHORE_WAS_DELETED:
+ return( RTEMS_OBJECT_WAS_DELETED );
+ case CORE_SEMAPHORE_TIMEOUT:
+ return( RTEMS_TIMEOUT );
+ case THREAD_STATUS_PROXY_BLOCKING:
+ return( THREAD_STATUS_PROXY_BLOCKING );
}
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_RTEMS_API,
+ TRUE,
+ the_semaphore_status
+ );
+ return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */
+ return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */
+}
- if ( _Options_Is_no_wait( option_set ) ) {
- _ISR_Enable( level );
- executing->Wait.return_code = RTEMS_UNSATISFIED;
- return( TRUE );
- }
+/*PAGE
+ *
+ * _Semaphore_Core_mutex_mp_support
+ *
+ * Input parameters:
+ * the_thread - the remote thread the semaphore was surrendered to
+ * id - id of the surrendered semaphore
+ *
+ * Output parameters: NONE
+ */
+
+void _Semaphore_Core_mutex_mp_support (
+ Thread_Control *the_thread,
+ Objects_Id id
+)
+{
+ the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL;
+
+ _Semaphore_MP_Send_response_packet(
+ SEMAPHORE_MP_OBTAIN_RESPONSE,
+ id,
+ the_thread
+ );
+}
- if ( _Attributes_Is_binary_semaphore( the_semaphore->attribute_set ) ) {
- if ( _Objects_Are_ids_equal(
- _Thread_Executing->Object.id, the_semaphore->holder_id ) ) {
- the_semaphore->nest_count++;
- _ISR_Enable( level );
- return( TRUE );
- }
- }
- the_semaphore->Wait_queue.sync = TRUE;
- executing->Wait.queue = &the_semaphore->Wait_queue;
- executing->Wait.id = the_semaphore->Object.id;
- executing->Wait.option_set = option_set;
- _ISR_Enable( level );
- return( FALSE );
+/*PAGE
+ *
+ * _Semaphore_Core_semaphore_mp_support
+ *
+ * Input parameters:
+ * the_thread - the remote thread the semaphore was surrendered to
+ * id - id of the surrendered semaphore
+ *
+ * Output parameters: NONE
+ */
+
+void _Semaphore_Core_semaphore_mp_support (
+ Thread_Control *the_thread,
+ Objects_Id id
+)
+{
+ the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL;
+
+ _Semaphore_MP_Send_response_packet(
+ SEMAPHORE_MP_OBTAIN_RESPONSE,
+ id,
+ the_thread
+ );
}