forked from Imagelibrary/rtems
posix: Implement self-contained POSIX semaphores
For semaphore object pointer and object validation see POSIX_SEMAPHORE_VALIDATE_OBJECT(). Destruction or close of a busy semaphore returns an error status. The object is not flushed. POSIX semaphores are now available in all configurations and no longer depend on --enable-posix. Update #2514. Update #3116.
This commit is contained in:
@@ -21,6 +21,8 @@ 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/semaphore.h
|
||||
include_rtems_posix_HEADERS += include/rtems/posix/semaphoreimpl.h
|
||||
include_rtems_posix_HEADERS += include/rtems/posix/spinlockimpl.h
|
||||
|
||||
if HAS_PTHREADS
|
||||
@@ -44,8 +46,6 @@ include_rtems_posix_HEADERS += include/rtems/posix/pthreadimpl.h
|
||||
include_rtems_posix_HEADERS += include/rtems/posix/ptimer.h
|
||||
include_rtems_posix_HEADERS += include/rtems/posix/shm.h
|
||||
include_rtems_posix_HEADERS += include/rtems/posix/shmimpl.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/threadsup.h
|
||||
include_rtems_posix_HEADERS += include/rtems/posix/timer.h
|
||||
include_rtems_posix_HEADERS += include/rtems/posix/timerimpl.h
|
||||
@@ -186,6 +186,15 @@ libposix_a_SOURCES += src/pspininit.c
|
||||
libposix_a_SOURCES += src/pspinlock.c
|
||||
libposix_a_SOURCES += src/pspinunlock.c
|
||||
|
||||
## SEMAPHORE_C_FILES
|
||||
libposix_a_SOURCES += src/semdestroy.c
|
||||
libposix_a_SOURCES += src/semgetvalue.c
|
||||
libposix_a_SOURCES += src/seminit.c
|
||||
libposix_a_SOURCES += src/sempost.c
|
||||
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 \
|
||||
@@ -199,12 +208,11 @@ libposix_a_SOURCES += src/prwlock.c src/prwlockdestroy.c src/prwlockinit.c \
|
||||
src/rwlockattrinit.c src/rwlockattrsetpshared.c
|
||||
|
||||
## SEMAPHORE_C_FILES
|
||||
libposix_a_SOURCES += src/semaphore.c src/semaphorecreatesupp.c \
|
||||
src/semaphoredeletesupp.c \
|
||||
src/semaphorewaitsupp.c \
|
||||
src/semclose.c src/semdestroy.c src/semgetvalue.c src/seminit.c \
|
||||
src/semopen.c src/sempost.c src/semtimedwait.c src/semtrywait.c \
|
||||
src/semunlink.c src/semwait.c
|
||||
libposix_a_SOURCES += src/semaphore.c
|
||||
libposix_a_SOURCES += src/semaphoredeletesupp.c
|
||||
libposix_a_SOURCES += src/semclose.c
|
||||
libposix_a_SOURCES += src/semopen.c
|
||||
libposix_a_SOURCES += src/semunlink.c
|
||||
|
||||
## TIME_C_FILES
|
||||
libposix_a_SOURCES += src/adjtime.c src/clockgetcpuclockid.c
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
#include <semaphore.h>
|
||||
#include <rtems/score/object.h>
|
||||
#include <rtems/score/coresem.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -41,19 +40,10 @@ extern "C" {
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
Objects_Control Object;
|
||||
CORE_semaphore_Control Semaphore;
|
||||
bool named;
|
||||
bool linked;
|
||||
uint32_t open_count;
|
||||
/*
|
||||
* sem_t is 32-bit. If Object_Id is 16-bit, then they are not
|
||||
* interchangeable. We have to be able to return a pointer to
|
||||
* a 32-bit form of the 16-bit Id.
|
||||
*/
|
||||
#if defined(RTEMS_USE_16_BIT_OBJECT)
|
||||
sem_t Semaphore_id;
|
||||
#endif
|
||||
Objects_Control Object;
|
||||
sem_t Semaphore;
|
||||
bool linked;
|
||||
uint32_t open_count;
|
||||
} POSIX_Semaphore_Control;
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -21,21 +21,25 @@
|
||||
|
||||
#include <rtems/posix/semaphore.h>
|
||||
#include <rtems/posix/posixapi.h>
|
||||
#include <rtems/score/coresemimpl.h>
|
||||
#include <rtems/score/semaphoreimpl.h>
|
||||
#include <rtems/seterr.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief This is a random number used to check if a semaphore object is
|
||||
* properly initialized.
|
||||
*/
|
||||
#define POSIX_SEMAPHORE_MAGIC 0x5d367fe7UL
|
||||
|
||||
/**
|
||||
* This defines the information control block used to manage
|
||||
* this class of objects.
|
||||
*/
|
||||
extern Objects_Information _POSIX_Semaphore_Information;
|
||||
|
||||
#define POSIX_SEMAPHORE_TQ_OPERATIONS &_Thread_queue_Operations_FIFO
|
||||
|
||||
RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *
|
||||
_POSIX_Semaphore_Allocate_unprotected( void )
|
||||
{
|
||||
@@ -57,53 +61,45 @@ RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Free (
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *_POSIX_Semaphore_Get(
|
||||
const sem_t *id,
|
||||
Thread_queue_Context *queue_context
|
||||
sem_t *sem
|
||||
)
|
||||
{
|
||||
_Thread_queue_Context_initialize( queue_context );
|
||||
return (POSIX_Semaphore_Control *) _Objects_Get(
|
||||
(Objects_Id) *id,
|
||||
&queue_context->Lock_context.Lock_context,
|
||||
&_POSIX_Semaphore_Information
|
||||
);
|
||||
return RTEMS_CONTAINER_OF( sem, POSIX_Semaphore_Control, Semaphore );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief POSIX Semaphore Create Support
|
||||
*
|
||||
* This routine supports the sem_init and sem_open routines.
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE bool _POSIX_Semaphore_Is_named( const sem_t *sem )
|
||||
{
|
||||
return sem->_Semaphore._Queue._name != NULL;
|
||||
}
|
||||
|
||||
int _POSIX_Semaphore_Create_support(
|
||||
const char *name,
|
||||
size_t name_len,
|
||||
unsigned int value,
|
||||
POSIX_Semaphore_Control **the_sem
|
||||
);
|
||||
RTEMS_INLINE_ROUTINE bool _POSIX_Semaphore_Is_busy( const sem_t *sem )
|
||||
{
|
||||
return sem->_Semaphore._Queue._heads != NULL;
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Initialize(
|
||||
sem_t *sem,
|
||||
const char *name,
|
||||
unsigned int value
|
||||
)
|
||||
{
|
||||
sem->_flags = (uintptr_t) sem ^ POSIX_SEMAPHORE_MAGIC;
|
||||
_Semaphore_Initialize_named( &sem->_Semaphore, name, value );
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Destroy( sem_t *sem )
|
||||
{
|
||||
sem->_flags = 0;
|
||||
_Semaphore_Destroy( &sem->_Semaphore );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief POSIX Semaphore Delete
|
||||
*
|
||||
* This routine supports the sem_close and sem_unlink routines.
|
||||
*/
|
||||
void _POSIX_Semaphore_Delete(
|
||||
POSIX_Semaphore_Control *the_semaphore,
|
||||
Thread_queue_Context *queue_context
|
||||
);
|
||||
void _POSIX_Semaphore_Delete( POSIX_Semaphore_Control *the_semaphore );
|
||||
|
||||
/**
|
||||
* @brief POSIX semaphore wait support.
|
||||
*
|
||||
* This routine supports the sem_wait, sem_trywait, and sem_timedwait
|
||||
* services.
|
||||
*/
|
||||
int _POSIX_Semaphore_Wait_support(
|
||||
sem_t *sem,
|
||||
bool blocking,
|
||||
Watchdog_Interval timeout
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief POSIX Semaphore Namespace Remove
|
||||
*/
|
||||
@@ -129,6 +125,16 @@ RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *_POSIX_Semaphore_Get_by_name(
|
||||
);
|
||||
}
|
||||
|
||||
#define POSIX_SEMAPHORE_VALIDATE_OBJECT( sem ) \
|
||||
do { \
|
||||
if ( \
|
||||
( sem ) == NULL \
|
||||
|| ( (uintptr_t) ( sem ) ^ POSIX_SEMAPHORE_MAGIC ) != ( sem )->_flags \
|
||||
) { \
|
||||
rtems_set_errno_and_return_minus_one( EINVAL ); \
|
||||
} \
|
||||
} while ( 0 )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -47,6 +47,14 @@ $(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/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
|
||||
|
||||
$(PROJECT_INCLUDE)/rtems/posix/semaphoreimpl.h: include/rtems/posix/semaphoreimpl.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/semaphoreimpl.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/semaphoreimpl.h
|
||||
|
||||
$(PROJECT_INCLUDE)/rtems/posix/spinlockimpl.h: include/rtems/posix/spinlockimpl.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/spinlockimpl.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/spinlockimpl.h
|
||||
@@ -120,14 +128,6 @@ $(PROJECT_INCLUDE)/rtems/posix/shmimpl.h: include/rtems/posix/shmimpl.h $(PROJEC
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/shmimpl.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/shmimpl.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
|
||||
|
||||
$(PROJECT_INCLUDE)/rtems/posix/semaphoreimpl.h: include/rtems/posix/semaphoreimpl.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/semaphoreimpl.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/semaphoreimpl.h
|
||||
|
||||
$(PROJECT_INCLUDE)/rtems/posix/threadsup.h: include/rtems/posix/threadsup.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/threadsup.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/threadsup.h
|
||||
|
||||
@@ -18,19 +18,11 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/posix/semaphoreimpl.h>
|
||||
#include <rtems/config.h>
|
||||
#include <rtems/sysinit.h>
|
||||
#include <rtems/posix/semaphoreimpl.h>
|
||||
#include <rtems/seterr.h>
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
Objects_Information _POSIX_Semaphore_Information;
|
||||
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @brief Function does Actual creation and Initialization of POSIX Semaphore
|
||||
* @ingroup POSIXAPI
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-2009.
|
||||
* 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 <stdarg.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <limits.h>
|
||||
#include <string.h> /* strlen */
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
#include <rtems/posix/semaphoreimpl.h>
|
||||
#include <rtems/seterr.h>
|
||||
|
||||
/*
|
||||
* _POSIX_Semaphore_Create_support
|
||||
*
|
||||
* This routine does the actual creation and initialization of
|
||||
* a poxix semaphore. It is a support routine for sem_init and
|
||||
* sem_open.
|
||||
*/
|
||||
int _POSIX_Semaphore_Create_support(
|
||||
const char *name_arg,
|
||||
size_t name_len,
|
||||
unsigned int value,
|
||||
POSIX_Semaphore_Control **the_sem
|
||||
)
|
||||
{
|
||||
POSIX_Semaphore_Control *the_semaphore;
|
||||
char *name;
|
||||
|
||||
/*
|
||||
* Make a copy of the user's string for name just in case it was
|
||||
* dynamically constructed.
|
||||
*/
|
||||
if ( name_arg != NULL ) {
|
||||
name = _Workspace_String_duplicate( name_arg, name_len );
|
||||
if ( !name ) {
|
||||
rtems_set_errno_and_return_minus_one( ENOMEM );
|
||||
}
|
||||
} else {
|
||||
name = NULL;
|
||||
}
|
||||
|
||||
the_semaphore = _POSIX_Semaphore_Allocate_unprotected();
|
||||
if ( !the_semaphore ) {
|
||||
_Workspace_Free( name );
|
||||
rtems_set_errno_and_return_minus_one( ENOSPC );
|
||||
}
|
||||
|
||||
if ( name ) {
|
||||
the_semaphore->named = true;
|
||||
the_semaphore->open_count = 1;
|
||||
the_semaphore->linked = true;
|
||||
} else {
|
||||
the_semaphore->named = false;
|
||||
the_semaphore->open_count = 0;
|
||||
the_semaphore->linked = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* POSIX does not appear to specify what the discipline for
|
||||
* blocking tasks on this semaphore should be. It could somehow
|
||||
* be derived from the current scheduling policy. One
|
||||
* thing is certain, no matter what we decide, it won't be
|
||||
* the same as all other POSIX implementations. :)
|
||||
*/
|
||||
_CORE_semaphore_Initialize( &the_semaphore->Semaphore, value );
|
||||
|
||||
/*
|
||||
* Make the semaphore available for use.
|
||||
*/
|
||||
_Objects_Open_string(
|
||||
&_POSIX_Semaphore_Information,
|
||||
&the_semaphore->Object,
|
||||
name
|
||||
);
|
||||
|
||||
*the_sem = the_semaphore;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -20,20 +20,11 @@
|
||||
|
||||
#include <rtems/posix/semaphoreimpl.h>
|
||||
|
||||
void _POSIX_Semaphore_Delete(
|
||||
POSIX_Semaphore_Control *the_semaphore,
|
||||
Thread_queue_Context *queue_context
|
||||
)
|
||||
void _POSIX_Semaphore_Delete( POSIX_Semaphore_Control *the_semaphore )
|
||||
{
|
||||
if ( !the_semaphore->linked && !the_semaphore->open_count ) {
|
||||
_Objects_Close( &_POSIX_Semaphore_Information, &the_semaphore->Object );
|
||||
_CORE_semaphore_Destroy(
|
||||
&the_semaphore->Semaphore,
|
||||
POSIX_SEMAPHORE_TQ_OPERATIONS,
|
||||
queue_context
|
||||
);
|
||||
_POSIX_Semaphore_Destroy( &the_semaphore->Semaphore );
|
||||
_POSIX_Semaphore_Free( the_semaphore );
|
||||
} else {
|
||||
_CORE_semaphore_Release( &the_semaphore->Semaphore, queue_context );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @brief POSIX Semaphore Wait Support
|
||||
* @ingroup POSIXSemaphorePrivate
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-2012.
|
||||
* 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 <semaphore.h>
|
||||
|
||||
#include <rtems/posix/semaphoreimpl.h>
|
||||
#include <rtems/posix/posixapi.h>
|
||||
|
||||
THREAD_QUEUE_OBJECT_ASSERT( POSIX_Semaphore_Control, Semaphore.Wait_queue );
|
||||
|
||||
int _POSIX_Semaphore_Wait_support(
|
||||
sem_t *sem,
|
||||
bool blocking,
|
||||
Watchdog_Interval timeout
|
||||
)
|
||||
{
|
||||
POSIX_Semaphore_Control *the_semaphore;
|
||||
Thread_queue_Context queue_context;
|
||||
Status_Control status;
|
||||
|
||||
the_semaphore = _POSIX_Semaphore_Get( sem, &queue_context );
|
||||
|
||||
if ( the_semaphore == NULL ) {
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
}
|
||||
|
||||
_Thread_queue_Context_set_relative_timeout( &queue_context, timeout );
|
||||
status = _CORE_semaphore_Seize(
|
||||
&the_semaphore->Semaphore,
|
||||
POSIX_SEMAPHORE_TQ_OPERATIONS,
|
||||
_Thread_Executing,
|
||||
blocking,
|
||||
&queue_context
|
||||
);
|
||||
return _POSIX_Zero_or_minus_one_plus_errno( status );
|
||||
}
|
||||
@@ -18,32 +18,37 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <semaphore.h>
|
||||
|
||||
#include <rtems/posix/semaphoreimpl.h>
|
||||
|
||||
int sem_close(
|
||||
sem_t *sem
|
||||
)
|
||||
int sem_close( sem_t *sem )
|
||||
{
|
||||
POSIX_Semaphore_Control *the_semaphore;
|
||||
Thread_queue_Context queue_context;
|
||||
uint32_t open_count;
|
||||
|
||||
POSIX_SEMAPHORE_VALIDATE_OBJECT( sem );
|
||||
|
||||
if ( !_POSIX_Semaphore_Is_named( sem ) ) {
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
}
|
||||
|
||||
the_semaphore = _POSIX_Semaphore_Get( sem );
|
||||
|
||||
_Objects_Allocator_lock();
|
||||
the_semaphore = _POSIX_Semaphore_Get( sem, &queue_context );
|
||||
|
||||
if ( the_semaphore == NULL ) {
|
||||
open_count = the_semaphore->open_count;
|
||||
|
||||
if ( open_count == 0 ) {
|
||||
_Objects_Allocator_unlock();
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
}
|
||||
|
||||
_CORE_semaphore_Acquire_critical(
|
||||
&the_semaphore->Semaphore,
|
||||
&queue_context
|
||||
);
|
||||
the_semaphore->open_count -= 1;
|
||||
_POSIX_Semaphore_Delete( the_semaphore, &queue_context );
|
||||
if ( open_count == 1 && _POSIX_Semaphore_Is_busy( sem ) ) {
|
||||
_Objects_Allocator_unlock();
|
||||
rtems_set_errno_and_return_minus_one( EBUSY );
|
||||
}
|
||||
|
||||
the_semaphore->open_count = open_count - 1;
|
||||
_POSIX_Semaphore_Delete( the_semaphore );
|
||||
_Objects_Allocator_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -18,39 +18,20 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <semaphore.h>
|
||||
|
||||
#include <rtems/posix/semaphoreimpl.h>
|
||||
|
||||
int sem_destroy(
|
||||
sem_t *sem
|
||||
)
|
||||
int sem_destroy( sem_t *sem )
|
||||
{
|
||||
POSIX_Semaphore_Control *the_semaphore;
|
||||
Thread_queue_Context queue_context;
|
||||
POSIX_SEMAPHORE_VALIDATE_OBJECT( sem );
|
||||
|
||||
_Objects_Allocator_lock();
|
||||
the_semaphore = _POSIX_Semaphore_Get( sem, &queue_context );
|
||||
|
||||
if ( the_semaphore == NULL ) {
|
||||
_Objects_Allocator_unlock();
|
||||
if ( _POSIX_Semaphore_Is_named( sem ) ) {
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
}
|
||||
|
||||
_CORE_semaphore_Acquire_critical(
|
||||
&the_semaphore->Semaphore,
|
||||
&queue_context
|
||||
);
|
||||
|
||||
if ( the_semaphore->named ) {
|
||||
/* Undefined operation on a named semaphore */
|
||||
_CORE_semaphore_Release( &the_semaphore->Semaphore, &queue_context );
|
||||
_Objects_Allocator_unlock();
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
if ( _POSIX_Semaphore_Is_busy( sem ) ) {
|
||||
rtems_set_errno_and_return_minus_one( EBUSY );
|
||||
}
|
||||
|
||||
_POSIX_Semaphore_Delete( the_semaphore, &queue_context );
|
||||
|
||||
_Objects_Allocator_unlock();
|
||||
_POSIX_Semaphore_Destroy( sem );
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -18,31 +18,24 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <semaphore.h>
|
||||
|
||||
#include <rtems/posix/semaphoreimpl.h>
|
||||
|
||||
int sem_getvalue(
|
||||
sem_t *__restrict sem,
|
||||
sem_t *__restrict _sem,
|
||||
int *__restrict sval
|
||||
)
|
||||
{
|
||||
POSIX_Semaphore_Control *the_semaphore;
|
||||
Thread_queue_Context queue_context;
|
||||
Sem_Control *sem;
|
||||
ISR_Level level;
|
||||
Thread_queue_Context queue_context;
|
||||
|
||||
the_semaphore = _POSIX_Semaphore_Get( sem, &queue_context );
|
||||
POSIX_SEMAPHORE_VALIDATE_OBJECT( _sem );
|
||||
|
||||
if ( the_semaphore == NULL ) {
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
}
|
||||
|
||||
_CORE_semaphore_Acquire_critical(
|
||||
&the_semaphore->Semaphore,
|
||||
&queue_context
|
||||
);
|
||||
|
||||
*sval = _CORE_semaphore_Get_count( &the_semaphore->Semaphore );
|
||||
|
||||
_CORE_semaphore_Release( &the_semaphore->Semaphore, &queue_context );
|
||||
sem = _Sem_Get( &_sem->_Semaphore );
|
||||
_Thread_queue_Context_initialize( &queue_context );
|
||||
_Thread_queue_Context_ISR_disable( &queue_context, level );
|
||||
_Sem_Queue_acquire_critical( sem, &queue_context );
|
||||
*sval = (int) sem->count;
|
||||
_Sem_Queue_release( sem, level, &queue_context );
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -18,17 +18,11 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <rtems/posix/semaphoreimpl.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/posix/semaphoreimpl.h>
|
||||
#include <rtems/seterr.h>
|
||||
RTEMS_STATIC_ASSERT(NULL == SEM_FAILED, sem_failed);
|
||||
|
||||
/*
|
||||
* 11.2.1 Initialize an Unnamed Semaphore, P1003.1b-1993, p.219
|
||||
@@ -40,9 +34,6 @@ int sem_init(
|
||||
unsigned int value
|
||||
)
|
||||
{
|
||||
int status;
|
||||
POSIX_Semaphore_Control *the_semaphore;
|
||||
|
||||
if ( sem == NULL ) {
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
}
|
||||
@@ -51,17 +42,6 @@ int sem_init(
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
}
|
||||
|
||||
_Objects_Allocator_lock();
|
||||
status = _POSIX_Semaphore_Create_support(
|
||||
NULL,
|
||||
0,
|
||||
value,
|
||||
&the_semaphore
|
||||
);
|
||||
_Objects_Allocator_unlock();
|
||||
|
||||
if ( status != -1 )
|
||||
*sem = the_semaphore->Object.id;
|
||||
|
||||
return status;
|
||||
_POSIX_Semaphore_Initialize( sem, NULL, value );
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -18,17 +18,64 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <rtems/posix/semaphoreimpl.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/posix/semaphoreimpl.h>
|
||||
#include <rtems/seterr.h>
|
||||
static sem_t *_POSIX_Semaphore_Create_support(
|
||||
const char *name_arg,
|
||||
size_t name_len,
|
||||
unsigned int value
|
||||
)
|
||||
{
|
||||
POSIX_Semaphore_Control *the_semaphore;
|
||||
char *name;
|
||||
|
||||
if ( value > SEM_VALUE_MAX ) {
|
||||
rtems_set_errno_and_return_value( EINVAL, SEM_FAILED );
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a copy of the user's string for name just in case it was
|
||||
* dynamically constructed.
|
||||
*/
|
||||
name = _Workspace_String_duplicate( name_arg, name_len );
|
||||
if ( name == NULL ) {
|
||||
rtems_set_errno_and_return_value( ENOMEM, SEM_FAILED );
|
||||
}
|
||||
|
||||
the_semaphore = _POSIX_Semaphore_Allocate_unprotected();
|
||||
if ( the_semaphore == NULL ) {
|
||||
_Workspace_Free( name );
|
||||
rtems_set_errno_and_return_value( ENOSPC, SEM_FAILED );
|
||||
}
|
||||
|
||||
the_semaphore->open_count = 1;
|
||||
the_semaphore->linked = true;
|
||||
|
||||
/*
|
||||
* POSIX does not appear to specify what the discipline for
|
||||
* blocking tasks on this semaphore should be. It could somehow
|
||||
* be derived from the current scheduling policy. One
|
||||
* thing is certain, no matter what we decide, it won't be
|
||||
* the same as all other POSIX implementations. :)
|
||||
*/
|
||||
_POSIX_Semaphore_Initialize( &the_semaphore->Semaphore, name, value );
|
||||
|
||||
/*
|
||||
* Make the semaphore available for use.
|
||||
*/
|
||||
_Objects_Open_string(
|
||||
&_POSIX_Semaphore_Information,
|
||||
&the_semaphore->Object,
|
||||
name
|
||||
);
|
||||
|
||||
return &the_semaphore->Semaphore;
|
||||
}
|
||||
|
||||
/*
|
||||
* sem_open
|
||||
@@ -59,10 +106,10 @@ sem_t *sem_open(
|
||||
|
||||
va_list arg;
|
||||
unsigned int value = 0;
|
||||
int status;
|
||||
POSIX_Semaphore_Control *the_semaphore;
|
||||
size_t name_len;
|
||||
Objects_Get_by_name_error error;
|
||||
sem_t *sem;
|
||||
|
||||
if ( oflag & O_CREAT ) {
|
||||
va_start(arg, oflag);
|
||||
@@ -108,7 +155,7 @@ sem_t *sem_open(
|
||||
|
||||
the_semaphore->open_count += 1;
|
||||
_Objects_Allocator_unlock();
|
||||
goto return_id;
|
||||
return &the_semaphore->Semaphore;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -116,27 +163,12 @@ sem_t *sem_open(
|
||||
* checked. We should go ahead and create a semaphore.
|
||||
*/
|
||||
|
||||
status =_POSIX_Semaphore_Create_support(
|
||||
sem = _POSIX_Semaphore_Create_support(
|
||||
name,
|
||||
name_len,
|
||||
value,
|
||||
&the_semaphore
|
||||
value
|
||||
);
|
||||
|
||||
/*
|
||||
* errno was set by Create_support, so don't set it again.
|
||||
*/
|
||||
|
||||
_Objects_Allocator_unlock();
|
||||
|
||||
if ( status != 0 )
|
||||
return SEM_FAILED;
|
||||
|
||||
return_id:
|
||||
#if defined(RTEMS_USE_16_BIT_OBJECT)
|
||||
the_semaphore->Semaphore_id = the_semaphore->Object.id;
|
||||
return &the_semaphore->Semaphore_id;
|
||||
#else
|
||||
return &the_semaphore->Object.id;
|
||||
#endif
|
||||
return sem;
|
||||
}
|
||||
|
||||
@@ -18,31 +18,51 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <semaphore.h>
|
||||
#include <rtems/posix/semaphoreimpl.h>
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <rtems/posix/semaphoreimpl.h>
|
||||
#include <rtems/posix/posixapi.h>
|
||||
|
||||
int sem_post(
|
||||
sem_t *sem
|
||||
)
|
||||
int sem_post( sem_t *_sem )
|
||||
{
|
||||
POSIX_Semaphore_Control *the_semaphore;
|
||||
Thread_queue_Context queue_context;
|
||||
Status_Control status;
|
||||
Sem_Control *sem;
|
||||
ISR_Level level;
|
||||
Thread_queue_Context queue_context;
|
||||
Thread_queue_Heads *heads;
|
||||
unsigned int count;
|
||||
|
||||
the_semaphore = _POSIX_Semaphore_Get( sem, &queue_context );
|
||||
POSIX_SEMAPHORE_VALIDATE_OBJECT( _sem );
|
||||
|
||||
if ( the_semaphore == NULL ) {
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
sem = _Sem_Get( &_sem->_Semaphore );
|
||||
_Thread_queue_Context_initialize( &queue_context );
|
||||
_Thread_queue_Context_ISR_disable( &queue_context, level );
|
||||
_Sem_Queue_acquire_critical( sem, &queue_context );
|
||||
|
||||
heads = sem->Queue.Queue.heads;
|
||||
count = sem->count;
|
||||
|
||||
if ( __predict_true( heads == NULL && count < SEM_VALUE_MAX ) ) {
|
||||
sem->count = count + 1;
|
||||
_Sem_Queue_release( sem, level, &queue_context );
|
||||
return 0;
|
||||
}
|
||||
|
||||
status = _CORE_semaphore_Surrender(
|
||||
&the_semaphore->Semaphore,
|
||||
POSIX_SEMAPHORE_TQ_OPERATIONS,
|
||||
SEM_VALUE_MAX,
|
||||
&queue_context
|
||||
);
|
||||
return _POSIX_Zero_or_minus_one_plus_errno( status );
|
||||
if ( __predict_true( heads != NULL ) ) {
|
||||
const Thread_queue_Operations *operations;
|
||||
Thread_Control *first;
|
||||
|
||||
_Thread_queue_Context_set_ISR_level( &queue_context, level );
|
||||
operations = SEMAPHORE_TQ_OPERATIONS;
|
||||
first = ( *operations->first )( heads );
|
||||
|
||||
_Thread_queue_Extract_critical(
|
||||
&sem->Queue.Queue,
|
||||
operations,
|
||||
first,
|
||||
&queue_context
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
_Sem_Queue_release( sem, level, &queue_context );
|
||||
rtems_set_errno_and_return_minus_one( EOVERFLOW );
|
||||
}
|
||||
|
||||
@@ -18,18 +18,8 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/score/todimpl.h>
|
||||
#include <rtems/posix/semaphoreimpl.h>
|
||||
#include <rtems/seterr.h>
|
||||
#include <rtems/score/todimpl.h>
|
||||
|
||||
/*
|
||||
* 11.2.6 Lock a Semaphore, P1003.1b-1993, p.226
|
||||
@@ -38,47 +28,60 @@
|
||||
*/
|
||||
|
||||
int sem_timedwait(
|
||||
sem_t *__restrict sem,
|
||||
sem_t *__restrict _sem,
|
||||
const struct timespec *__restrict abstime
|
||||
)
|
||||
{
|
||||
Watchdog_Interval ticks;
|
||||
bool do_wait = true;
|
||||
TOD_Absolute_timeout_conversion_results status;
|
||||
int lock_status;
|
||||
Sem_Control *sem;
|
||||
Thread_queue_Context queue_context;
|
||||
ISR_Level level;
|
||||
Thread_Control *executing;
|
||||
unsigned int count;
|
||||
|
||||
/*
|
||||
* POSIX requires that blocking calls with timeouts that take
|
||||
* an absolute timeout must ignore issues with the absolute
|
||||
* time provided if the operation would otherwise succeed.
|
||||
* So we check the abstime provided, and hold on to whether it
|
||||
* is valid or not. If it isn't correct and in the future,
|
||||
* then we do a polling operation and convert the UNSATISFIED
|
||||
* status into the appropriate error.
|
||||
*
|
||||
* If the status is TOD_ABSOLUTE_TIMEOUT_INVALID,
|
||||
* TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST, or TOD_ABSOLUTE_TIMEOUT_IS_NOW,
|
||||
* then we should not wait.
|
||||
*/
|
||||
status = _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks );
|
||||
if ( status != TOD_ABSOLUTE_TIMEOUT_IS_IN_FUTURE )
|
||||
do_wait = false;
|
||||
POSIX_SEMAPHORE_VALIDATE_OBJECT( _sem );
|
||||
|
||||
lock_status = _POSIX_Semaphore_Wait_support( sem, do_wait, ticks );
|
||||
sem = _Sem_Get( &_sem->_Semaphore );
|
||||
_Thread_queue_Context_initialize( &queue_context );
|
||||
_Thread_queue_Context_ISR_disable( &queue_context, level );
|
||||
executing = _Sem_Queue_acquire_critical( sem, &queue_context );
|
||||
|
||||
/*
|
||||
* This service only gives us the option to block. We used a polling
|
||||
* attempt to obtain if the abstime was not in the future. If we did
|
||||
* not obtain the semaphore, then not look at the status immediately,
|
||||
* make sure the right reason is returned.
|
||||
*/
|
||||
if ( !do_wait && (lock_status == EBUSY) ) {
|
||||
if ( lock_status == TOD_ABSOLUTE_TIMEOUT_INVALID )
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
if ( lock_status == TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST ||
|
||||
lock_status == TOD_ABSOLUTE_TIMEOUT_IS_NOW )
|
||||
rtems_set_errno_and_return_minus_one( ETIMEDOUT );
|
||||
count = sem->count;
|
||||
if ( __predict_true( count > 0 ) ) {
|
||||
sem->count = count - 1;
|
||||
_Sem_Queue_release( sem, level, &queue_context );
|
||||
return 0;
|
||||
} else {
|
||||
Watchdog_Interval ticks;
|
||||
Status_Control status;
|
||||
|
||||
switch ( _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks ) ) {
|
||||
case TOD_ABSOLUTE_TIMEOUT_INVALID:
|
||||
_Sem_Queue_release( sem, level, &queue_context );
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
break;
|
||||
case TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST:
|
||||
case TOD_ABSOLUTE_TIMEOUT_IS_NOW:
|
||||
_Sem_Queue_release( sem, level, &queue_context );
|
||||
rtems_set_errno_and_return_minus_one( ETIMEDOUT );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_Thread_queue_Context_set_thread_state(
|
||||
&queue_context,
|
||||
STATES_WAITING_FOR_SEMAPHORE
|
||||
);
|
||||
_Thread_queue_Context_set_do_nothing_enqueue_callout( &queue_context );
|
||||
_Thread_queue_Context_set_relative_timeout( &queue_context, ticks );
|
||||
_Thread_queue_Context_set_ISR_level( &queue_context, level );
|
||||
_Thread_queue_Enqueue(
|
||||
&sem->Queue.Queue,
|
||||
SEMAPHORE_TQ_OPERATIONS,
|
||||
executing,
|
||||
&queue_context
|
||||
);
|
||||
status = _Thread_Wait_get_status( executing );
|
||||
return _POSIX_Zero_or_minus_one_plus_errno( status );
|
||||
}
|
||||
|
||||
return lock_status;
|
||||
}
|
||||
|
||||
@@ -18,21 +18,29 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/posix/semaphoreimpl.h>
|
||||
#include <rtems/seterr.h>
|
||||
|
||||
int sem_trywait(
|
||||
sem_t *sem
|
||||
)
|
||||
int sem_trywait( sem_t *_sem )
|
||||
{
|
||||
return _POSIX_Semaphore_Wait_support(sem, false, WATCHDOG_NO_TIMEOUT);
|
||||
Sem_Control *sem;
|
||||
Thread_queue_Context queue_context;
|
||||
ISR_Level level;
|
||||
unsigned int count;
|
||||
|
||||
POSIX_SEMAPHORE_VALIDATE_OBJECT( _sem );
|
||||
|
||||
sem = _Sem_Get( &_sem->_Semaphore );
|
||||
_Thread_queue_Context_initialize( &queue_context );
|
||||
_Thread_queue_Context_ISR_disable( &queue_context, level );
|
||||
_Sem_Queue_acquire_critical( sem, &queue_context );
|
||||
|
||||
count = sem->count;
|
||||
if ( __predict_true( count > 0 ) ) {
|
||||
sem->count = count - 1;
|
||||
_Sem_Queue_release( sem, level, &queue_context );
|
||||
return 0;
|
||||
} else {
|
||||
_Sem_Queue_release( sem, level, &queue_context );
|
||||
rtems_set_errno_and_return_minus_one( EAGAIN );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,17 +18,12 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <semaphore.h>
|
||||
|
||||
#include <rtems/posix/semaphoreimpl.h>
|
||||
|
||||
int sem_unlink(
|
||||
const char *name
|
||||
)
|
||||
int sem_unlink( const char *name )
|
||||
{
|
||||
POSIX_Semaphore_Control *the_semaphore;
|
||||
Objects_Get_by_name_error error;
|
||||
Thread_queue_Context queue_context;
|
||||
|
||||
_Objects_Allocator_lock();
|
||||
|
||||
@@ -39,12 +34,8 @@ int sem_unlink(
|
||||
}
|
||||
|
||||
_POSIX_Semaphore_Namespace_remove( the_semaphore );
|
||||
|
||||
_ISR_lock_ISR_disable( &queue_context.Lock_context.Lock_context );
|
||||
_CORE_semaphore_Acquire_critical( &the_semaphore->Semaphore, &queue_context );
|
||||
the_semaphore->linked = false;
|
||||
_POSIX_Semaphore_Delete( the_semaphore, &queue_context );
|
||||
|
||||
_POSIX_Semaphore_Delete( the_semaphore );
|
||||
_Objects_Allocator_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -18,21 +18,11 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/posix/semaphoreimpl.h>
|
||||
#include <rtems/seterr.h>
|
||||
|
||||
int sem_wait(
|
||||
sem_t *sem
|
||||
)
|
||||
int sem_wait( sem_t *sem )
|
||||
{
|
||||
return _POSIX_Semaphore_Wait_support( sem, true, WATCHDOG_NO_TIMEOUT );
|
||||
POSIX_SEMAPHORE_VALIDATE_OBJECT( sem );
|
||||
_Semaphore_Wait( &sem->_Semaphore );
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,31 @@
|
||||
#endif
|
||||
|
||||
#include <rtems/posix/posixapi.h>
|
||||
#include <rtems/posix/semaphoreimpl.h>
|
||||
#include <rtems/score/heap.h>
|
||||
|
||||
#ifdef HEAP_PROTECTION
|
||||
RTEMS_STATIC_ASSERT(
|
||||
POSIX_SEMAPHORE_MAGIC != HEAP_BEGIN_PROTECTOR_0,
|
||||
POSIX_SEMAPHORE_MAGIC_0
|
||||
);
|
||||
RTEMS_STATIC_ASSERT(
|
||||
POSIX_SEMAPHORE_MAGIC != HEAP_BEGIN_PROTECTOR_1,
|
||||
POSIX_SEMAPHORE_MAGIC_1
|
||||
);
|
||||
RTEMS_STATIC_ASSERT(
|
||||
POSIX_SEMAPHORE_MAGIC != HEAP_END_PROTECTOR_0,
|
||||
POSIX_SEMAPHORE_MAGIC_2
|
||||
);
|
||||
RTEMS_STATIC_ASSERT(
|
||||
POSIX_SEMAPHORE_MAGIC != HEAP_END_PROTECTOR_1,
|
||||
POSIX_SEMAPHORE_MAGIC_3
|
||||
);
|
||||
RTEMS_STATIC_ASSERT(
|
||||
POSIX_SEMAPHORE_MAGIC != HEAP_FREE_PATTERN,
|
||||
POSIX_SEMAPHORE_MAGIC_4
|
||||
);
|
||||
#endif
|
||||
|
||||
void _POSIX_Fatal_error( POSIX_Fatal_domain domain, int eno )
|
||||
{
|
||||
|
||||
@@ -80,6 +80,7 @@ include_rtems_score_HEADERS += include/rtems/score/schedulersimple.h
|
||||
include_rtems_score_HEADERS += include/rtems/score/schedulersimpleimpl.h
|
||||
include_rtems_score_HEADERS += include/rtems/score/schedulersmp.h
|
||||
include_rtems_score_HEADERS += include/rtems/score/schedulersmpimpl.h
|
||||
include_rtems_score_HEADERS += include/rtems/score/semaphoreimpl.h
|
||||
include_rtems_score_HEADERS += include/rtems/score/smp.h
|
||||
include_rtems_score_HEADERS += include/rtems/score/smpbarrier.h
|
||||
include_rtems_score_HEADERS += include/rtems/score/smplock.h
|
||||
|
||||
73
cpukit/score/include/rtems/score/semaphoreimpl.h
Normal file
73
cpukit/score/include/rtems/score/semaphoreimpl.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2017 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* 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_SEMAPHOREIMPL_H
|
||||
#define _RTEMS_SCORE_SEMAPHOREIMPL_H
|
||||
|
||||
#include <sys/lock.h>
|
||||
|
||||
#include <rtems/score/percpu.h>
|
||||
#include <rtems/score/threadqimpl.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef struct {
|
||||
Thread_queue_Syslock_queue Queue;
|
||||
unsigned int count;
|
||||
} Sem_Control;
|
||||
|
||||
#define SEMAPHORE_TQ_OPERATIONS &_Thread_queue_Operations_priority
|
||||
|
||||
static inline Sem_Control *_Sem_Get( struct _Semaphore_Control *_sem )
|
||||
{
|
||||
return (Sem_Control *) _sem;
|
||||
}
|
||||
|
||||
static inline Thread_Control *_Sem_Queue_acquire_critical(
|
||||
Sem_Control *sem,
|
||||
Thread_queue_Context *queue_context
|
||||
)
|
||||
{
|
||||
Thread_Control *executing;
|
||||
|
||||
executing = _Thread_Executing;
|
||||
_Thread_queue_Queue_acquire_critical(
|
||||
&sem->Queue.Queue,
|
||||
&executing->Potpourri_stats,
|
||||
&queue_context->Lock_context.Lock_context
|
||||
);
|
||||
|
||||
return executing;
|
||||
}
|
||||
|
||||
static inline void _Sem_Queue_release(
|
||||
Sem_Control *sem,
|
||||
ISR_Level level,
|
||||
Thread_queue_Context *queue_context
|
||||
)
|
||||
{
|
||||
_Thread_queue_Queue_release_critical(
|
||||
&sem->Queue.Queue,
|
||||
&queue_context->Lock_context.Lock_context
|
||||
);
|
||||
_ISR_Local_enable( level );
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _RTEMS_SCORE_SEMAPHOREIMPL_H */
|
||||
@@ -288,6 +288,10 @@ $(PROJECT_INCLUDE)/rtems/score/schedulersmpimpl.h: include/rtems/score/scheduler
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulersmpimpl.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulersmpimpl.h
|
||||
|
||||
$(PROJECT_INCLUDE)/rtems/score/semaphoreimpl.h: include/rtems/score/semaphoreimpl.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/semaphoreimpl.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/semaphoreimpl.h
|
||||
|
||||
$(PROJECT_INCLUDE)/rtems/score/smp.h: include/rtems/score/smp.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/smp.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/smp.h
|
||||
|
||||
@@ -16,92 +16,45 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/lock.h>
|
||||
#include <rtems/score/semaphoreimpl.h>
|
||||
#include <rtems/score/statesimpl.h>
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <rtems/score/assert.h>
|
||||
#include <rtems/score/threadimpl.h>
|
||||
#include <rtems/score/threadqimpl.h>
|
||||
|
||||
#define SEMAPHORE_TQ_OPERATIONS &_Thread_queue_Operations_priority
|
||||
|
||||
typedef struct {
|
||||
Thread_queue_Syslock_queue Queue;
|
||||
unsigned int count;
|
||||
} Semaphore_Control;
|
||||
|
||||
RTEMS_STATIC_ASSERT(
|
||||
offsetof( Semaphore_Control, Queue )
|
||||
offsetof( Sem_Control, Queue )
|
||||
== offsetof( struct _Semaphore_Control, _Queue ),
|
||||
SEMAPHORE_CONTROL_QUEUE
|
||||
);
|
||||
|
||||
RTEMS_STATIC_ASSERT(
|
||||
offsetof( Semaphore_Control, count )
|
||||
offsetof( Sem_Control, count )
|
||||
== offsetof( struct _Semaphore_Control, _count ),
|
||||
SEMAPHORE_CONTROL_COUNT
|
||||
);
|
||||
|
||||
RTEMS_STATIC_ASSERT(
|
||||
sizeof( Semaphore_Control ) == sizeof( struct _Semaphore_Control ),
|
||||
sizeof( Sem_Control ) == sizeof( struct _Semaphore_Control ),
|
||||
SEMAPHORE_CONTROL_SIZE
|
||||
);
|
||||
|
||||
static Semaphore_Control *_Semaphore_Get(
|
||||
struct _Semaphore_Control *_sem
|
||||
)
|
||||
{
|
||||
return (Semaphore_Control *) _sem;
|
||||
}
|
||||
|
||||
static Thread_Control *_Semaphore_Queue_acquire_critical(
|
||||
Semaphore_Control *sem,
|
||||
Thread_queue_Context *queue_context
|
||||
)
|
||||
{
|
||||
Thread_Control *executing;
|
||||
|
||||
executing = _Thread_Executing;
|
||||
_Thread_queue_Queue_acquire_critical(
|
||||
&sem->Queue.Queue,
|
||||
&executing->Potpourri_stats,
|
||||
&queue_context->Lock_context.Lock_context
|
||||
);
|
||||
|
||||
return executing;
|
||||
}
|
||||
|
||||
static void _Semaphore_Queue_release(
|
||||
Semaphore_Control *sem,
|
||||
ISR_Level level,
|
||||
Thread_queue_Context *queue_context
|
||||
)
|
||||
{
|
||||
_Thread_queue_Queue_release_critical(
|
||||
&sem->Queue.Queue,
|
||||
&queue_context->Lock_context.Lock_context
|
||||
);
|
||||
_ISR_Local_enable( level );
|
||||
}
|
||||
|
||||
void _Semaphore_Wait( struct _Semaphore_Control *_sem )
|
||||
{
|
||||
Semaphore_Control *sem ;
|
||||
Sem_Control *sem;
|
||||
ISR_Level level;
|
||||
Thread_queue_Context queue_context;
|
||||
Thread_Control *executing;
|
||||
unsigned int count;
|
||||
|
||||
sem = _Semaphore_Get( _sem );
|
||||
sem = _Sem_Get( _sem );
|
||||
_Thread_queue_Context_initialize( &queue_context );
|
||||
_Thread_queue_Context_ISR_disable( &queue_context, level );
|
||||
executing = _Semaphore_Queue_acquire_critical( sem, &queue_context );
|
||||
executing = _Sem_Queue_acquire_critical( sem, &queue_context );
|
||||
|
||||
count = sem->count;
|
||||
if ( __predict_true( count > 0 ) ) {
|
||||
sem->count = count - 1;
|
||||
_Semaphore_Queue_release( sem, level, &queue_context );
|
||||
_Sem_Queue_release( sem, level, &queue_context );
|
||||
} else {
|
||||
_Thread_queue_Context_set_thread_state(
|
||||
&queue_context,
|
||||
@@ -121,21 +74,21 @@ void _Semaphore_Wait( struct _Semaphore_Control *_sem )
|
||||
|
||||
void _Semaphore_Post( struct _Semaphore_Control *_sem )
|
||||
{
|
||||
Semaphore_Control *sem;
|
||||
Sem_Control *sem;
|
||||
ISR_Level level;
|
||||
Thread_queue_Context queue_context;
|
||||
Thread_queue_Heads *heads;
|
||||
|
||||
sem = _Semaphore_Get( _sem );
|
||||
sem = _Sem_Get( _sem );
|
||||
_Thread_queue_Context_initialize( &queue_context );
|
||||
_Thread_queue_Context_ISR_disable( &queue_context, level );
|
||||
_Semaphore_Queue_acquire_critical( sem, &queue_context );
|
||||
_Sem_Queue_acquire_critical( sem, &queue_context );
|
||||
|
||||
heads = sem->Queue.Queue.heads;
|
||||
if ( __predict_true( heads == NULL ) ) {
|
||||
_Assert( sem->count < UINT_MAX );
|
||||
++sem->count;
|
||||
_Semaphore_Queue_release( sem, level, &queue_context );
|
||||
_Sem_Queue_release( sem, level, &queue_context );
|
||||
} else {
|
||||
const Thread_queue_Operations *operations;
|
||||
Thread_Control *first;
|
||||
|
||||
@@ -263,7 +263,6 @@ static void resourceSnapshotCheck( void )
|
||||
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
|
||||
|
||||
#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
|
||||
#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 2
|
||||
|
||||
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
|
||||
|
||||
|
||||
@@ -130,7 +130,6 @@ void *POSIX_Init( void *arg )
|
||||
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
|
||||
|
||||
#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
|
||||
#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 1
|
||||
|
||||
#define CONFIGURE_INIT
|
||||
#include <rtems/confdefs.h>
|
||||
|
||||
@@ -38,10 +38,8 @@ static void *sem_wait_task(void *arg)
|
||||
rv = sem_wait( sem );
|
||||
rtems_test_assert( rv == 0 );
|
||||
|
||||
errno = 0;
|
||||
rv = sem_wait( sem );
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
rtems_test_assert( rv == 0 );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -70,11 +68,69 @@ static void test_sem_wait_during_delete(void)
|
||||
rtems_test_assert( rv == 0 );
|
||||
rtems_test_assert( val == 0 );
|
||||
|
||||
errno = 0;
|
||||
rv = sem_destroy( &sem );
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EBUSY );
|
||||
|
||||
rv = sem_post( &sem );
|
||||
rtems_test_assert( rv == 0 );
|
||||
|
||||
eno = pthread_join( th, NULL );
|
||||
rtems_test_assert( eno == 0 );
|
||||
|
||||
rv = sem_destroy( &sem );
|
||||
rtems_test_assert( rv == 0 );
|
||||
}
|
||||
|
||||
static void test_named_sem_wait_during_delete(void)
|
||||
{
|
||||
sem_t *sem;
|
||||
sem_t *sem2;
|
||||
int rv;
|
||||
pthread_t th;
|
||||
int eno;
|
||||
int val;
|
||||
|
||||
sem = sem_open( "sem", O_CREAT | O_EXCL, 0777, 1 );
|
||||
rtems_test_assert( sem != SEM_FAILED );
|
||||
|
||||
sem2 = sem_open( "sem", 0 );
|
||||
rtems_test_assert( sem2 != SEM_FAILED );
|
||||
rtems_test_assert( sem == sem2 );
|
||||
|
||||
eno = pthread_create( &th, NULL, sem_wait_task, sem );
|
||||
rtems_test_assert( eno == 0 );
|
||||
|
||||
rv = sem_getvalue( sem, &val );
|
||||
rtems_test_assert( rv == 0 );
|
||||
rtems_test_assert( val == 1 );
|
||||
|
||||
sched_yield();
|
||||
|
||||
rv = sem_getvalue( sem, &val );
|
||||
rtems_test_assert( rv == 0 );
|
||||
rtems_test_assert( val == 0 );
|
||||
|
||||
rv = sem_close( sem2 );
|
||||
rtems_test_assert( rv == 0 );
|
||||
|
||||
errno = 0;
|
||||
rv = sem_close( sem );
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EBUSY );
|
||||
|
||||
rv = sem_post( sem );
|
||||
rtems_test_assert( rv == 0 );
|
||||
|
||||
eno = pthread_join( th, NULL );
|
||||
rtems_test_assert( eno == 0 );
|
||||
|
||||
rv = sem_close( sem );
|
||||
rtems_test_assert( rv == 0 );
|
||||
|
||||
rv = sem_unlink( "sem" );
|
||||
rtems_test_assert( rv == 0 );
|
||||
}
|
||||
|
||||
static void test_sem_post_overflow(void)
|
||||
@@ -111,13 +167,163 @@ static void test_sem_post_overflow(void)
|
||||
|
||||
static void test_sem_init_too_large_inital_value(void)
|
||||
{
|
||||
sem_t sem;
|
||||
int rv;
|
||||
sem_t sem;
|
||||
sem_t *sem2;
|
||||
int rv;
|
||||
|
||||
errno = 0;
|
||||
rv = sem_init( &sem, 0, (unsigned int) SEM_VALUE_MAX + 1 );
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
|
||||
errno = 0;
|
||||
sem2 = sem_open(
|
||||
"sem",
|
||||
O_CREAT | O_EXCL,
|
||||
0777,
|
||||
(unsigned int) SEM_VALUE_MAX + 1
|
||||
);
|
||||
rtems_test_assert( sem2 == SEM_FAILED );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
}
|
||||
|
||||
static void test_sem_null(void)
|
||||
{
|
||||
int rv;
|
||||
int val;
|
||||
struct timespec to;
|
||||
|
||||
rtems_test_assert( NULL == SEM_FAILED );
|
||||
|
||||
errno = 0;
|
||||
rv = sem_init( NULL, 0, 0 );
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
|
||||
errno = 0;
|
||||
rv = sem_wait( NULL );
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
|
||||
errno = 0;
|
||||
rv = sem_post( NULL );
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
|
||||
errno = 0;
|
||||
rv = sem_wait( NULL );
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
|
||||
errno = 0;
|
||||
rv = sem_trywait( NULL );
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
|
||||
to.tv_sec = 1;
|
||||
to.tv_nsec = 1;
|
||||
errno = 0;
|
||||
rv = sem_timedwait( NULL, &to );
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
|
||||
errno = 0;
|
||||
rv = sem_getvalue( NULL, &val );
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
|
||||
errno = 0;
|
||||
rv = sem_destroy( NULL );
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
|
||||
errno = 0;
|
||||
rv = sem_close( NULL );
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
}
|
||||
|
||||
static void test_sem_not_initialized(void)
|
||||
{
|
||||
sem_t sem;
|
||||
int rv;
|
||||
int val;
|
||||
struct timespec to;
|
||||
|
||||
memset( &sem, 0xff, sizeof( sem ) );
|
||||
|
||||
errno = 0;
|
||||
rv = sem_wait( &sem );
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
|
||||
errno = 0;
|
||||
rv = sem_post( &sem );
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
|
||||
errno = 0;
|
||||
rv = sem_wait( &sem );
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
|
||||
errno = 0;
|
||||
rv = sem_trywait( &sem );
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
|
||||
to.tv_sec = 1;
|
||||
to.tv_nsec = 1;
|
||||
errno = 0;
|
||||
rv = sem_timedwait( &sem, &to );
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
|
||||
errno = 0;
|
||||
rv = sem_getvalue( &sem, &val );
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
|
||||
errno = 0;
|
||||
rv = sem_destroy( &sem );
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
|
||||
errno = 0;
|
||||
rv = sem_close( &sem );
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
}
|
||||
|
||||
static void test_sem_invalid_copy(void)
|
||||
{
|
||||
sem_t sem;
|
||||
sem_t sem2;
|
||||
int rv;
|
||||
int val;
|
||||
|
||||
rv = sem_init( &sem, 0, 0 );
|
||||
rtems_test_assert( rv == 0 );
|
||||
|
||||
val = 1;
|
||||
rv = sem_getvalue( &sem, &val );
|
||||
rtems_test_assert( rv == 0 );
|
||||
rtems_test_assert( val == 0 );
|
||||
|
||||
memcpy( &sem2, &sem, sizeof( sem2 ) );
|
||||
|
||||
errno = 0;
|
||||
rv = sem_getvalue( &sem2, &val );
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
|
||||
rv = sem_destroy( &sem );
|
||||
rtems_test_assert( rv == 0 );
|
||||
|
||||
errno = 0;
|
||||
rv = sem_getvalue( &sem, &val );
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
}
|
||||
|
||||
void *POSIX_Init(
|
||||
@@ -155,10 +361,14 @@ void *POSIX_Init(
|
||||
sprintf(failure_msg, "sem_init %d", i );
|
||||
fatal_posix_service_status( status, 0, failure_msg);
|
||||
}
|
||||
puts( "Init: sem_init - UNSUCCESSFUL (ENOSPC)" );
|
||||
|
||||
puts( "Init: sem_init - SUCCESSFUL" );
|
||||
status = sem_init(&sem2, 0, 1);
|
||||
fatal_posix_service_status( status, -1, "sem_init error return status");
|
||||
fatal_posix_service_status( errno, ENOSPC, "sem_init errorno ENOSPC" );
|
||||
fatal_posix_service_status( status, 0, "sem_init");
|
||||
|
||||
puts( "Init: sem_destroy - SUCCESSFUL" );
|
||||
status = sem_destroy(&sem2);
|
||||
fatal_posix_service_status( status, 0, "sem_destroy");
|
||||
|
||||
puts( "Init: sem_getvalue - SUCCESSFUL ");
|
||||
for (i = 0; i < MAX_SEMS; i++) {
|
||||
@@ -168,8 +378,7 @@ void *POSIX_Init(
|
||||
fatal_posix_service_status( value, i, "sem_getvalue correct value" );
|
||||
}
|
||||
puts( "Init: sem_getvalue - UNSUCCESSFUL ");
|
||||
sem2 = 0;
|
||||
status = sem_getvalue(&sem2, &value);
|
||||
status = sem_getvalue(SEM_FAILED, &value);
|
||||
fatal_posix_service_status( status, -1, "sem_getvalue error return status");
|
||||
fatal_posix_service_status( errno, EINVAL, "sem_getvalue errno EINVAL");
|
||||
|
||||
@@ -178,7 +387,7 @@ void *POSIX_Init(
|
||||
fatal_posix_service_status( status, 0, "sem_destroy semaphore 0");
|
||||
|
||||
puts( "Init: sem_destroy - UNSUCCESSFUL (EINVAL)" );
|
||||
status = sem_destroy(&sem2);
|
||||
status = sem_destroy(SEM_FAILED);
|
||||
fatal_posix_service_status( status, -1, "sem_destroy error return status");
|
||||
fatal_posix_service_status( errno, EINVAL, "sem_destroy errno EINVAL");
|
||||
|
||||
@@ -188,7 +397,7 @@ void *POSIX_Init(
|
||||
/* sem[1].count = 0 */
|
||||
|
||||
puts( "Init: sem_wait - UNSUCCESSFUL (EINVAL)" );
|
||||
status = sem_wait(&sem2);
|
||||
status = sem_wait(SEM_FAILED);
|
||||
fatal_posix_service_status( status, -1, "sem_wait error return status");
|
||||
fatal_posix_service_status( errno, EINVAL, "sem_wait errno EINVAL");
|
||||
|
||||
@@ -214,7 +423,7 @@ void *POSIX_Init(
|
||||
/* sem[1].count = 0 */
|
||||
|
||||
puts( "Init: sem_trywait - UNSUCCESSFUL (EINVAL)" );
|
||||
status = sem_trywait(&sem2);
|
||||
status = sem_trywait(SEM_FAILED);
|
||||
fatal_posix_service_status( status, -1, "sem_trywait error return status");
|
||||
fatal_posix_service_status( errno, EINVAL, "sem_trywait errno EINVAL");
|
||||
|
||||
@@ -256,7 +465,7 @@ void *POSIX_Init(
|
||||
#endif
|
||||
|
||||
puts( "Init: sem_post - UNSUCCESSFUL (EINVAL)" );
|
||||
status = sem_post(&sem2);
|
||||
status = sem_post(SEM_FAILED);
|
||||
fatal_posix_service_status( status, -1, "sem_post error return status");
|
||||
fatal_posix_service_status( errno, EINVAL, "sem_post errno EINVAL");
|
||||
|
||||
@@ -392,9 +601,13 @@ void *POSIX_Init(
|
||||
fatal_posix_service_status( errno, ENOENT, "sem_unlink errno ENOENT");
|
||||
rtems_test_assert( (status == -1) && (errno == ENOENT) );
|
||||
|
||||
test_named_sem_wait_during_delete();
|
||||
test_sem_wait_during_delete();
|
||||
test_sem_post_overflow();
|
||||
test_sem_init_too_large_inital_value();
|
||||
test_sem_null();
|
||||
test_sem_not_initialized();
|
||||
test_sem_invalid_copy();
|
||||
|
||||
/* Try adding in unlinking before closing... (can we still open?) */
|
||||
|
||||
@@ -413,7 +626,7 @@ void *POSIX_Init(
|
||||
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
|
||||
|
||||
#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
|
||||
#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES MAX_SEMS
|
||||
#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 2
|
||||
|
||||
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
|
||||
#define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE \
|
||||
|
||||
@@ -159,7 +159,6 @@ void *POSIX_Init(void *argument)
|
||||
#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
|
||||
|
||||
#define CONFIGURE_MAXIMUM_POSIX_THREADS 1
|
||||
#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 2
|
||||
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
|
||||
|
||||
#define CONFIGURE_INIT
|
||||
|
||||
@@ -124,7 +124,6 @@ void *POSIX_Init(
|
||||
#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
|
||||
|
||||
#define CONFIGURE_MAXIMUM_POSIX_THREADS OPERATION_COUNT + 2
|
||||
#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES MAX_SEMS
|
||||
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
|
||||
|
||||
#define CONFIGURE_INIT
|
||||
|
||||
@@ -99,7 +99,6 @@ void *POSIX_Init(void *argument)
|
||||
#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
|
||||
|
||||
#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
|
||||
#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES MAX_SEMS
|
||||
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
|
||||
|
||||
#define CONFIGURE_INIT
|
||||
|
||||
@@ -159,7 +159,6 @@ void *POSIX_Init(
|
||||
#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
|
||||
|
||||
#define CONFIGURE_MAXIMUM_POSIX_THREADS OPERATION_COUNT + 2
|
||||
#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES MAX_SEMS
|
||||
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
|
||||
|
||||
#define CONFIGURE_INIT
|
||||
|
||||
@@ -40,7 +40,6 @@ typedef struct {
|
||||
rtems_id mq;
|
||||
rtems_id br;
|
||||
#if defined(RTEMS_POSIX_API)
|
||||
sem_t psem;
|
||||
pthread_mutex_t pmtx;
|
||||
pthread_cond_t pcv;
|
||||
pthread_rwlock_t prw;
|
||||
@@ -120,12 +119,6 @@ static void posix_worker(test_context *ctx)
|
||||
int eno;
|
||||
char buf[1];
|
||||
|
||||
wake_up_master(ctx);
|
||||
rtems_test_assert(get_wait_id(ctx) == ctx->psem);
|
||||
|
||||
rv = sem_post(&ctx->psem);
|
||||
rtems_test_assert(rv == 0);
|
||||
|
||||
eno = pthread_mutex_lock(&ctx->pmtx);
|
||||
rtems_test_assert(eno == 0);
|
||||
|
||||
@@ -217,13 +210,9 @@ static void test_classic_init(test_context *ctx)
|
||||
static void test_posix_init(test_context *ctx)
|
||||
{
|
||||
#if defined(RTEMS_POSIX_API)
|
||||
int rv;
|
||||
int eno;
|
||||
struct mq_attr attr;
|
||||
|
||||
rv = sem_init(&ctx->psem, 0, 0);
|
||||
rtems_test_assert(rv == 0);
|
||||
|
||||
eno = pthread_mutex_init(&ctx->pmtx, NULL);
|
||||
rtems_test_assert(eno == 0);
|
||||
|
||||
@@ -306,7 +295,6 @@ static void test_classic_obj(test_context *ctx)
|
||||
static void test_posix_obj(test_context *ctx)
|
||||
{
|
||||
#if defined(RTEMS_POSIX_API)
|
||||
int rv;
|
||||
int eno;
|
||||
char buf[1];
|
||||
unsigned prio;
|
||||
@@ -314,11 +302,6 @@ static void test_posix_obj(test_context *ctx)
|
||||
|
||||
wait_for_worker(ctx);
|
||||
|
||||
rv = sem_wait(&ctx->psem);
|
||||
rtems_test_assert(rv == 0);
|
||||
|
||||
wait_for_worker(ctx);
|
||||
|
||||
eno = pthread_mutex_lock(&ctx->pmtx);
|
||||
rtems_test_assert(eno == 0);
|
||||
|
||||
@@ -377,7 +360,6 @@ static rtems_task Init(
|
||||
#define CONFIGURE_MAXIMUM_BARRIERS 1
|
||||
|
||||
#if defined(RTEMS_POSIX_API)
|
||||
#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 1
|
||||
#define CONFIGURE_MAXIMUM_POSIX_MUTEXES 1
|
||||
#define CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES 1
|
||||
#define CONFIGURE_MAXIMUM_POSIX_RWLOCKS 1
|
||||
|
||||
Reference in New Issue
Block a user