[PATCH rtems v2 1/2] libblock: Add rtems_bdbuf_peek()

Christian MAUDERER christian.mauderer at embedded-brains.de
Mon Mar 22 15:32:43 UTC 2021


Am 22.03.21 um 15:55 schrieb Gedare Bloom:
> On Mon, Mar 22, 2021 at 2:27 AM Christian Mauderer
> <christian.mauderer at embedded-brains.de> wrote:
>>
>> Adds a peek function that allows (for example) a file system to suggest
>> the next blocks that should be used for read ahead. This can increase
>> the read speed of fragmented files.
>> ---
>>   cpukit/include/rtems/bdbuf.h             |  21 ++++
>>   cpukit/include/rtems/diskdevs.h          |  24 ++++-
>>   cpukit/libblock/src/bdbuf.c              |  84 +++++++++++----
>>   cpukit/libblock/src/blkdev-print-stats.c |   2 +
>>   testsuites/fstests/fsdosfswrite01/init.c |   3 +
>>   testsuites/libtests/block14/block14.scn  |  19 +++-
>>   testsuites/libtests/block14/init.c       | 124 +++++++++++++++++------
>>   7 files changed, 217 insertions(+), 60 deletions(-)
>>
>> diff --git a/cpukit/include/rtems/bdbuf.h b/cpukit/include/rtems/bdbuf.h
>> index fbb4fc05e9..0cde571816 100644
>> --- a/cpukit/include/rtems/bdbuf.h
>> +++ b/cpukit/include/rtems/bdbuf.h
>> @@ -539,6 +539,27 @@ rtems_bdbuf_read (
>>     rtems_bdbuf_buffer** bd
>>   );
>>
>> +/**
> missing @brief?
> 
> rest of this looks fine on a quick skim

Didn't seem to be the style of the other comments in that header. So I 
didn't add one here either. Would the following one be OK:

@brief: Give a hint which blocks should be cached next.

> 
>> + * Provide a hint to the read ahead mechanism which blocks should be cached
>> + * next. This overwrites the default linear pattern. You should use it in (for
>> + * example) a file system to tell bdbuf where the next part of a fragmented file
>> + * is. If you know the length of the file, you can provide that too.
>> + *
>> + * Before you can use this function, the rtems_bdbuf_init() routine must be
>> + * called at least once to initialize everything. Otherwise you might get
>> + * unexpected results.
>> + *
>> + * @param dd [in] The disk device.
>> + * @param block [in] Linear media block number.
>> + * @param nr_blocks [in] Number of consecutive blocks that can be pre-fetched.
>> + */
>> +void
>> +rtems_bdbuf_peek (
>> +  rtems_disk_device *dd,
>> +  rtems_blkdev_bnum block,
>> +  uint32_t nr_blocks
>> +);
>> +
>>   /**
>>    * Release the buffer obtained by a read call back to the cache. If the buffer
>>    * was obtained by a get call and was not already in the cache the release
>> diff --git a/cpukit/include/rtems/diskdevs.h b/cpukit/include/rtems/diskdevs.h
>> index 85d157dcd5..527a8cc955 100644
>> --- a/cpukit/include/rtems/diskdevs.h
>> +++ b/cpukit/include/rtems/diskdevs.h
>> @@ -58,6 +58,11 @@ typedef int (*rtems_block_device_ioctl)(
>>    */
>>   #define RTEMS_DISK_READ_AHEAD_NO_TRIGGER ((rtems_blkdev_bnum) -1)
>>
>> +/**
>> + * @brief Size value to set number of blocks based on config and disk size.
>> + */
>> +#define RTEMS_DISK_READ_AHEAD_SIZE_AUTO (0)
>> +
>>   /**
>>    * @brief Block device read-ahead control.
>>    */
>> @@ -71,7 +76,8 @@ typedef struct {
>>      * @brief Block value to trigger the read-ahead request.
>>      *
>>      * A value of @ref RTEMS_DISK_READ_AHEAD_NO_TRIGGER will disable further
>> -   * read-ahead requests since no valid block can have this value.
>> +   * read-ahead requests (except the ones triggered by @a rtems_bdbuf_peek)
>> +   * since no valid block can have this value.
>>      */
>>     rtems_blkdev_bnum trigger;
>>
>> @@ -82,6 +88,14 @@ typedef struct {
>>      * be arbitrary.
>>      */
>>     rtems_blkdev_bnum next;
>> +
>> +  /**
>> +   * @brief Size of the next read-ahead request in blocks.
>> +   *
>> +   * A value of @ref RTEMS_DISK_READ_AHEAD_SIZE_AUTO will try to read the rest
>> +   * of the disk but at most the configured max_read_ahead_blocks.
>> +   */
>> +  uint32_t nr_blocks;
>>   } rtems_blkdev_read_ahead;
>>
>>   /**
>> @@ -110,10 +124,16 @@ typedef struct {
>>     /**
>>      * @brief Read-ahead transfer count.
>>      *
>> -   * Each read-ahead transfer may read multiple blocks.
>> +   * Each read-ahead transfer may read multiple blocks. This counts all
>> +   * transfers (including peeks).
>>      */
>>     uint32_t read_ahead_transfers;
>>
>> +  /**
>> +   * @brief Read-ahead transfers caused by a peek.
>> +   */
>> +  uint32_t read_ahead_peeks;
>> +
>>     /**
>>      * @brief Count of blocks transfered from the device.
>>      */
>> diff --git a/cpukit/libblock/src/bdbuf.c b/cpukit/libblock/src/bdbuf.c
>> index a7d471507c..8aadf9c8ae 100644
>> --- a/cpukit/libblock/src/bdbuf.c
>> +++ b/cpukit/libblock/src/bdbuf.c
>> @@ -2018,6 +2018,23 @@ rtems_bdbuf_read_ahead_reset (rtems_disk_device *dd)
>>     dd->read_ahead.trigger = RTEMS_DISK_READ_AHEAD_NO_TRIGGER;
>>   }
>>
>> +static void
>> +rtems_bdbuf_read_ahead_add_to_chain (rtems_disk_device *dd)
>> +{
>> +  rtems_status_code sc;
>> +  rtems_chain_control *chain = &bdbuf_cache.read_ahead_chain;
>> +
>> +  if (rtems_chain_is_empty (chain))
>> +  {
>> +    sc = rtems_event_send (bdbuf_cache.read_ahead_task,
>> +                           RTEMS_BDBUF_READ_AHEAD_WAKE_UP);
>> +    if (sc != RTEMS_SUCCESSFUL)
>> +      rtems_bdbuf_fatal (RTEMS_BDBUF_FATAL_RA_WAKE_UP);
>> +  }
>> +
>> +  rtems_chain_append_unprotected (chain, &dd->read_ahead.node);
>> +}
>> +
>>   static void
>>   rtems_bdbuf_check_read_ahead_trigger (rtems_disk_device *dd,
>>                                         rtems_blkdev_bnum  block)
>> @@ -2026,18 +2043,8 @@ rtems_bdbuf_check_read_ahead_trigger (rtems_disk_device *dd,
>>         && dd->read_ahead.trigger == block
>>         && !rtems_bdbuf_is_read_ahead_active (dd))
>>     {
>> -    rtems_status_code sc;
>> -    rtems_chain_control *chain = &bdbuf_cache.read_ahead_chain;
>> -
>> -    if (rtems_chain_is_empty (chain))
>> -    {
>> -      sc = rtems_event_send (bdbuf_cache.read_ahead_task,
>> -                             RTEMS_BDBUF_READ_AHEAD_WAKE_UP);
>> -      if (sc != RTEMS_SUCCESSFUL)
>> -        rtems_bdbuf_fatal (RTEMS_BDBUF_FATAL_RA_WAKE_UP);
>> -    }
>> -
>> -    rtems_chain_append_unprotected (chain, &dd->read_ahead.node);
>> +    dd->read_ahead.nr_blocks = RTEMS_DISK_READ_AHEAD_SIZE_AUTO;
>> +    rtems_bdbuf_read_ahead_add_to_chain(dd);
>>     }
>>   }
>>
>> @@ -2112,6 +2119,24 @@ rtems_bdbuf_read (rtems_disk_device   *dd,
>>     return sc;
>>   }
>>
>> +void
>> +rtems_bdbuf_peek (rtems_disk_device *dd,
>> +                  rtems_blkdev_bnum block,
>> +                  uint32_t nr_blocks)
>> +{
>> +  rtems_bdbuf_lock_cache ();
>> +
>> +  if (bdbuf_cache.read_ahead_enabled && nr_blocks > 0)
>> +  {
>> +    rtems_bdbuf_read_ahead_reset(dd);
>> +    dd->read_ahead.next = block;
>> +    dd->read_ahead.nr_blocks = nr_blocks;
>> +    rtems_bdbuf_read_ahead_add_to_chain(dd);
>> +  }
>> +
>> +  rtems_bdbuf_unlock_cache ();
>> +}
>> +
>>   static rtems_status_code
>>   rtems_bdbuf_check_bd_and_lock_cache (rtems_bdbuf_buffer *bd, const char *kind)
>>   {
>> @@ -2952,18 +2977,33 @@ rtems_bdbuf_read_ahead_task (rtems_task_argument arg)
>>
>>           if (bd != NULL)
>>           {
>> -          uint32_t transfer_count = dd->block_count - block;
>> +          uint32_t transfer_count = dd->read_ahead.nr_blocks;
>> +          uint32_t blocks_until_end_of_disk = dd->block_count - block;
>>             uint32_t max_transfer_count = bdbuf_config.max_read_ahead_blocks;
>>
>> -          if (transfer_count >= max_transfer_count)
>> -          {
>> -            transfer_count = max_transfer_count;
>> -            dd->read_ahead.trigger = block + transfer_count / 2;
>> -            dd->read_ahead.next = block + transfer_count;
>> -          }
>> -          else
>> -          {
>> -            dd->read_ahead.trigger = RTEMS_DISK_READ_AHEAD_NO_TRIGGER;
>> +          if (transfer_count == RTEMS_DISK_READ_AHEAD_SIZE_AUTO) {
>> +            transfer_count = blocks_until_end_of_disk;
>> +
>> +            if (transfer_count >= max_transfer_count)
>> +            {
>> +              transfer_count = max_transfer_count;
>> +              dd->read_ahead.trigger = block + transfer_count / 2;
>> +              dd->read_ahead.next = block + transfer_count;
>> +            }
>> +            else
>> +            {
>> +              dd->read_ahead.trigger = RTEMS_DISK_READ_AHEAD_NO_TRIGGER;
>> +            }
>> +          } else {
>> +            if (transfer_count > blocks_until_end_of_disk) {
>> +              transfer_count = blocks_until_end_of_disk;
>> +            }
>> +
>> +            if (transfer_count > max_transfer_count) {
>> +              transfer_count = max_transfer_count;
>> +            }
>> +
>> +            ++dd->stats.read_ahead_peeks;
>>             }
>>
>>             ++dd->stats.read_ahead_transfers;
>> diff --git a/cpukit/libblock/src/blkdev-print-stats.c b/cpukit/libblock/src/blkdev-print-stats.c
>> index 8edf24fd8c..539ff08157 100644
>> --- a/cpukit/libblock/src/blkdev-print-stats.c
>> +++ b/cpukit/libblock/src/blkdev-print-stats.c
>> @@ -47,6 +47,7 @@ void rtems_blkdev_print_stats(
>>        " READ HITS            | %" PRIu32 "\n"
>>        " READ MISSES          | %" PRIu32 "\n"
>>        " READ AHEAD TRANSFERS | %" PRIu32 "\n"
>> +     " READ AHEAD PEEKS     | %" PRIu32 "\n"
>>        " READ BLOCKS          | %" PRIu32 "\n"
>>        " READ ERRORS          | %" PRIu32 "\n"
>>        " WRITE TRANSFERS      | %" PRIu32 "\n"
>> @@ -59,6 +60,7 @@ void rtems_blkdev_print_stats(
>>        stats->read_hits,
>>        stats->read_misses,
>>        stats->read_ahead_transfers,
>> +     stats->read_ahead_peeks,
>>        stats->read_blocks,
>>        stats->read_errors,
>>        stats->write_transfers,
>> diff --git a/testsuites/fstests/fsdosfswrite01/init.c b/testsuites/fstests/fsdosfswrite01/init.c
>> index e5d8e5d6dd..64b43b7919 100644
>> --- a/testsuites/fstests/fsdosfswrite01/init.c
>> +++ b/testsuites/fstests/fsdosfswrite01/init.c
>> @@ -129,6 +129,7 @@ static void test_normal_file_write(
>>       .read_hits            = 0,
>>       .read_misses          = 0,
>>       .read_ahead_transfers = 0,
>> +    .read_ahead_peeks     = 0,
>>       .read_blocks          = 0,
>>       .read_errors          = 0,
>>       .write_transfers      = 1,
>> @@ -139,6 +140,7 @@ static void test_normal_file_write(
>>       .read_hits            = 3,
>>       .read_misses          = 2,
>>       .read_ahead_transfers = 0,
>> +    .read_ahead_peeks     = 0,
>>       .read_blocks          = 2,
>>       .read_errors          = 0,
>>       .write_transfers      = 1,
>> @@ -149,6 +151,7 @@ static void test_normal_file_write(
>>       .read_hits            = 3,
>>       .read_misses          = 3,
>>       .read_ahead_transfers = 0,
>> +    .read_ahead_peeks     = 0,
>>       .read_blocks          = 3,
>>       .read_errors          = 0,
>>       .write_transfers      = 1,
>> diff --git a/testsuites/libtests/block14/block14.scn b/testsuites/libtests/block14/block14.scn
>> index 7170522579..cf5518adfd 100644
>> --- a/testsuites/libtests/block14/block14.scn
>> +++ b/testsuites/libtests/block14/block14.scn
>> @@ -6,19 +6,30 @@ action 3
>>   action 4
>>   action 5
>>   action 6
>> +action 7
>> +action 8
>> +action 9
>> +action 10
>> +action 11
>> +action 12
>> +action 13
>> +action 14
>> +action 15
>>   -------------------------------------------------------------------------------
>>                                  DEVICE STATISTICS
>>   ----------------------+--------------------------------------------------------
>>    MEDIA BLOCK SIZE     | 0
>>    MEDIA BLOCK COUNT    | 1
>>    BLOCK SIZE           | 2
>> - READ HITS            | 2
>> - READ MISSES          | 3
>> - READ AHEAD TRANSFERS | 2
>> - READ BLOCKS          | 5
>> + READ HITS            | 4
>> + READ MISSES          | 7
>> + READ AHEAD TRANSFERS | 6
>> + READ AHEAD PEEKS     | 3
>> + READ BLOCKS          | 13
>>    READ ERRORS          | 1
>>    WRITE TRANSFERS      | 2
>>    WRITE BLOCKS         | 2
>>    WRITE ERRORS         | 1
>>   ----------------------+--------------------------------------------------------
>> +
>>   *** END OF TEST BLOCK 14 ***
>> diff --git a/testsuites/libtests/block14/init.c b/testsuites/libtests/block14/init.c
>> index b4e73aadc9..13b7ab05ad 100644
>> --- a/testsuites/libtests/block14/init.c
>> +++ b/testsuites/libtests/block14/init.c
>> @@ -29,9 +29,9 @@
>>
>>   const char rtems_test_name[] = "BLOCK 14";
>>
>> -#define ACTION_COUNT 7
>> +#define ACTION_COUNT 16
>>
>> -#define BLOCK_COUNT 6
>> +#define BLOCK_COUNT 14
>>
>>   #define DISK_PATH "/disk"
>>
>> @@ -42,50 +42,104 @@ typedef struct {
>>       rtems_blkdev_bnum block,
>>       rtems_bdbuf_buffer **bd_ptr
>>     );
>> +  void (*peek)(
>> +    rtems_disk_device *dd,
>> +    rtems_blkdev_bnum block,
>> +    uint32_t nr_blocks
>> +  );
>>     rtems_status_code expected_get_status;
>>     rtems_status_code (*release)(rtems_bdbuf_buffer *bd);
>>   } test_action;
>>
>>   static const test_action actions [ACTION_COUNT] = {
>> -  { 0, rtems_bdbuf_read, RTEMS_SUCCESSFUL, rtems_bdbuf_release },
>> -  { 1, rtems_bdbuf_read, RTEMS_SUCCESSFUL, rtems_bdbuf_release },
>> -  { 2, rtems_bdbuf_read, RTEMS_SUCCESSFUL, rtems_bdbuf_release },
>> -  { 0, rtems_bdbuf_read, RTEMS_SUCCESSFUL, rtems_bdbuf_release },
>> -  { 4, rtems_bdbuf_get, RTEMS_SUCCESSFUL, rtems_bdbuf_sync },
>> -  { 5, rtems_bdbuf_read, RTEMS_IO_ERROR, rtems_bdbuf_release },
>> -  { 5, rtems_bdbuf_get, RTEMS_SUCCESSFUL, rtems_bdbuf_sync }
>> +  /* normal read ahead */
>> +  { 0, rtems_bdbuf_read, NULL, RTEMS_SUCCESSFUL, rtems_bdbuf_release },
>> +  { 1, rtems_bdbuf_read, NULL, RTEMS_SUCCESSFUL, rtems_bdbuf_release },
>> +  { 2, rtems_bdbuf_read, NULL, RTEMS_SUCCESSFUL, rtems_bdbuf_release },
>> +
>> +  /* re-read a cached block */
>> +  { 0, rtems_bdbuf_read, NULL, RTEMS_SUCCESSFUL, rtems_bdbuf_release },
>> +
>> +  /* cause some writes */
>> +  { 4, rtems_bdbuf_get, NULL, RTEMS_SUCCESSFUL, rtems_bdbuf_sync },
>> +  { 5, rtems_bdbuf_read, NULL, RTEMS_IO_ERROR, rtems_bdbuf_release },
>> +  { 5, rtems_bdbuf_get, NULL, RTEMS_SUCCESSFUL, rtems_bdbuf_sync },
>> +
>> +  /* interrupt normal read ahead with a peek */
>> +  { 9, rtems_bdbuf_read, NULL, RTEMS_SUCCESSFUL, rtems_bdbuf_release },
>> +  { 13, NULL, rtems_bdbuf_peek, 0, NULL },
>> +  { 10, rtems_bdbuf_read, NULL, RTEMS_SUCCESSFUL, rtems_bdbuf_release },
>> +  { 11, rtems_bdbuf_read, NULL, RTEMS_SUCCESSFUL, rtems_bdbuf_release },
>> +  { 12, rtems_bdbuf_read, NULL, RTEMS_SUCCESSFUL, rtems_bdbuf_release },
>> +
>> +  /* peek with hit */
>> +  { 6, NULL, rtems_bdbuf_peek, 0, NULL },
>> +  { 6, rtems_bdbuf_read, NULL, RTEMS_SUCCESSFUL, rtems_bdbuf_release },
>> +
>> +  /* (wrong) peek with reading different block */
>> +  { 8, NULL, rtems_bdbuf_peek, 0, NULL },
>> +  { 7, rtems_bdbuf_read, NULL, RTEMS_SUCCESSFUL, rtems_bdbuf_release },
>>   };
>>
>> -#define STATS(a, b, c, d, e, f, g, h) \
>> +#define STATS(a, b, c, d, e, f, g, h, i) \
>>     { \
>>       .read_hits = a, \
>>       .read_misses = b, \
>>       .read_ahead_transfers = c, \
>> -    .read_blocks = d, \
>> -    .read_errors = e, \
>> -    .write_transfers = f, \
>> -    .write_blocks = g, \
>> -    .write_errors = h \
>> +    .read_ahead_peeks = d, \
>> +    .read_blocks = e, \
>> +    .read_errors = f, \
>> +    .write_transfers = g, \
>> +    .write_blocks = h, \
>> +    .write_errors = i \
>>     }
>>
>>   static const rtems_blkdev_stats expected_stats [ACTION_COUNT] = {
>> -  STATS(0, 1, 0, 1, 0, 0, 0, 0),
>> -  STATS(0, 2, 1, 3, 0, 0, 0, 0),
>> -  STATS(1, 2, 2, 4, 0, 0, 0, 0),
>> -  STATS(2, 2, 2, 4, 0, 0, 0, 0),
>> -  STATS(2, 2, 2, 4, 0, 1, 1, 0),
>> -  STATS(2, 3, 2, 5, 1, 1, 1, 0),
>> -  STATS(2, 3, 2, 5, 1, 2, 2, 1)
>> +  STATS(0, 1, 0, 0, 1, 0, 0, 0, 0),
>> +  STATS(0, 2, 1, 0, 3, 0, 0, 0, 0),
>> +  STATS(1, 2, 2, 0, 4, 0, 0, 0, 0),
>> +
>> +  STATS(2, 2, 2, 0, 4, 0, 0, 0, 0),
>> +
>> +  STATS(2, 2, 2, 0, 4, 0, 1, 1, 0),
>> +  STATS(2, 3, 2, 0, 5, 1, 1, 1, 0),
>> +  STATS(2, 3, 2, 0, 5, 1, 2, 2, 1),
>> +
>> +  STATS(2, 4, 2, 0, 6, 1, 2, 2, 1),
>> +  STATS(2, 4, 3, 1, 7, 1, 2, 2, 1),
>> +  STATS(2, 5, 3, 1, 8, 1, 2, 2, 1),
>> +  STATS(2, 6, 4, 1, 10, 1, 2, 2, 1),
>> +  STATS(3, 6, 4, 1, 10, 1, 2, 2, 1),
>> +
>> +  STATS(3, 6, 5, 2, 11, 1, 2, 2, 1),
>> +  STATS(4, 6, 5, 2, 11, 1, 2, 2, 1),
>> +
>> +  STATS(4, 6, 6, 3, 12, 1, 2, 2, 1),
>> +  STATS(4, 7, 6, 3, 13, 1, 2, 2, 1),
>>   };
>>
>>   static const int expected_block_access_counts [ACTION_COUNT] [BLOCK_COUNT] = {
>> -   { 1, 0, 0, 0, 0, 0 },
>> -   { 1, 1, 1, 0, 0, 0 },
>> -   { 1, 1, 1, 1, 0, 0 },
>> -   { 1, 1, 1, 1, 0, 0 },
>> -   { 1, 1, 1, 1, 1, 0 },
>> -   { 1, 1, 1, 1, 1, 1 },
>> -   { 1, 1, 1, 1, 1, 2 }
>> +   { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
>> +   { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
>> +   { 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
>> +
>> +   { 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
>> +
>> +   { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
>> +   { 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
>> +   { 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0 },
>> +
>> +   { 1, 1, 1, 1, 1, 2, 0, 0, 0, 1, 0, 0, 0, 0 },
>> +   { 1, 1, 1, 1, 1, 2, 0, 0, 0, 1, 0, 0, 0, 1 },
>> +   { 1, 1, 1, 1, 1, 2, 0, 0, 0, 1, 1, 0, 0, 1 },
>> +   { 1, 1, 1, 1, 1, 2, 0, 0, 0, 1, 1, 1, 1, 1 },
>> +   { 1, 1, 1, 1, 1, 2, 0, 0, 0, 1, 1, 1, 1, 1 },
>> +
>> +   { 1, 1, 1, 1, 1, 2, 1, 0, 0, 1, 1, 1, 1, 1 },
>> +   { 1, 1, 1, 1, 1, 2, 1, 0, 0, 1, 1, 1, 1, 1 },
>> +
>> +   { 1, 1, 1, 1, 1, 2, 1, 0, 1, 1, 1, 1, 1, 1 },
>> +   { 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1 },
>>   };
>>
>>   static int block_access_counts [BLOCK_COUNT];
>> @@ -132,10 +186,16 @@ static void test_actions(rtems_disk_device *dd)
>>
>>       printf("action %i\n", i);
>>
>> -    sc = (*action->get)(dd, action->block, &bd);
>> -    rtems_test_assert(sc == action->expected_get_status);
>> +    if (action->get != NULL) {
>> +      sc = (*action->get)(dd, action->block, &bd);
>> +      rtems_test_assert(sc == action->expected_get_status);
>> +    }
>> +
>> +    if (action->peek != NULL) {
>> +      (*action->peek)(dd, action->block, 1);
>> +    }
>>
>> -    if (sc == RTEMS_SUCCESSFUL) {
>> +    if (sc == RTEMS_SUCCESSFUL && action->release != NULL) {
>>         sc = (*action->release)(bd);
>>         rtems_test_assert(sc == RTEMS_SUCCESSFUL);
>>       }
>> --
>> 2.26.2
>>
>> _______________________________________________
>> devel mailing list
>> devel at rtems.org
>> http://lists.rtems.org/mailman/listinfo/devel

-- 
--------------------------------------------
embedded brains GmbH
Herr Christian MAUDERER
Dornierstr. 4
82178 Puchheim
Germany
email: christian.mauderer at embedded-brains.de
phone: +49-89-18 94 741 - 18
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


More information about the devel mailing list