Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*! @file
0004  * @brief Check how rtems_bdbuf_read() handles two readers waiting
0005  * for a buffer with the same block number in cases when disk device
0006  * driver reports failure in read complete notification.
0007  *
0008  * Test sequence:
0009  * -# Call rtems_bdbuf_read() function in thread #1 and block on
0010  *    waiting for read complete notification.
0011  * -# Call rtems_bdbuf_read() function in thread #2 for the same
0012  *    block number. As the result it blocks on this read as well
0013  *    (but it will block on transfer semaphore).
0014  * -# Disk device reports an error in read complete notification.
0015  *    As the result an error is returned from rtems_bdbuf_read() in
0016  *    thread #1.
0017  * -# rtems_bdbuf_read() called in thread #2 should try to re-read
0018  *    data again so disk device ioctl() function is called again for
0019  *    this block number.
0020  * -# Disk device reports an error in read complete notification.
0021  *    As the result an error is returned from rtems_bdbuf_read()
0022  *    in thread #2.
0023  * .
0024  *
0025  * Copyright (C) 2010 OKTET Labs, St.-Petersburg, Russia
0026  * Author: Oleg Kravtsov <Oleg.Kravtsov@oktetlabs.ru>
0027  *
0028  * Redistribution and use in source and binary forms, with or without
0029  * modification, are permitted provided that the following conditions
0030  * are met:
0031  * 1. Redistributions of source code must retain the above copyright
0032  *    notice, this list of conditions and the following disclaimer.
0033  * 2. Redistributions in binary form must reproduce the above copyright
0034  *    notice, this list of conditions and the following disclaimer in the
0035  *    documentation and/or other materials provided with the distribution.
0036  *
0037  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0038  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0039  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0040  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0041  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0042  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0043  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0044  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0045  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0046  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0047  * POSSIBILITY OF SUCH DAMAGE.
0048  */
0049 
0050 #ifdef HAVE_CONFIG_H
0051 #include "config.h"
0052 #endif
0053 
0054 #include "bdbuf_tests.h"
0055 
0056 static rtems_task bdbuf_test1_2_thread1(rtems_task_argument arg);
0057 static rtems_task bdbuf_test1_2_thread2(rtems_task_argument arg);
0058 
0059 #define TEST_BLK_NUM 20
0060 
0061 void
0062 bdbuf_test1_2_main()
0063 {
0064     bdbuf_test_msg msg;
0065 
0066     TEST_START("Test 1.2");
0067 
0068     START_THREAD(1, bdbuf_test1_2_thread1);
0069     START_THREAD(2, bdbuf_test1_2_thread2);
0070 
0071     /*
0072      * Step 1:
0073      * Thread #1 calls rtems_bdbuf_read() and we block
0074      * this thread on data transfer operation.
0075      */
0076     WAIT_DRV_MSG(&msg);
0077 
0078     /*
0079      * Step 2:
0080      * Thread #2 calls rtems_bdbuf_read() for the same
0081      * block number, as the result it shall block waiting
0082      * on buffer state change.
0083      */
0084     CONTINUE_THREAD(2);
0085 
0086     /* Make sure thread #2 managed to block on the buffer. */
0087     CHECK_THREAD_BLOCKED(2);
0088 
0089     /*
0090      * Step 3:
0091      * Unblock thread #1 by reporting data transfer result.
0092      */
0093     SEND_DRV_MSG(0, 0, RTEMS_IO_ERROR, EFAULT);
0094 
0095     /*
0096      * Wait for sync from thread #1.
0097      */
0098     WAIT_THREAD_SYNC(1);
0099     CONTINUE_THREAD(1);
0100     TEST_CHECK_RESULT("3");
0101 
0102     /*
0103      * Step 4:
0104      * For thread #2 bdbuf shall try to re-read data.
0105      * As the result we will get read call to device driver.
0106      */
0107     WAIT_DRV_MSG(&msg);
0108 
0109     /* Check that thread #2 is still blocked */
0110     CHECK_THREAD_BLOCKED(2);
0111     /*
0112      * Step 5:
0113      * Report an error again from the driver.
0114      */
0115     SEND_DRV_MSG(0, 0, RTEMS_IO_ERROR, EFAULT);
0116 
0117     /*
0118      * Wait for sync from thread #2.
0119      */
0120     WAIT_THREAD_SYNC(2);
0121     CONTINUE_THREAD(2);
0122     TEST_CHECK_RESULT("5");
0123 
0124     TEST_STOP();
0125 }
0126 
0127 static rtems_task
0128 bdbuf_test1_2_thread1(rtems_task_argument arg)
0129 {
0130     rtems_status_code   rc;
0131     rtems_bdbuf_buffer *bd = NULL;
0132 
0133     /*
0134      * Step 1 - 3:
0135      * Try to read blk #N on thread #1
0136      * We will block on this read and meanwhile
0137      * thread #2 will try to read the same block.
0138      * After blocking on read in thread #2, device
0139      * driver will notify about an error, and as the
0140      * result this call will return an error.
0141      */
0142     rc = rtems_bdbuf_read(test_dd, TEST_BLK_NUM, &bd);
0143     if (rc != RTEMS_IO_ERROR || bd != NULL)
0144     {
0145         TEST_FAILED();
0146     }
0147 
0148     CONTINUE_MAIN(1);
0149 
0150     THREAD_END();
0151 }
0152 
0153 static rtems_task
0154 bdbuf_test1_2_thread2(rtems_task_argument arg)
0155 {
0156     rtems_status_code   rc;
0157     rtems_bdbuf_buffer *bd = NULL;
0158 
0159     WAIT_MAIN_SYNC(2);
0160 
0161     /*
0162      * Step 2:
0163      * Try to read block #N. Right now thread #1 is waiting
0164      * on data transfer operation, so we will block here as well.
0165      *
0166      * Step 4:
0167      * Due to the fact that thread #1 failed to read required block
0168      * number, bdbuf library should ask for re-read data again.
0169      * But main test task will agin tell device driver to return
0170      * RTEMS_IO_ERROR data transfer result.
0171      */
0172     rc = rtems_bdbuf_read(test_dd, TEST_BLK_NUM, &bd);
0173     if (rc != RTEMS_IO_ERROR || bd != NULL)
0174     {
0175         TEST_FAILED();
0176     }
0177 
0178     CONTINUE_MAIN(2);
0179 
0180     THREAD_END();
0181 }