[PATCH 08/12] cpukit/libblock: No preempt handling in bdbuf init
Joel Sherrill
joel.sherrill at OARcorp.com
Tue May 27 14:57:47 UTC 2014
On 5/27/2014 9:47 AM, Ralf Kirchner wrote:
> 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 pthred_once().
I am ok with this in concept but have problems with some implementation
details.
Are there disable critical section points left?
> ---
> cpukit/libblock/src/bdbuf.c | 79 +++++++++++++++++++++++++++----------------
> 1 Datei geändert, 49 Zeilen hinzugefügt(+), 30 Zeilen entfernt(-)
>
> diff --git a/cpukit/libblock/src/bdbuf.c b/cpukit/libblock/src/bdbuf.c
> index 07f479f..1e4887c 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,6 @@ 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_bdbuf_cache;
>
> typedef enum {
> @@ -171,6 +170,20 @@ typedef enum {
> RTEMS_BDBUF_FATAL_WAIT_TRANS_EVNT
> } rtems_bdbuf_fatal_code;
>
> +typedef struct {
> + pthread_once_t is_initialized;
> + rtems_status_code return_status;
> +} rtems_bdbuf_init_data_type;
> +
> +#define RTEMS_BDBUF_INIT_DATA_TYPE_INITIALIZER( \
> +) \
> +{ \
> + PTHREAD_ONCE_INIT, \
> + RTEMS_SUCCESSFUL \
> +}
> +
> +static rtems_bdbuf_init_data_type rtems_bdbuf_data = RTEMS_BDBUF_INIT_DATA_TYPE_INITIALIZER();
> +
> /**
> * The events used in this code. These should be system events rather than
> * application events.
> @@ -1388,10 +1401,9 @@ rtems_bdbuf_read_request_size (uint32_t transfer_count)
> /**
> * Initialise the cache.
> *
> - * @return rtems_status_code The initialisation status.
> */
> -rtems_status_code
> -rtems_bdbuf_init (void)
> +static void
> +rtems_bdbuf_init_once (void)
> {
> rtems_bdbuf_group* group;
> rtems_bdbuf_buffer* bd;
> @@ -1399,41 +1411,30 @@ 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");
>
> - if (rtems_interrupt_is_in_progress())
> - return RTEMS_CALLED_FROM_ISR;
> + if (rtems_interrupt_is_in_progress()) {
> + rtems_bdbuf_data.return_status = RTEMS_CALLED_FROM_ISR;
> + goto end;
> + }
>
You add a goto to avoid an early out with no work being done on
the goto destination. Leave the early out.
Applies multiple times.
> /*
> * Check the configuration table values.
> */
>
> - if ((bdbuf_config.buffer_max % bdbuf_config.buffer_min) != 0)
> - return RTEMS_INVALID_NUMBER;
> + if ((bdbuf_config.buffer_max % bdbuf_config.buffer_min) != 0) {
> + rtems_bdbuf_data.return_status = RTEMS_INVALID_NUMBER;
> + goto end;
> + }
>
> if (rtems_bdbuf_read_request_size (bdbuf_config.max_read_ahead_blocks)
> - > 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;
> + > RTEMS_MINIMUM_STACK_SIZE / 8U) {
> + rtems_bdbuf_data.return_status = RTEMS_INVALID_NUMBER;
> + goto end;
> }
>
> - 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.
> */
> @@ -1605,7 +1606,8 @@ rtems_bdbuf_init (void)
>
> rtems_bdbuf_unlock_cache ();
>
> - return RTEMS_SUCCESSFUL;
> + rtems_bdbuf_data.return_status = RTEMS_SUCCESSFUL;
> + goto end;
>
> error:
>
> @@ -1650,9 +1652,26 @@ error:
> rtems_semaphore_delete (bdbuf_cache.lock);
> }
>
> - bdbuf_cache.initialised = false;
> + rtems_bdbuf_data.return_status = RTEMS_UNSATISFIED;
> +
> +end:;
> +}
>
> - return RTEMS_UNSATISFIED;
> +/**
> + * Initialise the cache.
> + *
> + * @return rtems_status_code The initialisation status.
> + */
> +rtems_status_code
> +rtems_bdbuf_init (void)
> +{
> + int eno = pthread_once (&rtems_bdbuf_data.is_initialized, rtems_bdbuf_init_once);
> +
> + if (eno != 0) {
> + return RTEMS_UNSATISFIED;
> + } else {
> + return rtems_bdbuf_data.return_status;
> + }
> }
And then you code having early outs.
This is inconsistent.
>
> static void
--
Joel Sherrill, Ph.D. Director of Research & Development
joel.sherrill at OARcorp.com On-Line Applications Research
Ask me about RTEMS: a free RTOS Huntsville AL 35805
Support Available (256) 722-9985
More information about the devel
mailing list