int pthread_rwlock_timedrdlock( pthread_rwlock_t *rwlock, const struct timespec *abstime ) { POSIX_RWLock_Control *the_rwlock; Thread_queue_Context queue_context; Watchdog_Interval ticks; bool do_wait; TOD_Absolute_timeout_conversion_results timeout_status; Status_Control status; /* * POSIX requires that blocking calls with timeouts that take * an absolute timeout must ignore issues with the absolute * time provided if the operation would otherwise succeed. * So we check the abstime provided, and hold on to whether it * is valid or not. If it isn't correct and in the future, * then we do a polling operation and convert the STATUS_UNAVAILABLE * status into the appropriate error. * * If the timeout status is TOD_ABSOLUTE_TIMEOUT_INVALID, * TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST, or TOD_ABSOLUTE_TIMEOUT_IS_NOW, * then we should not wait. */ timeout_status = _TOD_Absolute_timeout_to_ticks( abstime, &ticks ); do_wait = ( timeout_status == TOD_ABSOLUTE_TIMEOUT_IS_IN_FUTURE ); the_rwlock = _POSIX_RWLock_Get( rwlock, &queue_context ); if ( the_rwlock == NULL ) { return EINVAL; } status = _CORE_RWLock_Seize_for_reading( &the_rwlock->RWLock, _Thread_Executing, do_wait, ticks, &queue_context ); if ( !do_wait && status == STATUS_UNAVAILABLE ) { if ( timeout_status == TOD_ABSOLUTE_TIMEOUT_INVALID ) { return EINVAL; } if ( timeout_status == TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST || timeout_status == TOD_ABSOLUTE_TIMEOUT_IS_NOW ) { return ETIMEDOUT; } } return _POSIX_Get_error( status ); }
int _POSIX_Mutex_Lock_support( pthread_mutex_t *mutex, bool wait, Watchdog_Interval timeout ) { POSIX_Mutex_Control *the_mutex; Thread_queue_Context queue_context; Thread_Control *executing; Status_Control status; the_mutex = _POSIX_Mutex_Get( mutex, &queue_context ); if ( the_mutex == NULL ) { return EINVAL; } executing = _Thread_Executing; _Thread_queue_Context_set_relative_timeout( &queue_context, timeout ); switch ( the_mutex->protocol ) { case POSIX_MUTEX_PRIORITY_CEILING: status = _CORE_ceiling_mutex_Seize( &the_mutex->Mutex, executing, wait, _POSIX_Mutex_Lock_nested, &queue_context ); break; case POSIX_MUTEX_NO_PROTOCOL: status = _CORE_recursive_mutex_Seize( &the_mutex->Mutex.Recursive, POSIX_MUTEX_NO_PROTOCOL_TQ_OPERATIONS, executing, wait, _POSIX_Mutex_Lock_nested, &queue_context ); break; default: _Assert( the_mutex->protocol == POSIX_MUTEX_PRIORITY_INHERIT ); status = _CORE_recursive_mutex_Seize( &the_mutex->Mutex.Recursive, CORE_MUTEX_TQ_PRIORITY_INHERIT_OPERATIONS, executing, wait, _POSIX_Mutex_Lock_nested, &queue_context ); break; } return _POSIX_Get_error( status ); }
int pthread_rwlock_unlock( pthread_rwlock_t *rwlock ) { POSIX_RWLock_Control *the_rwlock; Status_Control status; the_rwlock = _POSIX_RWLock_Get( rwlock ); POSIX_RWLOCK_VALIDATE_OBJECT( the_rwlock ); status = _CORE_RWLock_Surrender( &the_rwlock->RWLock ); return _POSIX_Get_error( status ); }
int pthread_spin_lock( pthread_spinlock_t *spinlock ) { POSIX_Spinlock_Control *the_spinlock; ISR_lock_Context lock_context; Status_Control status; the_spinlock = _POSIX_Spinlock_Get( spinlock, &lock_context ); if ( the_spinlock == NULL ) { return EINVAL; } status = _CORE_spinlock_Seize( &the_spinlock->Spinlock, true, 0, &lock_context ); return _POSIX_Get_error( status ); }
int pthread_rwlock_tryrdlock( pthread_rwlock_t *rwlock ) { POSIX_RWLock_Control *the_rwlock; Thread_queue_Context queue_context; Status_Control status; the_rwlock = _POSIX_RWLock_Get( rwlock, &queue_context ); if ( the_rwlock == NULL ) { return EINVAL; } status = _CORE_RWLock_Seize_for_reading( &the_rwlock->RWLock, _Thread_Executing, false, /* do not wait for the rwlock */ &queue_context ); return _POSIX_Get_error( status ); }
int pthread_rwlock_timedwrlock( pthread_rwlock_t *rwlock, const struct timespec *abstime ) { POSIX_RWLock_Control *the_rwlock; Thread_queue_Context queue_context; Status_Control status; the_rwlock = _POSIX_RWLock_Get( rwlock ); POSIX_RWLOCK_VALIDATE_OBJECT( the_rwlock ); _Thread_queue_Context_initialize( &queue_context ); _Thread_queue_Context_set_enqueue_timeout_realtime_timespec( &queue_context, abstime ); status = _CORE_RWLock_Seize_for_writing( &the_rwlock->RWLock, true, &queue_context ); return _POSIX_Get_error( status ); }
ssize_t _POSIX_Message_queue_Receive_support( mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio, bool wait, Watchdog_Interval timeout ) { POSIX_Message_queue_Control *the_mq; Thread_queue_Context queue_context; size_t length_out; bool do_wait; Thread_Control *executing; Status_Control status; the_mq = _POSIX_Message_queue_Get( mqdes, &queue_context ); if ( the_mq == NULL ) { rtems_set_errno_and_return_minus_one( EBADF ); } if ( ( the_mq->oflag & O_ACCMODE ) == O_WRONLY ) { _ISR_lock_ISR_enable( &queue_context.Lock_context.Lock_context ); rtems_set_errno_and_return_minus_one( EBADF ); } if ( msg_len < the_mq->Message_queue.maximum_message_size ) { _ISR_lock_ISR_enable( &queue_context.Lock_context.Lock_context ); rtems_set_errno_and_return_minus_one( EMSGSIZE ); } /* * Now if something goes wrong, we return a "length" of -1 * to indicate an error. */ length_out = -1; /* * A timed receive with a bad time will do a poll regardless. */ if ( wait ) { do_wait = ( the_mq->oflag & O_NONBLOCK ) == 0; } else { do_wait = wait; } _CORE_message_queue_Acquire_critical( &the_mq->Message_queue, &queue_context ); if ( the_mq->open_count == 0 ) { _CORE_message_queue_Release( &the_mq->Message_queue, &queue_context ); rtems_set_errno_and_return_minus_one( EBADF ); } /* * Now perform the actual message receive */ executing = _Thread_Executing; _Thread_queue_Context_set_relative_timeout( &queue_context, timeout ); status = _CORE_message_queue_Seize( &the_mq->Message_queue, executing, msg_ptr, &length_out, do_wait, &queue_context ); if ( msg_prio != NULL ) { *msg_prio = _POSIX_Message_queue_Priority_from_core( executing->Wait.count ); } if ( status != STATUS_SUCCESSFUL ) { rtems_set_errno_and_return_minus_one( _POSIX_Get_error( status ) ); } return length_out; }