Changeset 98dca75 in rtems
- Timestamp:
- 11/02/99 18:25:26 (24 years ago)
- Branches:
- 4.10, 4.11, 4.8, 4.9, 5, master
- Children:
- 9f95a19
- Parents:
- 799c767
- Files:
-
- 24 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
c/src/exec/posix/include/rtems/posix/cond.h
r799c767 r98dca75 49 49 50 50 POSIX_EXTERN Objects_Information _POSIX_Condition_variables_Information; 51 52 /* 53 * The default condition variable attributes structure. 54 */ 55 56 extern const pthread_condattr_t _POSIX_Condition_variables_Default_attributes; 51 57 52 58 /* … … 119 125 ); 120 126 127 /* 128 * _POSIX_Condition_variables_Signal_support 129 * 130 * DESCRIPTION: 131 * 132 * A support routine which implements guts of the broadcast and single task 133 * wake up version of the "signal" operation. 134 */ 135 136 int _POSIX_Condition_variables_Signal_support( 137 pthread_cond_t *cond, 138 boolean is_broadcast 139 ); 140 141 /* 142 * _POSIX_Condition_variables_Wait_support 143 * 144 * DESCRIPTION: 145 * 146 * A support routine which implements guts of the blocking, non-blocking, and 147 * timed wait version of condition variable wait routines. 148 */ 149 150 int _POSIX_Condition_variables_Wait_support( 151 pthread_cond_t *cond, 152 pthread_mutex_t *mutex, 153 Watchdog_Interval timeout, 154 boolean already_timedout 155 ); 156 121 157 #include <rtems/posix/cond.inl> 122 158 #if defined(RTEMS_MULTIPROCESSING) -
c/src/exec/posix/src/Makefile.in
r799c767 r98dca75 23 23 wait waitpid 24 24 25 MESSAGE_QUEUE_PIECES= mqueue mqueueclose mqueuecreatesupp mqueuedeletesupp \ 25 CONDITION_VARIABLE_C_PIECES= cond condattrdestroy condattrgetpshared \ 26 condattrinit condattrsetpshared condbroadcast conddefaultattributes \ 27 condmp condsignal condsignalsupp condtimedwait condwait condwaitsupp 28 29 MESSAGE_QUEUE_C_PIECES= mqueue mqueueclose mqueuecreatesupp mqueuedeletesupp \ 26 30 mqueuegetattr mqueuenametoid mqueuenotify mqueueopen mqueuereceive \ 27 31 mqueuerecvsupp mqueuesend mqueuesendsupp mqueuesetattr \ … … 59 63 semunlink semwait 60 64 61 C_PIECES = adasupp cond getpid key $(MESSAGE_QUEUE_PIECES) \ 65 C_PIECES = adasupp $(CONDITION_VARIABLE_C_PIECES) \ 66 getpid key $(MESSAGE_QUEUE_C_PIECES) \ 62 67 $(MUTEX_C_PIECES) $(PTHREAD_C_PIECES) \ 63 68 $(PSIGNAL_C_PIECES) ptimer sched $(SEMAPHORE_C_PIECES) \ -
c/src/exec/posix/src/cond.c
r799c767 r98dca75 14 14 #include <rtems/posix/mutex.h> 15 15 16 /*17 * TEMPORARY18 */19 20 21 #if defined(RTEMS_MULTIPROCESSING)22 void _POSIX_Condition_variables_MP_Send_process_packet (23 POSIX_Condition_variables_MP_Remote_operations operation,24 Objects_Id condition_variables_id,25 Objects_Name name,26 Objects_Id proxy_id27 )28 {29 (void) POSIX_MP_NOT_IMPLEMENTED();30 }31 32 void _POSIX_Condition_variables_MP_Send_extract_proxy(33 Thread_Control *the_thread34 )35 {36 (void) POSIX_MP_NOT_IMPLEMENTED();37 }38 #endif39 40 /*41 * END OF TEMPORARY42 */43 44 /*PAGE45 *46 * The default condition variable attributes structure.47 */48 49 const pthread_condattr_t _POSIX_Condition_variables_Default_attributes = {50 TRUE, /* is_initialized */51 PTHREAD_PROCESS_PRIVATE /* process_shared */52 };53 54 16 /*PAGE 55 17 * … … 80 42 ); 81 43 } 82 83 /*PAGE84 *85 * 11.4.1 Condition Variable Initialization Attributes,86 * P1003.1c/Draft 10, p. 9687 */88 89 int pthread_condattr_init(90 pthread_condattr_t *attr91 )92 {93 if ( !attr )94 return EINVAL;95 96 *attr = _POSIX_Condition_variables_Default_attributes;97 return 0;98 }99 100 /*PAGE101 *102 * 11.4.1 Condition Variable Initialization Attributes,103 * P1003.1c/Draft 10, p. 96104 */105 106 int pthread_condattr_destroy(107 pthread_condattr_t *attr108 )109 {110 if ( !attr || attr->is_initialized == FALSE )111 return EINVAL;112 113 attr->is_initialized = FALSE;114 return 0;115 }116 117 /*PAGE118 *119 * 11.4.1 Condition Variable Initialization Attributes,120 * P1003.1c/Draft 10, p. 96121 */122 123 int pthread_condattr_getpshared(124 const pthread_condattr_t *attr,125 int *pshared126 )127 {128 if ( !attr )129 return EINVAL;130 131 *pshared = attr->process_shared;132 return 0;133 }134 135 /*PAGE136 *137 * 11.4.1 Condition Variable Initialization Attributes,138 * P1003.1c/Draft 10, p. 96139 */140 141 int pthread_condattr_setpshared(142 pthread_condattr_t *attr,143 int pshared144 )145 {146 if ( !attr )147 return EINVAL;148 149 switch ( pshared ) {150 case PTHREAD_PROCESS_SHARED:151 case PTHREAD_PROCESS_PRIVATE:152 attr->process_shared = pshared;153 return 0;154 155 default:156 return EINVAL;157 }158 }159 160 /*PAGE161 *162 * 11.4.2 Initializing and Destroying a Condition Variable,163 * P1003.1c/Draft 10, p. 87164 */165 166 int pthread_cond_init(167 pthread_cond_t *cond,168 const pthread_condattr_t *attr169 )170 {171 POSIX_Condition_variables_Control *the_cond;172 const pthread_condattr_t *the_attr;173 174 if ( attr ) the_attr = attr;175 else the_attr = &_POSIX_Condition_variables_Default_attributes;176 177 /*178 * XXX: Be careful about attributes when global!!!179 */180 181 if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )182 return POSIX_MP_NOT_IMPLEMENTED();183 184 if ( !the_attr->is_initialized )185 return EINVAL;186 187 _Thread_Disable_dispatch();188 189 the_cond = _POSIX_Condition_variables_Allocate();190 191 if ( !the_cond ) {192 _Thread_Enable_dispatch();193 return ENOMEM;194 }195 196 #if defined(RTEMS_MULTIPROCESSING)197 if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED &&198 !( _Objects_MP_Allocate_and_open( &_POSIX_Condition_variables_Information,199 0, the_cond->Object.id, FALSE ) ) ) {200 _POSIX_Condition_variables_Free( the_cond );201 _Thread_Enable_dispatch();202 return EAGAIN;203 }204 #endif205 206 the_cond->process_shared = the_attr->process_shared;207 208 the_cond->Mutex = POSIX_CONDITION_VARIABLES_NO_MUTEX;209 210 /* XXX some more initialization might need to go here */211 _Thread_queue_Initialize(212 &the_cond->Wait_queue,213 OBJECTS_POSIX_CONDITION_VARIABLES,214 THREAD_QUEUE_DISCIPLINE_FIFO,215 STATES_WAITING_FOR_CONDITION_VARIABLE,216 #if defined(RTEMS_MULTIPROCESSING)217 _POSIX_Condition_variables_MP_Send_extract_proxy,218 #else219 NULL,220 #endif221 ETIMEDOUT222 );223 224 _Objects_Open(225 &_POSIX_Condition_variables_Information,226 &the_cond->Object,227 0228 );229 230 *cond = the_cond->Object.id;231 232 #if defined(RTEMS_MULTIPROCESSING)233 if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )234 _POSIX_Condition_variables_MP_Send_process_packet(235 POSIX_CONDITION_VARIABLES_MP_ANNOUNCE_CREATE,236 the_cond->Object.id,237 0, /* Name not used */238 0 /* Not used */239 );240 #endif241 242 _Thread_Enable_dispatch();243 244 return 0;245 }246 247 /*PAGE248 *249 * 11.4.2 Initializing and Destroying a Condition Variable,250 * P1003.1c/Draft 10, p. 87251 */252 253 int pthread_cond_destroy(254 pthread_cond_t *cond255 )256 {257 register POSIX_Condition_variables_Control *the_cond;258 Objects_Locations location;259 260 the_cond = _POSIX_Condition_variables_Get( cond, &location );261 switch ( location ) {262 case OBJECTS_REMOTE:263 #if defined(RTEMS_MULTIPROCESSING)264 _Thread_Dispatch();265 return POSIX_MP_NOT_IMPLEMENTED();266 return EINVAL;267 #endif268 269 case OBJECTS_ERROR:270 return EINVAL;271 272 273 case OBJECTS_LOCAL:274 275 if ( _Thread_queue_First( &the_cond->Wait_queue ) ) {276 _Thread_Enable_dispatch();277 return EBUSY;278 }279 280 _Objects_Close(281 &_POSIX_Condition_variables_Information,282 &the_cond->Object283 );284 285 _POSIX_Condition_variables_Free( the_cond );286 287 #if defined(RTEMS_MULTIPROCESSING)288 if ( the_cond->process_shared == PTHREAD_PROCESS_SHARED ) {289 290 _Objects_MP_Close(291 &_POSIX_Condition_variables_Information,292 the_cond->Object.id293 );294 295 _POSIX_Condition_variables_MP_Send_process_packet(296 POSIX_CONDITION_VARIABLES_MP_ANNOUNCE_DELETE,297 the_cond->Object.id,298 0, /* Not used */299 0 /* Not used */300 );301 }302 #endif303 _Thread_Enable_dispatch();304 return 0;305 }306 return POSIX_BOTTOM_REACHED();307 }308 309 /*PAGE310 *311 * _POSIX_Condition_variables_Signal_support312 *313 * A support routine which implements guts of the broadcast and single task314 * wake up version of the "signal" operation.315 */316 317 int _POSIX_Condition_variables_Signal_support(318 pthread_cond_t *cond,319 boolean is_broadcast320 )321 {322 register POSIX_Condition_variables_Control *the_cond;323 Objects_Locations location;324 Thread_Control *the_thread;325 326 the_cond = _POSIX_Condition_variables_Get( cond, &location );327 switch ( location ) {328 case OBJECTS_REMOTE:329 #if defined(RTEMS_MULTIPROCESSING)330 _Thread_Dispatch();331 return POSIX_MP_NOT_IMPLEMENTED();332 return EINVAL;333 #endif334 335 case OBJECTS_ERROR:336 return EINVAL;337 case OBJECTS_LOCAL:338 339 do {340 the_thread = _Thread_queue_Dequeue( &the_cond->Wait_queue );341 if ( !the_thread )342 the_cond->Mutex = POSIX_CONDITION_VARIABLES_NO_MUTEX;343 } while ( is_broadcast && the_thread );344 345 _Thread_Enable_dispatch();346 347 return 0;348 }349 return POSIX_BOTTOM_REACHED();350 }351 352 /*PAGE353 *354 * 11.4.3 Broadcasting and Signaling a Condition, P1003.1c/Draft 10, p. 101355 */356 357 int pthread_cond_signal(358 pthread_cond_t *cond359 )360 {361 return _POSIX_Condition_variables_Signal_support( cond, FALSE );362 }363 364 /*PAGE365 *366 * 11.4.3 Broadcasting and Signaling a Condition, P1003.1c/Draft 10, p. 101367 */368 369 int pthread_cond_broadcast(370 pthread_cond_t *cond371 )372 {373 return _POSIX_Condition_variables_Signal_support( cond, TRUE );374 }375 376 /*PAGE377 *378 * _POSIX_Condition_variables_Wait_support379 *380 * A support routine which implements guts of the blocking, non-blocking, and381 * timed wait version of condition variable wait routines.382 */383 384 int _POSIX_Condition_variables_Wait_support(385 pthread_cond_t *cond,386 pthread_mutex_t *mutex,387 Watchdog_Interval timeout,388 boolean already_timedout389 )390 {391 register POSIX_Condition_variables_Control *the_cond;392 Objects_Locations location;393 int status;394 int mutex_status;395 396 if ( !_POSIX_Mutex_Get( mutex, &location ) ) {397 return EINVAL;398 }399 400 _Thread_Unnest_dispatch();401 402 the_cond = _POSIX_Condition_variables_Get( cond, &location );403 switch ( location ) {404 case OBJECTS_REMOTE:405 #if defined(RTEMS_MULTIPROCESSING)406 _Thread_Dispatch();407 return POSIX_MP_NOT_IMPLEMENTED();408 return EINVAL;409 #endif410 case OBJECTS_ERROR:411 return EINVAL;412 case OBJECTS_LOCAL:413 414 if ( the_cond->Mutex && ( the_cond->Mutex != *mutex ) ) {415 _Thread_Enable_dispatch();416 return EINVAL;417 }418 419 (void) pthread_mutex_unlock( mutex );420 /* XXX ignore this for now since behavior is undefined421 if ( mutex_status ) {422 _Thread_Enable_dispatch();423 return EINVAL;424 }425 */426 427 if ( !already_timedout ) {428 the_cond->Mutex = *mutex;429 430 _Thread_queue_Enter_critical_section( &the_cond->Wait_queue );431 _Thread_Executing->Wait.return_code = 0;432 _Thread_Executing->Wait.queue = &the_cond->Wait_queue;433 _Thread_Executing->Wait.id = *cond;434 435 _Thread_queue_Enqueue( &the_cond->Wait_queue, timeout );436 437 _Thread_Enable_dispatch();438 439 /*440 * Switch ourself out because we blocked as a result of the441 * _Thread_queue_Enqueue.442 */443 444 status = _Thread_Executing->Wait.return_code;445 if ( status && status != ETIMEDOUT )446 return status;447 448 } else {449 _Thread_Enable_dispatch();450 status = ETIMEDOUT;451 }452 453 /*454 * When we get here the dispatch disable level is 0.455 */456 457 mutex_status = pthread_mutex_lock( mutex );458 if ( mutex_status )459 return EINVAL;460 461 return status;462 }463 return POSIX_BOTTOM_REACHED();464 }465 466 /*PAGE467 *468 * 11.4.4 Waiting on a Condition, P1003.1c/Draft 10, p. 105469 */470 471 int pthread_cond_wait(472 pthread_cond_t *cond,473 pthread_mutex_t *mutex474 )475 {476 return _POSIX_Condition_variables_Wait_support(477 cond,478 mutex,479 THREAD_QUEUE_WAIT_FOREVER,480 FALSE481 );482 }483 484 /*PAGE485 *486 * 11.4.4 Waiting on a Condition, P1003.1c/Draft 10, p. 105487 */488 489 int pthread_cond_timedwait(490 pthread_cond_t *cond,491 pthread_mutex_t *mutex,492 const struct timespec *abstime493 )494 {495 Watchdog_Interval timeout;496 struct timespec current_time;497 struct timespec difference;498 boolean already_timedout = FALSE;499 500 if ( !abstime )501 return EINVAL;502 503 /*504 * The abstime is a walltime. We turn it into an interval.505 */506 507 (void) clock_gettime( CLOCK_REALTIME, ¤t_time );508 509 /* XXX probably some error checking should go here */510 511 _POSIX_Timespec_subtract( ¤t_time, abstime, &difference );512 513 if ( ( difference.tv_sec < 0 ) || ( ( difference.tv_sec == 0 ) &&514 ( difference.tv_nsec < 0 ) ) )515 already_timedout = TRUE;516 517 timeout = _POSIX_Timespec_to_interval( &difference );518 519 return _POSIX_Condition_variables_Wait_support(520 cond,521 mutex,522 timeout,523 already_timedout524 );525 } -
cpukit/posix/include/rtems/posix/cond.h
r799c767 r98dca75 49 49 50 50 POSIX_EXTERN Objects_Information _POSIX_Condition_variables_Information; 51 52 /* 53 * The default condition variable attributes structure. 54 */ 55 56 extern const pthread_condattr_t _POSIX_Condition_variables_Default_attributes; 51 57 52 58 /* … … 119 125 ); 120 126 127 /* 128 * _POSIX_Condition_variables_Signal_support 129 * 130 * DESCRIPTION: 131 * 132 * A support routine which implements guts of the broadcast and single task 133 * wake up version of the "signal" operation. 134 */ 135 136 int _POSIX_Condition_variables_Signal_support( 137 pthread_cond_t *cond, 138 boolean is_broadcast 139 ); 140 141 /* 142 * _POSIX_Condition_variables_Wait_support 143 * 144 * DESCRIPTION: 145 * 146 * A support routine which implements guts of the blocking, non-blocking, and 147 * timed wait version of condition variable wait routines. 148 */ 149 150 int _POSIX_Condition_variables_Wait_support( 151 pthread_cond_t *cond, 152 pthread_mutex_t *mutex, 153 Watchdog_Interval timeout, 154 boolean already_timedout 155 ); 156 121 157 #include <rtems/posix/cond.inl> 122 158 #if defined(RTEMS_MULTIPROCESSING) -
cpukit/posix/src/cond.c
r799c767 r98dca75 14 14 #include <rtems/posix/mutex.h> 15 15 16 /*17 * TEMPORARY18 */19 20 21 #if defined(RTEMS_MULTIPROCESSING)22 void _POSIX_Condition_variables_MP_Send_process_packet (23 POSIX_Condition_variables_MP_Remote_operations operation,24 Objects_Id condition_variables_id,25 Objects_Name name,26 Objects_Id proxy_id27 )28 {29 (void) POSIX_MP_NOT_IMPLEMENTED();30 }31 32 void _POSIX_Condition_variables_MP_Send_extract_proxy(33 Thread_Control *the_thread34 )35 {36 (void) POSIX_MP_NOT_IMPLEMENTED();37 }38 #endif39 40 /*41 * END OF TEMPORARY42 */43 44 /*PAGE45 *46 * The default condition variable attributes structure.47 */48 49 const pthread_condattr_t _POSIX_Condition_variables_Default_attributes = {50 TRUE, /* is_initialized */51 PTHREAD_PROCESS_PRIVATE /* process_shared */52 };53 54 16 /*PAGE 55 17 * … … 80 42 ); 81 43 } 82 83 /*PAGE84 *85 * 11.4.1 Condition Variable Initialization Attributes,86 * P1003.1c/Draft 10, p. 9687 */88 89 int pthread_condattr_init(90 pthread_condattr_t *attr91 )92 {93 if ( !attr )94 return EINVAL;95 96 *attr = _POSIX_Condition_variables_Default_attributes;97 return 0;98 }99 100 /*PAGE101 *102 * 11.4.1 Condition Variable Initialization Attributes,103 * P1003.1c/Draft 10, p. 96104 */105 106 int pthread_condattr_destroy(107 pthread_condattr_t *attr108 )109 {110 if ( !attr || attr->is_initialized == FALSE )111 return EINVAL;112 113 attr->is_initialized = FALSE;114 return 0;115 }116 117 /*PAGE118 *119 * 11.4.1 Condition Variable Initialization Attributes,120 * P1003.1c/Draft 10, p. 96121 */122 123 int pthread_condattr_getpshared(124 const pthread_condattr_t *attr,125 int *pshared126 )127 {128 if ( !attr )129 return EINVAL;130 131 *pshared = attr->process_shared;132 return 0;133 }134 135 /*PAGE136 *137 * 11.4.1 Condition Variable Initialization Attributes,138 * P1003.1c/Draft 10, p. 96139 */140 141 int pthread_condattr_setpshared(142 pthread_condattr_t *attr,143 int pshared144 )145 {146 if ( !attr )147 return EINVAL;148 149 switch ( pshared ) {150 case PTHREAD_PROCESS_SHARED:151 case PTHREAD_PROCESS_PRIVATE:152 attr->process_shared = pshared;153 return 0;154 155 default:156 return EINVAL;157 }158 }159 160 /*PAGE161 *162 * 11.4.2 Initializing and Destroying a Condition Variable,163 * P1003.1c/Draft 10, p. 87164 */165 166 int pthread_cond_init(167 pthread_cond_t *cond,168 const pthread_condattr_t *attr169 )170 {171 POSIX_Condition_variables_Control *the_cond;172 const pthread_condattr_t *the_attr;173 174 if ( attr ) the_attr = attr;175 else the_attr = &_POSIX_Condition_variables_Default_attributes;176 177 /*178 * XXX: Be careful about attributes when global!!!179 */180 181 if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )182 return POSIX_MP_NOT_IMPLEMENTED();183 184 if ( !the_attr->is_initialized )185 return EINVAL;186 187 _Thread_Disable_dispatch();188 189 the_cond = _POSIX_Condition_variables_Allocate();190 191 if ( !the_cond ) {192 _Thread_Enable_dispatch();193 return ENOMEM;194 }195 196 #if defined(RTEMS_MULTIPROCESSING)197 if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED &&198 !( _Objects_MP_Allocate_and_open( &_POSIX_Condition_variables_Information,199 0, the_cond->Object.id, FALSE ) ) ) {200 _POSIX_Condition_variables_Free( the_cond );201 _Thread_Enable_dispatch();202 return EAGAIN;203 }204 #endif205 206 the_cond->process_shared = the_attr->process_shared;207 208 the_cond->Mutex = POSIX_CONDITION_VARIABLES_NO_MUTEX;209 210 /* XXX some more initialization might need to go here */211 _Thread_queue_Initialize(212 &the_cond->Wait_queue,213 OBJECTS_POSIX_CONDITION_VARIABLES,214 THREAD_QUEUE_DISCIPLINE_FIFO,215 STATES_WAITING_FOR_CONDITION_VARIABLE,216 #if defined(RTEMS_MULTIPROCESSING)217 _POSIX_Condition_variables_MP_Send_extract_proxy,218 #else219 NULL,220 #endif221 ETIMEDOUT222 );223 224 _Objects_Open(225 &_POSIX_Condition_variables_Information,226 &the_cond->Object,227 0228 );229 230 *cond = the_cond->Object.id;231 232 #if defined(RTEMS_MULTIPROCESSING)233 if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )234 _POSIX_Condition_variables_MP_Send_process_packet(235 POSIX_CONDITION_VARIABLES_MP_ANNOUNCE_CREATE,236 the_cond->Object.id,237 0, /* Name not used */238 0 /* Not used */239 );240 #endif241 242 _Thread_Enable_dispatch();243 244 return 0;245 }246 247 /*PAGE248 *249 * 11.4.2 Initializing and Destroying a Condition Variable,250 * P1003.1c/Draft 10, p. 87251 */252 253 int pthread_cond_destroy(254 pthread_cond_t *cond255 )256 {257 register POSIX_Condition_variables_Control *the_cond;258 Objects_Locations location;259 260 the_cond = _POSIX_Condition_variables_Get( cond, &location );261 switch ( location ) {262 case OBJECTS_REMOTE:263 #if defined(RTEMS_MULTIPROCESSING)264 _Thread_Dispatch();265 return POSIX_MP_NOT_IMPLEMENTED();266 return EINVAL;267 #endif268 269 case OBJECTS_ERROR:270 return EINVAL;271 272 273 case OBJECTS_LOCAL:274 275 if ( _Thread_queue_First( &the_cond->Wait_queue ) ) {276 _Thread_Enable_dispatch();277 return EBUSY;278 }279 280 _Objects_Close(281 &_POSIX_Condition_variables_Information,282 &the_cond->Object283 );284 285 _POSIX_Condition_variables_Free( the_cond );286 287 #if defined(RTEMS_MULTIPROCESSING)288 if ( the_cond->process_shared == PTHREAD_PROCESS_SHARED ) {289 290 _Objects_MP_Close(291 &_POSIX_Condition_variables_Information,292 the_cond->Object.id293 );294 295 _POSIX_Condition_variables_MP_Send_process_packet(296 POSIX_CONDITION_VARIABLES_MP_ANNOUNCE_DELETE,297 the_cond->Object.id,298 0, /* Not used */299 0 /* Not used */300 );301 }302 #endif303 _Thread_Enable_dispatch();304 return 0;305 }306 return POSIX_BOTTOM_REACHED();307 }308 309 /*PAGE310 *311 * _POSIX_Condition_variables_Signal_support312 *313 * A support routine which implements guts of the broadcast and single task314 * wake up version of the "signal" operation.315 */316 317 int _POSIX_Condition_variables_Signal_support(318 pthread_cond_t *cond,319 boolean is_broadcast320 )321 {322 register POSIX_Condition_variables_Control *the_cond;323 Objects_Locations location;324 Thread_Control *the_thread;325 326 the_cond = _POSIX_Condition_variables_Get( cond, &location );327 switch ( location ) {328 case OBJECTS_REMOTE:329 #if defined(RTEMS_MULTIPROCESSING)330 _Thread_Dispatch();331 return POSIX_MP_NOT_IMPLEMENTED();332 return EINVAL;333 #endif334 335 case OBJECTS_ERROR:336 return EINVAL;337 case OBJECTS_LOCAL:338 339 do {340 the_thread = _Thread_queue_Dequeue( &the_cond->Wait_queue );341 if ( !the_thread )342 the_cond->Mutex = POSIX_CONDITION_VARIABLES_NO_MUTEX;343 } while ( is_broadcast && the_thread );344 345 _Thread_Enable_dispatch();346 347 return 0;348 }349 return POSIX_BOTTOM_REACHED();350 }351 352 /*PAGE353 *354 * 11.4.3 Broadcasting and Signaling a Condition, P1003.1c/Draft 10, p. 101355 */356 357 int pthread_cond_signal(358 pthread_cond_t *cond359 )360 {361 return _POSIX_Condition_variables_Signal_support( cond, FALSE );362 }363 364 /*PAGE365 *366 * 11.4.3 Broadcasting and Signaling a Condition, P1003.1c/Draft 10, p. 101367 */368 369 int pthread_cond_broadcast(370 pthread_cond_t *cond371 )372 {373 return _POSIX_Condition_variables_Signal_support( cond, TRUE );374 }375 376 /*PAGE377 *378 * _POSIX_Condition_variables_Wait_support379 *380 * A support routine which implements guts of the blocking, non-blocking, and381 * timed wait version of condition variable wait routines.382 */383 384 int _POSIX_Condition_variables_Wait_support(385 pthread_cond_t *cond,386 pthread_mutex_t *mutex,387 Watchdog_Interval timeout,388 boolean already_timedout389 )390 {391 register POSIX_Condition_variables_Control *the_cond;392 Objects_Locations location;393 int status;394 int mutex_status;395 396 if ( !_POSIX_Mutex_Get( mutex, &location ) ) {397 return EINVAL;398 }399 400 _Thread_Unnest_dispatch();401 402 the_cond = _POSIX_Condition_variables_Get( cond, &location );403 switch ( location ) {404 case OBJECTS_REMOTE:405 #if defined(RTEMS_MULTIPROCESSING)406 _Thread_Dispatch();407 return POSIX_MP_NOT_IMPLEMENTED();408 return EINVAL;409 #endif410 case OBJECTS_ERROR:411 return EINVAL;412 case OBJECTS_LOCAL:413 414 if ( the_cond->Mutex && ( the_cond->Mutex != *mutex ) ) {415 _Thread_Enable_dispatch();416 return EINVAL;417 }418 419 (void) pthread_mutex_unlock( mutex );420 /* XXX ignore this for now since behavior is undefined421 if ( mutex_status ) {422 _Thread_Enable_dispatch();423 return EINVAL;424 }425 */426 427 if ( !already_timedout ) {428 the_cond->Mutex = *mutex;429 430 _Thread_queue_Enter_critical_section( &the_cond->Wait_queue );431 _Thread_Executing->Wait.return_code = 0;432 _Thread_Executing->Wait.queue = &the_cond->Wait_queue;433 _Thread_Executing->Wait.id = *cond;434 435 _Thread_queue_Enqueue( &the_cond->Wait_queue, timeout );436 437 _Thread_Enable_dispatch();438 439 /*440 * Switch ourself out because we blocked as a result of the441 * _Thread_queue_Enqueue.442 */443 444 status = _Thread_Executing->Wait.return_code;445 if ( status && status != ETIMEDOUT )446 return status;447 448 } else {449 _Thread_Enable_dispatch();450 status = ETIMEDOUT;451 }452 453 /*454 * When we get here the dispatch disable level is 0.455 */456 457 mutex_status = pthread_mutex_lock( mutex );458 if ( mutex_status )459 return EINVAL;460 461 return status;462 }463 return POSIX_BOTTOM_REACHED();464 }465 466 /*PAGE467 *468 * 11.4.4 Waiting on a Condition, P1003.1c/Draft 10, p. 105469 */470 471 int pthread_cond_wait(472 pthread_cond_t *cond,473 pthread_mutex_t *mutex474 )475 {476 return _POSIX_Condition_variables_Wait_support(477 cond,478 mutex,479 THREAD_QUEUE_WAIT_FOREVER,480 FALSE481 );482 }483 484 /*PAGE485 *486 * 11.4.4 Waiting on a Condition, P1003.1c/Draft 10, p. 105487 */488 489 int pthread_cond_timedwait(490 pthread_cond_t *cond,491 pthread_mutex_t *mutex,492 const struct timespec *abstime493 )494 {495 Watchdog_Interval timeout;496 struct timespec current_time;497 struct timespec difference;498 boolean already_timedout = FALSE;499 500 if ( !abstime )501 return EINVAL;502 503 /*504 * The abstime is a walltime. We turn it into an interval.505 */506 507 (void) clock_gettime( CLOCK_REALTIME, ¤t_time );508 509 /* XXX probably some error checking should go here */510 511 _POSIX_Timespec_subtract( ¤t_time, abstime, &difference );512 513 if ( ( difference.tv_sec < 0 ) || ( ( difference.tv_sec == 0 ) &&514 ( difference.tv_nsec < 0 ) ) )515 already_timedout = TRUE;516 517 timeout = _POSIX_Timespec_to_interval( &difference );518 519 return _POSIX_Condition_variables_Wait_support(520 cond,521 mutex,522 timeout,523 already_timedout524 );525 }
Note: See TracChangeset
for help on using the changeset viewer.