mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-28 15:53:06 +08:00
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().
This commit is contained in:
committed by
Sebastian Huber
parent
25f5730fe5
commit
606ed52568
+25
-29
@@ -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");
|
||||
@@ -1418,22 +1415,6 @@ rtems_bdbuf_init (void)
|
||||
> RTEMS_MINIMUM_STACK_SIZE / 8U)
|
||||
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.
|
||||
*/
|
||||
@@ -1650,11 +1631,26 @@ 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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user