mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-21 14:06:00 +08:00
@@ -23,6 +23,7 @@
|
||||
#include <rtems/score/corerwlockimpl.h>
|
||||
#include <rtems/score/objectimpl.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -86,8 +87,8 @@ RTEMS_INLINE_ROUTINE void _POSIX_RWLock_Free (
|
||||
}
|
||||
|
||||
POSIX_RWLock_Control *_POSIX_RWLock_Get(
|
||||
pthread_rwlock_t *rwlock,
|
||||
Objects_Locations *location
|
||||
pthread_rwlock_t *rwlock,
|
||||
ISR_lock_Context *lock_context
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -17,68 +17,42 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/posix/rwlockimpl.h>
|
||||
#include <rtems/score/threadqimpl.h>
|
||||
|
||||
/**
|
||||
* This directive allows a thread to delete a rwlock specified by
|
||||
* the rwlock id. The rwlock is freed back to the inactive
|
||||
* rwlock chain.
|
||||
*
|
||||
* @param[in] rwlock is the rwlock id
|
||||
*
|
||||
* @return This method returns 0 if there was not an
|
||||
* error. Otherwise, a status code is returned indicating the
|
||||
* source of the error.
|
||||
*/
|
||||
int pthread_rwlock_destroy(
|
||||
pthread_rwlock_t *rwlock
|
||||
)
|
||||
{
|
||||
POSIX_RWLock_Control *the_rwlock = NULL;
|
||||
Objects_Locations location;
|
||||
POSIX_RWLock_Control *the_rwlock;
|
||||
ISR_lock_Context lock_context;
|
||||
|
||||
_Objects_Allocator_lock();
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock, &location );
|
||||
switch ( location ) {
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock, &lock_context );
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
/*
|
||||
* If there is at least one thread waiting, then do not delete it.
|
||||
*/
|
||||
if (
|
||||
_Thread_queue_First(
|
||||
&the_rwlock->RWLock.Wait_queue,
|
||||
CORE_RWLOCK_TQ_OPERATIONS
|
||||
) != NULL
|
||||
) {
|
||||
_Objects_Put( &the_rwlock->Object );
|
||||
_Objects_Allocator_unlock();
|
||||
return EBUSY;
|
||||
}
|
||||
|
||||
/*
|
||||
* POSIX doesn't require behavior when it is locked.
|
||||
*/
|
||||
|
||||
_Objects_Close( &_POSIX_RWLock_Information, &the_rwlock->Object );
|
||||
_Objects_Put( &the_rwlock->Object );
|
||||
_POSIX_RWLock_Free( the_rwlock );
|
||||
_Objects_Allocator_unlock();
|
||||
|
||||
return 0;
|
||||
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
case OBJECTS_REMOTE:
|
||||
#endif
|
||||
case OBJECTS_ERROR:
|
||||
break;
|
||||
if ( the_rwlock == NULL ) {
|
||||
_Objects_Allocator_unlock();
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
_Objects_Allocator_unlock();
|
||||
_CORE_RWLock_Acquire_critical( &the_rwlock->RWLock, &lock_context );
|
||||
|
||||
return EINVAL;
|
||||
/*
|
||||
* If there is at least one thread waiting, then do not delete it.
|
||||
*/
|
||||
|
||||
if ( !_Thread_queue_Is_empty( &the_rwlock->RWLock.Wait_queue.Queue ) ) {
|
||||
_CORE_RWLock_Release( &the_rwlock->RWLock, &lock_context );
|
||||
_Objects_Allocator_unlock();
|
||||
return EBUSY;
|
||||
}
|
||||
|
||||
/*
|
||||
* POSIX doesn't require behavior when it is locked.
|
||||
*/
|
||||
|
||||
_Objects_Close( &_POSIX_RWLock_Information, &the_rwlock->Object );
|
||||
_CORE_RWLock_Release( &the_rwlock->RWLock, &lock_context );
|
||||
_POSIX_RWLock_Free( the_rwlock );
|
||||
_Objects_Allocator_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -20,20 +20,14 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/posix/rwlockimpl.h>
|
||||
#include <rtems/score/apimutex.h>
|
||||
|
||||
static bool _POSIX_RWLock_Check_id_and_auto_init(
|
||||
pthread_mutex_t *rwlock,
|
||||
Objects_Locations *location
|
||||
pthread_mutex_t *rwlock
|
||||
)
|
||||
{
|
||||
if ( rwlock == NULL ) {
|
||||
*location = OBJECTS_ERROR;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -51,8 +45,6 @@ static bool _POSIX_RWLock_Check_id_and_auto_init(
|
||||
_Once_Unlock();
|
||||
|
||||
if ( eno != 0 ) {
|
||||
*location = OBJECTS_ERROR;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -61,18 +53,18 @@ static bool _POSIX_RWLock_Check_id_and_auto_init(
|
||||
}
|
||||
|
||||
POSIX_RWLock_Control *_POSIX_RWLock_Get(
|
||||
pthread_rwlock_t *rwlock,
|
||||
Objects_Locations *location
|
||||
pthread_rwlock_t *rwlock,
|
||||
ISR_lock_Context *lock_context
|
||||
)
|
||||
{
|
||||
if ( !_POSIX_RWLock_Check_id_and_auto_init( rwlock, location ) ) {
|
||||
if ( !_POSIX_RWLock_Check_id_and_auto_init( rwlock ) ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (POSIX_RWLock_Control *) _Objects_Get(
|
||||
&_POSIX_RWLock_Information,
|
||||
return (POSIX_RWLock_Control *) _Objects_Get_local(
|
||||
*rwlock,
|
||||
location
|
||||
&_POSIX_RWLock_Information,
|
||||
lock_context
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,53 +18,31 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/posix/rwlockimpl.h>
|
||||
#include <rtems/score/thread.h>
|
||||
|
||||
/**
|
||||
* This directive attempts to obtain a read only lock on an rwlock instance.
|
||||
*
|
||||
* @param[in] rwlock is the pointer to rwlock id
|
||||
*
|
||||
* @retval 0 if successful
|
||||
* @retval error_code if unsuccessful
|
||||
*/
|
||||
|
||||
int pthread_rwlock_rdlock(
|
||||
pthread_rwlock_t *rwlock
|
||||
)
|
||||
{
|
||||
POSIX_RWLock_Control *the_rwlock;
|
||||
Objects_Locations location;
|
||||
Thread_Control *executing;
|
||||
POSIX_RWLock_Control *the_rwlock;
|
||||
ISR_lock_Context lock_context;
|
||||
Thread_Control *executing;
|
||||
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock, &location );
|
||||
switch ( location ) {
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock, &lock_context );
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
|
||||
executing = _Thread_Executing;
|
||||
_CORE_RWLock_Seize_for_reading(
|
||||
&the_rwlock->RWLock,
|
||||
executing,
|
||||
true, /* we are willing to wait forever */
|
||||
0
|
||||
);
|
||||
|
||||
_Objects_Put( &the_rwlock->Object );
|
||||
return _POSIX_RWLock_Translate_core_RWLock_return_code(
|
||||
(CORE_RWLock_Status) executing->Wait.return_code
|
||||
);
|
||||
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
case OBJECTS_REMOTE:
|
||||
#endif
|
||||
case OBJECTS_ERROR:
|
||||
break;
|
||||
if ( the_rwlock == NULL ) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
return EINVAL;
|
||||
executing = _Thread_Executing;
|
||||
_CORE_RWLock_Seize_for_reading(
|
||||
&the_rwlock->RWLock,
|
||||
executing,
|
||||
true, /* we are willing to wait forever */
|
||||
0,
|
||||
&lock_context
|
||||
);
|
||||
return _POSIX_RWLock_Translate_core_RWLock_return_code(
|
||||
(CORE_RWLock_Status) executing->Wait.return_code
|
||||
);
|
||||
}
|
||||
|
||||
@@ -18,37 +18,20 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/posix/rwlockimpl.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/todimpl.h>
|
||||
|
||||
/*
|
||||
* pthread_rwlock_timedrdlock
|
||||
*
|
||||
* This directive attempts to obtain a read only lock on an rwlock instance.
|
||||
*
|
||||
* Input parameters:
|
||||
* rwlock - pointer to rwlock id
|
||||
*
|
||||
* Output parameters:
|
||||
* 0 - if successful
|
||||
* error code - if unsuccessful
|
||||
*/
|
||||
|
||||
int pthread_rwlock_timedrdlock(
|
||||
pthread_rwlock_t *rwlock,
|
||||
const struct timespec *abstime
|
||||
)
|
||||
{
|
||||
POSIX_RWLock_Control *the_rwlock;
|
||||
Objects_Locations location;
|
||||
Watchdog_Interval ticks;
|
||||
bool do_wait = true;
|
||||
POSIX_RWLock_Control *the_rwlock;
|
||||
ISR_lock_Context lock_context;
|
||||
Watchdog_Interval ticks;
|
||||
bool do_wait;
|
||||
TOD_Absolute_timeout_conversion_results status;
|
||||
Thread_Control *executing;
|
||||
Thread_Control *executing;
|
||||
|
||||
/*
|
||||
* POSIX requires that blocking calls with timeouts that take
|
||||
@@ -64,43 +47,40 @@ int pthread_rwlock_timedrdlock(
|
||||
* then we should not wait.
|
||||
*/
|
||||
status = _TOD_Absolute_timeout_to_ticks( abstime, &ticks );
|
||||
if ( status != TOD_ABSOLUTE_TIMEOUT_IS_IN_FUTURE )
|
||||
do_wait = false;
|
||||
do_wait = ( status == TOD_ABSOLUTE_TIMEOUT_IS_IN_FUTURE );
|
||||
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock, &location );
|
||||
switch ( location ) {
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock, &lock_context );
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
|
||||
executing = _Thread_Executing;
|
||||
_CORE_RWLock_Seize_for_reading(
|
||||
&the_rwlock->RWLock,
|
||||
executing,
|
||||
do_wait,
|
||||
ticks
|
||||
);
|
||||
|
||||
_Objects_Put( &the_rwlock->Object );
|
||||
if ( !do_wait ) {
|
||||
if ( executing->Wait.return_code == CORE_RWLOCK_UNAVAILABLE ) {
|
||||
if ( status == TOD_ABSOLUTE_TIMEOUT_INVALID )
|
||||
return EINVAL;
|
||||
if ( status == TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST ||
|
||||
status == TOD_ABSOLUTE_TIMEOUT_IS_NOW )
|
||||
return ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
return _POSIX_RWLock_Translate_core_RWLock_return_code(
|
||||
(CORE_RWLock_Status) executing->Wait.return_code
|
||||
);
|
||||
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
case OBJECTS_REMOTE:
|
||||
#endif
|
||||
case OBJECTS_ERROR:
|
||||
break;
|
||||
if ( the_rwlock == NULL ) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
return EINVAL;
|
||||
executing = _Thread_Executing;
|
||||
_CORE_RWLock_Seize_for_reading(
|
||||
&the_rwlock->RWLock,
|
||||
executing,
|
||||
do_wait,
|
||||
ticks,
|
||||
&lock_context
|
||||
);
|
||||
|
||||
if (
|
||||
!do_wait
|
||||
&& ( executing->Wait.return_code == CORE_RWLOCK_UNAVAILABLE )
|
||||
) {
|
||||
if ( status == TOD_ABSOLUTE_TIMEOUT_INVALID ) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (
|
||||
status == TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST
|
||||
|| status == TOD_ABSOLUTE_TIMEOUT_IS_NOW
|
||||
) {
|
||||
return ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
return _POSIX_RWLock_Translate_core_RWLock_return_code(
|
||||
(CORE_RWLock_Status) executing->Wait.return_code
|
||||
);
|
||||
}
|
||||
|
||||
@@ -20,37 +20,20 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/posix/rwlockimpl.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/todimpl.h>
|
||||
|
||||
/*
|
||||
* pthread_rwlock_timedwrlock
|
||||
*
|
||||
* This directive attempts to obtain a write only lock on an rwlock instance.
|
||||
*
|
||||
* Input parameters:
|
||||
* rwlock - pointer to rwlock id
|
||||
*
|
||||
* Output parameters:
|
||||
* 0 - if successful
|
||||
* error code - if unsuccessful
|
||||
*/
|
||||
|
||||
int pthread_rwlock_timedwrlock(
|
||||
pthread_rwlock_t *rwlock,
|
||||
const struct timespec *abstime
|
||||
)
|
||||
{
|
||||
POSIX_RWLock_Control *the_rwlock;
|
||||
Objects_Locations location;
|
||||
Watchdog_Interval ticks;
|
||||
bool do_wait = true;
|
||||
POSIX_RWLock_Control *the_rwlock;
|
||||
ISR_lock_Context lock_context;
|
||||
Watchdog_Interval ticks;
|
||||
bool do_wait;
|
||||
TOD_Absolute_timeout_conversion_results status;
|
||||
Thread_Control *executing;
|
||||
Thread_Control *executing;
|
||||
|
||||
/*
|
||||
* POSIX requires that blocking calls with timeouts that take
|
||||
@@ -66,42 +49,40 @@ int pthread_rwlock_timedwrlock(
|
||||
* then we should not wait.
|
||||
*/
|
||||
status = _TOD_Absolute_timeout_to_ticks( abstime, &ticks );
|
||||
if ( status != TOD_ABSOLUTE_TIMEOUT_IS_IN_FUTURE )
|
||||
do_wait = false;
|
||||
do_wait = ( status == TOD_ABSOLUTE_TIMEOUT_IS_IN_FUTURE );
|
||||
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock, &location );
|
||||
switch ( location ) {
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock, &lock_context );
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
|
||||
executing = _Thread_Executing;
|
||||
_CORE_RWLock_Seize_for_writing(
|
||||
&the_rwlock->RWLock,
|
||||
executing,
|
||||
do_wait,
|
||||
ticks
|
||||
);
|
||||
|
||||
_Objects_Put( &the_rwlock->Object );
|
||||
if ( !do_wait &&
|
||||
(executing->Wait.return_code == CORE_RWLOCK_UNAVAILABLE) ) {
|
||||
if ( status == TOD_ABSOLUTE_TIMEOUT_INVALID )
|
||||
return EINVAL;
|
||||
if ( status == TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST ||
|
||||
status == TOD_ABSOLUTE_TIMEOUT_IS_NOW )
|
||||
return ETIMEDOUT;
|
||||
}
|
||||
|
||||
return _POSIX_RWLock_Translate_core_RWLock_return_code(
|
||||
(CORE_RWLock_Status) executing->Wait.return_code
|
||||
);
|
||||
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
case OBJECTS_REMOTE:
|
||||
#endif
|
||||
case OBJECTS_ERROR:
|
||||
break;
|
||||
if ( the_rwlock == NULL ) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
return EINVAL;
|
||||
executing = _Thread_Executing;
|
||||
_CORE_RWLock_Seize_for_writing(
|
||||
&the_rwlock->RWLock,
|
||||
executing,
|
||||
do_wait,
|
||||
ticks,
|
||||
&lock_context
|
||||
);
|
||||
|
||||
if (
|
||||
!do_wait
|
||||
&& ( executing->Wait.return_code == CORE_RWLOCK_UNAVAILABLE )
|
||||
) {
|
||||
if ( status == TOD_ABSOLUTE_TIMEOUT_INVALID ) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (
|
||||
status == TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST
|
||||
|| status == TOD_ABSOLUTE_TIMEOUT_IS_NOW
|
||||
) {
|
||||
return ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
return _POSIX_RWLock_Translate_core_RWLock_return_code(
|
||||
(CORE_RWLock_Status) executing->Wait.return_code
|
||||
);
|
||||
}
|
||||
|
||||
@@ -18,58 +18,31 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/posix/rwlockimpl.h>
|
||||
#include <rtems/score/thread.h>
|
||||
|
||||
/*
|
||||
* pthread_rwlock_tryrdlock
|
||||
*
|
||||
* This directive attempts to obtain a read only lock on an rwlock instance.
|
||||
*
|
||||
* Input parameters:
|
||||
* rwlock - pointer to rwlock id
|
||||
*
|
||||
* Output parameters:
|
||||
* 0 - if successful
|
||||
* error code - if unsuccessful
|
||||
*/
|
||||
|
||||
int pthread_rwlock_tryrdlock(
|
||||
pthread_rwlock_t *rwlock
|
||||
)
|
||||
{
|
||||
POSIX_RWLock_Control *the_rwlock;
|
||||
Objects_Locations location;
|
||||
Thread_Control *executing;
|
||||
POSIX_RWLock_Control *the_rwlock;
|
||||
ISR_lock_Context lock_context;
|
||||
Thread_Control *executing;
|
||||
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock, &location );
|
||||
switch ( location ) {
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock, &lock_context );
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
|
||||
executing = _Thread_Executing;
|
||||
_CORE_RWLock_Seize_for_reading(
|
||||
&the_rwlock->RWLock,
|
||||
executing,
|
||||
false, /* do not wait for the rwlock */
|
||||
0
|
||||
);
|
||||
|
||||
|
||||
_Objects_Put( &the_rwlock->Object );
|
||||
return _POSIX_RWLock_Translate_core_RWLock_return_code(
|
||||
(CORE_RWLock_Status) executing->Wait.return_code
|
||||
);
|
||||
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
case OBJECTS_REMOTE:
|
||||
#endif
|
||||
case OBJECTS_ERROR:
|
||||
break;
|
||||
if ( the_rwlock == NULL ) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
return EINVAL;
|
||||
executing = _Thread_Executing;
|
||||
_CORE_RWLock_Seize_for_reading(
|
||||
&the_rwlock->RWLock,
|
||||
executing,
|
||||
false, /* do not wait for the rwlock */
|
||||
0,
|
||||
&lock_context
|
||||
);
|
||||
return _POSIX_RWLock_Translate_core_RWLock_return_code(
|
||||
(CORE_RWLock_Status) executing->Wait.return_code
|
||||
);
|
||||
}
|
||||
|
||||
@@ -18,57 +18,31 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/posix/rwlockimpl.h>
|
||||
#include <rtems/score/thread.h>
|
||||
|
||||
/*
|
||||
* pthread_rwlock_trywrlock
|
||||
*
|
||||
* This directive attempts to obtain a Write only lock on an rwlock instance.
|
||||
*
|
||||
* Input parameters:
|
||||
* rwlock - pointer to rwlock id
|
||||
*
|
||||
* Output parameters:
|
||||
* 0 - if successful
|
||||
* error code - if unsuccessful
|
||||
*/
|
||||
|
||||
int pthread_rwlock_trywrlock(
|
||||
pthread_rwlock_t *rwlock
|
||||
)
|
||||
{
|
||||
POSIX_RWLock_Control *the_rwlock;
|
||||
Objects_Locations location;
|
||||
Thread_Control *executing;
|
||||
POSIX_RWLock_Control *the_rwlock;
|
||||
ISR_lock_Context lock_context;
|
||||
Thread_Control *executing;
|
||||
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock, &location );
|
||||
switch ( location ) {
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock, &lock_context );
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
|
||||
executing = _Thread_Executing;
|
||||
_CORE_RWLock_Seize_for_writing(
|
||||
&the_rwlock->RWLock,
|
||||
executing,
|
||||
false, /* we are not willing to wait */
|
||||
0
|
||||
);
|
||||
|
||||
_Objects_Put( &the_rwlock->Object );
|
||||
return _POSIX_RWLock_Translate_core_RWLock_return_code(
|
||||
(CORE_RWLock_Status) executing->Wait.return_code
|
||||
);
|
||||
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
case OBJECTS_REMOTE:
|
||||
#endif
|
||||
case OBJECTS_ERROR:
|
||||
break;
|
||||
if ( the_rwlock == NULL ) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
return EINVAL;
|
||||
executing = _Thread_Executing;
|
||||
_CORE_RWLock_Seize_for_writing(
|
||||
&the_rwlock->RWLock,
|
||||
executing,
|
||||
false, /* we are not willing to wait */
|
||||
0,
|
||||
&lock_context
|
||||
);
|
||||
return _POSIX_RWLock_Translate_core_RWLock_return_code(
|
||||
(CORE_RWLock_Status) executing->Wait.return_code
|
||||
);
|
||||
}
|
||||
|
||||
@@ -20,47 +20,22 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/posix/rwlockimpl.h>
|
||||
|
||||
/*
|
||||
* pthread_rwlock_unlock
|
||||
*
|
||||
* This directive attempts to release a lock on an RWLock.
|
||||
*
|
||||
* Input parameters:
|
||||
* rwlock - pointer to rwlock id
|
||||
*
|
||||
* Output parameters:
|
||||
* 0 - if successful
|
||||
* error code - if unsuccessful
|
||||
*/
|
||||
|
||||
int pthread_rwlock_unlock(
|
||||
pthread_rwlock_t *rwlock
|
||||
)
|
||||
{
|
||||
POSIX_RWLock_Control *the_rwlock;
|
||||
Objects_Locations location;
|
||||
CORE_RWLock_Status status;
|
||||
POSIX_RWLock_Control *the_rwlock;
|
||||
ISR_lock_Context lock_context;
|
||||
CORE_RWLock_Status status;
|
||||
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock, &location );
|
||||
switch ( location ) {
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock, &lock_context );
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
status = _CORE_RWLock_Surrender( &the_rwlock->RWLock, _Thread_Executing );
|
||||
_Objects_Put( &the_rwlock->Object );
|
||||
return _POSIX_RWLock_Translate_core_RWLock_return_code( status );
|
||||
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
case OBJECTS_REMOTE:
|
||||
#endif
|
||||
case OBJECTS_ERROR:
|
||||
break;
|
||||
if ( the_rwlock == NULL ) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
return EINVAL;
|
||||
status = _CORE_RWLock_Surrender( &the_rwlock->RWLock, &lock_context );
|
||||
return _POSIX_RWLock_Translate_core_RWLock_return_code( status );
|
||||
}
|
||||
|
||||
@@ -28,51 +28,29 @@
|
||||
|
||||
THREAD_WAIT_QUEUE_OBJECT_ASSERT( POSIX_RWLock_Control, RWLock.Wait_queue );
|
||||
|
||||
/*
|
||||
* pthread_rwlock_wrlock
|
||||
*
|
||||
* This directive attempts to obtain a write only lock on an rwlock instance.
|
||||
*
|
||||
* Input parameters:
|
||||
* rwlock - pointer to rwlock id
|
||||
*
|
||||
* Output parameters:
|
||||
* 0 - if successful
|
||||
* error code - if unsuccessful
|
||||
*/
|
||||
|
||||
int pthread_rwlock_wrlock(
|
||||
pthread_rwlock_t *rwlock
|
||||
)
|
||||
{
|
||||
POSIX_RWLock_Control *the_rwlock;
|
||||
Objects_Locations location;
|
||||
Thread_Control *executing;
|
||||
POSIX_RWLock_Control *the_rwlock;
|
||||
ISR_lock_Context lock_context;
|
||||
Thread_Control *executing;
|
||||
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock, &location );
|
||||
switch ( location ) {
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock, &lock_context );
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
|
||||
executing = _Thread_Executing;
|
||||
_CORE_RWLock_Seize_for_writing(
|
||||
&the_rwlock->RWLock,
|
||||
executing,
|
||||
true, /* do not timeout -- wait forever */
|
||||
0
|
||||
);
|
||||
|
||||
_Objects_Put( &the_rwlock->Object );
|
||||
return _POSIX_RWLock_Translate_core_RWLock_return_code(
|
||||
(CORE_RWLock_Status) executing->Wait.return_code
|
||||
);
|
||||
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
case OBJECTS_REMOTE:
|
||||
#endif
|
||||
case OBJECTS_ERROR:
|
||||
break;
|
||||
if ( the_rwlock == NULL ) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
return EINVAL;
|
||||
executing = _Thread_Executing;
|
||||
_CORE_RWLock_Seize_for_writing(
|
||||
&the_rwlock->RWLock,
|
||||
executing,
|
||||
true, /* do not timeout -- wait forever */
|
||||
0,
|
||||
&lock_context
|
||||
);
|
||||
return _POSIX_RWLock_Translate_core_RWLock_return_code(
|
||||
(CORE_RWLock_Status) executing->Wait.return_code
|
||||
);
|
||||
}
|
||||
|
||||
@@ -86,6 +86,22 @@ RTEMS_INLINE_ROUTINE void _CORE_RWLock_Destroy(
|
||||
_Thread_queue_Destroy( &the_rwlock->Wait_queue );
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _CORE_RWLock_Acquire_critical(
|
||||
CORE_RWLock_Control *the_rwlock,
|
||||
ISR_lock_Context *lock_context
|
||||
)
|
||||
{
|
||||
_Thread_queue_Acquire_critical( &the_rwlock->Wait_queue, lock_context );
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _CORE_RWLock_Release(
|
||||
CORE_RWLock_Control *the_rwlock,
|
||||
ISR_lock_Context *lock_context
|
||||
)
|
||||
{
|
||||
_Thread_queue_Release( &the_rwlock->Wait_queue, lock_context );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Obtain RWLock for reading.
|
||||
*
|
||||
@@ -103,7 +119,8 @@ void _CORE_RWLock_Seize_for_reading(
|
||||
CORE_RWLock_Control *the_rwlock,
|
||||
Thread_Control *executing,
|
||||
bool wait,
|
||||
Watchdog_Interval timeout
|
||||
Watchdog_Interval timeout,
|
||||
ISR_lock_Context *lock_context
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -122,7 +139,8 @@ void _CORE_RWLock_Seize_for_writing(
|
||||
CORE_RWLock_Control *the_rwlock,
|
||||
Thread_Control *executing,
|
||||
bool wait,
|
||||
Watchdog_Interval timeout
|
||||
Watchdog_Interval timeout,
|
||||
ISR_lock_Context *lock_context
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -137,7 +155,7 @@ void _CORE_RWLock_Seize_for_writing(
|
||||
*/
|
||||
CORE_RWLock_Status _CORE_RWLock_Surrender(
|
||||
CORE_RWLock_Control *the_rwlock,
|
||||
Thread_Control *executing
|
||||
ISR_lock_Context *lock_context
|
||||
);
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -27,70 +27,68 @@ void _CORE_RWLock_Seize_for_reading(
|
||||
CORE_RWLock_Control *the_rwlock,
|
||||
Thread_Control *executing,
|
||||
bool wait,
|
||||
Watchdog_Interval timeout
|
||||
Watchdog_Interval timeout,
|
||||
ISR_lock_Context *lock_context
|
||||
)
|
||||
{
|
||||
ISR_lock_Context lock_context;
|
||||
|
||||
/*
|
||||
* If unlocked, then OK to read.
|
||||
* If locked for reading and no waiters, then OK to read.
|
||||
* If any thread is waiting, then we wait.
|
||||
*/
|
||||
|
||||
_Thread_queue_Acquire( &the_rwlock->Wait_queue, &lock_context );
|
||||
switch ( the_rwlock->current_state ) {
|
||||
case CORE_RWLOCK_UNLOCKED:
|
||||
the_rwlock->current_state = CORE_RWLOCK_LOCKED_FOR_READING;
|
||||
the_rwlock->number_of_readers += 1;
|
||||
_Thread_queue_Release( &the_rwlock->Wait_queue, &lock_context );
|
||||
executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
|
||||
return;
|
||||
_CORE_RWLock_Acquire_critical( the_rwlock, lock_context );
|
||||
|
||||
case CORE_RWLOCK_LOCKED_FOR_READING: {
|
||||
Thread_Control *waiter;
|
||||
waiter = _Thread_queue_First_locked(
|
||||
&the_rwlock->Wait_queue,
|
||||
CORE_RWLOCK_TQ_OPERATIONS
|
||||
);
|
||||
if ( !waiter ) {
|
||||
the_rwlock->number_of_readers += 1;
|
||||
_Thread_queue_Release( &the_rwlock->Wait_queue, &lock_context );
|
||||
executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CORE_RWLOCK_LOCKED_FOR_WRITING:
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the thread is not willing to wait, then return immediately.
|
||||
*/
|
||||
|
||||
if ( !wait ) {
|
||||
_Thread_queue_Release( &the_rwlock->Wait_queue, &lock_context );
|
||||
executing->Wait.return_code = CORE_RWLOCK_UNAVAILABLE;
|
||||
switch ( the_rwlock->current_state ) {
|
||||
case CORE_RWLOCK_UNLOCKED:
|
||||
the_rwlock->current_state = CORE_RWLOCK_LOCKED_FOR_READING;
|
||||
the_rwlock->number_of_readers += 1;
|
||||
_CORE_RWLock_Release( the_rwlock, lock_context );
|
||||
executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
|
||||
return;
|
||||
|
||||
case CORE_RWLOCK_LOCKED_FOR_READING: {
|
||||
Thread_Control *waiter;
|
||||
waiter = _Thread_queue_First_locked(
|
||||
&the_rwlock->Wait_queue,
|
||||
CORE_RWLOCK_TQ_OPERATIONS
|
||||
);
|
||||
if ( !waiter ) {
|
||||
the_rwlock->number_of_readers += 1;
|
||||
_CORE_RWLock_Release( the_rwlock, lock_context );
|
||||
executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CORE_RWLOCK_LOCKED_FOR_WRITING:
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to wait to enter this critical section
|
||||
*/
|
||||
/*
|
||||
* If the thread is not willing to wait, then return immediately.
|
||||
*/
|
||||
|
||||
executing->Wait.option = CORE_RWLOCK_THREAD_WAITING_FOR_READ;
|
||||
executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
|
||||
if ( !wait ) {
|
||||
_CORE_RWLock_Release( the_rwlock, lock_context );
|
||||
executing->Wait.return_code = CORE_RWLOCK_UNAVAILABLE;
|
||||
return;
|
||||
}
|
||||
|
||||
_Thread_queue_Enqueue_critical(
|
||||
&the_rwlock->Wait_queue.Queue,
|
||||
CORE_RWLOCK_TQ_OPERATIONS,
|
||||
executing,
|
||||
STATES_WAITING_FOR_RWLOCK,
|
||||
timeout,
|
||||
CORE_RWLOCK_TIMEOUT,
|
||||
&lock_context
|
||||
);
|
||||
/*
|
||||
* We need to wait to enter this critical section
|
||||
*/
|
||||
|
||||
/* return to API level so it can dispatch and we block */
|
||||
executing->Wait.option = CORE_RWLOCK_THREAD_WAITING_FOR_READ;
|
||||
executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
|
||||
|
||||
_Thread_queue_Enqueue_critical(
|
||||
&the_rwlock->Wait_queue.Queue,
|
||||
CORE_RWLOCK_TQ_OPERATIONS,
|
||||
executing,
|
||||
STATES_WAITING_FOR_RWLOCK,
|
||||
timeout,
|
||||
CORE_RWLOCK_TIMEOUT,
|
||||
lock_context
|
||||
);
|
||||
}
|
||||
|
||||
@@ -24,14 +24,13 @@
|
||||
#include <rtems/score/watchdog.h>
|
||||
|
||||
void _CORE_RWLock_Seize_for_writing(
|
||||
CORE_RWLock_Control *the_rwlock,
|
||||
Thread_Control *executing,
|
||||
bool wait,
|
||||
Watchdog_Interval timeout
|
||||
CORE_RWLock_Control *the_rwlock,
|
||||
Thread_Control *executing,
|
||||
bool wait,
|
||||
Watchdog_Interval timeout,
|
||||
ISR_lock_Context *lock_context
|
||||
)
|
||||
{
|
||||
ISR_lock_Context lock_context;
|
||||
|
||||
/*
|
||||
* If unlocked, then OK to read.
|
||||
* Otherwise, we have to block.
|
||||
@@ -39,45 +38,44 @@ void _CORE_RWLock_Seize_for_writing(
|
||||
* If any thread is waiting, then we wait.
|
||||
*/
|
||||
|
||||
_Thread_queue_Acquire( &the_rwlock->Wait_queue, &lock_context );
|
||||
switch ( the_rwlock->current_state ) {
|
||||
case CORE_RWLOCK_UNLOCKED:
|
||||
the_rwlock->current_state = CORE_RWLOCK_LOCKED_FOR_WRITING;
|
||||
_Thread_queue_Release( &the_rwlock->Wait_queue, &lock_context );
|
||||
executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
|
||||
return;
|
||||
_CORE_RWLock_Acquire_critical( the_rwlock, lock_context );
|
||||
|
||||
case CORE_RWLOCK_LOCKED_FOR_READING:
|
||||
case CORE_RWLOCK_LOCKED_FOR_WRITING:
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the thread is not willing to wait, then return immediately.
|
||||
*/
|
||||
|
||||
if ( !wait ) {
|
||||
_Thread_queue_Release( &the_rwlock->Wait_queue, &lock_context );
|
||||
executing->Wait.return_code = CORE_RWLOCK_UNAVAILABLE;
|
||||
switch ( the_rwlock->current_state ) {
|
||||
case CORE_RWLOCK_UNLOCKED:
|
||||
the_rwlock->current_state = CORE_RWLOCK_LOCKED_FOR_WRITING;
|
||||
_CORE_RWLock_Release( the_rwlock, lock_context );
|
||||
executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to wait to enter this critical section
|
||||
*/
|
||||
case CORE_RWLOCK_LOCKED_FOR_READING:
|
||||
case CORE_RWLOCK_LOCKED_FOR_WRITING:
|
||||
break;
|
||||
}
|
||||
|
||||
executing->Wait.option = CORE_RWLOCK_THREAD_WAITING_FOR_WRITE;
|
||||
executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
|
||||
/*
|
||||
* If the thread is not willing to wait, then return immediately.
|
||||
*/
|
||||
|
||||
_Thread_queue_Enqueue_critical(
|
||||
&the_rwlock->Wait_queue.Queue,
|
||||
CORE_RWLOCK_TQ_OPERATIONS,
|
||||
executing,
|
||||
STATES_WAITING_FOR_RWLOCK,
|
||||
timeout,
|
||||
CORE_RWLOCK_TIMEOUT,
|
||||
&lock_context
|
||||
);
|
||||
if ( !wait ) {
|
||||
_CORE_RWLock_Release( the_rwlock, lock_context );
|
||||
executing->Wait.return_code = CORE_RWLOCK_UNAVAILABLE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* return to API level so it can dispatch and we block */
|
||||
/*
|
||||
* We need to wait to enter this critical section
|
||||
*/
|
||||
|
||||
executing->Wait.option = CORE_RWLOCK_THREAD_WAITING_FOR_WRITE;
|
||||
executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
|
||||
|
||||
_Thread_queue_Enqueue_critical(
|
||||
&the_rwlock->Wait_queue.Queue,
|
||||
CORE_RWLOCK_TQ_OPERATIONS,
|
||||
executing,
|
||||
STATES_WAITING_FOR_RWLOCK,
|
||||
timeout,
|
||||
CORE_RWLOCK_TIMEOUT,
|
||||
lock_context
|
||||
);
|
||||
}
|
||||
|
||||
@@ -19,19 +19,65 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/score/corerwlockimpl.h>
|
||||
#include <rtems/score/threadqimpl.h>
|
||||
#include <rtems/score/watchdog.h>
|
||||
#include <rtems/score/assert.h>
|
||||
|
||||
static bool _CORE_RWLock_Is_waiting_for_reading(
|
||||
const Thread_Control *the_thread
|
||||
)
|
||||
{
|
||||
if ( the_thread->Wait.option == CORE_RWLOCK_THREAD_WAITING_FOR_READ ) {
|
||||
return true;
|
||||
} else {
|
||||
_Assert( the_thread->Wait.option == CORE_RWLOCK_THREAD_WAITING_FOR_WRITE );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static Thread_Control *_CORE_RWLock_Flush_filter(
|
||||
Thread_Control *the_thread,
|
||||
Thread_queue_Queue *queue,
|
||||
ISR_lock_Context *lock_context
|
||||
)
|
||||
{
|
||||
CORE_RWLock_Control *the_rwlock;
|
||||
|
||||
the_rwlock = RTEMS_CONTAINER_OF(
|
||||
queue,
|
||||
CORE_RWLock_Control,
|
||||
Wait_queue.Queue
|
||||
);
|
||||
|
||||
switch ( the_rwlock->current_state ) {
|
||||
case CORE_RWLOCK_LOCKED_FOR_READING:
|
||||
if ( _CORE_RWLock_Is_waiting_for_reading( the_thread ) ) {
|
||||
the_rwlock->number_of_readers += 1;
|
||||
} else {
|
||||
the_thread = NULL;
|
||||
}
|
||||
break;
|
||||
case CORE_RWLOCK_LOCKED_FOR_WRITING:
|
||||
the_thread = NULL;
|
||||
break;
|
||||
default:
|
||||
_Assert( the_rwlock->current_state == CORE_RWLOCK_UNLOCKED );
|
||||
if ( _CORE_RWLock_Is_waiting_for_reading( the_thread ) ) {
|
||||
the_rwlock->current_state = CORE_RWLOCK_LOCKED_FOR_READING;
|
||||
the_rwlock->number_of_readers = 1;
|
||||
} else {
|
||||
the_rwlock->current_state = CORE_RWLOCK_LOCKED_FOR_WRITING;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return the_thread;
|
||||
}
|
||||
|
||||
CORE_RWLock_Status _CORE_RWLock_Surrender(
|
||||
CORE_RWLock_Control *the_rwlock,
|
||||
Thread_Control *executing
|
||||
ISR_lock_Context *lock_context
|
||||
)
|
||||
{
|
||||
ISR_Level level;
|
||||
Thread_Control *next;
|
||||
|
||||
/*
|
||||
* If unlocked, then OK to read.
|
||||
* Otherwise, we have to block.
|
||||
@@ -39,67 +85,43 @@ CORE_RWLock_Status _CORE_RWLock_Surrender(
|
||||
* If any thread is waiting, then we wait.
|
||||
*/
|
||||
|
||||
_ISR_Disable( level );
|
||||
if ( the_rwlock->current_state == CORE_RWLOCK_UNLOCKED){
|
||||
_ISR_Enable( level );
|
||||
executing->Wait.return_code = CORE_RWLOCK_UNAVAILABLE;
|
||||
_CORE_RWLock_Acquire_critical( the_rwlock, lock_context );
|
||||
|
||||
if ( the_rwlock->current_state == CORE_RWLOCK_UNLOCKED){
|
||||
/* This is an error at the caller site */
|
||||
_CORE_RWLock_Release( the_rwlock, lock_context );
|
||||
return CORE_RWLOCK_SUCCESSFUL;
|
||||
}
|
||||
|
||||
if ( the_rwlock->current_state == CORE_RWLOCK_LOCKED_FOR_READING ) {
|
||||
the_rwlock->number_of_readers -= 1;
|
||||
|
||||
if ( the_rwlock->number_of_readers != 0 ) {
|
||||
/* must be unlocked again */
|
||||
_CORE_RWLock_Release( the_rwlock, lock_context );
|
||||
return CORE_RWLOCK_SUCCESSFUL;
|
||||
}
|
||||
if ( the_rwlock->current_state == CORE_RWLOCK_LOCKED_FOR_READING ) {
|
||||
the_rwlock->number_of_readers -= 1;
|
||||
if ( the_rwlock->number_of_readers != 0 ) {
|
||||
/* must be unlocked again */
|
||||
_ISR_Enable( level );
|
||||
return CORE_RWLOCK_SUCCESSFUL;
|
||||
}
|
||||
}
|
||||
|
||||
/* CORE_RWLOCK_LOCKED_FOR_WRITING or READING with readers */
|
||||
executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
|
||||
|
||||
/*
|
||||
* Implicitly transition to "unlocked" and find another thread interested
|
||||
* in obtaining this rwlock.
|
||||
*/
|
||||
the_rwlock->current_state = CORE_RWLOCK_UNLOCKED;
|
||||
_ISR_Enable( level );
|
||||
|
||||
next = _Thread_queue_Dequeue(
|
||||
&the_rwlock->Wait_queue,
|
||||
CORE_RWLOCK_TQ_OPERATIONS,
|
||||
NULL,
|
||||
0
|
||||
);
|
||||
|
||||
if ( next ) {
|
||||
if ( next->Wait.option == CORE_RWLOCK_THREAD_WAITING_FOR_WRITE ) {
|
||||
the_rwlock->current_state = CORE_RWLOCK_LOCKED_FOR_WRITING;
|
||||
return CORE_RWLOCK_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Must be CORE_RWLOCK_THREAD_WAITING_FOR_READING
|
||||
*/
|
||||
the_rwlock->number_of_readers += 1;
|
||||
the_rwlock->current_state = CORE_RWLOCK_LOCKED_FOR_READING;
|
||||
|
||||
/*
|
||||
* Now see if more readers can be let go.
|
||||
*/
|
||||
while ( 1 ) {
|
||||
next = _Thread_queue_First(
|
||||
&the_rwlock->Wait_queue,
|
||||
CORE_RWLOCK_TQ_OPERATIONS
|
||||
);
|
||||
if ( !next ||
|
||||
next->Wait.option == CORE_RWLOCK_THREAD_WAITING_FOR_WRITE )
|
||||
return CORE_RWLOCK_SUCCESSFUL;
|
||||
the_rwlock->number_of_readers += 1;
|
||||
_Thread_queue_Extract( next );
|
||||
}
|
||||
}
|
||||
|
||||
/* indentation is to match _ISR_Disable at top */
|
||||
_Assert(
|
||||
the_rwlock->current_state == CORE_RWLOCK_LOCKED_FOR_WRITING
|
||||
|| ( the_rwlock->current_state == CORE_RWLOCK_LOCKED_FOR_READING
|
||||
&& the_rwlock->number_of_readers == 0 )
|
||||
);
|
||||
|
||||
/*
|
||||
* Implicitly transition to "unlocked" and find another thread interested
|
||||
* in obtaining this rwlock.
|
||||
*/
|
||||
the_rwlock->current_state = CORE_RWLOCK_UNLOCKED;
|
||||
|
||||
_Thread_queue_Flush_critical(
|
||||
&the_rwlock->Wait_queue.Queue,
|
||||
CORE_RWLOCK_TQ_OPERATIONS,
|
||||
_CORE_RWLock_Flush_filter,
|
||||
NULL,
|
||||
0,
|
||||
lock_context
|
||||
);
|
||||
return CORE_RWLOCK_SUCCESSFUL;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user