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:
Sebastian Huber
2017-10-05 14:29:02 +02:00
parent e67929c4c0
commit 89fc9345de
43 changed files with 417 additions and 550 deletions
@@ -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 }
+3 -8
View File
@@ -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.
*/
-63
View File
@@ -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 */
+21 -33
View 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
}
+4 -8
View File
@@ -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
-48
View File
@@ -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
);
+6 -14
View File
@@ -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;
}
+32 -49
View File
@@ -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;
}
+3 -6
View File
@@ -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
);
+3 -6
View File
@@ -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
);
+3 -6
View File
@@ -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
);
+3 -6
View File
@@ -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
);
+3 -6
View File
@@ -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
);
+19 -7
View File
@@ -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 );
}
+3 -8
View File
@@ -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}
};
-26
View File
@@ -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!!"
+29
View File
@@ -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 )
{
+1 -7
View File
@@ -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;
-1
View File
@@ -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
+4 -9
View File
@@ -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
+1 -2
View File
@@ -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 );
}
+6 -11
View File
@@ -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
+4 -3
View File
@@ -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
+10 -10
View File
@@ -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;
}
-13
View File
@@ -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;
-1
View File
@@ -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 ***
+201 -54
View File
@@ -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
-16
View File
@@ -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
-19
View File
@@ -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))