mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-20 16:08:37 +08:00
posix: Implement self-contained POSIX rwlocks
POSIX rwlocks are now available in all configurations and no longer depend on --enable-posix. Update #2514. Update #3115.
This commit is contained in:
@@ -114,7 +114,6 @@ typedef struct {
|
||||
uint32_t active_condition_variables;
|
||||
uint32_t active_message_queues;
|
||||
uint32_t active_mutexes;
|
||||
uint32_t active_rwlocks;
|
||||
uint32_t active_semaphores;
|
||||
uint32_t active_threads;
|
||||
uint32_t active_timers;
|
||||
|
||||
@@ -47,7 +47,6 @@
|
||||
#include <rtems/posix/muteximpl.h>
|
||||
#include <rtems/posix/psignal.h>
|
||||
#include <rtems/posix/pthreadimpl.h>
|
||||
#include <rtems/posix/rwlockimpl.h>
|
||||
#include <rtems/posix/semaphoreimpl.h>
|
||||
#include <rtems/posix/timerimpl.h>
|
||||
#endif
|
||||
@@ -72,7 +71,6 @@ static const struct {
|
||||
{ OBJECTS_POSIX_API, OBJECTS_POSIX_CONDITION_VARIABLES },
|
||||
{ OBJECTS_POSIX_API, OBJECTS_POSIX_MESSAGE_QUEUES },
|
||||
{ OBJECTS_POSIX_API, OBJECTS_POSIX_MUTEXES },
|
||||
{ OBJECTS_POSIX_API, OBJECTS_POSIX_RWLOCKS },
|
||||
{ OBJECTS_POSIX_API, OBJECTS_POSIX_SEMAPHORES },
|
||||
{ OBJECTS_POSIX_API, OBJECTS_POSIX_THREADS },
|
||||
{ OBJECTS_POSIX_API, OBJECTS_POSIX_TIMERS }
|
||||
|
||||
@@ -22,6 +22,7 @@ include_rtems_posix_HEADERS += include/rtems/posix/keyimpl.h
|
||||
include_rtems_posix_HEADERS += include/rtems/posix/config.h
|
||||
include_rtems_posix_HEADERS += include/rtems/posix/posixapi.h
|
||||
include_rtems_posix_HEADERS += include/rtems/posix/priorityimpl.h
|
||||
include_rtems_posix_HEADERS += include/rtems/posix/rwlockimpl.h
|
||||
include_rtems_posix_HEADERS += include/rtems/posix/semaphore.h
|
||||
include_rtems_posix_HEADERS += include/rtems/posix/semaphoreimpl.h
|
||||
include_rtems_posix_HEADERS += include/rtems/posix/spinlockimpl.h
|
||||
@@ -50,8 +51,6 @@ include_rtems_posix_HEADERS += include/rtems/posix/shmimpl.h
|
||||
include_rtems_posix_HEADERS += include/rtems/posix/threadsup.h
|
||||
include_rtems_posix_HEADERS += include/rtems/posix/timer.h
|
||||
include_rtems_posix_HEADERS += include/rtems/posix/timerimpl.h
|
||||
include_rtems_posix_HEADERS += include/rtems/posix/rwlock.h
|
||||
include_rtems_posix_HEADERS += include/rtems/posix/rwlockimpl.h
|
||||
|
||||
## src
|
||||
libposix_a_SOURCES += src/aio_cancel.c src/aio_error.c src/aio_fsync.c \
|
||||
@@ -194,18 +193,14 @@ libposix_a_SOURCES += src/semtimedwait.c
|
||||
libposix_a_SOURCES += src/semtrywait.c
|
||||
libposix_a_SOURCES += src/semwait.c
|
||||
|
||||
if HAS_PTHREADS
|
||||
libposix_a_SOURCES += src/sigpending.c \
|
||||
src/sigqueue.c src/sigsuspend.c src/sigtimedwait.c \
|
||||
src/sigwait.c src/sigwaitinfo.c src/signal_2.c src/ualarm.c
|
||||
|
||||
## RWLOCK_C_FILES
|
||||
libposix_a_SOURCES += src/prwlock.c src/prwlockdestroy.c src/prwlockinit.c \
|
||||
libposix_a_SOURCES += src/prwlockdestroy.c src/prwlockinit.c \
|
||||
src/prwlockrdlock.c src/prwlocktimedrdlock.c src/prwlocktimedwrlock.c \
|
||||
src/prwlocktryrdlock.c src/prwlocktrywrlock.c src/prwlockunlock.c \
|
||||
src/prwlockwrlock.c src/rwlockattrdestroy.c src/rwlockattrgetpshared.c \
|
||||
src/rwlockattrinit.c src/rwlockattrsetpshared.c
|
||||
|
||||
if HAS_PTHREADS
|
||||
## SEMAPHORE_C_FILES
|
||||
libposix_a_SOURCES += src/semaphore.c
|
||||
libposix_a_SOURCES += src/semaphoredeletesupp.c
|
||||
|
||||
@@ -98,12 +98,6 @@ typedef struct {
|
||||
*/
|
||||
uint32_t maximum_semaphores;
|
||||
|
||||
/**
|
||||
* This field contains the maximum number of POSIX API
|
||||
* read/write locks which are configured for this application.
|
||||
*/
|
||||
uint32_t maximum_rwlocks;
|
||||
|
||||
/**
|
||||
* Maximum configured number of POSIX Shared memory objects.
|
||||
*/
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @brief Constants and Structures Associated with the POSIX RWLock Manager
|
||||
*
|
||||
* This include file contains all the constants and structures associated
|
||||
* with the POSIX RWLock Manager.
|
||||
*
|
||||
* Directives provided are:
|
||||
*
|
||||
* - create a RWLock
|
||||
* - delete a RWLock
|
||||
* - wait for a RWLock
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-2011.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#ifndef _RTEMS_POSIX_RWLOCK_H
|
||||
#define _RTEMS_POSIX_RWLOCK_H
|
||||
|
||||
#include <rtems/score/object.h>
|
||||
#include <rtems/score/corerwlock.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup POSIX_RWLOCK POSIX RWLock Manager
|
||||
*
|
||||
* @ingroup POSIXAPI
|
||||
*
|
||||
* @brief Constants and Structures Associated with the POSIX RWLock Manager
|
||||
*
|
||||
*/
|
||||
/**@{**/
|
||||
|
||||
/**
|
||||
* This type defines the control block used to manage each RWLock.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
/** This is used to manage a RWLock as an object. */
|
||||
Objects_Control Object;
|
||||
/** This is used to implement the RWLock. */
|
||||
CORE_RWLock_Control RWLock;
|
||||
} POSIX_RWLock_Control;
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* end of include file */
|
||||
@@ -19,9 +19,7 @@
|
||||
#ifndef _RTEMS_POSIX_RWLOCKIMPL_H
|
||||
#define _RTEMS_POSIX_RWLOCKIMPL_H
|
||||
|
||||
#include <rtems/posix/rwlock.h>
|
||||
#include <rtems/score/corerwlockimpl.h>
|
||||
#include <rtems/score/objectimpl.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
@@ -30,43 +28,33 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The following defines the information control block used to manage
|
||||
* this class of objects.
|
||||
*/
|
||||
#define POSIX_RWLOCK_MAGIC 0x9621dabdUL
|
||||
|
||||
extern Objects_Information _POSIX_RWLock_Information;
|
||||
typedef struct {
|
||||
unsigned long flags;
|
||||
CORE_RWLock_Control RWLock;
|
||||
} POSIX_RWLock_Control;
|
||||
|
||||
/**
|
||||
* @brief Allocate a RWLock control block.
|
||||
*
|
||||
* This function allocates a RWLock control block from
|
||||
* the inactive chain of free RWLock control blocks.
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE POSIX_RWLock_Control *_POSIX_RWLock_Allocate( void )
|
||||
{
|
||||
return (POSIX_RWLock_Control *)
|
||||
_Objects_Allocate( &_POSIX_RWLock_Information );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free a RWLock control block.
|
||||
*
|
||||
* This routine frees a RWLock control block to the
|
||||
* inactive chain of free RWLock control blocks.
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE void _POSIX_RWLock_Free (
|
||||
POSIX_RWLock_Control *the_RWLock
|
||||
RTEMS_INLINE_ROUTINE POSIX_RWLock_Control *_POSIX_RWLock_Get(
|
||||
pthread_rwlock_t *rwlock
|
||||
)
|
||||
{
|
||||
_CORE_RWLock_Destroy( &the_RWLock->RWLock );
|
||||
_Objects_Free( &_POSIX_RWLock_Information, &the_RWLock->Object );
|
||||
return (POSIX_RWLock_Control *) rwlock;
|
||||
}
|
||||
|
||||
POSIX_RWLock_Control *_POSIX_RWLock_Get(
|
||||
pthread_rwlock_t *rwlock,
|
||||
Thread_queue_Context *queue_context
|
||||
);
|
||||
bool _POSIX_RWLock_Auto_initialization( POSIX_RWLock_Control *the_rwlock );
|
||||
|
||||
#define POSIX_RWLOCK_VALIDATE_OBJECT( rw ) \
|
||||
do { \
|
||||
if ( ( rw ) == NULL ) { \
|
||||
return EINVAL; \
|
||||
} \
|
||||
if ( ( (uintptr_t) ( rw ) ^ POSIX_RWLOCK_MAGIC ) != ( rw )->flags ) { \
|
||||
if ( !_POSIX_RWLock_Auto_initialization( rw ) ) { \
|
||||
return EINVAL; \
|
||||
} \
|
||||
} \
|
||||
} while ( 0 )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -51,6 +51,10 @@ $(PROJECT_INCLUDE)/rtems/posix/priorityimpl.h: include/rtems/posix/priorityimpl.
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/priorityimpl.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/priorityimpl.h
|
||||
|
||||
$(PROJECT_INCLUDE)/rtems/posix/rwlockimpl.h: include/rtems/posix/rwlockimpl.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/rwlockimpl.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/rwlockimpl.h
|
||||
|
||||
$(PROJECT_INCLUDE)/rtems/posix/semaphore.h: include/rtems/posix/semaphore.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/semaphore.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/semaphore.h
|
||||
@@ -143,14 +147,6 @@ PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/timer.h
|
||||
$(PROJECT_INCLUDE)/rtems/posix/timerimpl.h: include/rtems/posix/timerimpl.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/timerimpl.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/timerimpl.h
|
||||
|
||||
$(PROJECT_INCLUDE)/rtems/posix/rwlock.h: include/rtems/posix/rwlock.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/rwlock.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/rwlock.h
|
||||
|
||||
$(PROJECT_INCLUDE)/rtems/posix/rwlockimpl.h: include/rtems/posix/rwlockimpl.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/rwlockimpl.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/rwlockimpl.h
|
||||
endif
|
||||
if HAS_PTHREADS
|
||||
endif
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* RWLock Manager -- Initialization
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2008.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/config.h>
|
||||
#include <rtems/sysinit.h>
|
||||
#include <rtems/posix/rwlockimpl.h>
|
||||
|
||||
Objects_Information _POSIX_RWLock_Information;
|
||||
|
||||
/**
|
||||
* @brief _POSIX_RWLock_Manager_initialization
|
||||
*/
|
||||
|
||||
static void _POSIX_RWLock_Manager_initialization(void)
|
||||
{
|
||||
_Objects_Initialize_information(
|
||||
&_POSIX_RWLock_Information, /* object information table */
|
||||
OBJECTS_POSIX_API, /* object API */
|
||||
OBJECTS_POSIX_RWLOCKS, /* object class */
|
||||
Configuration_POSIX_API.maximum_rwlocks,
|
||||
/* maximum objects of this class */
|
||||
sizeof( POSIX_RWLock_Control ), /* size of this object's control block */
|
||||
true, /* true if the name is a string */
|
||||
_POSIX_PATH_MAX, /* maximum length of each object's name */
|
||||
NULL /* Proxy extraction support callout */
|
||||
);
|
||||
}
|
||||
|
||||
RTEMS_SYSINIT_ITEM(
|
||||
_POSIX_RWLock_Manager_initialization,
|
||||
RTEMS_SYSINIT_POSIX_RWLOCK,
|
||||
RTEMS_SYSINIT_ORDER_MIDDLE
|
||||
);
|
||||
@@ -20,29 +20,23 @@
|
||||
#include <rtems/posix/rwlockimpl.h>
|
||||
|
||||
int pthread_rwlock_destroy(
|
||||
pthread_rwlock_t *rwlock
|
||||
pthread_rwlock_t *_rwlock
|
||||
)
|
||||
{
|
||||
POSIX_RWLock_Control *the_rwlock;
|
||||
Thread_queue_Context queue_context;
|
||||
|
||||
_Objects_Allocator_lock();
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock, &queue_context );
|
||||
the_rwlock = _POSIX_RWLock_Get( _rwlock );
|
||||
POSIX_RWLOCK_VALIDATE_OBJECT( the_rwlock );
|
||||
|
||||
if ( the_rwlock == NULL ) {
|
||||
_Objects_Allocator_unlock();
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
_CORE_RWLock_Acquire_critical( &the_rwlock->RWLock, &queue_context );
|
||||
_CORE_RWLock_Acquire( &the_rwlock->RWLock, &queue_context );
|
||||
|
||||
/*
|
||||
* If there is at least one thread waiting, then do not delete it.
|
||||
*/
|
||||
|
||||
if ( !_Thread_queue_Is_empty( &the_rwlock->RWLock.Wait_queue.Queue ) ) {
|
||||
if ( !_Thread_queue_Is_empty( &the_rwlock->RWLock.Queue.Queue ) ) {
|
||||
_CORE_RWLock_Release( &the_rwlock->RWLock, &queue_context );
|
||||
_Objects_Allocator_unlock();
|
||||
return EBUSY;
|
||||
}
|
||||
|
||||
@@ -50,9 +44,7 @@ int pthread_rwlock_destroy(
|
||||
* POSIX doesn't require behavior when it is locked.
|
||||
*/
|
||||
|
||||
_Objects_Close( &_POSIX_RWLock_Information, &the_rwlock->Object );
|
||||
the_rwlock->flags = ~the_rwlock->flags;
|
||||
_CORE_RWLock_Release( &the_rwlock->RWLock, &queue_context );
|
||||
_POSIX_RWLock_Free( the_rwlock );
|
||||
_Objects_Allocator_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -23,35 +23,34 @@
|
||||
#include <rtems/posix/rwlockimpl.h>
|
||||
#include <rtems/posix/posixapi.h>
|
||||
|
||||
POSIX_RWLock_Control *_POSIX_RWLock_Get(
|
||||
pthread_rwlock_t *rwlock,
|
||||
Thread_queue_Context *queue_context
|
||||
)
|
||||
{
|
||||
_POSIX_Get_object_body(
|
||||
POSIX_RWLock_Control,
|
||||
rwlock,
|
||||
queue_context,
|
||||
&_POSIX_RWLock_Information,
|
||||
PTHREAD_RWLOCK_INITIALIZER,
|
||||
pthread_rwlock_init
|
||||
);
|
||||
}
|
||||
RTEMS_STATIC_ASSERT(
|
||||
offsetof( POSIX_RWLock_Control, flags )
|
||||
== offsetof( pthread_rwlock_t, _flags ),
|
||||
POSIX_RWLOCK_CONTROL_FLAGS
|
||||
);
|
||||
|
||||
/*
|
||||
* pthread_rwlock_init
|
||||
*
|
||||
* This directive creates a rwlock. A rwlock id is returned.
|
||||
*
|
||||
* Input parameters:
|
||||
* rwlock - pointer to rwlock id
|
||||
* attr - rwlock attributes
|
||||
*
|
||||
* Output parameters:
|
||||
* rwlock - rwlock id
|
||||
* 0 - if successful
|
||||
* error code - if unsuccessful
|
||||
*/
|
||||
RTEMS_STATIC_ASSERT(
|
||||
offsetof( POSIX_RWLock_Control, RWLock.current_state )
|
||||
== offsetof( pthread_rwlock_t, _current_state ),
|
||||
POSIX_RWLOCK_CONTROL_CURRENT_STATE
|
||||
);
|
||||
|
||||
RTEMS_STATIC_ASSERT(
|
||||
offsetof( POSIX_RWLock_Control, RWLock.number_of_readers )
|
||||
== offsetof( pthread_rwlock_t, _number_of_readers ),
|
||||
POSIX_RWLOCK_CONTROL_NUMBER_OF_READERS
|
||||
);
|
||||
|
||||
RTEMS_STATIC_ASSERT(
|
||||
offsetof( POSIX_RWLock_Control, RWLock.Queue )
|
||||
== offsetof( pthread_rwlock_t, _Queue ),
|
||||
POSIX_RWLOCK_CONTROL_QUEUE
|
||||
);
|
||||
|
||||
RTEMS_STATIC_ASSERT(
|
||||
sizeof( POSIX_RWLock_Control ) == sizeof( pthread_rwlock_t ),
|
||||
POSIX_RWLOCK_CONTROL_SIZE
|
||||
);
|
||||
|
||||
int pthread_rwlock_init(
|
||||
pthread_rwlock_t *rwlock,
|
||||
@@ -60,11 +59,11 @@ int pthread_rwlock_init(
|
||||
{
|
||||
POSIX_RWLock_Control *the_rwlock;
|
||||
|
||||
/*
|
||||
* Error check parameters
|
||||
*/
|
||||
if ( !rwlock )
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock );
|
||||
|
||||
if ( the_rwlock == NULL ) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if ( attr != NULL ) {
|
||||
if ( !attr->is_initialized ) {
|
||||
@@ -76,23 +75,7 @@ int pthread_rwlock_init(
|
||||
}
|
||||
}
|
||||
|
||||
the_rwlock = _POSIX_RWLock_Allocate();
|
||||
|
||||
if ( !the_rwlock ) {
|
||||
_Objects_Allocator_unlock();
|
||||
return EAGAIN;
|
||||
}
|
||||
|
||||
the_rwlock->flags = (uintptr_t) the_rwlock ^ POSIX_RWLOCK_MAGIC;
|
||||
_CORE_RWLock_Initialize( &the_rwlock->RWLock );
|
||||
|
||||
_Objects_Open_u32(
|
||||
&_POSIX_RWLock_Information,
|
||||
&the_rwlock->Object,
|
||||
0
|
||||
);
|
||||
|
||||
*rwlock = the_rwlock->Object.id;
|
||||
|
||||
_Objects_Allocator_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -29,16 +29,13 @@ int pthread_rwlock_rdlock(
|
||||
Thread_queue_Context queue_context;
|
||||
Status_Control status;
|
||||
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock, &queue_context );
|
||||
|
||||
if ( the_rwlock == NULL ) {
|
||||
return EINVAL;
|
||||
}
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock );
|
||||
POSIX_RWLOCK_VALIDATE_OBJECT( the_rwlock );
|
||||
|
||||
_Thread_queue_Context_initialize( &queue_context );
|
||||
_Thread_queue_Context_set_no_timeout( &queue_context );
|
||||
status = _CORE_RWLock_Seize_for_reading(
|
||||
&the_rwlock->RWLock,
|
||||
_Thread_Executing,
|
||||
true, /* we are willing to wait forever */
|
||||
&queue_context
|
||||
);
|
||||
|
||||
@@ -50,16 +50,13 @@ int pthread_rwlock_timedrdlock(
|
||||
timeout_status = _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &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;
|
||||
}
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock );
|
||||
POSIX_RWLOCK_VALIDATE_OBJECT( the_rwlock );
|
||||
|
||||
_Thread_queue_Context_initialize( &queue_context );
|
||||
_Thread_queue_Context_set_relative_timeout( &queue_context, ticks );
|
||||
status = _CORE_RWLock_Seize_for_reading(
|
||||
&the_rwlock->RWLock,
|
||||
_Thread_Executing,
|
||||
do_wait,
|
||||
&queue_context
|
||||
);
|
||||
|
||||
@@ -52,16 +52,13 @@ int pthread_rwlock_timedwrlock(
|
||||
timeout_status = _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &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;
|
||||
}
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock );
|
||||
POSIX_RWLOCK_VALIDATE_OBJECT( the_rwlock );
|
||||
|
||||
_Thread_queue_Context_initialize( &queue_context );
|
||||
_Thread_queue_Context_set_relative_timeout( &queue_context, ticks );
|
||||
status = _CORE_RWLock_Seize_for_writing(
|
||||
&the_rwlock->RWLock,
|
||||
_Thread_Executing,
|
||||
do_wait,
|
||||
&queue_context
|
||||
);
|
||||
|
||||
@@ -29,15 +29,12 @@ int pthread_rwlock_tryrdlock(
|
||||
Thread_queue_Context queue_context;
|
||||
Status_Control status;
|
||||
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock, &queue_context );
|
||||
|
||||
if ( the_rwlock == NULL ) {
|
||||
return EINVAL;
|
||||
}
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock );
|
||||
POSIX_RWLOCK_VALIDATE_OBJECT( the_rwlock );
|
||||
|
||||
_Thread_queue_Context_initialize( &queue_context );
|
||||
status = _CORE_RWLock_Seize_for_reading(
|
||||
&the_rwlock->RWLock,
|
||||
_Thread_Executing,
|
||||
false, /* do not wait for the rwlock */
|
||||
&queue_context
|
||||
);
|
||||
|
||||
@@ -29,15 +29,12 @@ int pthread_rwlock_trywrlock(
|
||||
Thread_queue_Context queue_context;
|
||||
Status_Control status;
|
||||
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock, &queue_context );
|
||||
|
||||
if ( the_rwlock == NULL ) {
|
||||
return EINVAL;
|
||||
}
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock );
|
||||
POSIX_RWLOCK_VALIDATE_OBJECT( the_rwlock );
|
||||
|
||||
_Thread_queue_Context_initialize( &queue_context );
|
||||
status = _CORE_RWLock_Seize_for_writing(
|
||||
&the_rwlock->RWLock,
|
||||
_Thread_Executing,
|
||||
false, /* we are not willing to wait */
|
||||
&queue_context
|
||||
);
|
||||
|
||||
@@ -23,20 +23,32 @@
|
||||
#include <rtems/posix/rwlockimpl.h>
|
||||
#include <rtems/posix/posixapi.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
bool _POSIX_RWLock_Auto_initialization( POSIX_RWLock_Control *the_rwlock )
|
||||
{
|
||||
POSIX_RWLock_Control zero;
|
||||
|
||||
memset( &zero, 0, sizeof( zero ) );
|
||||
|
||||
if ( memcmp( the_rwlock, &zero, sizeof( *the_rwlock ) ) != 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
the_rwlock->flags = POSIX_RWLOCK_MAGIC;
|
||||
return true;
|
||||
}
|
||||
|
||||
int pthread_rwlock_unlock(
|
||||
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 );
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock );
|
||||
POSIX_RWLOCK_VALIDATE_OBJECT( the_rwlock );
|
||||
|
||||
if ( the_rwlock == NULL ) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
status = _CORE_RWLock_Surrender( &the_rwlock->RWLock, &queue_context );
|
||||
status = _CORE_RWLock_Surrender( &the_rwlock->RWLock );
|
||||
return _POSIX_Get_error( status );
|
||||
}
|
||||
|
||||
@@ -23,8 +23,6 @@
|
||||
#include <rtems/posix/rwlockimpl.h>
|
||||
#include <rtems/posix/posixapi.h>
|
||||
|
||||
THREAD_QUEUE_OBJECT_ASSERT( POSIX_RWLock_Control, RWLock.Wait_queue );
|
||||
|
||||
int pthread_rwlock_wrlock(
|
||||
pthread_rwlock_t *rwlock
|
||||
)
|
||||
@@ -33,16 +31,13 @@ int pthread_rwlock_wrlock(
|
||||
Thread_queue_Context queue_context;
|
||||
Status_Control status;
|
||||
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock, &queue_context );
|
||||
|
||||
if ( the_rwlock == NULL ) {
|
||||
return EINVAL;
|
||||
}
|
||||
the_rwlock = _POSIX_RWLock_Get( rwlock );
|
||||
POSIX_RWLOCK_VALIDATE_OBJECT( the_rwlock );
|
||||
|
||||
_Thread_queue_Context_initialize( &queue_context );
|
||||
_Thread_queue_Context_set_no_timeout( &queue_context );
|
||||
status = _CORE_RWLock_Seize_for_writing(
|
||||
&the_rwlock->RWLock,
|
||||
_Thread_Executing,
|
||||
true, /* do not timeout -- wait forever */
|
||||
&queue_context
|
||||
);
|
||||
|
||||
@@ -53,7 +53,6 @@ static const rtems_assoc_t rtems_object_api_posix_assoc[] = {
|
||||
{ "Semaphore", OBJECTS_POSIX_SEMAPHORES, 0},
|
||||
{ "Condition Variable", OBJECTS_POSIX_CONDITION_VARIABLES, 0},
|
||||
{ "Timer", OBJECTS_POSIX_TIMERS, 0},
|
||||
{ "RWLock", OBJECTS_POSIX_RWLOCKS, 0},
|
||||
{ "Shared Memory", OBJECTS_POSIX_SHMS, 0},
|
||||
{ NULL, 0, 0}
|
||||
};
|
||||
|
||||
@@ -2081,10 +2081,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
|
||||
#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES \
|
||||
rtems_resource_unlimited(CONFIGURE_UNLIMITED_ALLOCATION_SIZE)
|
||||
#endif
|
||||
#if !defined(CONFIGURE_MAXIMUM_POSIX_RWLOCKS)
|
||||
#define CONFIGURE_MAXIMUM_POSIX_RWLOCKS \
|
||||
rtems_resource_unlimited(CONFIGURE_UNLIMITED_ALLOCATION_SIZE)
|
||||
#endif
|
||||
#if !defined(CONFIGURE_MAXIMUM_POSIX_SHMS)
|
||||
#define CONFIGURE_MAXIMUM_POSIX_SHMS \
|
||||
rtems_resource_unlimited(CONFIGURE_UNLIMITED_ALLOCATION_SIZE)
|
||||
@@ -2449,7 +2445,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
|
||||
#include <rtems/posix/mutex.h>
|
||||
#include <rtems/posix/psignal.h>
|
||||
#include <rtems/posix/pthread.h>
|
||||
#include <rtems/posix/rwlock.h>
|
||||
#include <rtems/posix/semaphore.h>
|
||||
#include <rtems/posix/shm.h>
|
||||
#include <rtems/posix/threadsup.h>
|
||||
@@ -2566,21 +2561,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
|
||||
_Configure_POSIX_Named_Object_RAM( \
|
||||
_semaphores, sizeof(POSIX_Semaphore_Control) )
|
||||
|
||||
/**
|
||||
* This configuration parameter specifies the maximum number of
|
||||
* POSIX API rwlocks.
|
||||
*/
|
||||
#ifndef CONFIGURE_MAXIMUM_POSIX_RWLOCKS
|
||||
#define CONFIGURE_MAXIMUM_POSIX_RWLOCKS 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This macro is calculated to specify the memory required for
|
||||
* POSIX API rwlocks.
|
||||
*/
|
||||
#define _CONFIGURE_MEMORY_FOR_POSIX_RWLOCKS(_rwlocks) \
|
||||
_Configure_Object_RAM(_rwlocks, sizeof(POSIX_RWLock_Control) )
|
||||
|
||||
/**
|
||||
* Configure the maximum number of POSIX shared memory objects.
|
||||
*/
|
||||
@@ -2822,8 +2802,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
|
||||
CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES) + \
|
||||
_CONFIGURE_MEMORY_FOR_POSIX_SEMAPHORES( \
|
||||
CONFIGURE_MAXIMUM_POSIX_SEMAPHORES) + \
|
||||
_CONFIGURE_MEMORY_FOR_POSIX_RWLOCKS( \
|
||||
CONFIGURE_MAXIMUM_POSIX_RWLOCKS) + \
|
||||
_CONFIGURE_MEMORY_FOR_POSIX_SHMS( \
|
||||
CONFIGURE_MAXIMUM_POSIX_SHMS) + \
|
||||
_CONFIGURE_MEMORY_FOR_POSIX_TIMERS(CONFIGURE_MAXIMUM_POSIX_TIMERS))
|
||||
@@ -3275,7 +3253,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
|
||||
CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS,
|
||||
CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES,
|
||||
CONFIGURE_MAXIMUM_POSIX_SEMAPHORES,
|
||||
CONFIGURE_MAXIMUM_POSIX_RWLOCKS,
|
||||
CONFIGURE_MAXIMUM_POSIX_SHMS,
|
||||
CONFIGURE_POSIX_INIT_THREAD_TABLE_SIZE,
|
||||
CONFIGURE_POSIX_INIT_THREAD_TABLE_NAME
|
||||
@@ -3490,7 +3467,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
|
||||
uint32_t POSIX_QUEUED_SIGNALS;
|
||||
uint32_t POSIX_MESSAGE_QUEUES;
|
||||
uint32_t POSIX_SEMAPHORES;
|
||||
uint32_t POSIX_RWLOCKS;
|
||||
uint32_t POSIX_SHMS;
|
||||
#endif
|
||||
|
||||
@@ -3543,7 +3519,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
|
||||
_CONFIGURE_MEMORY_FOR_POSIX_MESSAGE_QUEUES(
|
||||
CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES ),
|
||||
_CONFIGURE_MEMORY_FOR_POSIX_SEMAPHORES( CONFIGURE_MAXIMUM_POSIX_SEMAPHORES ),
|
||||
_CONFIGURE_MEMORY_FOR_POSIX_RWLOCKS( CONFIGURE_MAXIMUM_POSIX_RWLOCKS ),
|
||||
_CONFIGURE_MEMORY_FOR_POSIX_SHMS( CONFIGURE_MAXIMUM_POSIX_SHMS ),
|
||||
_CONFIGURE_MEMORY_FOR_POSIX_TIMERS( CONFIGURE_MAXIMUM_POSIX_TIMERS ),
|
||||
#endif
|
||||
@@ -3614,7 +3589,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
|
||||
(CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS != 0) || \
|
||||
(CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES != 0) || \
|
||||
(CONFIGURE_MAXIMUM_POSIX_SEMAPHORES != 0) || \
|
||||
(CONFIGURE_MAXIMUM_POSIX_RWLOCKS != 0) || \
|
||||
(CONFIGURE_MAXIMUM_POSIX_SHMS != 0) || \
|
||||
defined(CONFIGURE_POSIX_INIT_THREAD_TABLE))
|
||||
#error "CONFIGURATION ERROR: POSIX API support not configured!!"
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include <rtems/posix/posixapi.h>
|
||||
#include <rtems/posix/barrierimpl.h>
|
||||
#include <rtems/posix/rwlockimpl.h>
|
||||
#include <rtems/posix/semaphoreimpl.h>
|
||||
#include <rtems/score/heap.h>
|
||||
|
||||
@@ -65,12 +66,40 @@ RTEMS_STATIC_ASSERT(
|
||||
POSIX_BARRIER_MAGIC != HEAP_FREE_PATTERN,
|
||||
POSIX_BARRIER_MAGIC_4
|
||||
);
|
||||
RTEMS_STATIC_ASSERT(
|
||||
POSIX_RWLOCK_MAGIC != HEAP_BEGIN_PROTECTOR_0,
|
||||
POSIX_RWLOCK_MAGIC_0
|
||||
);
|
||||
RTEMS_STATIC_ASSERT(
|
||||
POSIX_RWLOCK_MAGIC != HEAP_BEGIN_PROTECTOR_1,
|
||||
POSIX_RWLOCK_MAGIC_1
|
||||
);
|
||||
RTEMS_STATIC_ASSERT(
|
||||
POSIX_RWLOCK_MAGIC != HEAP_END_PROTECTOR_0,
|
||||
POSIX_RWLOCK_MAGIC_2
|
||||
);
|
||||
RTEMS_STATIC_ASSERT(
|
||||
POSIX_RWLOCK_MAGIC != HEAP_END_PROTECTOR_1,
|
||||
POSIX_RWLOCK_MAGIC_3
|
||||
);
|
||||
RTEMS_STATIC_ASSERT(
|
||||
POSIX_RWLOCK_MAGIC != HEAP_FREE_PATTERN,
|
||||
POSIX_RWLOCK_MAGIC_4
|
||||
);
|
||||
#endif
|
||||
|
||||
RTEMS_STATIC_ASSERT(
|
||||
POSIX_SEMAPHORE_MAGIC != POSIX_BARRIER_MAGIC,
|
||||
POSIX_SEMAPHORE_MAGIC_5
|
||||
);
|
||||
RTEMS_STATIC_ASSERT(
|
||||
POSIX_SEMAPHORE_MAGIC != POSIX_RWLOCK_MAGIC,
|
||||
POSIX_SEMAPHORE_MAGIC_6
|
||||
);
|
||||
RTEMS_STATIC_ASSERT(
|
||||
POSIX_BARRIER_MAGIC != POSIX_RWLOCK_MAGIC,
|
||||
POSIX_BARRIER_MAGIC_5
|
||||
);
|
||||
|
||||
void _POSIX_Fatal_error( POSIX_Fatal_domain domain, int eno )
|
||||
{
|
||||
|
||||
@@ -38,6 +38,7 @@ include_rtems_score_HEADERS += include/rtems/score/coremsg.h
|
||||
include_rtems_score_HEADERS += include/rtems/score/coremsgimpl.h
|
||||
include_rtems_score_HEADERS += include/rtems/score/coremutex.h
|
||||
include_rtems_score_HEADERS += include/rtems/score/coremuteximpl.h
|
||||
include_rtems_score_HEADERS += include/rtems/score/corerwlockimpl.h
|
||||
include_rtems_score_HEADERS += include/rtems/score/coresem.h
|
||||
include_rtems_score_HEADERS += include/rtems/score/coresemimpl.h
|
||||
include_rtems_score_HEADERS += include/rtems/score/cpuset.h
|
||||
@@ -112,11 +113,6 @@ include_rtems_score_HEADERS += include/rtems/score/wkspace.h
|
||||
include_rtems_score_HEADERS += include/rtems/score/cpuopts.h
|
||||
include_rtems_score_HEADERS += include/rtems/score/basedefs.h
|
||||
|
||||
if HAS_PTHREADS
|
||||
include_rtems_score_HEADERS += include/rtems/score/corerwlock.h
|
||||
include_rtems_score_HEADERS += include/rtems/score/corerwlockimpl.h
|
||||
endif
|
||||
|
||||
if HAS_MP
|
||||
# We only build multiprocessing related files if HAS_MP was defined
|
||||
include_rtems_score_HEADERS += include/rtems/score/mpci.h
|
||||
@@ -189,10 +185,8 @@ libscore_a_SOURCES += src/percpu.c
|
||||
libscore_a_SOURCES += src/percpuasm.c
|
||||
|
||||
## CORE_RWLOCK_C_FILES
|
||||
if HAS_PTHREADS
|
||||
libscore_a_SOURCES += src/corerwlock.c src/corerwlockobtainread.c \
|
||||
src/corerwlockobtainwrite.c src/corerwlockrelease.c
|
||||
endif
|
||||
|
||||
## CORE_SEMAPHORE_C_FILES
|
||||
libscore_a_SOURCES += src/coresem.c
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
/**
|
||||
* @file rtems/score/corerwlock.h
|
||||
*
|
||||
* @brief Constants and Structures Associated with the RWLock Handler
|
||||
*
|
||||
* This include file contains all the constants and structures associated
|
||||
* with the RWLock Handler.
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-2008.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#ifndef _RTEMS_SCORE_CORERWLOCK_H
|
||||
#define _RTEMS_SCORE_CORERWLOCK_H
|
||||
|
||||
#include <rtems/score/threadq.h>
|
||||
|
||||
/**
|
||||
* @defgroup ScoreRWLock RWLock Handler
|
||||
*
|
||||
* @ingroup Score
|
||||
*
|
||||
* This handler encapsulates functionality which provides the foundation
|
||||
* RWLock services used in all of the APIs supported by RTEMS.
|
||||
*/
|
||||
/**@{*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* RWLock State.
|
||||
*/
|
||||
typedef enum {
|
||||
/** This indicates the the RWLock is not currently locked.
|
||||
*/
|
||||
CORE_RWLOCK_UNLOCKED,
|
||||
/** This indicates the the RWLock is currently locked for reading.
|
||||
*/
|
||||
CORE_RWLOCK_LOCKED_FOR_READING,
|
||||
/** This indicates the the RWLock is currently locked for reading.
|
||||
*/
|
||||
CORE_RWLOCK_LOCKED_FOR_WRITING
|
||||
} CORE_RWLock_States;
|
||||
|
||||
/**
|
||||
* The following defines the control block used to manage each
|
||||
* RWLock.
|
||||
*/
|
||||
typedef struct {
|
||||
/** This field is the Waiting Queue used to manage the set of tasks
|
||||
* which are blocked waiting for the RWLock to be released.
|
||||
*/
|
||||
Thread_queue_Control Wait_queue;
|
||||
/** This element is the current state of the RWLock.
|
||||
*/
|
||||
CORE_RWLock_States current_state;
|
||||
/** This element contains the current number of thread waiting for this
|
||||
* RWLock to be released. */
|
||||
uint32_t number_of_readers;
|
||||
} CORE_RWLock_Control;
|
||||
|
||||
/**@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* end of include file */
|
||||
@@ -19,10 +19,10 @@
|
||||
#ifndef _RTEMS_SCORE_CORERWLOCKIMPL_H
|
||||
#define _RTEMS_SCORE_CORERWLOCKIMPL_H
|
||||
|
||||
#include <rtems/score/corerwlock.h>
|
||||
#include <rtems/score/percpu.h>
|
||||
#include <rtems/score/status.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/threadqimpl.h>
|
||||
#include <rtems/score/status.h>
|
||||
#include <rtems/score/watchdog.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -48,6 +48,40 @@ extern "C" {
|
||||
*/
|
||||
#define CORE_RWLOCK_THREAD_WAITING_FOR_WRITE 1
|
||||
|
||||
/**
|
||||
* RWLock State.
|
||||
*/
|
||||
typedef enum {
|
||||
/** This indicates the the RWLock is not currently locked.
|
||||
*/
|
||||
CORE_RWLOCK_UNLOCKED,
|
||||
/** This indicates the the RWLock is currently locked for reading.
|
||||
*/
|
||||
CORE_RWLOCK_LOCKED_FOR_READING,
|
||||
/** This indicates the the RWLock is currently locked for reading.
|
||||
*/
|
||||
CORE_RWLOCK_LOCKED_FOR_WRITING
|
||||
} CORE_RWLock_States;
|
||||
|
||||
/**
|
||||
* The following defines the control block used to manage each
|
||||
* RWLock.
|
||||
*/
|
||||
typedef struct {
|
||||
/** This field is the Waiting Queue used to manage the set of tasks
|
||||
* which are blocked waiting for the RWLock to be released.
|
||||
*/
|
||||
Thread_queue_Syslock_queue Queue;
|
||||
|
||||
/** This element is the current state of the RWLock.
|
||||
*/
|
||||
CORE_RWLock_States current_state;
|
||||
|
||||
/** This element contains the current number of thread waiting for this
|
||||
* RWLock to be released. */
|
||||
unsigned int number_of_readers;
|
||||
} CORE_RWLock_Control;
|
||||
|
||||
/**
|
||||
* @brief Initialize a RWlock.
|
||||
*
|
||||
@@ -63,15 +97,27 @@ RTEMS_INLINE_ROUTINE void _CORE_RWLock_Destroy(
|
||||
CORE_RWLock_Control *the_rwlock
|
||||
)
|
||||
{
|
||||
_Thread_queue_Destroy( &the_rwlock->Wait_queue );
|
||||
(void) the_rwlock;
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _CORE_RWLock_Acquire_critical(
|
||||
RTEMS_INLINE_ROUTINE Thread_Control *_CORE_RWLock_Acquire(
|
||||
CORE_RWLock_Control *the_rwlock,
|
||||
Thread_queue_Context *queue_context
|
||||
)
|
||||
{
|
||||
_Thread_queue_Acquire_critical( &the_rwlock->Wait_queue, queue_context );
|
||||
ISR_Level level;
|
||||
Thread_Control *executing;
|
||||
|
||||
_Thread_queue_Context_ISR_disable( queue_context, level );
|
||||
_Thread_queue_Context_set_ISR_level( queue_context, level );
|
||||
executing = _Thread_Executing;
|
||||
_Thread_queue_Queue_acquire_critical(
|
||||
&the_rwlock->Queue.Queue,
|
||||
&executing->Potpourri_stats,
|
||||
&queue_context->Lock_context.Lock_context
|
||||
);
|
||||
|
||||
return executing;
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _CORE_RWLock_Release(
|
||||
@@ -79,7 +125,10 @@ RTEMS_INLINE_ROUTINE void _CORE_RWLock_Release(
|
||||
Thread_queue_Context *queue_context
|
||||
)
|
||||
{
|
||||
_Thread_queue_Release( &the_rwlock->Wait_queue, queue_context );
|
||||
_Thread_queue_Queue_release(
|
||||
&the_rwlock->Queue.Queue,
|
||||
&queue_context->Lock_context.Lock_context
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,7 +142,6 @@ RTEMS_INLINE_ROUTINE void _CORE_RWLock_Release(
|
||||
|
||||
Status_Control _CORE_RWLock_Seize_for_reading(
|
||||
CORE_RWLock_Control *the_rwlock,
|
||||
Thread_Control *executing,
|
||||
bool wait,
|
||||
Thread_queue_Context *queue_context
|
||||
);
|
||||
@@ -108,7 +156,6 @@ Status_Control _CORE_RWLock_Seize_for_reading(
|
||||
*/
|
||||
Status_Control _CORE_RWLock_Seize_for_writing(
|
||||
CORE_RWLock_Control *the_rwlock,
|
||||
Thread_Control *executing,
|
||||
bool wait,
|
||||
Thread_queue_Context *queue_context
|
||||
);
|
||||
@@ -123,10 +170,7 @@ Status_Control _CORE_RWLock_Seize_for_writing(
|
||||
*
|
||||
* @retval Status is returned to indicate successful or failure.
|
||||
*/
|
||||
Status_Control _CORE_RWLock_Surrender(
|
||||
CORE_RWLock_Control *the_rwlock,
|
||||
Thread_queue_Context *queue_context
|
||||
);
|
||||
Status_Control _CORE_RWLock_Surrender( CORE_RWLock_Control *the_rwlock );
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
@@ -91,7 +91,6 @@ typedef enum {
|
||||
OBJECTS_POSIX_SEMAPHORES = 7,
|
||||
OBJECTS_POSIX_CONDITION_VARIABLES = 8,
|
||||
OBJECTS_POSIX_TIMERS = 9,
|
||||
OBJECTS_POSIX_RWLOCKS = 11,
|
||||
OBJECTS_POSIX_SHMS = 12
|
||||
} Objects_POSIX_API;
|
||||
|
||||
|
||||
@@ -52,7 +52,6 @@ extern "C" {
|
||||
#define RTEMS_SYSINIT_POSIX_MESSAGE_QUEUE 000364
|
||||
#define RTEMS_SYSINIT_POSIX_SEMAPHORE 000365
|
||||
#define RTEMS_SYSINIT_POSIX_TIMER 000366
|
||||
#define RTEMS_SYSINIT_POSIX_RWLOCK 000368
|
||||
#define RTEMS_SYSINIT_POSIX_SHM 000369
|
||||
#define RTEMS_SYSINIT_POSIX_KEYS 00036a
|
||||
#define RTEMS_SYSINIT_POSIX_CLEANUP 00036b
|
||||
|
||||
@@ -120,6 +120,10 @@ $(PROJECT_INCLUDE)/rtems/score/coremuteximpl.h: include/rtems/score/coremuteximp
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/coremuteximpl.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/coremuteximpl.h
|
||||
|
||||
$(PROJECT_INCLUDE)/rtems/score/corerwlockimpl.h: include/rtems/score/corerwlockimpl.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/corerwlockimpl.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/corerwlockimpl.h
|
||||
|
||||
$(PROJECT_INCLUDE)/rtems/score/coresem.h: include/rtems/score/coresem.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/coresem.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/coresem.h
|
||||
@@ -412,15 +416,6 @@ $(PROJECT_INCLUDE)/rtems/score/basedefs.h: include/rtems/score/basedefs.h $(PROJ
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/basedefs.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/basedefs.h
|
||||
|
||||
if HAS_PTHREADS
|
||||
$(PROJECT_INCLUDE)/rtems/score/corerwlock.h: include/rtems/score/corerwlock.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/corerwlock.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/corerwlock.h
|
||||
|
||||
$(PROJECT_INCLUDE)/rtems/score/corerwlockimpl.h: include/rtems/score/corerwlockimpl.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/corerwlockimpl.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/corerwlockimpl.h
|
||||
endif
|
||||
if HAS_MP
|
||||
$(PROJECT_INCLUDE)/rtems/score/mpci.h: include/rtems/score/mpci.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/mpci.h
|
||||
|
||||
@@ -27,6 +27,5 @@ void _CORE_RWLock_Initialize(
|
||||
{
|
||||
the_rwlock->number_of_readers = 0;
|
||||
the_rwlock->current_state = CORE_RWLOCK_UNLOCKED;
|
||||
|
||||
_Thread_queue_Object_initialize( &the_rwlock->Wait_queue );
|
||||
_Thread_queue_Queue_initialize( &the_rwlock->Queue.Queue, NULL );
|
||||
}
|
||||
|
||||
@@ -26,18 +26,19 @@
|
||||
|
||||
Status_Control _CORE_RWLock_Seize_for_reading(
|
||||
CORE_RWLock_Control *the_rwlock,
|
||||
Thread_Control *executing,
|
||||
bool wait,
|
||||
Thread_queue_Context *queue_context
|
||||
)
|
||||
{
|
||||
Thread_Control *executing;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
_CORE_RWLock_Acquire_critical( the_rwlock, queue_context );
|
||||
executing = _CORE_RWLock_Acquire( the_rwlock, queue_context );
|
||||
|
||||
switch ( the_rwlock->current_state ) {
|
||||
case CORE_RWLOCK_UNLOCKED:
|
||||
@@ -46,19 +47,13 @@ Status_Control _CORE_RWLock_Seize_for_reading(
|
||||
_CORE_RWLock_Release( the_rwlock, queue_context );
|
||||
return STATUS_SUCCESSFUL;
|
||||
|
||||
case CORE_RWLOCK_LOCKED_FOR_READING: {
|
||||
Thread_Control *waiter;
|
||||
waiter = _Thread_queue_First_locked(
|
||||
&the_rwlock->Wait_queue,
|
||||
CORE_RWLOCK_TQ_OPERATIONS
|
||||
);
|
||||
if ( !waiter ) {
|
||||
case CORE_RWLOCK_LOCKED_FOR_READING:
|
||||
if ( _Thread_queue_Is_empty( &the_rwlock->Queue.Queue ) ) {
|
||||
the_rwlock->number_of_readers += 1;
|
||||
_CORE_RWLock_Release( the_rwlock, queue_context );
|
||||
return STATUS_SUCCESSFUL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CORE_RWLOCK_LOCKED_FOR_WRITING:
|
||||
break;
|
||||
}
|
||||
@@ -84,7 +79,7 @@ Status_Control _CORE_RWLock_Seize_for_reading(
|
||||
);
|
||||
_Thread_queue_Context_set_do_nothing_enqueue_callout( queue_context );
|
||||
_Thread_queue_Enqueue(
|
||||
&the_rwlock->Wait_queue.Queue,
|
||||
&the_rwlock->Queue.Queue,
|
||||
CORE_RWLOCK_TQ_OPERATIONS,
|
||||
executing,
|
||||
queue_context
|
||||
|
||||
@@ -26,11 +26,12 @@
|
||||
|
||||
Status_Control _CORE_RWLock_Seize_for_writing(
|
||||
CORE_RWLock_Control *the_rwlock,
|
||||
Thread_Control *executing,
|
||||
bool wait,
|
||||
Thread_queue_Context *queue_context
|
||||
)
|
||||
{
|
||||
Thread_Control *executing;
|
||||
|
||||
/*
|
||||
* If unlocked, then OK to read.
|
||||
* Otherwise, we have to block.
|
||||
@@ -38,7 +39,7 @@ Status_Control _CORE_RWLock_Seize_for_writing(
|
||||
* If any thread is waiting, then we wait.
|
||||
*/
|
||||
|
||||
_CORE_RWLock_Acquire_critical( the_rwlock, queue_context );
|
||||
executing = _CORE_RWLock_Acquire( the_rwlock, queue_context );
|
||||
|
||||
switch ( the_rwlock->current_state ) {
|
||||
case CORE_RWLOCK_UNLOCKED:
|
||||
@@ -72,7 +73,7 @@ Status_Control _CORE_RWLock_Seize_for_writing(
|
||||
);
|
||||
_Thread_queue_Context_set_do_nothing_enqueue_callout( queue_context );
|
||||
_Thread_queue_Enqueue(
|
||||
&the_rwlock->Wait_queue.Queue,
|
||||
&the_rwlock->Queue.Queue,
|
||||
CORE_RWLOCK_TQ_OPERATIONS,
|
||||
executing,
|
||||
queue_context
|
||||
|
||||
@@ -45,7 +45,7 @@ static Thread_Control *_CORE_RWLock_Flush_filter(
|
||||
the_rwlock = RTEMS_CONTAINER_OF(
|
||||
queue,
|
||||
CORE_RWLock_Control,
|
||||
Wait_queue.Queue
|
||||
Queue.Queue
|
||||
);
|
||||
|
||||
switch ( the_rwlock->current_state ) {
|
||||
@@ -73,11 +73,10 @@ static Thread_Control *_CORE_RWLock_Flush_filter(
|
||||
return the_thread;
|
||||
}
|
||||
|
||||
Status_Control _CORE_RWLock_Surrender(
|
||||
CORE_RWLock_Control *the_rwlock,
|
||||
Thread_queue_Context *queue_context
|
||||
)
|
||||
Status_Control _CORE_RWLock_Surrender( CORE_RWLock_Control *the_rwlock )
|
||||
{
|
||||
Thread_queue_Context queue_context;
|
||||
|
||||
/*
|
||||
* If unlocked, then OK to read.
|
||||
* Otherwise, we have to block.
|
||||
@@ -85,11 +84,12 @@ Status_Control _CORE_RWLock_Surrender(
|
||||
* If any thread is waiting, then we wait.
|
||||
*/
|
||||
|
||||
_CORE_RWLock_Acquire_critical( the_rwlock, queue_context );
|
||||
_Thread_queue_Context_initialize( &queue_context );
|
||||
_CORE_RWLock_Acquire( the_rwlock, &queue_context );
|
||||
|
||||
if ( the_rwlock->current_state == CORE_RWLOCK_UNLOCKED){
|
||||
/* This is an error at the caller site */
|
||||
_CORE_RWLock_Release( the_rwlock, queue_context );
|
||||
_CORE_RWLock_Release( the_rwlock, &queue_context );
|
||||
return STATUS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ Status_Control _CORE_RWLock_Surrender(
|
||||
|
||||
if ( the_rwlock->number_of_readers != 0 ) {
|
||||
/* must be unlocked again */
|
||||
_CORE_RWLock_Release( the_rwlock, queue_context );
|
||||
_CORE_RWLock_Release( the_rwlock, &queue_context );
|
||||
return STATUS_SUCCESSFUL;
|
||||
}
|
||||
}
|
||||
@@ -116,10 +116,10 @@ Status_Control _CORE_RWLock_Surrender(
|
||||
the_rwlock->current_state = CORE_RWLOCK_UNLOCKED;
|
||||
|
||||
_Thread_queue_Flush_critical(
|
||||
&the_rwlock->Wait_queue.Queue,
|
||||
&the_rwlock->Queue.Queue,
|
||||
CORE_RWLOCK_TQ_OPERATIONS,
|
||||
_CORE_RWLock_Flush_filter,
|
||||
queue_context
|
||||
&queue_context
|
||||
);
|
||||
return STATUS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,6 @@ const char rtems_test_name[] = "PSXCONFIG 1";
|
||||
#define POSIX_MQ_COUNT 5
|
||||
#define CONFIGURE_MAXIMUM_POSIX_MUTEXES 19
|
||||
#define CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS 7
|
||||
#define CONFIGURE_MAXIMUM_POSIX_RWLOCKS 31
|
||||
#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 41
|
||||
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
|
||||
|
||||
@@ -474,18 +473,6 @@ static rtems_task Init(rtems_task_argument argument)
|
||||
);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIGURE_MAXIMUM_POSIX_RWLOCKS
|
||||
for (i = 0; i < CONFIGURE_MAXIMUM_POSIX_RWLOCKS; ++i) {
|
||||
pthread_rwlock_t rwlock;
|
||||
eno = pthread_rwlock_init(&rwlock, NULL);
|
||||
rtems_test_assert(eno == 0);
|
||||
}
|
||||
rtems_resource_snapshot_take(&snapshot);
|
||||
rtems_test_assert(
|
||||
snapshot.posix_api.active_rwlocks == CONFIGURE_MAXIMUM_POSIX_RWLOCKS
|
||||
);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIGURE_MAXIMUM_POSIX_SEMAPHORES
|
||||
for (i = 0; i < CONFIGURE_MAXIMUM_POSIX_SEMAPHORES; ++i) {
|
||||
int oflag = O_RDWR | O_CREAT | O_EXCL;
|
||||
|
||||
@@ -39,7 +39,6 @@ rtems_task Init(
|
||||
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
|
||||
|
||||
#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
|
||||
#define CONFIGURE_MAXIMUM_POSIX_RWLOCKS 1
|
||||
|
||||
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*** POSIX RWLOCK TEST 01 ***
|
||||
*** BEGIN OF TEST PSXRWLOCK 1 ***
|
||||
pthread_rwlockattr_init( NULL ) -- EINVAL
|
||||
pthread_rwlockattr_setpshared( NULL, private ) -- EINVAL
|
||||
pthread_rwlockattr_setpshared( NULL, shared ) -- EINVAL
|
||||
@@ -37,7 +37,6 @@ pthread_rwlock_trywrlock(BadId) -- EINVAL
|
||||
pthread_rwlock_unlock(BadId) -- EINVAL
|
||||
pthread_rwlockattr_init( &attr ) -- OK
|
||||
pthread_rwlock_init( &rwlock, &attr ) -- OK
|
||||
pthread_rwlock_init( &rwlock, &attr ) -- EAGAIN
|
||||
pthread_rwlock_destroy( &rwlock ) -- OK
|
||||
pthread_rwlock_init( &rwlock, NULL ) -- OK
|
||||
pthread_rwlock_destroy( &rwlock ) -- OK
|
||||
@@ -94,4 +93,4 @@ pthread_rwlock_destroy( &RWLock ) -- OK
|
||||
pthread_rwlock_init( &rwlock, NULL ) -- OK
|
||||
pthread_rwlock_unlock ( &rwlock ) -- OK
|
||||
pthread_rwlock_unlock ( &rwlock ) -- OK
|
||||
*** END OF POSIX RWLOCK TEST 01 ***
|
||||
*** END OF TEST PSXRWLOCK 1 ***
|
||||
|
||||
@@ -90,7 +90,7 @@ void *WriteLockThread(void *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void test_pshared_init(void)
|
||||
static void test_rwlock_pshared_init(void)
|
||||
{
|
||||
pthread_rwlock_t rwlock;
|
||||
pthread_rwlockattr_t attr;
|
||||
@@ -126,6 +126,193 @@ static void test_pshared_init(void)
|
||||
rtems_test_assert(eno == 0);
|
||||
}
|
||||
|
||||
static void test_rwlock_null( void )
|
||||
{
|
||||
struct timespec to;
|
||||
int eno;
|
||||
|
||||
eno = pthread_rwlock_destroy( NULL );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
|
||||
eno = pthread_rwlock_init( NULL, NULL );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
|
||||
eno = pthread_rwlock_rdlock( NULL );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
|
||||
to.tv_sec = 1;
|
||||
to.tv_nsec = 1;
|
||||
eno = pthread_rwlock_timedrdlock( NULL, &to );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
|
||||
to.tv_sec = 1;
|
||||
to.tv_nsec = 1;
|
||||
eno = pthread_rwlock_timedwrlock( NULL, &to );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
|
||||
eno = pthread_rwlock_tryrdlock( NULL );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
|
||||
eno = pthread_rwlock_trywrlock( NULL );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
|
||||
eno = pthread_rwlock_unlock( NULL );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
|
||||
eno = pthread_rwlock_wrlock( NULL );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
}
|
||||
|
||||
static void test_rwlock_not_initialized( void )
|
||||
{
|
||||
pthread_rwlock_t rw;
|
||||
struct timespec to;
|
||||
int eno;
|
||||
|
||||
memset( &rw, 0xff, sizeof( rw ) );
|
||||
|
||||
eno = pthread_rwlock_destroy( &rw );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
|
||||
eno = pthread_rwlock_rdlock( &rw );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
|
||||
to.tv_sec = 1;
|
||||
to.tv_nsec = 1;
|
||||
eno = pthread_rwlock_timedrdlock( &rw, &to );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
|
||||
to.tv_sec = 1;
|
||||
to.tv_nsec = 1;
|
||||
eno = pthread_rwlock_timedwrlock( &rw, &to );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
|
||||
eno = pthread_rwlock_tryrdlock( &rw );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
|
||||
eno = pthread_rwlock_trywrlock( &rw );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
|
||||
eno = pthread_rwlock_unlock( &rw );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
|
||||
eno = pthread_rwlock_wrlock( &rw );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
}
|
||||
|
||||
static void test_rwlock_invalid_copy( void )
|
||||
{
|
||||
pthread_rwlock_t rw;
|
||||
pthread_rwlock_t rw2;
|
||||
struct timespec to;
|
||||
int eno;
|
||||
|
||||
eno = pthread_rwlock_init( &rw, NULL );
|
||||
rtems_test_assert( eno == 0 );
|
||||
|
||||
memcpy( &rw2, &rw, sizeof( rw2 ) );
|
||||
|
||||
eno = pthread_rwlock_destroy( &rw2 );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
|
||||
eno = pthread_rwlock_rdlock( &rw2 );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
|
||||
to.tv_sec = 1;
|
||||
to.tv_nsec = 1;
|
||||
eno = pthread_rwlock_timedrdlock( &rw2, &to );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
|
||||
to.tv_sec = 1;
|
||||
to.tv_nsec = 1;
|
||||
eno = pthread_rwlock_timedwrlock( &rw2, &to );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
|
||||
eno = pthread_rwlock_tryrdlock( &rw2 );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
|
||||
eno = pthread_rwlock_trywrlock( &rw2 );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
|
||||
eno = pthread_rwlock_unlock( &rw2 );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
|
||||
eno = pthread_rwlock_wrlock( &rw2 );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
|
||||
eno = pthread_rwlock_destroy( &rw );
|
||||
rtems_test_assert( eno == 0 );
|
||||
}
|
||||
|
||||
static void test_rwlock_auto_initialization( void )
|
||||
{
|
||||
struct timespec to;
|
||||
int eno;
|
||||
|
||||
{
|
||||
static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
|
||||
|
||||
eno = pthread_rwlock_destroy( &rw );
|
||||
rtems_test_assert( eno == 0 );
|
||||
|
||||
eno = pthread_rwlock_destroy( &rw );
|
||||
rtems_test_assert( eno == EINVAL );
|
||||
}
|
||||
|
||||
{
|
||||
static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
|
||||
|
||||
eno = pthread_rwlock_rdlock( &rw );
|
||||
rtems_test_assert( eno == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
|
||||
|
||||
to.tv_sec = 1;
|
||||
to.tv_nsec = 1;
|
||||
eno = pthread_rwlock_timedrdlock( &rw, &to );
|
||||
rtems_test_assert( eno == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
|
||||
|
||||
to.tv_sec = 1;
|
||||
to.tv_nsec = 1;
|
||||
eno = pthread_rwlock_timedwrlock( &rw, &to );
|
||||
rtems_test_assert( eno == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
|
||||
|
||||
eno = pthread_rwlock_tryrdlock( &rw );
|
||||
rtems_test_assert( eno == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
|
||||
|
||||
eno = pthread_rwlock_trywrlock( &rw );
|
||||
rtems_test_assert( eno == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
|
||||
|
||||
eno = pthread_rwlock_unlock( &rw );
|
||||
rtems_test_assert( eno == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
|
||||
|
||||
eno = pthread_rwlock_wrlock( &rw );
|
||||
rtems_test_assert( eno == 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* main entry point to the test
|
||||
*/
|
||||
@@ -140,7 +327,6 @@ int main(
|
||||
#endif
|
||||
{
|
||||
pthread_rwlock_t rwlock;
|
||||
pthread_rwlock_t rwlock2;
|
||||
pthread_rwlockattr_t attr;
|
||||
int status;
|
||||
int p;
|
||||
@@ -149,7 +335,11 @@ int main(
|
||||
|
||||
TEST_BEGIN();
|
||||
|
||||
test_pshared_init();
|
||||
test_rwlock_pshared_init();
|
||||
test_rwlock_null();
|
||||
test_rwlock_not_initialized();
|
||||
test_rwlock_invalid_copy();
|
||||
test_rwlock_auto_initialization();
|
||||
|
||||
/*************** NULL POINTER CHECKS *****************/
|
||||
puts( "pthread_rwlockattr_init( NULL ) -- EINVAL" );
|
||||
@@ -192,42 +382,6 @@ int main(
|
||||
status = pthread_rwlockattr_setpshared( &attr, ~PTHREAD_PROCESS_PRIVATE );
|
||||
rtems_test_assert( status == EINVAL );
|
||||
|
||||
/*************** AUTO INITIALIZATION *****************/
|
||||
|
||||
rwlock = PTHREAD_RWLOCK_INITIALIZER;
|
||||
rwlock2 = PTHREAD_RWLOCK_INITIALIZER;
|
||||
|
||||
status = pthread_rwlock_rdlock( &rwlock );
|
||||
rtems_test_assert( status == 0 );
|
||||
|
||||
status = pthread_rwlock_rdlock( &rwlock2 );
|
||||
rtems_test_assert( status == EINVAL );
|
||||
|
||||
status = pthread_rwlock_destroy( &rwlock );
|
||||
rtems_test_assert( status == 0 );
|
||||
|
||||
status = pthread_rwlock_rdlock( &rwlock2 );
|
||||
rtems_test_assert( status == 0 );
|
||||
|
||||
status = pthread_rwlock_destroy( &rwlock );
|
||||
rtems_test_assert( status == 0 );
|
||||
|
||||
rwlock = PTHREAD_RWLOCK_INITIALIZER;
|
||||
rwlock2 = PTHREAD_RWLOCK_INITIALIZER;
|
||||
|
||||
status = pthread_rwlock_rdlock( &rwlock );
|
||||
rtems_test_assert( status == 0 );
|
||||
|
||||
status = pthread_rwlock_destroy( &rwlock2 );
|
||||
rtems_test_assert( status == EINVAL );
|
||||
|
||||
status = pthread_rwlock_destroy( &rwlock );
|
||||
rtems_test_assert( status == 0 );
|
||||
|
||||
status = pthread_rwlock_destroy( &rwlock2 );
|
||||
rtems_test_assert( status == 0 );
|
||||
rtems_test_assert( rwlock2 != PTHREAD_RWLOCK_INITIALIZER );
|
||||
|
||||
/*************** ACTUALLY WORK THIS TIME *****************/
|
||||
puts( "pthread_rwlockattr_init( &attr ) -- OK" );
|
||||
status = pthread_rwlockattr_init( &attr );
|
||||
@@ -309,7 +463,6 @@ int main(
|
||||
rtems_test_assert( status == EINVAL );
|
||||
|
||||
/*************** BAD ID CHECK *****************/
|
||||
rwlock = 1;
|
||||
/* make a valid abstime */
|
||||
puts( "clock_gettime(CLOCK_REALTIME, &abstime) -- OK" );
|
||||
status = clock_gettime( CLOCK_REALTIME, &abstime );
|
||||
@@ -317,35 +470,35 @@ int main(
|
||||
abstime.tv_sec += 5;
|
||||
|
||||
puts( "pthread_rwlock_destroy(BadId) -- EINVAL" );
|
||||
status = pthread_rwlock_destroy(&rwlock);
|
||||
status = pthread_rwlock_destroy(NULL);
|
||||
rtems_test_assert( status == EINVAL );
|
||||
|
||||
puts( "pthread_rwlock_rdlock(BadId) -- EINVAL" );
|
||||
status = pthread_rwlock_rdlock(&rwlock);
|
||||
status = pthread_rwlock_rdlock(NULL);
|
||||
rtems_test_assert( status == EINVAL );
|
||||
|
||||
puts( "pthread_rwlock_timedrdlock(BadId, &abstime) -- EINVAL" );
|
||||
status = pthread_rwlock_timedrdlock( &rwlock, &abstime);
|
||||
status = pthread_rwlock_timedrdlock( NULL, &abstime);
|
||||
rtems_test_assert( status == EINVAL );
|
||||
|
||||
puts( "pthread_rwlock_tryrdlock(BadId) -- EINVAL" );
|
||||
status = pthread_rwlock_tryrdlock(&rwlock);
|
||||
status = pthread_rwlock_tryrdlock(NULL);
|
||||
rtems_test_assert( status == EINVAL );
|
||||
|
||||
puts( "pthread_rwlock_wrlock(BadId) -- EINVAL" );
|
||||
status = pthread_rwlock_wrlock(&rwlock);
|
||||
status = pthread_rwlock_wrlock(NULL);
|
||||
rtems_test_assert( status == EINVAL );
|
||||
|
||||
puts( "pthread_rwlock_timedwrlock(BadId, &abstime) -- EINVAL" );
|
||||
status = pthread_rwlock_timedwrlock( &rwlock, &abstime );
|
||||
status = pthread_rwlock_timedwrlock( NULL, &abstime );
|
||||
rtems_test_assert( status == EINVAL );
|
||||
|
||||
puts( "pthread_rwlock_trywrlock(BadId) -- EINVAL" );
|
||||
status = pthread_rwlock_trywrlock(&rwlock);
|
||||
status = pthread_rwlock_trywrlock(NULL);
|
||||
rtems_test_assert( status == EINVAL );
|
||||
|
||||
puts( "pthread_rwlock_unlock(BadId) -- EINVAL" );
|
||||
status = pthread_rwlock_unlock(&rwlock);
|
||||
status = pthread_rwlock_unlock(NULL);
|
||||
rtems_test_assert( status == EINVAL );
|
||||
|
||||
/*************** BAD ABSTIME CHECK *****************/
|
||||
@@ -368,11 +521,6 @@ int main(
|
||||
puts( "pthread_rwlock_init( &rwlock, &attr ) -- OK" );
|
||||
status = pthread_rwlock_init( &rwlock, &attr );
|
||||
rtems_test_assert( status == 0 );
|
||||
rtems_test_assert( rwlock != 0 );
|
||||
|
||||
puts( "pthread_rwlock_init( &rwlock, &attr ) -- EAGAIN" );
|
||||
status = pthread_rwlock_init( &rwlock, &attr );
|
||||
rtems_test_assert( status == EAGAIN );
|
||||
|
||||
puts( "pthread_rwlock_destroy( &rwlock ) -- OK" );
|
||||
status = pthread_rwlock_destroy( &rwlock );
|
||||
@@ -549,7 +697,6 @@ int main(
|
||||
puts( "pthread_rwlock_init( &rwlock, NULL ) -- OK" );
|
||||
status = pthread_rwlock_init( &rwlock, NULL );
|
||||
rtems_test_assert( status == 0 );
|
||||
rtems_test_assert( rwlock != 0 );
|
||||
|
||||
puts( "pthread_rwlock_unlock ( &rwlock ) -- OK" );
|
||||
status = pthread_rwlock_unlock( &rwlock );
|
||||
|
||||
@@ -271,7 +271,6 @@ void *POSIX_Init(
|
||||
#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
|
||||
|
||||
#define CONFIGURE_MAXIMUM_POSIX_THREADS 1
|
||||
#define CONFIGURE_MAXIMUM_POSIX_RWLOCKS 1
|
||||
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
|
||||
|
||||
#define CONFIGURE_INIT
|
||||
|
||||
@@ -126,7 +126,6 @@ void *POSIX_Init(
|
||||
#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
|
||||
|
||||
#define CONFIGURE_MAXIMUM_POSIX_THREADS OPERATION_COUNT + 2
|
||||
#define CONFIGURE_MAXIMUM_POSIX_RWLOCKS 1
|
||||
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
|
||||
|
||||
#define CONFIGURE_INIT
|
||||
|
||||
@@ -139,7 +139,6 @@ void *POSIX_Init(
|
||||
#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
|
||||
|
||||
#define CONFIGURE_MAXIMUM_POSIX_THREADS OPERATION_COUNT + 2
|
||||
#define CONFIGURE_MAXIMUM_POSIX_RWLOCKS 1
|
||||
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
|
||||
|
||||
#define CONFIGURE_INIT
|
||||
|
||||
@@ -127,7 +127,6 @@ void *POSIX_Init(
|
||||
#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
|
||||
|
||||
#define CONFIGURE_MAXIMUM_POSIX_THREADS OPERATION_COUNT + 2
|
||||
#define CONFIGURE_MAXIMUM_POSIX_RWLOCKS 1
|
||||
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
|
||||
|
||||
#define CONFIGURE_INIT
|
||||
|
||||
@@ -139,7 +139,6 @@ void *POSIX_Init(
|
||||
#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
|
||||
|
||||
#define CONFIGURE_MAXIMUM_POSIX_THREADS OPERATION_COUNT + 2
|
||||
#define CONFIGURE_MAXIMUM_POSIX_RWLOCKS 1
|
||||
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
|
||||
|
||||
#define CONFIGURE_INIT
|
||||
|
||||
@@ -101,7 +101,6 @@ void *POSIX_Init(
|
||||
#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
|
||||
|
||||
#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
|
||||
#define CONFIGURE_MAXIMUM_POSIX_RWLOCKS 1
|
||||
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
|
||||
|
||||
#define CONFIGURE_INIT
|
||||
|
||||
@@ -158,7 +158,6 @@ void *POSIX_Init(
|
||||
#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
|
||||
|
||||
#define CONFIGURE_MAXIMUM_POSIX_THREADS OPERATION_COUNT + 2
|
||||
#define CONFIGURE_MAXIMUM_POSIX_RWLOCKS 1
|
||||
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
|
||||
|
||||
#define CONFIGURE_INIT
|
||||
|
||||
@@ -114,8 +114,6 @@ typedef enum {
|
||||
POSIX_SEMAPHORE_POST,
|
||||
POSIX_TIMER_PRE,
|
||||
POSIX_TIMER_POST,
|
||||
POSIX_RWLOCK_PRE,
|
||||
POSIX_RWLOCK_POST,
|
||||
POSIX_SHM_PRE,
|
||||
POSIX_SHM_POST,
|
||||
#endif /* RTEMS_POSIX_API */
|
||||
@@ -503,18 +501,6 @@ LAST(RTEMS_SYSINIT_POSIX_TIMER)
|
||||
next_step(POSIX_TIMER_POST);
|
||||
}
|
||||
|
||||
FIRST(RTEMS_SYSINIT_POSIX_RWLOCK)
|
||||
{
|
||||
assert(_POSIX_RWLock_Information.maximum == 0);
|
||||
next_step(POSIX_RWLOCK_PRE);
|
||||
}
|
||||
|
||||
LAST(RTEMS_SYSINIT_POSIX_RWLOCK)
|
||||
{
|
||||
assert(_POSIX_RWLock_Information.maximum != 0);
|
||||
next_step(POSIX_RWLOCK_POST);
|
||||
}
|
||||
|
||||
FIRST(RTEMS_SYSINIT_POSIX_SHM)
|
||||
{
|
||||
assert(_POSIX_Shm_Information.maximum == 0);
|
||||
@@ -749,8 +735,6 @@ static void *POSIX_Init(void *arg)
|
||||
|
||||
#define CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES 1
|
||||
|
||||
#define CONFIGURE_MAXIMUM_POSIX_RWLOCKS 1
|
||||
|
||||
#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 1
|
||||
|
||||
#define CONFIGURE_MAXIMUM_POSIX_SHMS 1
|
||||
|
||||
@@ -42,7 +42,6 @@ typedef struct {
|
||||
#if defined(RTEMS_POSIX_API)
|
||||
pthread_mutex_t pmtx;
|
||||
pthread_cond_t pcv;
|
||||
pthread_rwlock_t prw;
|
||||
mqd_t pmq;
|
||||
#endif
|
||||
} test_context;
|
||||
@@ -139,15 +138,6 @@ static void posix_worker(test_context *ctx)
|
||||
eno = pthread_mutex_unlock(&ctx->pmtx);
|
||||
rtems_test_assert(eno == 0);
|
||||
|
||||
eno = pthread_rwlock_wrlock(&ctx->prw);
|
||||
rtems_test_assert(eno == 0);
|
||||
|
||||
wake_up_master(ctx);
|
||||
rtems_test_assert(get_wait_id(ctx) == ctx->prw);
|
||||
|
||||
eno = pthread_rwlock_unlock(&ctx->prw);
|
||||
rtems_test_assert(eno == 0);
|
||||
|
||||
wake_up_master(ctx);
|
||||
rtems_test_assert(get_wait_id(ctx) == ctx->pmq);
|
||||
|
||||
@@ -219,9 +209,6 @@ static void test_posix_init(test_context *ctx)
|
||||
eno = pthread_cond_init(&ctx->pcv, NULL);
|
||||
rtems_test_assert(eno == 0);
|
||||
|
||||
eno = pthread_rwlock_init(&ctx->prw, NULL);
|
||||
rtems_test_assert(eno == 0);
|
||||
|
||||
memset(&attr, 0, sizeof(attr));
|
||||
attr.mq_maxmsg = 1;
|
||||
attr.mq_msgsize = sizeof(char);
|
||||
@@ -313,11 +300,6 @@ static void test_posix_obj(test_context *ctx)
|
||||
|
||||
wait_for_worker(ctx);
|
||||
|
||||
eno = pthread_rwlock_wrlock(&ctx->prw);
|
||||
rtems_test_assert(eno == 0);
|
||||
|
||||
wait_for_worker(ctx);
|
||||
|
||||
buf[0] = 'y';
|
||||
prio = 1;
|
||||
n = mq_receive(ctx->pmq, &buf[0], sizeof(buf), &prio);
|
||||
@@ -362,7 +344,6 @@ static rtems_task Init(
|
||||
#if defined(RTEMS_POSIX_API)
|
||||
#define CONFIGURE_MAXIMUM_POSIX_MUTEXES 1
|
||||
#define CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES 1
|
||||
#define CONFIGURE_MAXIMUM_POSIX_RWLOCKS 1
|
||||
#define CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES 1
|
||||
#define CONFIGURE_MESSAGE_BUFFER_MEMORY \
|
||||
(2 * CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE(1, 1))
|
||||
|
||||
Reference in New Issue
Block a user