summaryrefslogtreecommitdiffstats
path: root/cpukit/posix/src
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2017-09-26 07:49:17 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-10-05 14:29:02 +0200
commit5222488573e3ba8c2eceffe29f878a73a3a81694 (patch)
tree4b4ca72268b8f40da493ca252780c197bd23a5ef /cpukit/posix/src
parentposix: Implement self-contained POSIX rwlocks (diff)
downloadrtems-5222488573e3ba8c2eceffe29f878a73a3a81694.tar.bz2
posix: Implement self-contained POSIX condvar
POSIX condition variables are now available in all configurations and no longer depend on --enable-posix. Update #2514. Update #3113.
Diffstat (limited to 'cpukit/posix/src')
-rw-r--r--cpukit/posix/src/cond.c65
-rw-r--r--cpukit/posix/src/conddestroy.c26
-rw-r--r--cpukit/posix/src/condget.c30
-rw-r--r--cpukit/posix/src/condinit.c62
-rw-r--r--cpukit/posix/src/condsignalsupp.c35
-rw-r--r--cpukit/posix/src/condwait.c21
-rw-r--r--cpukit/posix/src/condwaitsupp.c27
7 files changed, 92 insertions, 174 deletions
diff --git a/cpukit/posix/src/cond.c b/cpukit/posix/src/cond.c
deleted file mode 100644
index 8ee57d89fd..0000000000
--- a/cpukit/posix/src/cond.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * @file
- *
- * @brief Initialization Necessary for this Manager
- * @ingroup POSIX_COND_VARS Condition Variables
- */
-
-/*
- * COPYRIGHT (c) 1989-2008.
- * On-Line Applications Research Corporation (OAR).
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <pthread.h>
-#include <errno.h>
-#include <limits.h>
-
-#include <rtems/system.h>
-#include <rtems/config.h>
-#include <rtems/sysinit.h>
-#include <rtems/score/watchdog.h>
-#include <rtems/posix/condimpl.h>
-#include <rtems/posix/muteximpl.h>
-
-Objects_Information _POSIX_Condition_variables_Information;
-
-/*
- * _POSIX_Condition_variables_Manager_initialization
- *
- * This routine initializes all condition variable manager related data
- * structures.
- *
- * Input parameters: NONE
- *
- * Output parameters: NONE
- */
-
-static void _POSIX_Condition_variables_Manager_initialization(void)
-{
- _Objects_Initialize_information(
- &_POSIX_Condition_variables_Information, /* object information table */
- OBJECTS_POSIX_API, /* object API */
- OBJECTS_POSIX_CONDITION_VARIABLES, /* object class */
- Configuration_POSIX_API.maximum_condition_variables,
- /* maximum objects of this class */
- sizeof( POSIX_Condition_variables_Control ),
- /* size of this object's control block */
- true, /* true if names for this object are strings */
- _POSIX_PATH_MAX, /* maximum length of each object's name */
- NULL /* Proxy extraction support callout */
- );
-}
-
-RTEMS_SYSINIT_ITEM(
- _POSIX_Condition_variables_Manager_initialization,
- RTEMS_SYSINIT_POSIX_CONDITION_VARIABLE,
- RTEMS_SYSINIT_ORDER_MIDDLE
-);
diff --git a/cpukit/posix/src/conddestroy.c b/cpukit/posix/src/conddestroy.c
index a2c8dc188f..63214362dc 100644
--- a/cpukit/posix/src/conddestroy.c
+++ b/cpukit/posix/src/conddestroy.c
@@ -24,36 +24,24 @@
* 11.4.2 Initializing and Destroying a Condition Variable,
* P1003.1c/Draft 10, p. 87
*/
-int pthread_cond_destroy(
- pthread_cond_t *cond
-)
+int pthread_cond_destroy( pthread_cond_t *cond )
{
POSIX_Condition_variables_Control *the_cond;
+ unsigned long flags;
Thread_queue_Context queue_context;
- _Objects_Allocator_lock();
- the_cond = _POSIX_Condition_variables_Get( cond, &queue_context );
+ the_cond = _POSIX_Condition_variables_Get( cond );
+ POSIX_CONDITION_VARIABLES_VALIDATE_OBJECT( the_cond, flags );
- if ( the_cond == NULL ) {
- _Objects_Allocator_unlock();
- return EINVAL;
- }
-
- _POSIX_Condition_variables_Acquire_critical( the_cond, &queue_context );
+ _Thread_queue_Context_initialize( &queue_context );
+ _POSIX_Condition_variables_Acquire( the_cond, &queue_context );
- if ( !_Thread_queue_Is_empty( &the_cond->Wait_queue.Queue ) ) {
+ if ( !_Thread_queue_Is_empty( &the_cond->Queue.Queue ) ) {
_POSIX_Condition_variables_Release( the_cond, &queue_context );
- _Objects_Allocator_unlock();
return EBUSY;
}
- _Objects_Close(
- &_POSIX_Condition_variables_Information,
- &the_cond->Object
- );
_POSIX_Condition_variables_Release( the_cond, &queue_context );
_POSIX_Condition_variables_Destroy( the_cond );
- _POSIX_Condition_variables_Free( the_cond );
- _Objects_Allocator_unlock();
return 0;
}
diff --git a/cpukit/posix/src/condget.c b/cpukit/posix/src/condget.c
deleted file mode 100644
index 5b086ef7c9..0000000000
--- a/cpukit/posix/src/condget.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * COPYRIGHT (c) 1989-2007.
- * 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 <rtems/posix/condimpl.h>
-#include <rtems/posix/posixapi.h>
-
-POSIX_Condition_variables_Control *_POSIX_Condition_variables_Get(
- pthread_cond_t *cond,
- Thread_queue_Context *queue_context
-)
-{
- _POSIX_Get_object_body(
- POSIX_Condition_variables_Control,
- cond,
- queue_context,
- &_POSIX_Condition_variables_Information,
- PTHREAD_COND_INITIALIZER,
- pthread_cond_init
- );
-}
diff --git a/cpukit/posix/src/condinit.c b/cpukit/posix/src/condinit.c
index 8d3aa8e244..aab26aa9f7 100644
--- a/cpukit/posix/src/condinit.c
+++ b/cpukit/posix/src/condinit.c
@@ -21,6 +21,29 @@
#include <rtems/posix/condimpl.h>
#include <rtems/posix/posixapi.h>
+RTEMS_STATIC_ASSERT(
+ offsetof( POSIX_Condition_variables_Control, flags )
+ == offsetof( pthread_cond_t, _flags ),
+ POSIX_CONDITION_VARIABLES_CONTROL_FLAGS
+);
+
+RTEMS_STATIC_ASSERT(
+ offsetof( POSIX_Condition_variables_Control, mutex )
+ == offsetof( pthread_cond_t, _mutex ),
+ POSIX_CONDITION_VARIABLES_CONTROL_COUNT
+);
+
+RTEMS_STATIC_ASSERT(
+ offsetof( POSIX_Condition_variables_Control, Queue )
+ == offsetof( pthread_cond_t, _Queue ),
+ POSIX_CONDITION_VARIABLES_CONTROL_QUEUE
+);
+
+RTEMS_STATIC_ASSERT(
+ sizeof( POSIX_Condition_variables_Control ) == sizeof( pthread_cond_t ),
+ POSIX_CONDITION_VARIABLES_CONTROL_SIZE
+);
+
/**
* 11.4.2 Initializing and Destroying a Condition Variable,
* P1003.1c/Draft 10, p. 87
@@ -30,41 +53,26 @@ int pthread_cond_init(
const pthread_condattr_t *attr
)
{
- POSIX_Condition_variables_Control *the_cond;
- const pthread_condattr_t *the_attr;
+ POSIX_Condition_variables_Control *the_cond;
- if ( attr ) the_attr = attr;
- else the_attr = &_POSIX_Condition_variables_Default_attributes;
-
- /*
- * Be careful about attributes when global!!!
- */
-
- if ( !the_attr->is_initialized )
- return EINVAL;
+ the_cond = _POSIX_Condition_variables_Get( cond );
- if ( !_POSIX_Is_valid_pshared( the_attr->process_shared ) ) {
+ if ( the_cond == NULL ) {
return EINVAL;
}
- the_cond = _POSIX_Condition_variables_Allocate();
-
- if ( !the_cond ) {
- _Objects_Allocator_unlock();
- return ENOMEM;
+ if ( attr == NULL ) {
+ attr = &_POSIX_Condition_variables_Default_attributes;
}
- _POSIX_Condition_variables_Initialize( the_cond, the_attr );
-
- _Objects_Open_u32(
- &_POSIX_Condition_variables_Information,
- &the_cond->Object,
- 0
- );
-
- *cond = the_cond->Object.id;
+ if ( !attr->is_initialized ) {
+ return EINVAL;
+ }
- _Objects_Allocator_unlock();
+ if ( !_POSIX_Is_valid_pshared( attr->process_shared ) ) {
+ return EINVAL;
+ }
+ _POSIX_Condition_variables_Initialize( the_cond, attr );
return 0;
}
diff --git a/cpukit/posix/src/condsignalsupp.c b/cpukit/posix/src/condsignalsupp.c
index e42476e1c4..1d9d4fc1ad 100644
--- a/cpukit/posix/src/condsignalsupp.c
+++ b/cpukit/posix/src/condsignalsupp.c
@@ -32,29 +32,30 @@ int _POSIX_Condition_variables_Signal_support(
bool is_broadcast
)
{
- Thread_Control *the_thread;
+ POSIX_Condition_variables_Control *the_cond;
+ unsigned long flags;
+ const Thread_queue_Operations *operations;
+ Thread_queue_Heads *heads;
- do {
- POSIX_Condition_variables_Control *the_cond;
- Thread_queue_Context queue_context;
+ the_cond = _POSIX_Condition_variables_Get( cond );
+ POSIX_CONDITION_VARIABLES_VALIDATE_OBJECT( the_cond, flags );
+ operations = POSIX_CONDITION_VARIABLES_TQ_OPERATIONS;
- the_cond = _POSIX_Condition_variables_Get( cond, &queue_context );
+ do {
+ Thread_queue_Context queue_context;
- if ( the_cond == NULL ) {
- return EINVAL;
- }
+ _Thread_queue_Context_initialize( &queue_context );
+ _POSIX_Condition_variables_Acquire( the_cond, &queue_context );
- _POSIX_Condition_variables_Acquire_critical( the_cond, &queue_context );
+ heads = the_cond->Queue.Queue.heads;
- the_thread = _Thread_queue_First_locked(
- &the_cond->Wait_queue,
- POSIX_CONDITION_VARIABLES_TQ_OPERATIONS
- );
+ if ( heads != NULL ) {
+ Thread_Control *the_thread;
- if ( the_thread != NULL ) {
+ the_thread = ( *operations->first )( heads );
_Thread_queue_Extract_critical(
- &the_cond->Wait_queue.Queue,
- POSIX_CONDITION_VARIABLES_TQ_OPERATIONS,
+ &the_cond->Queue.Queue,
+ operations,
the_thread,
&queue_context
);
@@ -62,7 +63,7 @@ int _POSIX_Condition_variables_Signal_support(
the_cond->mutex = POSIX_CONDITION_VARIABLES_NO_MUTEX;
_POSIX_Condition_variables_Release( the_cond, &queue_context );
}
- } while ( is_broadcast && the_thread != NULL );
+ } while ( is_broadcast && heads != NULL );
return 0;
}
diff --git a/cpukit/posix/src/condwait.c b/cpukit/posix/src/condwait.c
index 9a88287d0d..9527077757 100644
--- a/cpukit/posix/src/condwait.c
+++ b/cpukit/posix/src/condwait.c
@@ -20,6 +20,27 @@
#include <rtems/posix/condimpl.h>
+#include <string.h>
+
+bool _POSIX_Condition_variables_Auto_initialization(
+ POSIX_Condition_variables_Control *the_cond
+)
+{
+ POSIX_Condition_variables_Control zero;
+ unsigned long flags;
+
+ memset( &zero, 0, sizeof( zero ) );
+
+ if ( memcmp( the_cond, &zero, sizeof( *the_cond ) ) != 0 ) {
+ return false;
+ }
+
+ flags = (uintptr_t) the_cond ^ POSIX_CONDITION_VARIABLES_MAGIC;
+ flags &= ~POSIX_CONDITION_VARIABLES_FLAGS_MASK;
+ the_cond->flags = flags;
+ return true;
+}
+
/*
* 11.4.4 Waiting on a Condition, P1003.1c/Draft 10, p. 105
*/
diff --git a/cpukit/posix/src/condwaitsupp.c b/cpukit/posix/src/condwaitsupp.c
index 486bab879c..ceaa6eb1af 100644
--- a/cpukit/posix/src/condwaitsupp.c
+++ b/cpukit/posix/src/condwaitsupp.c
@@ -25,8 +25,6 @@
#include <rtems/score/status.h>
#include <rtems/score/threaddispatch.h>
-THREAD_QUEUE_OBJECT_ASSERT( POSIX_Condition_variables_Control, Wait_queue );
-
static void _POSIX_Condition_variables_Enqueue_callout(
Thread_queue_Queue *queue,
Thread_Control *the_thread,
@@ -58,6 +56,7 @@ int _POSIX_Condition_variables_Wait_support(
)
{
POSIX_Condition_variables_Control *the_cond;
+ unsigned long flags;
Thread_queue_Context queue_context;
int error;
int mutex_error;
@@ -66,16 +65,10 @@ int _POSIX_Condition_variables_Wait_support(
bool already_timedout;
TOD_Absolute_timeout_conversion_results status;
- if ( mutex == NULL ) {
- return EINVAL;
- }
-
- the_cond = _POSIX_Condition_variables_Get( cond, &queue_context );
-
- if ( the_cond == NULL ) {
- return EINVAL;
- }
+ the_cond = _POSIX_Condition_variables_Get( cond );
+ POSIX_CONDITION_VARIABLES_VALIDATE_OBJECT( the_cond, flags );
+ _Thread_queue_Context_initialize( &queue_context );
already_timedout = false;
if ( abstime != NULL ) {
@@ -88,8 +81,11 @@ int _POSIX_Condition_variables_Wait_support(
* then we do a polling operation and convert the UNSATISFIED
* status into the appropriate error.
*/
- _Assert( the_cond->clock );
- status = _TOD_Absolute_timeout_to_ticks(abstime, the_cond->clock, &timeout);
+ status = _TOD_Absolute_timeout_to_ticks(
+ abstime,
+ _POSIX_Condition_variables_Get_clock( flags ),
+ &timeout
+ );
if ( status == TOD_ABSOLUTE_TIMEOUT_INVALID )
return EINVAL;
@@ -103,7 +99,7 @@ int _POSIX_Condition_variables_Wait_support(
_Thread_queue_Context_set_no_timeout( &queue_context );
}
- _POSIX_Condition_variables_Acquire_critical( the_cond, &queue_context );
+ executing = _POSIX_Condition_variables_Acquire( the_cond, &queue_context );
if (
the_cond->mutex != POSIX_CONDITION_VARIABLES_NO_MUTEX
@@ -114,7 +110,6 @@ int _POSIX_Condition_variables_Wait_support(
}
the_cond->mutex = mutex;
- executing = _Thread_Executing;
if ( !already_timedout ) {
_Thread_queue_Context_set_thread_state(
@@ -126,7 +121,7 @@ int _POSIX_Condition_variables_Wait_support(
_POSIX_Condition_variables_Enqueue_callout
);
_Thread_queue_Enqueue(
- &the_cond->Wait_queue.Queue,
+ &the_cond->Queue.Queue,
POSIX_CONDITION_VARIABLES_TQ_OPERATIONS,
executing,
&queue_context