summaryrefslogtreecommitdiffstats
path: root/cpukit/libblock
diff options
context:
space:
mode:
authorRalf Kirchner <ralf.kirchner@embedded-brains.de>2014-05-23 17:09:22 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-06-02 13:48:41 +0200
commit606ed52568f3b9edfe5098987cae70c775226dc5 (patch)
tree3f1e656b8794aa087a733e428fec2939ad7c8f5f /cpukit/libblock
parentscore: _Scheduler_Set_affinity() (diff)
downloadrtems-606ed52568f3b9edfe5098987cae70c775226dc5.tar.bz2
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().
Diffstat (limited to 'cpukit/libblock')
-rw-r--r--cpukit/libblock/src/bdbuf.c54
1 files changed, 25 insertions, 29 deletions
diff --git a/cpukit/libblock/src/bdbuf.c b/cpukit/libblock/src/bdbuf.c
index 07f479f036..a1d9cf736d 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;