<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Jan 22, 2021 at 7:08 AM Christian MAUDERER <<a href="mailto:christian.mauderer@embedded-brains.de">christian.mauderer@embedded-brains.de</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Am 22.01.21 um 14:59 schrieb Gedare Bloom:<br>
> <br>
> <br>
> On Fri, Jan 22, 2021 at 6:24 AM Christian Mauderer <br>
> <<a href="mailto:christian.mauderer@embedded-brains.de" target="_blank">christian.mauderer@embedded-brains.de</a> <br>
> <mailto:<a href="mailto:christian.mauderer@embedded-brains.de" target="_blank">christian.mauderer@embedded-brains.de</a>>> wrote:<br>
> <br>
>     Adds a peek function that allows (for example) a file system to suggest<br>
>     the next blocks that should be used for read ahead. This can increase<br>
>     the read speed of fragmented files.<br>
>     ---<br>
>       cpukit/include/rtems/bdbuf.h             |  21 ++++<br>
>       cpukit/include/rtems/diskdevs.h          |  27 ++++-<br>
>       cpukit/libblock/src/bdbuf.c              |  80 +++++++++++----<br>
>       cpukit/libblock/src/blkdev-print-stats.c |  28 ++---<br>
>       testsuites/fstests/fsdosfswrite01/init.c |  51 +++++-----<br>
>       testsuites/libtests/block14/block14.scn  |  37 ++++---<br>
>       testsuites/libtests/block14/init.c       | 124 +++++++++++++++++------<br>
>       7 files changed, 264 insertions(+), 104 deletions(-)<br>
> <br>
>     diff --git a/cpukit/include/rtems/bdbuf.h b/cpukit/include/rtems/bdbuf.h<br>
>     index fbb4fc05e9..0cde571816 100644<br>
>     --- a/cpukit/include/rtems/bdbuf.h<br>
>     +++ b/cpukit/include/rtems/bdbuf.h<br>
>     @@ -539,6 +539,27 @@ rtems_bdbuf_read (<br>
>         rtems_bdbuf_buffer** bd<br>
>       );<br>
> <br>
>     +/**<br>
>     + * Provide a hint to the read ahead mechanism which blocks should<br>
>     be cached<br>
>     + * next. This overwrites the default linear pattern. You should use<br>
>     it in (for<br>
>     + * example) a file system to tell bdbuf where the next part of a<br>
>     fragmented file<br>
>     + * is. If you know the length of the file, you can provide that too.<br>
>     + *<br>
>     + * Before you can use this function, the rtems_bdbuf_init() routine<br>
>     must be<br>
>     + * called at least once to initialize everything. Otherwise you<br>
>     might get<br>
>     + * unexpected results.<br>
>     + *<br>
>     + * @param dd [in] The disk device.<br>
>     + * @param block [in] Linear media block number.<br>
>     + * @param nr_blocks [in] Number of consecutive blocks that can be<br>
>     pre-fetched.<br>
>     + */<br>
>     +void<br>
>     +rtems_bdbuf_peek (<br>
>     +  rtems_disk_device *dd,<br>
>     +  rtems_blkdev_bnum block,<br>
>     +  uint32_t nr_blocks<br>
>     +);<br>
>     +<br>
>       /**<br>
>        * Release the buffer obtained by a read call back to the cache.<br>
>     If the buffer<br>
>        * was obtained by a get call and was not already in the cache the<br>
>     release<br>
>     diff --git a/cpukit/include/rtems/diskdevs.h<br>
>     b/cpukit/include/rtems/diskdevs.h<br>
>     index 85d157dcd5..d7529cbe89 100644<br>
>     --- a/cpukit/include/rtems/diskdevs.h<br>
>     +++ b/cpukit/include/rtems/diskdevs.h<br>
>     @@ -58,6 +58,11 @@ typedef int (*rtems_block_device_ioctl)(<br>
>        */<br>
>       #define RTEMS_DISK_READ_AHEAD_NO_TRIGGER ((rtems_blkdev_bnum) -1)<br>
> <br>
>     +/**<br>
>     + * @brief Size value to set number of blocks based on config and<br>
>     disk size.<br>
>     + */<br>
>     +#define RTEMS_DISK_READ_AHEAD_SIZE_AUTO (0)<br>
>     +<br>
>       /**<br>
>        * @brief Block device read-ahead control.<br>
>        */<br>
>     @@ -71,7 +76,8 @@ typedef struct {<br>
>          * @brief Block value to trigger the read-ahead request.<br>
>          *<br>
>          * A value of @ref RTEMS_DISK_READ_AHEAD_NO_TRIGGER will disable<br>
>     further<br>
>     -   * read-ahead requests since no valid block can have this value.<br>
>     +   * read-ahead requests (except the ones triggered by @a<br>
>     rtems_bdbuf_peek)<br>
>     +   * since no valid block can have this value.<br>
>          */<br>
>         rtems_blkdev_bnum trigger;<br>
> <br>
>     @@ -82,6 +88,14 @@ typedef struct {<br>
>          * be arbitrary.<br>
>          */<br>
>         rtems_blkdev_bnum next;<br>
>     +<br>
>     +  /**<br>
>     +   * @brief Size of the next read-ahead request in blocks.<br>
>     +   *<br>
>     +   * A value of @ref RTEMS_DISK_READ_AHEAD_SIZE_AUTO will try to<br>
>     read the rest<br>
>     +   * of the disk but at most the configured max_read_ahead_blocks.<br>
>     +   */<br>
>     +  uint32_t nr_blocks;<br>
>       } rtems_blkdev_read_ahead;<br>
> <br>
>       /**<br>
>     @@ -110,10 +124,19 @@ typedef struct {<br>
>         /**<br>
>          * @brief Read-ahead transfer count.<br>
>          *<br>
>     -   * Each read-ahead transfer may read multiple blocks.<br>
>     +   * Each read-ahead transfer may read multiple blocks. This counts all<br>
>     +   * transfers (with and without size).<br>
>          */<br>
>         uint32_t read_ahead_transfers;<br>
> <br>
>     +  /**<br>
>     +   * @brief Read-ahead transfers with given size.<br>
>     +   *<br>
>     +   * Number of times a read ahead transfer has been given a size.<br>
>     This is the<br>
>     +   * case for read ahead transfers that are caused by a peek.<br>
>     +   */<br>
>     +  uint32_t read_ahead_transfers_with_size;<br>
> <br>
> <br>
> A little bit wordy. Maybe you just want to count the number of peeks?<br>
<br>
I thought about that too. But in theory, someone could add another <br>
mechanism that uses the size. For example it would be possible to do the <br>
normal read ahead with that too.<br>
<br>
But if you prefer, I can rename it to "read_ahead_peeks". I would avoid <br>
removing the read_ahead altogether because it belongs to this mechanism.<br>
<br>
> <br>
>     +<br>
>         /**<br>
>          * @brief Count of blocks transfered from the device.<br>
>          */<br>
>     diff --git a/cpukit/libblock/src/bdbuf.c b/cpukit/libblock/src/bdbuf.c<br>
>     index a7d471507c..02acf11f54 100644<br>
>     --- a/cpukit/libblock/src/bdbuf.c<br>
>     +++ b/cpukit/libblock/src/bdbuf.c<br>
>     @@ -2018,6 +2018,23 @@ rtems_bdbuf_read_ahead_reset<br>
>     (rtems_disk_device *dd)<br>
>         dd->read_ahead.trigger = RTEMS_DISK_READ_AHEAD_NO_TRIGGER;<br>
>       }<br>
> <br>
>     +static void<br>
>     +rtems_bdbuf_read_ahead_add_to_chain (rtems_disk_device *dd)<br>
>     +{<br>
>     +  rtems_status_code sc;<br>
>     +  rtems_chain_control *chain = &bdbuf_cache.read_ahead_chain;<br>
>     +<br>
>     +  if (rtems_chain_is_empty (chain))<br>
>     +  {<br>
>     +    sc = rtems_event_send (bdbuf_cache.read_ahead_task,<br>
>     +                           RTEMS_BDBUF_READ_AHEAD_WAKE_UP);<br>
>     +    if (sc != RTEMS_SUCCESSFUL)<br>
>     +      rtems_bdbuf_fatal (RTEMS_BDBUF_FATAL_RA_WAKE_UP);<br>
>     +  }<br>
>     +<br>
>     +  rtems_chain_append_unprotected (chain, &dd->read_ahead.node);<br>
>     +}<br>
>     +<br>
>       static void<br>
>       rtems_bdbuf_check_read_ahead_trigger (rtems_disk_device *dd,<br>
>                                             rtems_blkdev_bnum  block)<br>
>     @@ -2026,18 +2043,8 @@ rtems_bdbuf_check_read_ahead_trigger<br>
>     (rtems_disk_device *dd,<br>
>             && dd->read_ahead.trigger == block<br>
>             && !rtems_bdbuf_is_read_ahead_active (dd))<br>
>         {<br>
>     -    rtems_status_code sc;<br>
>     -    rtems_chain_control *chain = &bdbuf_cache.read_ahead_chain;<br>
>     -<br>
>     -    if (rtems_chain_is_empty (chain))<br>
>     -    {<br>
>     -      sc = rtems_event_send (bdbuf_cache.read_ahead_task,<br>
>     -                             RTEMS_BDBUF_READ_AHEAD_WAKE_UP);<br>
>     -      if (sc != RTEMS_SUCCESSFUL)<br>
>     -        rtems_bdbuf_fatal (RTEMS_BDBUF_FATAL_RA_WAKE_UP);<br>
>     -    }<br>
>     -<br>
>     -    rtems_chain_append_unprotected (chain, &dd->read_ahead.node);<br>
>     +    dd->read_ahead.nr_blocks = RTEMS_DISK_READ_AHEAD_SIZE_AUTO;<br>
>     +    rtems_bdbuf_read_ahead_add_to_chain(dd);<br>
>         }<br>
>       }<br>
> <br>
>     @@ -2112,6 +2119,24 @@ rtems_bdbuf_read (rtems_disk_device   *dd,<br>
>         return sc;<br>
>       }<br>
> <br>
>     +void<br>
>     +rtems_bdbuf_peek (rtems_disk_device *dd,<br>
>     +                  rtems_blkdev_bnum block,<br>
>     +                  uint32_t nr_blocks)<br>
>     +{<br>
>     +  rtems_bdbuf_lock_cache ();<br>
>     +<br>
>     +  if (bdbuf_cache.read_ahead_enabled)<br>
>     +  {<br>
>     +    rtems_bdbuf_read_ahead_reset(dd);<br>
>     +    dd->read_ahead.next = block;<br>
>     +    dd->read_ahead.nr_blocks = nr_blocks;<br>
>     +    rtems_bdbuf_read_ahead_add_to_chain(dd);<br>
>     +  }<br>
>     +<br>
>     +  rtems_bdbuf_unlock_cache ();<br>
>     +}<br>
>     +<br>
>       static rtems_status_code<br>
>       rtems_bdbuf_check_bd_and_lock_cache (rtems_bdbuf_buffer *bd, const<br>
>     char *kind)<br>
>       {<br>
>     @@ -2952,18 +2977,33 @@ rtems_bdbuf_read_ahead_task<br>
>     (rtems_task_argument arg)<br>
> <br>
>               if (bd != NULL)<br>
>               {<br>
>     -          uint32_t transfer_count = dd->block_count - block;<br>
>     +          uint32_t transfer_count = dd->read_ahead.nr_blocks;<br>
>     +          uint32_t blocks_till_end_of_disk = dd->block_count - block;<br>
> <br>
> <br>
> Use "until" or "til" with one l. "Till" means something else (like a <br>
> cashier's register).<br>
<br>
OK. Thanks for the correction.<br>
<br>
> <br>
>                 uint32_t max_transfer_count =<br>
>     bdbuf_config.max_read_ahead_blocks;<br>
> <br>
>     -          if (transfer_count >= max_transfer_count)<br>
>     -          {<br>
>     +          if (transfer_count > blocks_till_end_of_disk) {<br>
>     +            transfer_count = blocks_till_end_of_disk;<br>
>     +          }<br>
>     +<br>
>     +          if (transfer_count > max_transfer_count) {<br>
>                   transfer_count = max_transfer_count;<br>
>     -            dd->read_ahead.trigger = block + transfer_count / 2;<br>
>     -            dd->read_ahead.next = block + transfer_count;<br>
>                 }<br>
>     -          else<br>
>     -          {<br>
>     -            dd->read_ahead.trigger = RTEMS_DISK_READ_AHEAD_NO_TRIGGER;<br>
>     +<br>
>     +          if (transfer_count == RTEMS_DISK_READ_AHEAD_SIZE_AUTO) {<br>
>     +            transfer_count = blocks_till_end_of_disk;<br>
>     +<br>
>     +            if (transfer_count >= max_transfer_count)<br>
> <br>
> I think this can only be == by this point?<br>
<br>
Just in the line above, I set it to "blocks_till_end_of_disk". It's <br>
basically to keep the old behavior. But with that it can be bigger then <br>
max_transfer_count.<br>
<br>
Maybe it's better if I do the check for RTEMS_DISK_READ_AHEAD_SIZE_AUTO <br>
first and do the other checks only in the else case. I'll change that.<br>
<br></blockquote><div><br></div><div>Yes, I think that will help reduce the complexity of this logic.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> <br>
>     +            {<br>
>     +              transfer_count = max_transfer_count;<br>
> <br>
> Then, this is redundant.<br>
> <br>
>     +              dd->read_ahead.trigger = block + transfer_count / 2;<br>
>     +              dd->read_ahead.next = block + transfer_count;<br>
>     +            }<br>
>     +            else<br>
>     +            {<br>
>     +              dd->read_ahead.trigger =<br>
>     RTEMS_DISK_READ_AHEAD_NO_TRIGGER;<br>
>     +            }<br>
>     +          } else {<br>
>     +            ++dd->stats.read_ahead_transfers_with_size;<br>
>                 }<br>
> <br>
>                 ++dd->stats.read_ahead_transfers;<br>
>     diff --git a/cpukit/libblock/src/blkdev-print-stats.c<br>
>     b/cpukit/libblock/src/blkdev-print-stats.c<br>
>     index 8edf24fd8c..8e07e97b68 100644<br>
>     --- a/cpukit/libblock/src/blkdev-print-stats.c<br>
>     +++ b/cpukit/libblock/src/blkdev-print-stats.c<br>
>     @@ -40,25 +40,27 @@ void rtems_blkdev_print_stats(<br>
>            printer,<br>
>           <br>
>     "-------------------------------------------------------------------------------\n"<br>
>            "                               DEVICE STATISTICS\n"<br>
>     -   <br>
>       "----------------------+--------------------------------------------------------\n"<br>
>     -     " MEDIA BLOCK SIZE     | %" PRIu32 "\n"<br>
>     -     " MEDIA BLOCK COUNT    | %" PRIu32 "\n"<br>
>     -     " BLOCK SIZE           | %" PRIu32 "\n"<br>
>     -     " READ HITS            | %" PRIu32 "\n"<br>
>     -     " READ MISSES          | %" PRIu32 "\n"<br>
>     -     " READ AHEAD TRANSFERS | %" PRIu32 "\n"<br>
>     -     " READ BLOCKS          | %" PRIu32 "\n"<br>
>     -     " READ ERRORS          | %" PRIu32 "\n"<br>
>     -     " WRITE TRANSFERS      | %" PRIu32 "\n"<br>
>     -     " WRITE BLOCKS         | %" PRIu32 "\n"<br>
>     -     " WRITE ERRORS         | %" PRIu32 "\n"<br>
>     -   <br>
>       "----------------------+--------------------------------------------------------\n",<br>
>     +   <br>
>       "--------------------------------+----------------------------------------------\n"<br>
>     +     " MEDIA BLOCK SIZE               | %" PRIu32 "\n"<br>
>     +     " MEDIA BLOCK COUNT              | %" PRIu32 "\n"<br>
>     +     " BLOCK SIZE                     | %" PRIu32 "\n"<br>
>     +     " READ HITS                      | %" PRIu32 "\n"<br>
>     +     " READ MISSES                    | %" PRIu32 "\n"<br>
>     +     " READ AHEAD TRANSFERS           | %" PRIu32 "\n"<br>
>     +     " READ AHEAD TRANSFERS WITH SIZE | %" PRIu32 "\n"<br>
>     +     " READ BLOCKS                    | %" PRIu32 "\n"<br>
>     +     " READ ERRORS                    | %" PRIu32 "\n"<br>
>     +     " WRITE TRANSFERS                | %" PRIu32 "\n"<br>
>     +     " WRITE BLOCKS                   | %" PRIu32 "\n"<br>
>     +     " WRITE ERRORS                   | %" PRIu32 "\n"<br>
>     +   <br>
>       "--------------------------------+----------------------------------------------\n",<br>
>            media_block_size,<br>
>            media_block_count,<br>
>            block_size,<br>
>            stats->read_hits,<br>
>            stats->read_misses,<br>
>            stats->read_ahead_transfers,<br>
>     +     stats->read_ahead_transfers_with_size,<br>
>            stats->read_blocks,<br>
>            stats->read_errors,<br>
>            stats->write_transfers,<br>
>     diff --git a/testsuites/fstests/fsdosfswrite01/init.c<br>
>     b/testsuites/fstests/fsdosfswrite01/init.c<br>
>     index e5d8e5d6dd..e87289cf6d 100644<br>
>     --- a/testsuites/fstests/fsdosfswrite01/init.c<br>
>     +++ b/testsuites/fstests/fsdosfswrite01/init.c<br>
>     @@ -126,34 +126,37 @@ static void test_normal_file_write(<br>
>         const char *file_name )<br>
>       {<br>
>         static const rtems_blkdev_stats complete_existing_block_stats = {<br>
>     -    .read_hits            = 0,<br>
>     -    .read_misses          = 0,<br>
>     -    .read_ahead_transfers = 0,<br>
>     -    .read_blocks          = 0,<br>
>     -    .read_errors          = 0,<br>
>     -    .write_transfers      = 1,<br>
>     -    .write_blocks         = 1,<br>
>     -    .write_errors         = 0<br>
>     +    .read_hits                      = 0,<br>
>     +    .read_misses                    = 0,<br>
>     +    .read_ahead_transfers           = 0,<br>
>     +    .read_ahead_transfers_with_size = 0,<br>
>     +    .read_blocks                    = 0,<br>
>     +    .read_errors                    = 0,<br>
>     +    .write_transfers                = 1,<br>
>     +    .write_blocks                   = 1,<br>
>     +    .write_errors                   = 0<br>
>         };<br>
>         static const rtems_blkdev_stats complete_new_block_stats = {<br>
>     -    .read_hits            = 3,<br>
>     -    .read_misses          = 2,<br>
>     -    .read_ahead_transfers = 0,<br>
>     -    .read_blocks          = 2,<br>
>     -    .read_errors          = 0,<br>
>     -    .write_transfers      = 1,<br>
>     -    .write_blocks         = 3,<br>
>     -    .write_errors         = 0<br>
>     +    .read_hits                      = 3,<br>
>     +    .read_misses                    = 2,<br>
>     +    .read_ahead_transfers           = 0,<br>
>     +    .read_ahead_transfers_with_size = 0,<br>
>     +    .read_blocks                    = 2,<br>
>     +    .read_errors                    = 0,<br>
>     +    .write_transfers                = 1,<br>
>     +    .write_blocks                   = 3,<br>
>     +    .write_errors                   = 0<br>
>         };<br>
>         static const rtems_blkdev_stats partial_new_block_stats = {<br>
>     -    .read_hits            = 3,<br>
>     -    .read_misses          = 3,<br>
>     -    .read_ahead_transfers = 0,<br>
>     -    .read_blocks          = 3,<br>
>     -    .read_errors          = 0,<br>
>     -    .write_transfers      = 1,<br>
>     -    .write_blocks         = 3,<br>
>     -    .write_errors         = 0<br>
>     +    .read_hits                      = 3,<br>
>     +    .read_misses                    = 3,<br>
>     +    .read_ahead_transfers           = 0,<br>
>     +    .read_ahead_transfers_with_size = 0,<br>
>     +    .read_blocks                    = 3,<br>
>     +    .read_errors                    = 0,<br>
>     +    .write_transfers                = 1,<br>
>     +    .write_blocks                   = 3,<br>
>     +    .write_errors                   = 0<br>
>         };<br>
> <br>
>         int                             rv;<br>
>     diff --git a/testsuites/libtests/block14/block14.scn<br>
>     b/testsuites/libtests/block14/block14.scn<br>
>     index 7170522579..48c22b716d 100644<br>
>     --- a/testsuites/libtests/block14/block14.scn<br>
>     +++ b/testsuites/libtests/block14/block14.scn<br>
>     @@ -6,19 +6,30 @@ action 3<br>
>       action 4<br>
>       action 5<br>
>       action 6<br>
>     +action 7<br>
>     +action 8<br>
>     +action 9<br>
>     +action 10<br>
>     +action 11<br>
>     +action 12<br>
>     +action 13<br>
>     +action 14<br>
>     +action 15<br>
>       -------------------------------------------------------------------------------<br>
>                                      DEVICE STATISTICS<br>
>     -----------------------+--------------------------------------------------------<br>
>     - MEDIA BLOCK SIZE     | 0<br>
>     - MEDIA BLOCK COUNT    | 1<br>
>     - BLOCK SIZE           | 2<br>
>     - READ HITS            | 2<br>
>     - READ MISSES          | 3<br>
>     - READ AHEAD TRANSFERS | 2<br>
>     - READ BLOCKS          | 5<br>
>     - READ ERRORS          | 1<br>
>     - WRITE TRANSFERS      | 2<br>
>     - WRITE BLOCKS         | 2<br>
>     - WRITE ERRORS         | 1<br>
>     -----------------------+--------------------------------------------------------<br>
>     +--------------------------------+----------------------------------------------<br>
>     + MEDIA BLOCK SIZE               | 0<br>
>     + MEDIA BLOCK COUNT              | 1<br>
>     + BLOCK SIZE                     | 2<br>
>     + READ HITS                      | 4<br>
>     + READ MISSES                    | 7<br>
>     + READ AHEAD TRANSFERS           | 6<br>
>     + READ AHEAD TRANSFERS WITH SIZE | 3<br>
>     + READ BLOCKS                    | 13<br>
>     + READ ERRORS                    | 1<br>
>     + WRITE TRANSFERS                | 2<br>
>     + WRITE BLOCKS                   | 2<br>
>     + WRITE ERRORS                   | 1<br>
>     +--------------------------------+----------------------------------------------<br>
>     +<br>
>       *** END OF TEST BLOCK 14 ***<br>
>     diff --git a/testsuites/libtests/block14/init.c<br>
>     b/testsuites/libtests/block14/init.c<br>
>     index b4e73aadc9..24441c4fe8 100644<br>
>     --- a/testsuites/libtests/block14/init.c<br>
>     +++ b/testsuites/libtests/block14/init.c<br>
>     @@ -29,9 +29,9 @@<br>
> <br>
>       const char rtems_test_name[] = "BLOCK 14";<br>
> <br>
>     -#define ACTION_COUNT 7<br>
>     +#define ACTION_COUNT 16<br>
> <br>
>     -#define BLOCK_COUNT 6<br>
>     +#define BLOCK_COUNT 14<br>
> <br>
>       #define DISK_PATH "/disk"<br>
> <br>
>     @@ -42,50 +42,104 @@ typedef struct {<br>
>           rtems_blkdev_bnum block,<br>
>           rtems_bdbuf_buffer **bd_ptr<br>
>         );<br>
>     +  void (*peek)(<br>
>     +    rtems_disk_device *dd,<br>
>     +    rtems_blkdev_bnum block,<br>
>     +    uint32_t nr_blocks<br>
>     +  );<br>
>         rtems_status_code expected_get_status;<br>
>         rtems_status_code (*release)(rtems_bdbuf_buffer *bd);<br>
>       } test_action;<br>
> <br>
>       static const test_action actions [ACTION_COUNT] = {<br>
>     -  { 0, rtems_bdbuf_read, RTEMS_SUCCESSFUL, rtems_bdbuf_release },<br>
>     -  { 1, rtems_bdbuf_read, RTEMS_SUCCESSFUL, rtems_bdbuf_release },<br>
>     -  { 2, rtems_bdbuf_read, RTEMS_SUCCESSFUL, rtems_bdbuf_release },<br>
>     -  { 0, rtems_bdbuf_read, RTEMS_SUCCESSFUL, rtems_bdbuf_release },<br>
>     -  { 4, rtems_bdbuf_get, RTEMS_SUCCESSFUL, rtems_bdbuf_sync },<br>
>     -  { 5, rtems_bdbuf_read, RTEMS_IO_ERROR, rtems_bdbuf_release },<br>
>     -  { 5, rtems_bdbuf_get, RTEMS_SUCCESSFUL, rtems_bdbuf_sync }<br>
>     +  /* normal read ahead */<br>
>     +  { 0, rtems_bdbuf_read, NULL, RTEMS_SUCCESSFUL, rtems_bdbuf_release },<br>
>     +  { 1, rtems_bdbuf_read, NULL, RTEMS_SUCCESSFUL, rtems_bdbuf_release },<br>
>     +  { 2, rtems_bdbuf_read, NULL, RTEMS_SUCCESSFUL, rtems_bdbuf_release },<br>
>     +<br>
>     +  /* re-read a cached block */<br>
>     +  { 0, rtems_bdbuf_read, NULL, RTEMS_SUCCESSFUL, rtems_bdbuf_release },<br>
>     +<br>
>     +  /* cause some writes */<br>
>     +  { 4, rtems_bdbuf_get, NULL, RTEMS_SUCCESSFUL, rtems_bdbuf_sync },<br>
>     +  { 5, rtems_bdbuf_read, NULL, RTEMS_IO_ERROR, rtems_bdbuf_release },<br>
>     +  { 5, rtems_bdbuf_get, NULL, RTEMS_SUCCESSFUL, rtems_bdbuf_sync },<br>
>     +<br>
>     +  /* interrupt normal read ahead with a peek */<br>
>     +  { 9, rtems_bdbuf_read, NULL, RTEMS_SUCCESSFUL, rtems_bdbuf_release },<br>
>     +  { 13, NULL, rtems_bdbuf_peek, 0, NULL },<br>
>     +  { 10, rtems_bdbuf_read, NULL, RTEMS_SUCCESSFUL,<br>
>     rtems_bdbuf_release },<br>
>     +  { 11, rtems_bdbuf_read, NULL, RTEMS_SUCCESSFUL,<br>
>     rtems_bdbuf_release },<br>
>     +  { 12, rtems_bdbuf_read, NULL, RTEMS_SUCCESSFUL,<br>
>     rtems_bdbuf_release },<br>
>     +<br>
>     +  /* peek with hit */<br>
>     +  { 6, NULL, rtems_bdbuf_peek, 0, NULL },<br>
>     +  { 6, rtems_bdbuf_read, NULL, RTEMS_SUCCESSFUL, rtems_bdbuf_release },<br>
>     +<br>
>     +  /* (wrong) peek with reading different block */<br>
>     +  { 8, NULL, rtems_bdbuf_peek, 0, NULL },<br>
>     +  { 7, rtems_bdbuf_read, NULL, RTEMS_SUCCESSFUL, rtems_bdbuf_release },<br>
>       };<br>
> <br>
>     -#define STATS(a, b, c, d, e, f, g, h) \<br>
>     +#define STATS(a, b, c, d, e, f, g, h, i) \<br>
>         { \<br>
>           .read_hits = a, \<br>
>           .read_misses = b, \<br>
>           .read_ahead_transfers = c, \<br>
>     -    .read_blocks = d, \<br>
>     -    .read_errors = e, \<br>
>     -    .write_transfers = f, \<br>
>     -    .write_blocks = g, \<br>
>     -    .write_errors = h \<br>
>     +    .read_ahead_transfers_with_size = d, \<br>
>     +    .read_blocks = e, \<br>
>     +    .read_errors = f, \<br>
>     +    .write_transfers = g, \<br>
>     +    .write_blocks = h, \<br>
>     +    .write_errors = i \<br>
>         }<br>
> <br>
>       static const rtems_blkdev_stats expected_stats [ACTION_COUNT] = {<br>
>     -  STATS(0, 1, 0, 1, 0, 0, 0, 0),<br>
>     -  STATS(0, 2, 1, 3, 0, 0, 0, 0),<br>
>     -  STATS(1, 2, 2, 4, 0, 0, 0, 0),<br>
>     -  STATS(2, 2, 2, 4, 0, 0, 0, 0),<br>
>     -  STATS(2, 2, 2, 4, 0, 1, 1, 0),<br>
>     -  STATS(2, 3, 2, 5, 1, 1, 1, 0),<br>
>     -  STATS(2, 3, 2, 5, 1, 2, 2, 1)<br>
>     +  STATS(0, 1, 0, 0, 1, 0, 0, 0, 0),<br>
>     +  STATS(0, 2, 1, 0, 3, 0, 0, 0, 0),<br>
>     +  STATS(1, 2, 2, 0, 4, 0, 0, 0, 0),<br>
>     +<br>
>     +  STATS(2, 2, 2, 0, 4, 0, 0, 0, 0),<br>
>     +<br>
>     +  STATS(2, 2, 2, 0, 4, 0, 1, 1, 0),<br>
>     +  STATS(2, 3, 2, 0, 5, 1, 1, 1, 0),<br>
>     +  STATS(2, 3, 2, 0, 5, 1, 2, 2, 1),<br>
>     +<br>
>     +  STATS(2, 4, 2, 0, 6, 1, 2, 2, 1),<br>
>     +  STATS(2, 4, 3, 1, 7, 1, 2, 2, 1),<br>
>     +  STATS(2, 5, 3, 1, 8, 1, 2, 2, 1),<br>
>     +  STATS(2, 6, 4, 1, 10, 1, 2, 2, 1),<br>
>     +  STATS(3, 6, 4, 1, 10, 1, 2, 2, 1),<br>
>     +<br>
>     +  STATS(3, 6, 5, 2, 11, 1, 2, 2, 1),<br>
>     +  STATS(4, 6, 5, 2, 11, 1, 2, 2, 1),<br>
>     +<br>
>     +  STATS(4, 6, 6, 3, 12, 1, 2, 2, 1),<br>
>     +  STATS(4, 7, 6, 3, 13, 1, 2, 2, 1),<br>
>       };<br>
> <br>
>       static const int expected_block_access_counts [ACTION_COUNT]<br>
>     [BLOCK_COUNT] = {<br>
>     -   { 1, 0, 0, 0, 0, 0 },<br>
>     -   { 1, 1, 1, 0, 0, 0 },<br>
>     -   { 1, 1, 1, 1, 0, 0 },<br>
>     -   { 1, 1, 1, 1, 0, 0 },<br>
>     -   { 1, 1, 1, 1, 1, 0 },<br>
>     -   { 1, 1, 1, 1, 1, 1 },<br>
>     -   { 1, 1, 1, 1, 1, 2 }<br>
>     +   { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },<br>
>     +   { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },<br>
>     +   { 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },<br>
>     +<br>
>     +   { 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },<br>
>     +<br>
>     +   { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },<br>
>     +   { 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },<br>
>     +   { 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0 },<br>
>     +<br>
>     +   { 1, 1, 1, 1, 1, 2, 0, 0, 0, 1, 0, 0, 0, 0 },<br>
>     +   { 1, 1, 1, 1, 1, 2, 0, 0, 0, 1, 0, 0, 0, 1 },<br>
>     +   { 1, 1, 1, 1, 1, 2, 0, 0, 0, 1, 1, 0, 0, 1 },<br>
>     +   { 1, 1, 1, 1, 1, 2, 0, 0, 0, 1, 1, 1, 1, 1 },<br>
>     +   { 1, 1, 1, 1, 1, 2, 0, 0, 0, 1, 1, 1, 1, 1 },<br>
>     +<br>
>     +   { 1, 1, 1, 1, 1, 2, 1, 0, 0, 1, 1, 1, 1, 1 },<br>
>     +   { 1, 1, 1, 1, 1, 2, 1, 0, 0, 1, 1, 1, 1, 1 },<br>
>     +<br>
>     +   { 1, 1, 1, 1, 1, 2, 1, 0, 1, 1, 1, 1, 1, 1 },<br>
>     +   { 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1 },<br>
>       };<br>
> <br>
>       static int block_access_counts [BLOCK_COUNT];<br>
>     @@ -132,10 +186,16 @@ static void test_actions(rtems_disk_device *dd)<br>
> <br>
>           printf("action %i\n", i);<br>
> <br>
>     -    sc = (*action->get)(dd, action->block, &bd);<br>
>     -    rtems_test_assert(sc == action->expected_get_status);<br>
>     +    if (action->get != NULL) {<br>
>     +      sc = (*action->get)(dd, action->block, &bd);<br>
>     +      rtems_test_assert(sc == action->expected_get_status);<br>
>     +    }<br>
>     +<br>
>     +    if (action->peek != NULL) {<br>
>     +      (*action->peek)(dd, action->block, 1);<br>
>     +    }<br>
> <br>
>     -    if (sc == RTEMS_SUCCESSFUL) {<br>
>     +    if (sc == RTEMS_SUCCESSFUL && action->release != NULL) {<br>
>             sc = (*action->release)(bd);<br>
>             rtems_test_assert(sc == RTEMS_SUCCESSFUL);<br>
>           }<br>
>     -- <br>
>     2.26.2<br>
> <br>
>     _______________________________________________<br>
>     devel mailing list<br>
>     <a href="mailto:devel@rtems.org" target="_blank">devel@rtems.org</a> <mailto:<a href="mailto:devel@rtems.org" target="_blank">devel@rtems.org</a>><br>
>     <a href="http://lists.rtems.org/mailman/listinfo/devel" rel="noreferrer" target="_blank">http://lists.rtems.org/mailman/listinfo/devel</a><br>
>     <<a href="http://lists.rtems.org/mailman/listinfo/devel" rel="noreferrer" target="_blank">http://lists.rtems.org/mailman/listinfo/devel</a>><br>
> <br>
<br>
-- <br>
--------------------------------------------<br>
embedded brains GmbH<br>
Herr Christian MAUDERER<br>
Dornierstr. 4<br>
82178 Puchheim<br>
Germany<br>
email: <a href="mailto:christian.mauderer@embedded-brains.de" target="_blank">christian.mauderer@embedded-brains.de</a><br>
phone: +49-89-18 94 741 - 18<br>
fax:   +49-89-18 94 741 - 08<br>
<br>
Registergericht: Amtsgericht München<br>
Registernummer: HRB 157899<br>
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler<br>
Unsere Datenschutzerklärung finden Sie hier:<br>
<a href="https://embedded-brains.de/datenschutzerklaerung/" rel="noreferrer" target="_blank">https://embedded-brains.de/datenschutzerklaerung/</a><br>
</blockquote></div></div>