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  * @ingroup RTEMSScoreRWLock
0007  *
0008  * @brief This header file provides interfaces of the
0009  *   @ref RTEMSScoreRWLock which are only used by the implementation.
0010  */
0011 
0012 /*
0013  *  COPYRIGHT (c) 1989-2008.
0014  *  On-Line Applications Research Corporation (OAR).
0015  *
0016  * Redistribution and use in source and binary forms, with or without
0017  * modification, are permitted provided that the following conditions
0018  * are met:
0019  * 1. Redistributions of source code must retain the above copyright
0020  *    notice, this list of conditions and the following disclaimer.
0021  * 2. Redistributions in binary form must reproduce the above copyright
0022  *    notice, this list of conditions and the following disclaimer in the
0023  *    documentation and/or other materials provided with the distribution.
0024  *
0025  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0026  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0028  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0029  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0030  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0031  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0032  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0033  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0034  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0035  * POSSIBILITY OF SUCH DAMAGE.
0036  */
0037 
0038 #ifndef _RTEMS_SCORE_CORERWLOCKIMPL_H
0039 #define _RTEMS_SCORE_CORERWLOCKIMPL_H
0040 
0041 #include <rtems/score/percpu.h>
0042 #include <rtems/score/status.h>
0043 #include <rtems/score/thread.h>
0044 #include <rtems/score/threadqimpl.h>
0045 #include <rtems/score/watchdog.h>
0046 
0047 /**
0048  * @defgroup RTEMSScoreRWLock Read-Write Lock
0049  *
0050  * @ingroup RTEMSScore
0051  *
0052  * @brief This group contains the Read-Write Lock implementation.
0053  *
0054  * @{
0055  */
0056 
0057 #ifdef __cplusplus
0058 extern "C" {
0059 #endif
0060 
0061 #define CORE_RWLOCK_TQ_OPERATIONS &_Thread_queue_Operations_FIFO
0062 
0063 /**
0064  *  This is used to denote that a thread is blocking waiting for
0065  *  read-only access to the RWLock.
0066  */
0067 #define CORE_RWLOCK_THREAD_WAITING_FOR_READ  0
0068 
0069 /**
0070  *  This is used to denote that a thread is blocking waiting for
0071  *  write-exclusive access to the RWLock.
0072  */
0073 #define CORE_RWLOCK_THREAD_WAITING_FOR_WRITE 1
0074 
0075 /**
0076  *  RWLock State.
0077  */
0078 typedef enum {
0079   /** This indicates the the RWLock is not currently locked.
0080    */
0081   CORE_RWLOCK_UNLOCKED,
0082   /** This indicates the the RWLock is currently locked for reading.
0083    */
0084   CORE_RWLOCK_LOCKED_FOR_READING,
0085   /** This indicates the the RWLock is currently locked for reading.
0086    */
0087   CORE_RWLOCK_LOCKED_FOR_WRITING
0088 }   CORE_RWLock_States;
0089 
0090 /**
0091  *  The following defines the control block used to manage each
0092  *  RWLock.
0093  */
0094 typedef struct {
0095   /** This field is the Waiting Queue used to manage the set of tasks
0096    *  which are blocked waiting for the RWLock to be released.
0097    */
0098   Thread_queue_Syslock_queue Queue;
0099 
0100   /** This element is the current state of the RWLock.
0101    */
0102   CORE_RWLock_States current_state;
0103 
0104   /** This element contains the current number of thread waiting for this
0105    *  RWLock to be released. */
0106   unsigned int number_of_readers;
0107 }   CORE_RWLock_Control;
0108 
0109 /**
0110  * @brief Initializes a RWlock.
0111  *
0112  * This routine initializes the RWLock.
0113  *
0114  * @param[out] the_rwlock is the RWLock to initialize.
0115  */
0116 void _CORE_RWLock_Initialize(
0117   CORE_RWLock_Control *the_rwlock
0118 );
0119 
0120 /**
0121  * @brief Destroys a RWlock.
0122  *
0123  * This routine destroys the RWLock.
0124  *
0125  * @param[out] the_rwlock is the RWLock to destroy.
0126  */
0127 static inline void _CORE_RWLock_Destroy(
0128   CORE_RWLock_Control *the_rwlock
0129 )
0130 {
0131   (void) the_rwlock;
0132 }
0133 
0134 /**
0135  * @brief Acquires the RWlock.
0136  *
0137  * @param[in, out] the_rwlock The RWlock to acquire.
0138  * @param queue_context The thread queue context.
0139  *
0140  * @return The executing thread.
0141  */
0142 static inline Thread_Control *_CORE_RWLock_Acquire(
0143   CORE_RWLock_Control  *the_rwlock,
0144   Thread_queue_Context *queue_context
0145 )
0146 {
0147   ISR_Level       level;
0148   Thread_Control *executing;
0149 
0150   _Thread_queue_Context_ISR_disable( queue_context, level );
0151   _Thread_queue_Context_set_ISR_level( queue_context, level );
0152   executing = _Thread_Executing;
0153   _Thread_queue_Queue_acquire_critical(
0154     &the_rwlock->Queue.Queue,
0155     &executing->Potpourri_stats,
0156     &queue_context->Lock_context.Lock_context
0157   );
0158 
0159   return executing;
0160 }
0161 
0162 /**
0163  * @brief Releases the RWlock.
0164  *
0165  * @param[in, out] the_rwlock The RWlock to release.
0166  * @param queue_context The thread queue context.
0167  */
0168 static inline void _CORE_RWLock_Release(
0169   CORE_RWLock_Control  *the_rwlock,
0170   Thread_queue_Context *queue_context
0171 )
0172 {
0173   _Thread_queue_Queue_release(
0174     &the_rwlock->Queue.Queue,
0175     &queue_context->Lock_context.Lock_context
0176   );
0177 }
0178 
0179 /**
0180  * @brief Obtains RWLock for reading.
0181  *
0182  * This routine attempts to obtain the RWLock for read access.
0183  *
0184  * @param[in, out] the_rwlock is the RWLock to wait for
0185  * @param wait Indicates whether the calling thread is willing to wait.
0186  * @param queue_context The thread queue context.
0187  *
0188  * @retval STATUS_SUCCESSFUL The RWlock was successfully seized.
0189  * @retval STATUS_UNAVAILABLE The RWlock is currently locked for writing
0190  *          and the calling thread is not willing to wait.
0191  * @retval STATUS_TIMEOUT A timeout occurred.
0192  */
0193 
0194 Status_Control _CORE_RWLock_Seize_for_reading(
0195   CORE_RWLock_Control  *the_rwlock,
0196   bool                  wait,
0197   Thread_queue_Context *queue_context
0198 );
0199 
0200 /**
0201  * @brief Obtains RWLock for writing.
0202  *
0203  * This routine attempts to obtain the RWLock for write exclusive access.
0204  *
0205  * @param[in, out] the_rwlock The RWLock to wait for.
0206  * @param wait Indicates whether the calling thread is willing to wait.
0207  * @param queue_context The thread queue context.
0208  *
0209  * @retval STATUS_SUCCESSFUL The RWLock was successfully obtained for write
0210  *          exclusive access.
0211  * @retval STATUS_UNAVAILABLE The RWlock is currently locked and the calling
0212  *          thread is not willing to wait.
0213  * @retval STATUS_TIMEOUT A timeout occurred.
0214  */
0215 Status_Control _CORE_RWLock_Seize_for_writing(
0216   CORE_RWLock_Control  *the_rwlock,
0217   bool                  wait,
0218   Thread_queue_Context *queue_context
0219 );
0220 
0221 /**
0222  * @brief Releases the RWLock.
0223  *
0224  * This routine manually releases @a the_rwlock.  All of the threads waiting
0225  * for the RWLock will be readied.
0226  *
0227  * @param[in, out] the_rwlock The RWLock to surrender.
0228  *
0229  * @return STATUS_SUCCESSFUL This method is always successful.
0230  */
0231 Status_Control _CORE_RWLock_Surrender( CORE_RWLock_Control *the_rwlock );
0232 
0233 /** @} */
0234 
0235 #ifdef __cplusplus
0236 }
0237 #endif
0238 
0239 #endif
0240 /* end of include file */