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 that when there are some tasks waiting for an available
0005  * buffer only one of them get a buffer after some other task releases one.
0006  *
0007  * Test sequence:
0008  * -# Call rtems_bdbuf_read(#N1) in thread #1.
0009  * -# Call rtems_bdbuf_get(#N2) in thread #2.
0010  *    This thread blocks because we have no buffers available.
0011  * -# Call rtems_bdbuf_get(#N3) in thread #3.
0012  *    This thread also blocks because we have no buffers available.
0013  * -# Call rtems_bdbuf_release_modified(#N1) in thread #1.
0014  * -# Check that only one thread (thread #2 or thread #3) got a buffer.
0015  *     Another thread shall still be blocked.
0016  *
0017  * Copyright (C) 2010 OKTET Labs, St.-Petersburg, Russia
0018  * Author: Oleg Kravtsov <Oleg.Kravtsov@oktetlabs.ru>
0019  *
0020  * Redistribution and use in source and binary forms, with or without
0021  * modification, are permitted provided that the following conditions
0022  * are met:
0023  * 1. Redistributions of source code must retain the above copyright
0024  *    notice, this list of conditions and the following disclaimer.
0025  * 2. Redistributions in binary form must reproduce the above copyright
0026  *    notice, this list of conditions and the following disclaimer in the
0027  *    documentation and/or other materials provided with the distribution.
0028  *
0029  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0030  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0031  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0032  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0033  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0034  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0035  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0036  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0037  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0038  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0039  * POSSIBILITY OF SUCH DAMAGE.
0040  */
0041 
0042 #ifdef HAVE_CONFIG_H
0043 #include "config.h"
0044 #endif
0045 
0046 #include "bdbuf_tests.h"
0047 
0048 static rtems_task bdbuf_test3_2_thread1(rtems_task_argument arg);
0049 static rtems_task bdbuf_test3_2_thread2(rtems_task_argument arg);
0050 static rtems_task bdbuf_test3_2_thread3(rtems_task_argument arg);
0051 
0052 /* Block number used in the test */
0053 #define TEST_BLK_NUM_N1 90
0054 #define TEST_BLK_NUM_N2 92
0055 #define TEST_BLK_NUM_N3 94
0056 
0057 void
0058 bdbuf_test3_2_main()
0059 {
0060     bdbuf_test_msg msg;
0061 
0062     TEST_START("Test 3.2");
0063 
0064     /*
0065      * Create working threads.
0066      */
0067     SET_THREAD_PRIORITY(2, LOW);
0068     SET_THREAD_PRIORITY(3, HIGH);
0069     START_THREAD(1, bdbuf_test3_2_thread1);
0070     START_THREAD(2, bdbuf_test3_2_thread2);
0071     START_THREAD(3, bdbuf_test3_2_thread3);
0072 
0073     /*
0074      * Start thread #1: it will read buffer #N1.
0075      * Driver is asked to read this buffer.
0076      */
0077     WAIT_DRV_MSG(&msg);
0078     SEND_DRV_MSG(0, 0, RTEMS_SUCCESSFUL, 0);
0079 
0080     WAIT_THREAD_SYNC(1);
0081 
0082     /*
0083      * Block thread #2 and thread #3 on get buffers #N1 and #N2
0084      * correspondingly.
0085      */
0086     CONTINUE_THREAD(2);
0087     CONTINUE_THREAD(3);
0088 
0089     /* Make sure threads managed to block on the buffers get. */
0090     CHECK_THREAD_BLOCKED(2);
0091     CHECK_THREAD_BLOCKED(3);
0092 
0093     /*
0094      * Step 4:
0095      * Thread #1 release buffer.
0096      */
0097     CONTINUE_THREAD(1);
0098 
0099     /*
0100      * Check that thread #2 unblocked after this.
0101      */
0102     WAIT_THREAD_SYNC(2);
0103     TEST_CHECK_RESULT("5");
0104 
0105     CHECK_THREAD_BLOCKED(3);
0106 
0107     /* Release buffer in thread #2 */
0108     CONTINUE_THREAD(2);
0109 
0110     /* wait for driver message to flush it onto a disk */
0111     WAIT_DRV_MSG_WR(&msg);
0112     SEND_DRV_MSG(0, 0, RTEMS_SUCCESSFUL, 0);
0113 
0114     /* Wait for thread #3 to be unblocked */
0115     WAIT_THREAD_SYNC(3);
0116 
0117     /* Release buffer in thread #3 */
0118     CONTINUE_THREAD(3);
0119 
0120     /* wait for driver message to flush it onto a disk */
0121     WAIT_DRV_MSG_WR(&msg);
0122     SEND_DRV_MSG(0, 0, RTEMS_SUCCESSFUL, 0);
0123 
0124     TEST_STOP();
0125 }
0126 
0127 static rtems_task
0128 bdbuf_test3_2_thread1(rtems_task_argument arg)
0129 {
0130     rtems_status_code   rc;
0131     rtems_bdbuf_buffer *bd = NULL;
0132 
0133     /*
0134      * Step 1:
0135      * Call rtems_bdbuf_read(#N) to get a buffer;
0136      */
0137     rc = rtems_bdbuf_read(test_dd, TEST_BLK_NUM_N1, &bd);
0138     if (rc != RTEMS_SUCCESSFUL)
0139     {
0140         TEST_FAILED();
0141     }
0142 
0143     CONTINUE_MAIN(1);
0144 
0145     /*
0146      * Step 4:
0147      * Call rtems_bdbuf_release(#N).
0148      */
0149     rc = rtems_bdbuf_release(bd);
0150     if (rc != RTEMS_SUCCESSFUL)
0151     {
0152         TEST_FAILED();
0153     }
0154 
0155     THREAD_END();
0156 }
0157 
0158 static rtems_task
0159 bdbuf_test3_2_thread2(rtems_task_argument arg)
0160 {
0161     rtems_status_code   rc;
0162     rtems_bdbuf_buffer *bd = NULL;
0163 
0164     WAIT_MAIN_SYNC(2);
0165 
0166     /*
0167      * Step 2:
0168      * In thread #2 call get(#N2)
0169      */
0170     rc = rtems_bdbuf_get(test_dd, TEST_BLK_NUM_N2, &bd);
0171     if (rc != RTEMS_SUCCESSFUL)
0172     {
0173         TEST_FAILED();
0174     }
0175 
0176     printf("Thread #2 DEBLOCK\n");
0177     CONTINUE_MAIN(2);
0178 
0179     rc = rtems_bdbuf_release_modified(bd);
0180     if (rc != RTEMS_SUCCESSFUL)
0181     {
0182         TEST_FAILED();
0183     }
0184 
0185     THREAD_END();
0186 }
0187 
0188 static rtems_task
0189 bdbuf_test3_2_thread3(rtems_task_argument arg)
0190 {
0191     rtems_status_code   rc;
0192     rtems_bdbuf_buffer *bd = NULL;
0193 
0194     WAIT_MAIN_SYNC(3);
0195 
0196     /*
0197      * Step 3:
0198      * In thread #3 call get(#N3)
0199      */
0200     rc = rtems_bdbuf_get(test_dd, TEST_BLK_NUM_N3, &bd);
0201     if (rc != RTEMS_SUCCESSFUL)
0202     {
0203         TEST_FAILED();
0204     }
0205 
0206     printf("Thread #3 DEBLOCK\n");
0207 
0208     CONTINUE_MAIN(3);
0209 
0210     rc = rtems_bdbuf_release_modified(bd);
0211     if (rc != RTEMS_SUCCESSFUL)
0212     {
0213         TEST_FAILED();
0214     }
0215 
0216     THREAD_END();
0217 }