[rtems commit] libblock: Use pthread_once() for initialization

Sebastian Huber sebh at rtems.org
Mon Jun 2 11:44:43 UTC 2014


Module:    rtems
Branch:    master
Commit:    606ed52568f3b9edfe5098987cae70c775226dc5
Changeset: http://git.rtems.org/rtems/commit/?id=606ed52568f3b9edfe5098987cae70c775226dc5

Author:    Ralf Kirchner <ralf.kirchner at embedded-brains.de>
Date:      Fri May 23 17:09:22 2014 +0200

libblock: Use pthread_once() for initialization

Enabling and disabling preemption as done for single core will not work
for SMP.  In the bdbuf initialization preemption handling can be avoided
in general by using pthread_once().

---

 cpukit/libblock/src/bdbuf.c |   54 ++++++++++++++++++++-----------------------
 1 files changed, 25 insertions(+), 29 deletions(-)

diff --git a/cpukit/libblock/src/bdbuf.c b/cpukit/libblock/src/bdbuf.c
index 07f479f..a1d9cf7 100644
--- a/cpukit/libblock/src/bdbuf.c
+++ b/cpukit/libblock/src/bdbuf.c
@@ -35,6 +35,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <inttypes.h>
+#include <pthread.h>
 
 #include <rtems.h>
 #include <rtems/error.h>
@@ -137,8 +138,7 @@ typedef struct rtems_bdbuf_cache
   rtems_id            read_ahead_task;   /**< Read-ahead task */
   rtems_chain_control read_ahead_chain;  /**< Read-ahead request chain */
   bool                read_ahead_enabled; /**< Read-ahead enabled */
-
-  bool                initialised;       /**< Initialised state. */
+  rtems_status_code   init_status;       /**< The initialization status */
 } rtems_bdbuf_cache;
 
 typedef enum {
@@ -168,7 +168,8 @@ typedef enum {
   RTEMS_BDBUF_FATAL_SYNC_UNLOCK,
   RTEMS_BDBUF_FATAL_TREE_RM,
   RTEMS_BDBUF_FATAL_WAIT_EVNT,
-  RTEMS_BDBUF_FATAL_WAIT_TRANS_EVNT
+  RTEMS_BDBUF_FATAL_WAIT_TRANS_EVNT,
+  RTEMS_BDBUF_FATAL_ONCE
 } rtems_bdbuf_fatal_code;
 
 /**
@@ -218,6 +219,8 @@ static rtems_task rtems_bdbuf_read_ahead_task(rtems_task_argument arg);
  */
 static rtems_bdbuf_cache bdbuf_cache;
 
+static pthread_once_t rtems_bdbuf_once_state = PTHREAD_ONCE_INIT;
+
 #if RTEMS_BDBUF_TRACE
 /**
  * If true output the trace message.
@@ -1385,13 +1388,8 @@ rtems_bdbuf_read_request_size (uint32_t transfer_count)
     + sizeof (rtems_blkdev_sg_buffer) * transfer_count;
 }
 
-/**
- * Initialise the cache.
- *
- * @return rtems_status_code The initialisation status.
- */
-rtems_status_code
-rtems_bdbuf_init (void)
+static rtems_status_code
+rtems_bdbuf_do_init (void)
 {
   rtems_bdbuf_group*  group;
   rtems_bdbuf_buffer* bd;
@@ -1399,7 +1397,6 @@ rtems_bdbuf_init (void)
   size_t              b;
   size_t              cache_aligment;
   rtems_status_code   sc;
-  rtems_mode          prev_mode;
 
   if (rtems_bdbuf_tracer)
     printf ("bdbuf:init\n");
@@ -1419,22 +1416,6 @@ rtems_bdbuf_init (void)
     return RTEMS_INVALID_NUMBER;
 
   /*
-   * We use a special variable to manage the initialisation incase we have
-   * completing threads doing this. You may get errors if the another thread
-   * makes a call and we have not finished initialisation.
-   */
-  prev_mode = rtems_bdbuf_disable_preemption ();
-  if (bdbuf_cache.initialised)
-  {
-    rtems_bdbuf_restore_preemption (prev_mode);
-    return RTEMS_RESOURCE_IN_USE;
-  }
-
-  memset(&bdbuf_cache, 0, sizeof(bdbuf_cache));
-  bdbuf_cache.initialised = true;
-  rtems_bdbuf_restore_preemption (prev_mode);
-
-  /*
    * For unspecified cache alignments we use the CPU alignment.
    */
   cache_aligment = 32; /* FIXME rtems_cache_get_data_line_size() */
@@ -1650,12 +1631,27 @@ error:
     rtems_semaphore_delete (bdbuf_cache.lock);
   }
 
-  bdbuf_cache.initialised = false;
-
   return RTEMS_UNSATISFIED;
 }
 
 static void
+rtems_bdbuf_init_once (void)
+{
+  bdbuf_cache.init_status = rtems_bdbuf_do_init();
+}
+
+rtems_status_code
+rtems_bdbuf_init (void)
+{
+  int eno = pthread_once (&rtems_bdbuf_once_state, rtems_bdbuf_init_once);
+
+  if (eno != 0)
+    rtems_bdbuf_fatal (RTEMS_BDBUF_FATAL_ONCE);
+
+  return bdbuf_cache.init_status;
+}
+
+static void
 rtems_bdbuf_wait_for_event (rtems_event_set event)
 {
   rtems_status_code sc = RTEMS_SUCCESSFUL;




More information about the vc mailing list