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