[PATCH 2/6] score: Simplify core barrier

Sebastian Huber sebastian.huber at embedded-brains.de
Mon Feb 22 08:43:45 UTC 2021


Use the number of threads which must arrive at the barrier to trip the
automatic release also to indicate if the barrier is a manual release
barrier.
---
 cpukit/include/rtems/score/corebarrier.h     | 56 +++++++-------------
 cpukit/include/rtems/score/corebarrierimpl.h | 56 +++++---------------
 cpukit/rtems/src/barriercreate.c             | 29 +++++-----
 cpukit/score/src/corebarrier.c               |  7 ++-
 cpukit/score/src/corebarrierwait.c           | 17 +++---
 5 files changed, 59 insertions(+), 106 deletions(-)

diff --git a/cpukit/include/rtems/score/corebarrier.h b/cpukit/include/rtems/score/corebarrier.h
index 60abbd6f8f..7cfaeddca7 100644
--- a/cpukit/include/rtems/score/corebarrier.h
+++ b/cpukit/include/rtems/score/corebarrier.h
@@ -40,50 +40,30 @@ extern "C" {
  */
 
 /**
- *  Flavors of barriers.
- */
-typedef enum {
-  /** This specifies that the barrier will automatically release when
-   *  the user specified number of threads have arrived at the barrier.
-   */
-  CORE_BARRIER_AUTOMATIC_RELEASE,
-  /** This specifies that the user will have to manually release the barrier
-   *  in order to release the waiting threads.
-   */
-  CORE_BARRIER_MANUAL_RELEASE
-}   CORE_barrier_Disciplines;
-
-/**
- *  The following defines the control block used to manage the
- *  attributes of each barrier.
+ * @brief This control block is used to manage a barrier.
  */
 typedef struct {
-  /** This field indicates whether the barrier is automatic or manual.
+  /**
+   * @brief This member is used to manage the set of tasks which are
+   *   blocked waiting for the barrier to be released.
    */
-  CORE_barrier_Disciplines  discipline;
-  /** This element indicates the number of threads which must arrive at the
-   *  barrier to trip the automatic release.
-   */
-  uint32_t                  maximum_count;
-}   CORE_barrier_Attributes;
+  Thread_queue_Control Wait_queue;
 
-/**
- *  The following defines the control block used to manage each
- *  barrier.
- */
-typedef struct {
-  /** This field is the Waiting Queue used to manage the set of tasks
-   *  which are blocked waiting for the barrier to be released.
+  /**
+   * @brief This member contains the current number of thread waiting at the
+   *   barrier to be released.
    */
-  Thread_queue_Control     Wait_queue;
-  /** This element is the set of attributes which define this instance's
-   *  behavior.
+  uint32_t number_of_waiting_threads;
+
+  /**
+   * @brief This member indicates the number of threads which must arrive at
+   *   the barrier to trip the automatic release.
+   *
+   * Use ::CORE_BARRIER_MANUAL_RELEASE_MAXIMUM_COUNT to indicate a manual
+   * release barrier.
    */
-  CORE_barrier_Attributes  Attributes;
-  /** This element contains the current number of thread waiting for this
-   *  barrier to be released. */
-  uint32_t                 number_of_waiting_threads;
-}   CORE_barrier_Control;
+  uint32_t maximum_count;
+} CORE_barrier_Control;
 
 /** @} */
 
