Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:32

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * Copyright (C) 2012, 2018 embedded brains GmbH & Co. KG
0005  *
0006  * Redistribution and use in source and binary forms, with or without
0007  * modification, are permitted provided that the following conditions
0008  * are met:
0009  * 1. Redistributions of source code must retain the above copyright
0010  *    notice, this list of conditions and the following disclaimer.
0011  * 2. Redistributions in binary form must reproduce the above copyright
0012  *    notice, this list of conditions and the following disclaimer in the
0013  *    documentation and/or other materials provided with the distribution.
0014  *
0015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0025  * POSSIBILITY OF SUCH DAMAGE.
0026  */
0027 
0028 #ifdef HAVE_CONFIG_H
0029 #include "config.h"
0030 #endif
0031 
0032 #include "tmacros.h"
0033 
0034 #include <sys/stat.h>
0035 #include <assert.h>
0036 #include <errno.h>
0037 #include <fcntl.h>
0038 #include <string.h>
0039 #include <unistd.h>
0040 
0041 #include <rtems/bdbuf.h>
0042 
0043 const char rtems_test_name[] = "BLOCK 13";
0044 
0045 #define BLOCK_COUNT 11
0046 #define READ_COUNT 23
0047 
0048 #define DISK_PATH "/disk"
0049 
0050 static int block_access_counts [BLOCK_COUNT];
0051 
0052 #define RESET_CACHE (-1)
0053 
0054 static const int action_sequence [READ_COUNT] = {
0055   0, 2, 3, 4, 5, 6, 7, 8, 9, 10,
0056   RESET_CACHE,
0057   10,
0058   RESET_CACHE,
0059   9,
0060   RESET_CACHE,
0061   8,
0062   RESET_CACHE,
0063   7, 8,
0064   RESET_CACHE,
0065   6, 7, 9
0066 };
0067 
0068 #define UNUSED_LINE { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
0069 
0070 static const int expected_block_access_counts [READ_COUNT] [BLOCK_COUNT] = {
0071    { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
0072    { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
0073    { 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
0074    { 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
0075    { 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
0076    { 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
0077    { 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
0078    { 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
0079    { 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
0080    { 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
0081    UNUSED_LINE,
0082    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
0083    UNUSED_LINE,
0084    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 },
0085    UNUSED_LINE,
0086    { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
0087    UNUSED_LINE,
0088    { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
0089    { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1 },
0090    UNUSED_LINE,
0091    { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 },
0092    { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1 },
0093    { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1 }
0094 };
0095 
0096 #define NO_TRIGGER RTEMS_DISK_READ_AHEAD_NO_TRIGGER
0097 
0098 #define TRIGGER_AFTER_RESET RTEMS_DISK_READ_AHEAD_NO_TRIGGER
0099 
0100 static const rtems_blkdev_bnum trigger [READ_COUNT] = {
0101   1, 3, 5, 5, 8, 8, 8, NO_TRIGGER, NO_TRIGGER, NO_TRIGGER,
0102   TRIGGER_AFTER_RESET,
0103   11,
0104   TRIGGER_AFTER_RESET,
0105   10,
0106   TRIGGER_AFTER_RESET,
0107   9,
0108   TRIGGER_AFTER_RESET,
0109   8, NO_TRIGGER,
0110   TRIGGER_AFTER_RESET,
0111   7, 9, NO_TRIGGER
0112 };
0113 
0114 #define NOT_CHANGED_BY_RESET(i) (i)
0115 
0116 static const rtems_blkdev_bnum next [READ_COUNT] = {
0117   2, 4, 7, 7, 10, 10, 10, 10, 10, 10,
0118   NOT_CHANGED_BY_RESET(10),
0119   12,
0120   NOT_CHANGED_BY_RESET(12),
0121   11,
0122   NOT_CHANGED_BY_RESET(11),
0123   10,
0124   NOT_CHANGED_BY_RESET(10),
0125   9, 9,
0126   NOT_CHANGED_BY_RESET(9),
0127   8, 11, 11
0128 };
0129 
0130 static int test_disk_ioctl(rtems_disk_device *dd, uint32_t req, void *arg)
0131 {
0132   int rv = 0;
0133 
0134   if (req == RTEMS_BLKIO_REQUEST) {
0135     rtems_blkdev_request *breq = arg;
0136     rtems_blkdev_sg_buffer *sg = breq->bufs;
0137     uint32_t i;
0138 
0139     rtems_test_assert(breq->req == RTEMS_BLKDEV_REQ_READ);
0140 
0141     for (i = 0; i < breq->bufnum; ++i) {
0142       rtems_blkdev_bnum block = sg [i].block;
0143 
0144       rtems_test_assert(block < BLOCK_COUNT);
0145 
0146       ++block_access_counts [block];
0147     }
0148 
0149     rtems_blkdev_request_done(breq, RTEMS_SUCCESSFUL);
0150   } else {
0151     rv = rtems_blkdev_ioctl(dd, req, arg);
0152   }
0153 
0154   return rv;
0155 }
0156 
0157 static void test_read_ahead(rtems_disk_device *dd)
0158 {
0159   int i;
0160 
0161   for (i = 0; i < READ_COUNT; ++i) {
0162     int action = action_sequence [i];
0163 
0164     if (action != RESET_CACHE) {
0165       rtems_blkdev_bnum block = (rtems_blkdev_bnum) action;
0166       rtems_status_code sc;
0167       rtems_bdbuf_buffer *bd;
0168 
0169       printf("%i ", action);
0170 
0171       sc = rtems_bdbuf_read(dd, block, &bd);
0172       rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0173 
0174       sc = rtems_bdbuf_release(bd);
0175       rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0176 
0177       rtems_test_assert(
0178         memcmp(
0179           block_access_counts,
0180           expected_block_access_counts [i],
0181           sizeof(block_access_counts)
0182         ) == 0
0183       );
0184     } else {
0185       printf("\nreset\n");
0186 
0187       rtems_bdbuf_purge_dev(dd);
0188       memset(&block_access_counts, 0, sizeof(block_access_counts));
0189     }
0190 
0191     rtems_test_assert(trigger [i] == dd->read_ahead.trigger);
0192     rtems_test_assert(next [i] == dd->read_ahead.next);
0193   }
0194 
0195   printf("\n");
0196 }
0197 
0198 static void test(void)
0199 {
0200   rtems_status_code sc;
0201   rtems_disk_device *dd;
0202   int fd;
0203   int rv;
0204 
0205   sc = rtems_blkdev_create(
0206     DISK_PATH,
0207     1,
0208     BLOCK_COUNT,
0209     test_disk_ioctl,
0210     NULL
0211   );
0212   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0213 
0214   fd = open(DISK_PATH, O_RDWR);
0215   rtems_test_assert(fd >= 0);
0216 
0217   rv = rtems_disk_fd_get_disk_device(fd, &dd);
0218   rtems_test_assert(rv == 0);
0219 
0220   rv = close(fd);
0221   rtems_test_assert(rv == 0);
0222 
0223   test_read_ahead(dd);
0224 
0225   rv = unlink(DISK_PATH);
0226   rtems_test_assert(rv == 0);
0227 }
0228 
0229 static void Init(rtems_task_argument arg)
0230 {
0231   TEST_BEGIN();
0232 
0233   test();
0234 
0235   TEST_END();
0236 
0237   rtems_test_exit(0);
0238 }
0239 
0240 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0241 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0242 #define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
0243 
0244 #define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 4
0245 
0246 #define CONFIGURE_BDBUF_BUFFER_MIN_SIZE 1
0247 #define CONFIGURE_BDBUF_BUFFER_MAX_SIZE 1
0248 #define CONFIGURE_BDBUF_CACHE_MEMORY_SIZE BLOCK_COUNT
0249 #define CONFIGURE_BDBUF_MAX_READ_AHEAD_BLOCKS 3
0250 #define CONFIGURE_BDBUF_READ_AHEAD_TASK_PRIORITY 1
0251 
0252 #define CONFIGURE_MAXIMUM_TASKS 1
0253 
0254 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0255 
0256 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0257 
0258 #define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
0259 #define CONFIGURE_INIT_TASK_PRIORITY 2
0260 
0261 #define CONFIGURE_INIT
0262 
0263 #include <rtems/confdefs.h>