[PATCH 08/12] cpukit/libblock: No preempt handling in bdbuf init

Gedare Bloom gedare at rtems.org
Tue May 27 15:02:52 UTC 2014


On Tue, May 27, 2014 at 10:57 AM, Joel Sherrill
<joel.sherrill at oarcorp.com> wrote:
>
> 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.
>
Yes, just 'return' if there is no cleanup to do.

>
>>    /*
>>     * 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.
Here you can omit the else { } block and just fall through to the
return rtems_bdbuf_data.return_status;

>>
>>  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
>
> _______________________________________________
> rtems-devel mailing list
> rtems-devel at rtems.org
> http://www.rtems.org/mailman/listinfo/rtems-devel




More information about the devel mailing list