File indexing completed on 2025-05-11 08:24:22
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 #ifdef HAVE_CONFIG_H
0039 #include "config.h"
0040 #endif
0041
0042 #include <rtems/rtems/semimpl.h>
0043 #include <rtems/rtems/optionsimpl.h>
0044 #include <rtems/rtems/statusimpl.h>
0045
0046 THREAD_QUEUE_OBJECT_ASSERT(
0047 Semaphore_Control,
0048 Core_control.Wait_queue,
0049 SEMAPHORE_CONTROL_GENERIC
0050 );
0051
0052 THREAD_QUEUE_OBJECT_ASSERT(
0053 Semaphore_Control,
0054 Core_control.Mutex.Recursive.Mutex.Wait_queue,
0055 SEMAPHORE_CONTROL_MUTEX
0056 );
0057
0058 THREAD_QUEUE_OBJECT_ASSERT(
0059 Semaphore_Control,
0060 Core_control.Semaphore.Wait_queue,
0061 SEMAPHORE_CONTROL_SEMAPHORE
0062 );
0063
0064 #if defined(RTEMS_SMP)
0065 THREAD_QUEUE_OBJECT_ASSERT(
0066 Semaphore_Control,
0067 Core_control.MRSP.Wait_queue,
0068 SEMAPHORE_CONTROL_MRSP
0069 );
0070 #endif
0071
0072 rtems_status_code rtems_semaphore_obtain(
0073 rtems_id id,
0074 rtems_option option_set,
0075 rtems_interval timeout
0076 )
0077 {
0078 Semaphore_Control *the_semaphore;
0079 Thread_queue_Context queue_context;
0080 Thread_Control *executing;
0081 bool wait;
0082 uintptr_t flags;
0083 Semaphore_Variant variant;
0084 Status_Control status;
0085
0086 the_semaphore = _Semaphore_Get( id, &queue_context );
0087
0088 if ( the_semaphore == NULL ) {
0089 #if defined(RTEMS_MULTIPROCESSING)
0090 return _Semaphore_MP_Obtain( id, option_set, timeout );
0091 #else
0092 return RTEMS_INVALID_ID;
0093 #endif
0094 }
0095
0096 executing = _Thread_Executing;
0097 wait = !_Options_Is_no_wait( option_set );
0098
0099 if ( wait ) {
0100 _Thread_queue_Context_set_enqueue_timeout_ticks( &queue_context, timeout );
0101 } else {
0102 _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
0103 }
0104
0105 flags = _Semaphore_Get_flags( the_semaphore );
0106 variant = _Semaphore_Get_variant( flags );
0107
0108 switch ( variant ) {
0109 case SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY:
0110 status = _CORE_recursive_mutex_Seize(
0111 &the_semaphore->Core_control.Mutex.Recursive,
0112 CORE_MUTEX_TQ_PRIORITY_INHERIT_OPERATIONS,
0113 executing,
0114 wait,
0115 _CORE_recursive_mutex_Seize_nested,
0116 &queue_context
0117 );
0118 break;
0119 case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING:
0120 status = _CORE_ceiling_mutex_Seize(
0121 &the_semaphore->Core_control.Mutex,
0122 executing,
0123 wait,
0124 _CORE_recursive_mutex_Seize_nested,
0125 &queue_context
0126 );
0127 break;
0128 case SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL:
0129 status = _CORE_recursive_mutex_Seize(
0130 &the_semaphore->Core_control.Mutex.Recursive,
0131 _Semaphore_Get_operations( flags ),
0132 executing,
0133 wait,
0134 _CORE_recursive_mutex_Seize_nested,
0135 &queue_context
0136 );
0137 break;
0138 #if defined(RTEMS_SMP)
0139 case SEMAPHORE_VARIANT_MRSP:
0140 status = _MRSP_Seize(
0141 &the_semaphore->Core_control.MRSP,
0142 executing,
0143 wait,
0144 &queue_context
0145 );
0146 break;
0147 #endif
0148 default:
0149 _Assert(
0150 variant == SEMAPHORE_VARIANT_SIMPLE_BINARY
0151 || variant == SEMAPHORE_VARIANT_COUNTING
0152 );
0153 status = _CORE_semaphore_Seize(
0154 &the_semaphore->Core_control.Semaphore,
0155 _Semaphore_Get_operations( flags ),
0156 executing,
0157 wait,
0158 &queue_context
0159 );
0160 break;
0161 }
0162
0163 return _Status_Get( status );
0164 }