Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:12

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * This include file contains the static inline implementation of the private 
0007  * inlined routines for POSIX condition variables.
0008  */
0009 
0010 /*
0011  *  COPYRIGHT (c) 1989-2013.
0012  *  On-Line Applications Research Corporation (OAR).
0013  *
0014  * Redistribution and use in source and binary forms, with or without
0015  * modification, are permitted provided that the following conditions
0016  * are met:
0017  * 1. Redistributions of source code must retain the above copyright
0018  *    notice, this list of conditions and the following disclaimer.
0019  * 2. Redistributions in binary form must reproduce the above copyright
0020  *    notice, this list of conditions and the following disclaimer in the
0021  *    documentation and/or other materials provided with the distribution.
0022  *
0023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0033  * POSSIBILITY OF SUCH DAMAGE.
0034  */
0035 
0036 #ifndef _RTEMS_POSIX_CONDIMPL_H
0037 #define _RTEMS_POSIX_CONDIMPL_H
0038 
0039 #include <errno.h>
0040 #include <pthread.h>
0041 
0042 #include <rtems/score/percpu.h>
0043 #include <rtems/score/threadqimpl.h>
0044 
0045 #ifdef __cplusplus
0046 extern "C" {
0047 #endif
0048 
0049 typedef struct {
0050   unsigned long flags;
0051   Thread_queue_Syslock_queue Queue;
0052   pthread_mutex_t *mutex;
0053 } POSIX_Condition_variables_Control;
0054 
0055 #define POSIX_CONDITION_VARIABLES_CLOCK_MONOTONIC 0x1UL
0056 
0057 #define POSIX_CONDITION_VARIABLES_FLAGS_MASK 0x1UL
0058 
0059 #define POSIX_CONDITION_VARIABLES_MAGIC 0x18dfb1feUL
0060 
0061 /**
0062  *  Constant to indicate condition variable does not currently have
0063  *  a mutex assigned to it.
0064  */
0065 #define POSIX_CONDITION_VARIABLES_NO_MUTEX NULL
0066 
0067 #define POSIX_CONDITION_VARIABLES_TQ_OPERATIONS &_Thread_queue_Operations_FIFO
0068 
0069 #define POSIX_CONDITION_VARIABLE_OF_THREAD_QUEUE_QUEUE( queue ) \
0070   RTEMS_CONTAINER_OF( \
0071     queue, POSIX_Condition_variables_Control, Queue.Queue )
0072 
0073 /**
0074  *  The default condition variable attributes structure.
0075  */
0076 extern const pthread_condattr_t _POSIX_Condition_variables_Default_attributes;
0077 
0078 static inline POSIX_Condition_variables_Control *_POSIX_Condition_variables_Get(
0079   pthread_cond_t *cond
0080 )
0081 {
0082   return (POSIX_Condition_variables_Control *) cond;
0083 }
0084 
0085 static inline void _POSIX_Condition_variables_Initialize(
0086   POSIX_Condition_variables_Control *the_cond,
0087   const pthread_condattr_t          *the_attr
0088 )
0089 {
0090   unsigned long flags;
0091 
0092   _Thread_queue_Queue_initialize( &the_cond->Queue.Queue, NULL );
0093   the_cond->mutex = POSIX_CONDITION_VARIABLES_NO_MUTEX;
0094 
0095   flags = (uintptr_t) the_cond ^ POSIX_CONDITION_VARIABLES_MAGIC;
0096   flags &= ~POSIX_CONDITION_VARIABLES_FLAGS_MASK;
0097 
0098   if ( the_attr->clock == CLOCK_MONOTONIC ) {
0099     flags |= POSIX_CONDITION_VARIABLES_CLOCK_MONOTONIC;
0100   }
0101 
0102   the_cond->flags = flags;
0103 }
0104 
0105 static inline void _POSIX_Condition_variables_Destroy(
0106   POSIX_Condition_variables_Control *the_cond
0107 )
0108 {
0109   the_cond->flags = ~the_cond->flags;
0110 }
0111 
0112 static inline clockid_t _POSIX_Condition_variables_Get_clock(
0113   unsigned long flags
0114 )
0115 {
0116   if ( ( flags & POSIX_CONDITION_VARIABLES_CLOCK_MONOTONIC ) != 0 ) {
0117     return CLOCK_MONOTONIC;
0118   }
0119 
0120   return CLOCK_REALTIME;
0121 }
0122 
0123 static inline Thread_Control *_POSIX_Condition_variables_Acquire(
0124   POSIX_Condition_variables_Control *the_cond,
0125   Thread_queue_Context              *queue_context
0126 )
0127 {
0128   ISR_Level       level;
0129   Thread_Control *executing;
0130 
0131   _Thread_queue_Context_ISR_disable( queue_context, level );
0132   _Thread_queue_Context_set_ISR_level( queue_context, level );
0133   executing = _Thread_Executing;
0134   _Thread_queue_Queue_acquire_critical(
0135     &the_cond->Queue.Queue,
0136     &executing->Potpourri_stats,
0137     &queue_context->Lock_context.Lock_context
0138   );
0139 
0140   return executing;
0141 }
0142 
0143 static inline void _POSIX_Condition_variables_Release(
0144   POSIX_Condition_variables_Control *the_cond,
0145   Thread_queue_Context              *queue_context
0146 )
0147 {
0148   _Thread_queue_Queue_release(
0149     &the_cond->Queue.Queue,
0150     &queue_context->Lock_context.Lock_context
0151   );
0152 }
0153 
0154 /**
0155  * @brief Implements wake up version of the "signal" operation.
0156  * 
0157  * A support routine which implements guts of the broadcast and single task
0158  * wake up version of the "signal" operation.
0159  */
0160 int _POSIX_Condition_variables_Signal_support(
0161   pthread_cond_t            *cond,
0162   bool                       is_broadcast
0163 );
0164 
0165 /**
0166  * @brief POSIX condition variables wait support.
0167  *
0168  * A support routine which implements guts of the blocking, non-blocking, and
0169  * timed wait version of condition variable wait routines.
0170  */
0171 int _POSIX_Condition_variables_Wait_support(
0172   pthread_cond_t            *cond,
0173   pthread_mutex_t           *mutex,
0174   const struct timespec     *abstime
0175 );
0176 
0177 bool _POSIX_Condition_variables_Auto_initialization(
0178   POSIX_Condition_variables_Control *the_cond
0179 );
0180 
0181 #define POSIX_CONDITION_VARIABLES_VALIDATE_OBJECT( the_cond, flags ) \
0182   do { \
0183     if ( ( the_cond ) == NULL ) { \
0184       return EINVAL; \
0185     } \
0186     flags = ( the_cond )->flags; \
0187     if ( \
0188       ( ( (uintptr_t) ( the_cond ) ^ POSIX_CONDITION_VARIABLES_MAGIC ) \
0189           & ~POSIX_CONDITION_VARIABLES_FLAGS_MASK ) \
0190         != ( flags & ~POSIX_CONDITION_VARIABLES_FLAGS_MASK ) \
0191     ) { \
0192       if ( !_POSIX_Condition_variables_Auto_initialization( the_cond ) ) { \
0193         return EINVAL; \
0194       } \
0195     } \
0196   } while ( 0 )
0197 
0198 #ifdef __cplusplus
0199 }
0200 #endif
0201 
0202 #endif
0203 /*  end of include file */