diff --git a/cpukit/include/rtems/score/corebarrierimpl.h b/cpukit/include/rtems/score/corebarrierimpl.h
index 922eb5d28f..86a3e956dc 100644
--- a/cpukit/include/rtems/score/corebarrierimpl.h
+++ b/cpukit/include/rtems/score/corebarrierimpl.h
@@ -33,6 +33,12 @@ extern "C" {
  * @{
  */
 
+/**
+ * @brief This maximum thread count constant indicates that the barrier is a
+ *   manual release barrier.
+ */
+#define CORE_BARRIER_MANUAL_RELEASE_MAXIMUM_COUNT 0
+
 /**
  * @brief These thread queue operations are used for core barriers.
  *
@@ -43,16 +49,18 @@ extern "C" {
 extern const Thread_queue_Operations _CORE_barrier_Thread_queue_operations;
 
 /**
- *  @brief Initializes the core barrier.
+ * @brief Initializes the core barrier.
  *
- *  This routine initializes the barrier based on the parameters passed.
+ * @param[out] the_barrier is the barrier to initialize.
  *
- *  @param[out] the_barrier The barrier to initialize.
- *  @param[out] the_barrier_attributes The attributes which define the behavior of this instance.
+ * @param maximum_count is the number of threads which must arrive at the
+ *   barrier to trip the automatic release or
+ *   ::CORE_BARRIER_MANUAL_RELEASE_MAXIMUM_COUNT to indicate a manual release
+ *   barrier.
  */
 void _CORE_barrier_Initialize(
-  CORE_barrier_Control       *the_barrier,
-  CORE_barrier_Attributes    *the_barrier_attributes
+  CORE_barrier_Control *the_barrier,
+  uint32_t              maximum_count
 );
 
 /**
@@ -173,42 +181,6 @@ RTEMS_INLINE_ROUTINE void _CORE_barrier_Flush(
   );
 }
 
-/**
- * @brief Checks if the barrier is automatic.
- *
- * This function returns true if the automatic release attribute is
- * enabled in the @a attribute_set and false otherwise.
- *
- * @param the_attribute The attribute set to test.
- *
- * @retval true The automatic release attribute is enabled.
- * @retval false The automatic release attribute is not enabled.
- */
-RTEMS_INLINE_ROUTINE bool _CORE_barrier_Is_automatic(
-  CORE_barrier_Attributes *the_attribute
-)
-{
-   return
-     (the_attribute->discipline == CORE_BARRIER_AUTOMATIC_RELEASE);
-}
-
-/**
- * @brief Returns the number of currently waiting threads.
- *
- * This routine returns the number of threads currently waiting at the barrier.
- *
- * @param[in] the_barrier The barrier to obtain the number of blocked
- *            threads of.
- *
- * @return the current count of waiting threads of this barrier.
- */
-RTEMS_INLINE_ROUTINE uint32_t  _CORE_barrier_Get_number_of_waiting_threads(
-  CORE_barrier_Control  *the_barrier
-)
-{
-  return the_barrier->number_of_waiting_threads;
-}
-
 /** @} */
 
 #ifdef __cplusplus
diff --git a/cpukit/rtems/src/barriercreate.c b/cpukit/rtems/src/barriercreate.c
index 99d916d8c7..80b10e1e0b 100644
--- a/cpukit/rtems/src/barriercreate.c
+++ b/cpukit/rtems/src/barriercreate.c
@@ -34,34 +34,35 @@ rtems_status_code rtems_barrier_create(
   rtems_id            *id
 )
 {
-  Barrier_Control         *the_barrier;
-  CORE_barrier_Attributes  the_attributes;
+  Barrier_Control *the_barrier;
+  uint32_t         maximum_count;
 
-  if ( !rtems_is_name_valid( name ) )
+  if ( !rtems_is_name_valid( name ) ) {
     return RTEMS_INVALID_NAME;
+  }
 
-  if ( !id )
+  if ( id == NULL ) {
     return RTEMS_INVALID_ADDRESS;
+  }
 
-  /* Initialize core barrier attributes */
   if ( _Attributes_Is_barrier_automatic( attribute_set ) ) {
-    the_attributes.discipline = CORE_BARRIER_AUTOMATIC_RELEASE;
-    if ( maximum_waiters == 0 )
+    if ( maximum_waiters == 0 ) {
       return RTEMS_INVALID_NUMBER;
-  } else
-    the_attributes.discipline = CORE_BARRIER_MANUAL_RELEASE;
-  the_attributes.maximum_count = maximum_waiters;
+    }
+
+    maximum_count = maximum_waiters;
+  } else {
+    maximum_count = CORE_BARRIER_MANUAL_RELEASE_MAXIMUM_COUNT;
+  }
 
   the_barrier = _Barrier_Allocate();
 
-  if ( !the_barrier ) {
+  if ( the_barrier == NULL ) {
     _Objects_Allocator_unlock();
     return RTEMS_TOO_MANY;
   }
 
-  the_barrier->attribute_set = attribute_set;
-
-  _CORE_barrier_Initialize( &the_barrier->Barrier, &the_attributes );
+  _CORE_barrier_Initialize( &the_barrier->Barrier, maximum_count );
 
   *id = _Objects_Open_u32( &_Barrier_Information, &the_barrier->Object, name );
   _Objects_Allocator_unlock();
diff --git a/cpukit/score/src/corebarrier.c b/cpukit/score/src/corebarrier.c
index c9c9b04ed5..edb37d7087 100644
--- a/cpukit/score/src/corebarrier.c
+++ b/cpukit/score/src/corebarrier.c
@@ -23,13 +23,12 @@
 #include <rtems/score/corebarrierimpl.h>
 
 void _CORE_barrier_Initialize(
-  CORE_barrier_Control       *the_barrier,
-  CORE_barrier_Attributes    *the_barrier_attributes
+  CORE_barrier_Control *the_barrier,
+  uint32_t              maximum_count
 )
 {
-
-  the_barrier->Attributes                = *the_barrier_attributes;
   the_barrier->number_of_waiting_threads = 0;
+  the_barrier->maximum_count = maximum_count;
 
   _Thread_queue_Object_initialize( &the_barrier->Wait_queue );
 }
diff --git a/cpukit/score/src/corebarrierwait.c b/cpukit/score/src/corebarrierwait.c
index 197e0cf405..078276bf05 100644
--- a/cpukit/score/src/corebarrierwait.c
+++ b/cpukit/score/src/corebarrierwait.c
@@ -61,21 +61,22 @@ Status_Control _CORE_barrier_Seize(
   Thread_queue_Context *queue_context
 )
 {
-  uint32_t number_of_waiting_threads;
+  uint32_t new_number_of_waiting_threads;
 
   _CORE_barrier_Acquire_critical( the_barrier, queue_context );
 
-  number_of_waiting_threads = the_barrier->number_of_waiting_threads;
-  ++number_of_waiting_threads;
+  /*
+   * In theory, this calculation can overflow.  If this happens, then about 4
+   * billion threads are accidentally released.  Currently, the system limit
+   * for threads is a bit lower with three times OBJECTS_INDEX_MASK - 1.
+   */
+  new_number_of_waiting_threads = the_barrier->number_of_waiting_threads + 1;
 
-  if (
-    _CORE_barrier_Is_automatic( &the_barrier->Attributes )
-      && number_of_waiting_threads == the_barrier->Attributes.maximum_count
-  ) {
+  if ( new_number_of_waiting_threads == the_barrier->maximum_count ) {
     _CORE_barrier_Surrender( the_barrier, queue_context );
     return STATUS_BARRIER_AUTOMATICALLY_RELEASED;
   } else {
-    the_barrier->number_of_waiting_threads = number_of_waiting_threads;
+    the_barrier->number_of_waiting_threads = new_number_of_waiting_threads;
     _Thread_queue_Context_set_thread_state(
       queue_context,
       STATES_WAITING_FOR_BARRIER
-- 
2.26.2



More information about the devel mailing list