File indexing completed on 2025-05-11 08:24:21
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 #ifdef HAVE_CONFIG_H
0038 #include "config.h"
0039 #endif
0040
0041 #include <rtems/posix/condimpl.h>
0042 #include <rtems/posix/posixapi.h>
0043 #include <rtems/score/assert.h>
0044 #include <rtems/score/statesimpl.h>
0045 #include <rtems/score/status.h>
0046 #include <rtems/score/threaddispatch.h>
0047
0048 static void _POSIX_Condition_variables_Mutex_unlock(
0049 Thread_queue_Queue *queue,
0050 Thread_Control *the_thread,
0051 Thread_queue_Context *queue_context
0052 )
0053 {
0054 POSIX_Condition_variables_Control *the_cond;
0055 int mutex_error;
0056
0057 the_cond = POSIX_CONDITION_VARIABLE_OF_THREAD_QUEUE_QUEUE( queue );
0058
0059 mutex_error = pthread_mutex_unlock( the_cond->mutex );
0060 if ( mutex_error != 0 ) {
0061
0062
0063
0064
0065
0066 _Assert( mutex_error == EINVAL || mutex_error == EPERM );
0067 _Thread_Continue( the_thread, STATUS_NOT_OWNER );
0068 }
0069 }
0070
0071 static void _POSIX_Condition_variables_Enqueue_no_timeout(
0072 Thread_queue_Queue *queue,
0073 Thread_Control *the_thread,
0074 Per_CPU_Control *cpu_self,
0075 Thread_queue_Context *queue_context
0076 )
0077 {
0078 _POSIX_Condition_variables_Mutex_unlock( queue, the_thread, queue_context );
0079 }
0080
0081 static void _POSIX_Condition_variables_Enqueue_with_timeout_monotonic(
0082 Thread_queue_Queue *queue,
0083 Thread_Control *the_thread,
0084 Per_CPU_Control *cpu_self,
0085 Thread_queue_Context *queue_context
0086 )
0087 {
0088 _Thread_queue_Add_timeout_monotonic_timespec(
0089 queue,
0090 the_thread,
0091 cpu_self,
0092 queue_context
0093 );
0094 _POSIX_Condition_variables_Mutex_unlock( queue, the_thread, queue_context );
0095 }
0096
0097 static void _POSIX_Condition_variables_Enqueue_with_timeout_realtime(
0098 Thread_queue_Queue *queue,
0099 Thread_Control *the_thread,
0100 Per_CPU_Control *cpu_self,
0101 Thread_queue_Context *queue_context
0102 )
0103 {
0104 _Thread_queue_Add_timeout_realtime_timespec(
0105 queue,
0106 the_thread,
0107 cpu_self,
0108 queue_context
0109 );
0110 _POSIX_Condition_variables_Mutex_unlock( queue, the_thread, queue_context );
0111 }
0112
0113 int _POSIX_Condition_variables_Wait_support(
0114 pthread_cond_t *cond,
0115 pthread_mutex_t *mutex,
0116 const struct timespec *abstime
0117 )
0118 {
0119 POSIX_Condition_variables_Control *the_cond;
0120 unsigned long flags;
0121 Thread_queue_Context queue_context;
0122 int error;
0123 Thread_Control *executing;
0124
0125 the_cond = _POSIX_Condition_variables_Get( cond );
0126 POSIX_CONDITION_VARIABLES_VALIDATE_OBJECT( the_cond, flags );
0127
0128 _Thread_queue_Context_initialize( &queue_context );
0129
0130 if ( abstime != NULL ) {
0131 _Thread_queue_Context_set_timeout_argument( &queue_context, abstime, true );
0132
0133 if ( _POSIX_Condition_variables_Get_clock( flags ) == CLOCK_MONOTONIC ) {
0134 _Thread_queue_Context_set_enqueue_callout(
0135 &queue_context,
0136 _POSIX_Condition_variables_Enqueue_with_timeout_monotonic
0137 );
0138 } else {
0139 _Thread_queue_Context_set_enqueue_callout(
0140 &queue_context,
0141 _POSIX_Condition_variables_Enqueue_with_timeout_realtime
0142 );
0143 }
0144 } else {
0145 _Thread_queue_Context_set_enqueue_callout(
0146 &queue_context,
0147 _POSIX_Condition_variables_Enqueue_no_timeout
0148 );
0149 }
0150
0151 executing = _POSIX_Condition_variables_Acquire( the_cond, &queue_context );
0152
0153 if (
0154 the_cond->mutex != POSIX_CONDITION_VARIABLES_NO_MUTEX
0155 && the_cond->mutex != mutex
0156 ) {
0157 _POSIX_Condition_variables_Release( the_cond, &queue_context );
0158 return EINVAL;
0159 }
0160
0161 the_cond->mutex = mutex;
0162
0163 _Thread_queue_Context_set_thread_state(
0164 &queue_context,
0165 STATES_WAITING_FOR_CONDITION_VARIABLE
0166 );
0167 _Thread_queue_Enqueue(
0168 &the_cond->Queue.Queue,
0169 POSIX_CONDITION_VARIABLES_TQ_OPERATIONS,
0170 executing,
0171 &queue_context
0172 );
0173 error = _POSIX_Get_error_after_wait( executing );
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183 if ( error == EINTR ) {
0184 error = 0;
0185 }
0186
0187
0188
0189
0190
0191 if ( error != EPERM ) {
0192 int mutex_error;
0193
0194 mutex_error = pthread_mutex_lock( mutex );
0195 if ( mutex_error != 0 ) {
0196 _Assert( mutex_error == EINVAL );
0197 error = EINVAL;
0198 }
0199 }
0200
0201 return error;
0202 }