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/config.h
|
||||||
include_rtems_posix_HEADERS += include/rtems/posix/posixapi.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/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
|
include_rtems_posix_HEADERS += include/rtems/posix/spinlockimpl.h
|
||||||
|
|
||||||
if HAS_PTHREADS
|
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/ptimer.h
|
||||||
include_rtems_posix_HEADERS += include/rtems/posix/shm.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/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/threadsup.h
|
||||||
include_rtems_posix_HEADERS += include/rtems/posix/timer.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/timerimpl.h
|
||||||
@@ -186,6 +186,15 @@ libposix_a_SOURCES += src/pspininit.c
|
|||||||
libposix_a_SOURCES += src/pspinlock.c
|
libposix_a_SOURCES += src/pspinlock.c
|
||||||
libposix_a_SOURCES += src/pspinunlock.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
|
if HAS_PTHREADS
|
||||||
libposix_a_SOURCES += src/sigpending.c \
|
libposix_a_SOURCES += src/sigpending.c \
|
||||||
src/sigqueue.c src/sigsuspend.c src/sigtimedwait.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
|
src/rwlockattrinit.c src/rwlockattrsetpshared.c
|
||||||
|
|
||||||
## SEMAPHORE_C_FILES
|
## SEMAPHORE_C_FILES
|
||||||
libposix_a_SOURCES += src/semaphore.c src/semaphorecreatesupp.c \
|
libposix_a_SOURCES += src/semaphore.c
|
||||||
src/semaphoredeletesupp.c \
|
libposix_a_SOURCES += src/semaphoredeletesupp.c
|
||||||
src/semaphorewaitsupp.c \
|
libposix_a_SOURCES += src/semclose.c
|
||||||
src/semclose.c src/semdestroy.c src/semgetvalue.c src/seminit.c \
|
libposix_a_SOURCES += src/semopen.c
|
||||||
src/semopen.c src/sempost.c src/semtimedwait.c src/semtrywait.c \
|
libposix_a_SOURCES += src/semunlink.c
|
||||||
src/semunlink.c src/semwait.c
|
|
||||||
|
|
||||||
## TIME_C_FILES
|
## TIME_C_FILES
|
||||||
libposix_a_SOURCES += src/adjtime.c src/clockgetcpuclockid.c
|
libposix_a_SOURCES += src/adjtime.c src/clockgetcpuclockid.c
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
#include <semaphore.h>
|
#include <semaphore.h>
|
||||||
#include <rtems/score/object.h>
|
#include <rtems/score/object.h>
|
||||||
#include <rtems/score/coresem.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -42,18 +41,9 @@ extern "C" {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Objects_Control Object;
|
Objects_Control Object;
|
||||||
CORE_semaphore_Control Semaphore;
|
sem_t Semaphore;
|
||||||
bool named;
|
|
||||||
bool linked;
|
bool linked;
|
||||||
uint32_t open_count;
|
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
|
|
||||||
} POSIX_Semaphore_Control;
|
} POSIX_Semaphore_Control;
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|||||||
@@ -21,21 +21,25 @@
|
|||||||
|
|
||||||
#include <rtems/posix/semaphore.h>
|
#include <rtems/posix/semaphore.h>
|
||||||
#include <rtems/posix/posixapi.h>
|
#include <rtems/posix/posixapi.h>
|
||||||
#include <rtems/score/coresemimpl.h>
|
#include <rtems/score/semaphoreimpl.h>
|
||||||
#include <rtems/seterr.h>
|
#include <rtems/seterr.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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 defines the information control block used to manage
|
||||||
* this class of objects.
|
* this class of objects.
|
||||||
*/
|
*/
|
||||||
extern Objects_Information _POSIX_Semaphore_Information;
|
extern Objects_Information _POSIX_Semaphore_Information;
|
||||||
|
|
||||||
#define POSIX_SEMAPHORE_TQ_OPERATIONS &_Thread_queue_Operations_FIFO
|
|
||||||
|
|
||||||
RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *
|
RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *
|
||||||
_POSIX_Semaphore_Allocate_unprotected( void )
|
_POSIX_Semaphore_Allocate_unprotected( void )
|
||||||
{
|
{
|
||||||
@@ -57,52 +61,44 @@ RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Free (
|
|||||||
}
|
}
|
||||||
|
|
||||||
RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *_POSIX_Semaphore_Get(
|
RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *_POSIX_Semaphore_Get(
|
||||||
const sem_t *id,
|
sem_t *sem
|
||||||
Thread_queue_Context *queue_context
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
_Thread_queue_Context_initialize( queue_context );
|
return RTEMS_CONTAINER_OF( sem, POSIX_Semaphore_Control, Semaphore );
|
||||||
return (POSIX_Semaphore_Control *) _Objects_Get(
|
|
||||||
(Objects_Id) *id,
|
|
||||||
&queue_context->Lock_context.Lock_context,
|
|
||||||
&_POSIX_Semaphore_Information
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
RTEMS_INLINE_ROUTINE bool _POSIX_Semaphore_Is_named( const sem_t *sem )
|
||||||
* @brief POSIX Semaphore Create Support
|
{
|
||||||
*
|
return sem->_Semaphore._Queue._name != NULL;
|
||||||
* This routine supports the sem_init and sem_open routines.
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
int _POSIX_Semaphore_Create_support(
|
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,
|
const char *name,
|
||||||
size_t name_len,
|
unsigned int value
|
||||||
unsigned int value,
|
)
|
||||||
POSIX_Semaphore_Control **the_sem
|
{
|
||||||
);
|
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
|
* @brief POSIX Semaphore Delete
|
||||||
*
|
*
|
||||||
* This routine supports the sem_close and sem_unlink routines.
|
* This routine supports the sem_close and sem_unlink routines.
|
||||||
*/
|
*/
|
||||||
void _POSIX_Semaphore_Delete(
|
void _POSIX_Semaphore_Delete( POSIX_Semaphore_Control *the_semaphore );
|
||||||
POSIX_Semaphore_Control *the_semaphore,
|
|
||||||
Thread_queue_Context *queue_context
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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
|
* @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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -47,6 +47,14 @@ $(PROJECT_INCLUDE)/rtems/posix/priorityimpl.h: include/rtems/posix/priorityimpl.
|
|||||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/priorityimpl.h
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/priorityimpl.h
|
||||||
PREINSTALL_FILES += $(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)
|
$(PROJECT_INCLUDE)/rtems/posix/spinlockimpl.h: include/rtems/posix/spinlockimpl.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
|
||||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/spinlockimpl.h
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/spinlockimpl.h
|
||||||
PREINSTALL_FILES += $(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
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/shmimpl.h
|
||||||
PREINSTALL_FILES += $(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)
|
$(PROJECT_INCLUDE)/rtems/posix/threadsup.h: include/rtems/posix/threadsup.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
|
||||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/threadsup.h
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/threadsup.h
|
||||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/threadsup.h
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/threadsup.h
|
||||||
|
|||||||
@@ -18,19 +18,11 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#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/config.h>
|
#include <rtems/config.h>
|
||||||
#include <rtems/sysinit.h>
|
#include <rtems/sysinit.h>
|
||||||
#include <rtems/posix/semaphoreimpl.h>
|
|
||||||
#include <rtems/seterr.h>
|
#include <limits.h>
|
||||||
|
|
||||||
Objects_Information _POSIX_Semaphore_Information;
|
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>
|
#include <rtems/posix/semaphoreimpl.h>
|
||||||
|
|
||||||
void _POSIX_Semaphore_Delete(
|
void _POSIX_Semaphore_Delete( POSIX_Semaphore_Control *the_semaphore )
|
||||||
POSIX_Semaphore_Control *the_semaphore,
|
|
||||||
Thread_queue_Context *queue_context
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if ( !the_semaphore->linked && !the_semaphore->open_count ) {
|
if ( !the_semaphore->linked && !the_semaphore->open_count ) {
|
||||||
_Objects_Close( &_POSIX_Semaphore_Information, &the_semaphore->Object );
|
_Objects_Close( &_POSIX_Semaphore_Information, &the_semaphore->Object );
|
||||||
_CORE_semaphore_Destroy(
|
_POSIX_Semaphore_Destroy( &the_semaphore->Semaphore );
|
||||||
&the_semaphore->Semaphore,
|
|
||||||
POSIX_SEMAPHORE_TQ_OPERATIONS,
|
|
||||||
queue_context
|
|
||||||
);
|
|
||||||
_POSIX_Semaphore_Free( the_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"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <semaphore.h>
|
|
||||||
|
|
||||||
#include <rtems/posix/semaphoreimpl.h>
|
#include <rtems/posix/semaphoreimpl.h>
|
||||||
|
|
||||||
int sem_close(
|
int sem_close( sem_t *sem )
|
||||||
sem_t *sem
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
POSIX_Semaphore_Control *the_semaphore;
|
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();
|
_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();
|
_Objects_Allocator_unlock();
|
||||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||||
}
|
}
|
||||||
|
|
||||||
_CORE_semaphore_Acquire_critical(
|
if ( open_count == 1 && _POSIX_Semaphore_Is_busy( sem ) ) {
|
||||||
&the_semaphore->Semaphore,
|
_Objects_Allocator_unlock();
|
||||||
&queue_context
|
rtems_set_errno_and_return_minus_one( EBUSY );
|
||||||
);
|
}
|
||||||
the_semaphore->open_count -= 1;
|
|
||||||
_POSIX_Semaphore_Delete( the_semaphore, &queue_context );
|
|
||||||
|
|
||||||
|
the_semaphore->open_count = open_count - 1;
|
||||||
|
_POSIX_Semaphore_Delete( the_semaphore );
|
||||||
_Objects_Allocator_unlock();
|
_Objects_Allocator_unlock();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,39 +18,20 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <semaphore.h>
|
|
||||||
|
|
||||||
#include <rtems/posix/semaphoreimpl.h>
|
#include <rtems/posix/semaphoreimpl.h>
|
||||||
|
|
||||||
int sem_destroy(
|
int sem_destroy( sem_t *sem )
|
||||||
sem_t *sem
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
POSIX_Semaphore_Control *the_semaphore;
|
POSIX_SEMAPHORE_VALIDATE_OBJECT( sem );
|
||||||
Thread_queue_Context queue_context;
|
|
||||||
|
|
||||||
_Objects_Allocator_lock();
|
if ( _POSIX_Semaphore_Is_named( sem ) ) {
|
||||||
the_semaphore = _POSIX_Semaphore_Get( sem, &queue_context );
|
|
||||||
|
|
||||||
if ( the_semaphore == NULL ) {
|
|
||||||
_Objects_Allocator_unlock();
|
|
||||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||||
}
|
}
|
||||||
|
|
||||||
_CORE_semaphore_Acquire_critical(
|
if ( _POSIX_Semaphore_Is_busy( sem ) ) {
|
||||||
&the_semaphore->Semaphore,
|
rtems_set_errno_and_return_minus_one( EBUSY );
|
||||||
&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 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_POSIX_Semaphore_Delete( the_semaphore, &queue_context );
|
_POSIX_Semaphore_Destroy( sem );
|
||||||
|
|
||||||
_Objects_Allocator_unlock();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,31 +18,24 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <semaphore.h>
|
|
||||||
|
|
||||||
#include <rtems/posix/semaphoreimpl.h>
|
#include <rtems/posix/semaphoreimpl.h>
|
||||||
|
|
||||||
int sem_getvalue(
|
int sem_getvalue(
|
||||||
sem_t *__restrict sem,
|
sem_t *__restrict _sem,
|
||||||
int *__restrict sval
|
int *__restrict sval
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
POSIX_Semaphore_Control *the_semaphore;
|
Sem_Control *sem;
|
||||||
|
ISR_Level level;
|
||||||
Thread_queue_Context queue_context;
|
Thread_queue_Context queue_context;
|
||||||
|
|
||||||
the_semaphore = _POSIX_Semaphore_Get( sem, &queue_context );
|
POSIX_SEMAPHORE_VALIDATE_OBJECT( _sem );
|
||||||
|
|
||||||
if ( the_semaphore == NULL ) {
|
sem = _Sem_Get( &_sem->_Semaphore );
|
||||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
_Thread_queue_Context_initialize( &queue_context );
|
||||||
}
|
_Thread_queue_Context_ISR_disable( &queue_context, level );
|
||||||
|
_Sem_Queue_acquire_critical( sem, &queue_context );
|
||||||
_CORE_semaphore_Acquire_critical(
|
*sval = (int) sem->count;
|
||||||
&the_semaphore->Semaphore,
|
_Sem_Queue_release( sem, level, &queue_context );
|
||||||
&queue_context
|
|
||||||
);
|
|
||||||
|
|
||||||
*sval = _CORE_semaphore_Get_count( &the_semaphore->Semaphore );
|
|
||||||
|
|
||||||
_CORE_semaphore_Release( &the_semaphore->Semaphore, &queue_context );
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,17 +18,11 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#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 <limits.h>
|
||||||
|
|
||||||
#include <rtems/system.h>
|
RTEMS_STATIC_ASSERT(NULL == SEM_FAILED, sem_failed);
|
||||||
#include <rtems/posix/semaphoreimpl.h>
|
|
||||||
#include <rtems/seterr.h>
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 11.2.1 Initialize an Unnamed Semaphore, P1003.1b-1993, p.219
|
* 11.2.1 Initialize an Unnamed Semaphore, P1003.1b-1993, p.219
|
||||||
@@ -40,9 +34,6 @@ int sem_init(
|
|||||||
unsigned int value
|
unsigned int value
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int status;
|
|
||||||
POSIX_Semaphore_Control *the_semaphore;
|
|
||||||
|
|
||||||
if ( sem == NULL ) {
|
if ( sem == NULL ) {
|
||||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||||
}
|
}
|
||||||
@@ -51,17 +42,6 @@ int sem_init(
|
|||||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||||
}
|
}
|
||||||
|
|
||||||
_Objects_Allocator_lock();
|
_POSIX_Semaphore_Initialize( sem, NULL, value );
|
||||||
status = _POSIX_Semaphore_Create_support(
|
return 0;
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
value,
|
|
||||||
&the_semaphore
|
|
||||||
);
|
|
||||||
_Objects_Allocator_unlock();
|
|
||||||
|
|
||||||
if ( status != -1 )
|
|
||||||
*sem = the_semaphore->Object.id;
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,17 +18,64 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <rtems/posix/semaphoreimpl.h>
|
||||||
|
#include <rtems/score/wkspace.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <stdarg.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <pthread.h>
|
|
||||||
#include <semaphore.h>
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
#include <rtems/system.h>
|
static sem_t *_POSIX_Semaphore_Create_support(
|
||||||
#include <rtems/posix/semaphoreimpl.h>
|
const char *name_arg,
|
||||||
#include <rtems/seterr.h>
|
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
|
* sem_open
|
||||||
@@ -59,10 +106,10 @@ sem_t *sem_open(
|
|||||||
|
|
||||||
va_list arg;
|
va_list arg;
|
||||||
unsigned int value = 0;
|
unsigned int value = 0;
|
||||||
int status;
|
|
||||||
POSIX_Semaphore_Control *the_semaphore;
|
POSIX_Semaphore_Control *the_semaphore;
|
||||||
size_t name_len;
|
size_t name_len;
|
||||||
Objects_Get_by_name_error error;
|
Objects_Get_by_name_error error;
|
||||||
|
sem_t *sem;
|
||||||
|
|
||||||
if ( oflag & O_CREAT ) {
|
if ( oflag & O_CREAT ) {
|
||||||
va_start(arg, oflag);
|
va_start(arg, oflag);
|
||||||
@@ -108,7 +155,7 @@ sem_t *sem_open(
|
|||||||
|
|
||||||
the_semaphore->open_count += 1;
|
the_semaphore->open_count += 1;
|
||||||
_Objects_Allocator_unlock();
|
_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.
|
* checked. We should go ahead and create a semaphore.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
status =_POSIX_Semaphore_Create_support(
|
sem = _POSIX_Semaphore_Create_support(
|
||||||
name,
|
name,
|
||||||
name_len,
|
name_len,
|
||||||
value,
|
value
|
||||||
&the_semaphore
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
|
||||||
* errno was set by Create_support, so don't set it again.
|
|
||||||
*/
|
|
||||||
|
|
||||||
_Objects_Allocator_unlock();
|
_Objects_Allocator_unlock();
|
||||||
|
return sem;
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,31 +18,51 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <semaphore.h>
|
#include <rtems/posix/semaphoreimpl.h>
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
#include <rtems/posix/semaphoreimpl.h>
|
int sem_post( sem_t *_sem )
|
||||||
#include <rtems/posix/posixapi.h>
|
|
||||||
|
|
||||||
int sem_post(
|
|
||||||
sem_t *sem
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
POSIX_Semaphore_Control *the_semaphore;
|
Sem_Control *sem;
|
||||||
|
ISR_Level level;
|
||||||
Thread_queue_Context queue_context;
|
Thread_queue_Context queue_context;
|
||||||
Status_Control status;
|
Thread_queue_Heads *heads;
|
||||||
|
unsigned int count;
|
||||||
|
|
||||||
the_semaphore = _POSIX_Semaphore_Get( sem, &queue_context );
|
POSIX_SEMAPHORE_VALIDATE_OBJECT( _sem );
|
||||||
|
|
||||||
if ( the_semaphore == NULL ) {
|
sem = _Sem_Get( &_sem->_Semaphore );
|
||||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
_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(
|
if ( __predict_true( heads != NULL ) ) {
|
||||||
&the_semaphore->Semaphore,
|
const Thread_queue_Operations *operations;
|
||||||
POSIX_SEMAPHORE_TQ_OPERATIONS,
|
Thread_Control *first;
|
||||||
SEM_VALUE_MAX,
|
|
||||||
|
_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
|
&queue_context
|
||||||
);
|
);
|
||||||
return _POSIX_Zero_or_minus_one_plus_errno( status );
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Sem_Queue_release( sem, level, &queue_context );
|
||||||
|
rtems_set_errno_and_return_minus_one( EOVERFLOW );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,18 +18,8 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#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/posix/semaphoreimpl.h>
|
||||||
#include <rtems/seterr.h>
|
#include <rtems/score/todimpl.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 11.2.6 Lock a Semaphore, P1003.1b-1993, p.226
|
* 11.2.6 Lock a Semaphore, P1003.1b-1993, p.226
|
||||||
@@ -38,47 +28,60 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int sem_timedwait(
|
int sem_timedwait(
|
||||||
sem_t *__restrict sem,
|
sem_t *__restrict _sem,
|
||||||
const struct timespec *__restrict abstime
|
const struct timespec *__restrict abstime
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
Sem_Control *sem;
|
||||||
|
Thread_queue_Context queue_context;
|
||||||
|
ISR_Level level;
|
||||||
|
Thread_Control *executing;
|
||||||
|
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 );
|
||||||
|
executing = _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 {
|
||||||
Watchdog_Interval ticks;
|
Watchdog_Interval ticks;
|
||||||
bool do_wait = true;
|
Status_Control status;
|
||||||
TOD_Absolute_timeout_conversion_results status;
|
|
||||||
int lock_status;
|
|
||||||
|
|
||||||
/*
|
switch ( _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks ) ) {
|
||||||
* POSIX requires that blocking calls with timeouts that take
|
case TOD_ABSOLUTE_TIMEOUT_INVALID:
|
||||||
* an absolute timeout must ignore issues with the absolute
|
_Sem_Queue_release( sem, level, &queue_context );
|
||||||
* 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;
|
|
||||||
|
|
||||||
lock_status = _POSIX_Semaphore_Wait_support( sem, do_wait, ticks );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 );
|
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||||
if ( lock_status == TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST ||
|
break;
|
||||||
lock_status == TOD_ABSOLUTE_TIMEOUT_IS_NOW )
|
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 );
|
rtems_set_errno_and_return_minus_one( ETIMEDOUT );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return lock_status;
|
_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 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,21 +18,29 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#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/posix/semaphoreimpl.h>
|
||||||
#include <rtems/seterr.h>
|
|
||||||
|
|
||||||
int sem_trywait(
|
int sem_trywait( sem_t *_sem )
|
||||||
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"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <semaphore.h>
|
|
||||||
|
|
||||||
#include <rtems/posix/semaphoreimpl.h>
|
#include <rtems/posix/semaphoreimpl.h>
|
||||||
|
|
||||||
int sem_unlink(
|
int sem_unlink( const char *name )
|
||||||
const char *name
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
POSIX_Semaphore_Control *the_semaphore;
|
POSIX_Semaphore_Control *the_semaphore;
|
||||||
Objects_Get_by_name_error error;
|
Objects_Get_by_name_error error;
|
||||||
Thread_queue_Context queue_context;
|
|
||||||
|
|
||||||
_Objects_Allocator_lock();
|
_Objects_Allocator_lock();
|
||||||
|
|
||||||
@@ -39,12 +34,8 @@ int sem_unlink(
|
|||||||
}
|
}
|
||||||
|
|
||||||
_POSIX_Semaphore_Namespace_remove( the_semaphore );
|
_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;
|
the_semaphore->linked = false;
|
||||||
_POSIX_Semaphore_Delete( the_semaphore, &queue_context );
|
_POSIX_Semaphore_Delete( the_semaphore );
|
||||||
|
|
||||||
_Objects_Allocator_unlock();
|
_Objects_Allocator_unlock();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,21 +18,11 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#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/posix/semaphoreimpl.h>
|
||||||
#include <rtems/seterr.h>
|
|
||||||
|
|
||||||
int sem_wait(
|
int sem_wait( sem_t *sem )
|
||||||
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
|
#endif
|
||||||
|
|
||||||
#include <rtems/posix/posixapi.h>
|
#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 )
|
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/schedulersimpleimpl.h
|
||||||
include_rtems_score_HEADERS += include/rtems/score/schedulersmp.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/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/smp.h
|
||||||
include_rtems_score_HEADERS += include/rtems/score/smpbarrier.h
|
include_rtems_score_HEADERS += include/rtems/score/smpbarrier.h
|
||||||
include_rtems_score_HEADERS += include/rtems/score/smplock.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
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulersmpimpl.h
|
||||||
PREINSTALL_FILES += $(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)
|
$(PROJECT_INCLUDE)/rtems/score/smp.h: include/rtems/score/smp.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
|
||||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/smp.h
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/smp.h
|
||||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/smp.h
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/smp.h
|
||||||
|
|||||||
@@ -16,92 +16,45 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <sys/lock.h>
|
#include <rtems/score/semaphoreimpl.h>
|
||||||
|
#include <rtems/score/statesimpl.h>
|
||||||
|
|
||||||
#include <limits.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(
|
RTEMS_STATIC_ASSERT(
|
||||||
offsetof( Semaphore_Control, Queue )
|
offsetof( Sem_Control, Queue )
|
||||||
== offsetof( struct _Semaphore_Control, _Queue ),
|
== offsetof( struct _Semaphore_Control, _Queue ),
|
||||||
SEMAPHORE_CONTROL_QUEUE
|
SEMAPHORE_CONTROL_QUEUE
|
||||||
);
|
);
|
||||||
|
|
||||||
RTEMS_STATIC_ASSERT(
|
RTEMS_STATIC_ASSERT(
|
||||||
offsetof( Semaphore_Control, count )
|
offsetof( Sem_Control, count )
|
||||||
== offsetof( struct _Semaphore_Control, _count ),
|
== offsetof( struct _Semaphore_Control, _count ),
|
||||||
SEMAPHORE_CONTROL_COUNT
|
SEMAPHORE_CONTROL_COUNT
|
||||||
);
|
);
|
||||||
|
|
||||||
RTEMS_STATIC_ASSERT(
|
RTEMS_STATIC_ASSERT(
|
||||||
sizeof( Semaphore_Control ) == sizeof( struct _Semaphore_Control ),
|
sizeof( Sem_Control ) == sizeof( struct _Semaphore_Control ),
|
||||||
SEMAPHORE_CONTROL_SIZE
|
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 )
|
void _Semaphore_Wait( struct _Semaphore_Control *_sem )
|
||||||
{
|
{
|
||||||
Semaphore_Control *sem ;
|
Sem_Control *sem;
|
||||||
ISR_Level level;
|
ISR_Level level;
|
||||||
Thread_queue_Context queue_context;
|
Thread_queue_Context queue_context;
|
||||||
Thread_Control *executing;
|
Thread_Control *executing;
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
|
|
||||||
sem = _Semaphore_Get( _sem );
|
sem = _Sem_Get( _sem );
|
||||||
_Thread_queue_Context_initialize( &queue_context );
|
_Thread_queue_Context_initialize( &queue_context );
|
||||||
_Thread_queue_Context_ISR_disable( &queue_context, level );
|
_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;
|
count = sem->count;
|
||||||
if ( __predict_true( count > 0 ) ) {
|
if ( __predict_true( count > 0 ) ) {
|
||||||
sem->count = count - 1;
|
sem->count = count - 1;
|
||||||
_Semaphore_Queue_release( sem, level, &queue_context );
|
_Sem_Queue_release( sem, level, &queue_context );
|
||||||
} else {
|
} else {
|
||||||
_Thread_queue_Context_set_thread_state(
|
_Thread_queue_Context_set_thread_state(
|
||||||
&queue_context,
|
&queue_context,
|
||||||
@@ -121,21 +74,21 @@ void _Semaphore_Wait( struct _Semaphore_Control *_sem )
|
|||||||
|
|
||||||
void _Semaphore_Post( struct _Semaphore_Control *_sem )
|
void _Semaphore_Post( struct _Semaphore_Control *_sem )
|
||||||
{
|
{
|
||||||
Semaphore_Control *sem;
|
Sem_Control *sem;
|
||||||
ISR_Level level;
|
ISR_Level level;
|
||||||
Thread_queue_Context queue_context;
|
Thread_queue_Context queue_context;
|
||||||
Thread_queue_Heads *heads;
|
Thread_queue_Heads *heads;
|
||||||
|
|
||||||
sem = _Semaphore_Get( _sem );
|
sem = _Sem_Get( _sem );
|
||||||
_Thread_queue_Context_initialize( &queue_context );
|
_Thread_queue_Context_initialize( &queue_context );
|
||||||
_Thread_queue_Context_ISR_disable( &queue_context, level );
|
_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;
|
heads = sem->Queue.Queue.heads;
|
||||||
if ( __predict_true( heads == NULL ) ) {
|
if ( __predict_true( heads == NULL ) ) {
|
||||||
_Assert( sem->count < UINT_MAX );
|
_Assert( sem->count < UINT_MAX );
|
||||||
++sem->count;
|
++sem->count;
|
||||||
_Semaphore_Queue_release( sem, level, &queue_context );
|
_Sem_Queue_release( sem, level, &queue_context );
|
||||||
} else {
|
} else {
|
||||||
const Thread_queue_Operations *operations;
|
const Thread_queue_Operations *operations;
|
||||||
Thread_Control *first;
|
Thread_Control *first;
|
||||||
|
|||||||
@@ -263,7 +263,6 @@ static void resourceSnapshotCheck( void )
|
|||||||
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
|
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
|
||||||
|
|
||||||
#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
|
#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
|
||||||
#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 2
|
|
||||||
|
|
||||||
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
|
#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_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
|
||||||
|
|
||||||
#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
|
#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
|
||||||
#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 1
|
|
||||||
|
|
||||||
#define CONFIGURE_INIT
|
#define CONFIGURE_INIT
|
||||||
#include <rtems/confdefs.h>
|
#include <rtems/confdefs.h>
|
||||||
|
|||||||
@@ -38,10 +38,8 @@ static void *sem_wait_task(void *arg)
|
|||||||
rv = sem_wait( sem );
|
rv = sem_wait( sem );
|
||||||
rtems_test_assert( rv == 0 );
|
rtems_test_assert( rv == 0 );
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
rv = sem_wait( sem );
|
rv = sem_wait( sem );
|
||||||
rtems_test_assert( rv == -1 );
|
rtems_test_assert( rv == 0 );
|
||||||
rtems_test_assert( errno == EINVAL );
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -70,11 +68,69 @@ static void test_sem_wait_during_delete(void)
|
|||||||
rtems_test_assert( rv == 0 );
|
rtems_test_assert( rv == 0 );
|
||||||
rtems_test_assert( val == 0 );
|
rtems_test_assert( val == 0 );
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
rv = sem_destroy( &sem );
|
rv = sem_destroy( &sem );
|
||||||
|
rtems_test_assert( rv == -1 );
|
||||||
|
rtems_test_assert( errno == EBUSY );
|
||||||
|
|
||||||
|
rv = sem_post( &sem );
|
||||||
rtems_test_assert( rv == 0 );
|
rtems_test_assert( rv == 0 );
|
||||||
|
|
||||||
eno = pthread_join( th, NULL );
|
eno = pthread_join( th, NULL );
|
||||||
rtems_test_assert( eno == 0 );
|
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)
|
static void test_sem_post_overflow(void)
|
||||||
@@ -112,12 +168,162 @@ static void test_sem_post_overflow(void)
|
|||||||
static void test_sem_init_too_large_inital_value(void)
|
static void test_sem_init_too_large_inital_value(void)
|
||||||
{
|
{
|
||||||
sem_t sem;
|
sem_t sem;
|
||||||
|
sem_t *sem2;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
rv = sem_init( &sem, 0, (unsigned int) SEM_VALUE_MAX + 1 );
|
rv = sem_init( &sem, 0, (unsigned int) SEM_VALUE_MAX + 1 );
|
||||||
rtems_test_assert( rv == -1 );
|
rtems_test_assert( rv == -1 );
|
||||||
rtems_test_assert( errno == EINVAL );
|
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(
|
void *POSIX_Init(
|
||||||
@@ -155,10 +361,14 @@ void *POSIX_Init(
|
|||||||
sprintf(failure_msg, "sem_init %d", i );
|
sprintf(failure_msg, "sem_init %d", i );
|
||||||
fatal_posix_service_status( status, 0, failure_msg);
|
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);
|
status = sem_init(&sem2, 0, 1);
|
||||||
fatal_posix_service_status( status, -1, "sem_init error return status");
|
fatal_posix_service_status( status, 0, "sem_init");
|
||||||
fatal_posix_service_status( errno, ENOSPC, "sem_init errorno ENOSPC" );
|
|
||||||
|
puts( "Init: sem_destroy - SUCCESSFUL" );
|
||||||
|
status = sem_destroy(&sem2);
|
||||||
|
fatal_posix_service_status( status, 0, "sem_destroy");
|
||||||
|
|
||||||
puts( "Init: sem_getvalue - SUCCESSFUL ");
|
puts( "Init: sem_getvalue - SUCCESSFUL ");
|
||||||
for (i = 0; i < MAX_SEMS; i++) {
|
for (i = 0; i < MAX_SEMS; i++) {
|
||||||
@@ -168,8 +378,7 @@ void *POSIX_Init(
|
|||||||
fatal_posix_service_status( value, i, "sem_getvalue correct value" );
|
fatal_posix_service_status( value, i, "sem_getvalue correct value" );
|
||||||
}
|
}
|
||||||
puts( "Init: sem_getvalue - UNSUCCESSFUL ");
|
puts( "Init: sem_getvalue - UNSUCCESSFUL ");
|
||||||
sem2 = 0;
|
status = sem_getvalue(SEM_FAILED, &value);
|
||||||
status = sem_getvalue(&sem2, &value);
|
|
||||||
fatal_posix_service_status( status, -1, "sem_getvalue error return status");
|
fatal_posix_service_status( status, -1, "sem_getvalue error return status");
|
||||||
fatal_posix_service_status( errno, EINVAL, "sem_getvalue errno EINVAL");
|
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");
|
fatal_posix_service_status( status, 0, "sem_destroy semaphore 0");
|
||||||
|
|
||||||
puts( "Init: sem_destroy - UNSUCCESSFUL (EINVAL)" );
|
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( status, -1, "sem_destroy error return status");
|
||||||
fatal_posix_service_status( errno, EINVAL, "sem_destroy errno EINVAL");
|
fatal_posix_service_status( errno, EINVAL, "sem_destroy errno EINVAL");
|
||||||
|
|
||||||
@@ -188,7 +397,7 @@ void *POSIX_Init(
|
|||||||
/* sem[1].count = 0 */
|
/* sem[1].count = 0 */
|
||||||
|
|
||||||
puts( "Init: sem_wait - UNSUCCESSFUL (EINVAL)" );
|
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( status, -1, "sem_wait error return status");
|
||||||
fatal_posix_service_status( errno, EINVAL, "sem_wait errno EINVAL");
|
fatal_posix_service_status( errno, EINVAL, "sem_wait errno EINVAL");
|
||||||
|
|
||||||
@@ -214,7 +423,7 @@ void *POSIX_Init(
|
|||||||
/* sem[1].count = 0 */
|
/* sem[1].count = 0 */
|
||||||
|
|
||||||
puts( "Init: sem_trywait - UNSUCCESSFUL (EINVAL)" );
|
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( status, -1, "sem_trywait error return status");
|
||||||
fatal_posix_service_status( errno, EINVAL, "sem_trywait errno EINVAL");
|
fatal_posix_service_status( errno, EINVAL, "sem_trywait errno EINVAL");
|
||||||
|
|
||||||
@@ -256,7 +465,7 @@ void *POSIX_Init(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
puts( "Init: sem_post - UNSUCCESSFUL (EINVAL)" );
|
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( status, -1, "sem_post error return status");
|
||||||
fatal_posix_service_status( errno, EINVAL, "sem_post errno EINVAL");
|
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");
|
fatal_posix_service_status( errno, ENOENT, "sem_unlink errno ENOENT");
|
||||||
rtems_test_assert( (status == -1) && (errno == ENOENT) );
|
rtems_test_assert( (status == -1) && (errno == ENOENT) );
|
||||||
|
|
||||||
|
test_named_sem_wait_during_delete();
|
||||||
test_sem_wait_during_delete();
|
test_sem_wait_during_delete();
|
||||||
test_sem_post_overflow();
|
test_sem_post_overflow();
|
||||||
test_sem_init_too_large_inital_value();
|
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?) */
|
/* 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_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
|
||||||
|
|
||||||
#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
|
#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_TABLE
|
||||||
#define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE \
|
#define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE \
|
||||||
|
|||||||
@@ -159,7 +159,6 @@ void *POSIX_Init(void *argument)
|
|||||||
#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
|
#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
|
||||||
|
|
||||||
#define CONFIGURE_MAXIMUM_POSIX_THREADS 1
|
#define CONFIGURE_MAXIMUM_POSIX_THREADS 1
|
||||||
#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 2
|
|
||||||
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
|
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
|
||||||
|
|
||||||
#define CONFIGURE_INIT
|
#define CONFIGURE_INIT
|
||||||
|
|||||||
@@ -124,7 +124,6 @@ void *POSIX_Init(
|
|||||||
#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
|
#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
|
||||||
|
|
||||||
#define CONFIGURE_MAXIMUM_POSIX_THREADS OPERATION_COUNT + 2
|
#define CONFIGURE_MAXIMUM_POSIX_THREADS OPERATION_COUNT + 2
|
||||||
#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES MAX_SEMS
|
|
||||||
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
|
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
|
||||||
|
|
||||||
#define CONFIGURE_INIT
|
#define CONFIGURE_INIT
|
||||||
|
|||||||
@@ -99,7 +99,6 @@ void *POSIX_Init(void *argument)
|
|||||||
#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
|
#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
|
||||||
|
|
||||||
#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
|
#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
|
||||||
#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES MAX_SEMS
|
|
||||||
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
|
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
|
||||||
|
|
||||||
#define CONFIGURE_INIT
|
#define CONFIGURE_INIT
|
||||||
|
|||||||
@@ -159,7 +159,6 @@ void *POSIX_Init(
|
|||||||
#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
|
#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
|
||||||
|
|
||||||
#define CONFIGURE_MAXIMUM_POSIX_THREADS OPERATION_COUNT + 2
|
#define CONFIGURE_MAXIMUM_POSIX_THREADS OPERATION_COUNT + 2
|
||||||
#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES MAX_SEMS
|
|
||||||
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
|
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
|
||||||
|
|
||||||
#define CONFIGURE_INIT
|
#define CONFIGURE_INIT
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ typedef struct {
|
|||||||
rtems_id mq;
|
rtems_id mq;
|
||||||
rtems_id br;
|
rtems_id br;
|
||||||
#if defined(RTEMS_POSIX_API)
|
#if defined(RTEMS_POSIX_API)
|
||||||
sem_t psem;
|
|
||||||
pthread_mutex_t pmtx;
|
pthread_mutex_t pmtx;
|
||||||
pthread_cond_t pcv;
|
pthread_cond_t pcv;
|
||||||
pthread_rwlock_t prw;
|
pthread_rwlock_t prw;
|
||||||
@@ -120,12 +119,6 @@ static void posix_worker(test_context *ctx)
|
|||||||
int eno;
|
int eno;
|
||||||
char buf[1];
|
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);
|
eno = pthread_mutex_lock(&ctx->pmtx);
|
||||||
rtems_test_assert(eno == 0);
|
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)
|
static void test_posix_init(test_context *ctx)
|
||||||
{
|
{
|
||||||
#if defined(RTEMS_POSIX_API)
|
#if defined(RTEMS_POSIX_API)
|
||||||
int rv;
|
|
||||||
int eno;
|
int eno;
|
||||||
struct mq_attr attr;
|
struct mq_attr attr;
|
||||||
|
|
||||||
rv = sem_init(&ctx->psem, 0, 0);
|
|
||||||
rtems_test_assert(rv == 0);
|
|
||||||
|
|
||||||
eno = pthread_mutex_init(&ctx->pmtx, NULL);
|
eno = pthread_mutex_init(&ctx->pmtx, NULL);
|
||||||
rtems_test_assert(eno == 0);
|
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)
|
static void test_posix_obj(test_context *ctx)
|
||||||
{
|
{
|
||||||
#if defined(RTEMS_POSIX_API)
|
#if defined(RTEMS_POSIX_API)
|
||||||
int rv;
|
|
||||||
int eno;
|
int eno;
|
||||||
char buf[1];
|
char buf[1];
|
||||||
unsigned prio;
|
unsigned prio;
|
||||||
@@ -314,11 +302,6 @@ static void test_posix_obj(test_context *ctx)
|
|||||||
|
|
||||||
wait_for_worker(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);
|
eno = pthread_mutex_lock(&ctx->pmtx);
|
||||||
rtems_test_assert(eno == 0);
|
rtems_test_assert(eno == 0);
|
||||||
|
|
||||||
@@ -377,7 +360,6 @@ static rtems_task Init(
|
|||||||
#define CONFIGURE_MAXIMUM_BARRIERS 1
|
#define CONFIGURE_MAXIMUM_BARRIERS 1
|
||||||
|
|
||||||
#if defined(RTEMS_POSIX_API)
|
#if defined(RTEMS_POSIX_API)
|
||||||
#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 1
|
|
||||||
#define CONFIGURE_MAXIMUM_POSIX_MUTEXES 1
|
#define CONFIGURE_MAXIMUM_POSIX_MUTEXES 1
|
||||||
#define CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES 1
|
#define CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES 1
|
||||||
#define CONFIGURE_MAXIMUM_POSIX_RWLOCKS 1
|
#define CONFIGURE_MAXIMUM_POSIX_RWLOCKS 1
|
||||||
|
|||||||
Reference in New Issue
Block a user