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 Implementation of auxiliary functions of bdbuf tests.
0005  *
0006  * Copyright (C) 2010 OKTET Labs, St.-Petersburg, Russia
0007  * Author: Oleg Kravtsov <Oleg.Kravtsov@oktetlabs.ru>
0008  *
0009  * Redistribution and use in source and binary forms, with or without
0010  * modification, are permitted provided that the following conditions
0011  * are met:
0012  * 1. Redistributions of source code must retain the above copyright
0013  *    notice, this list of conditions and the following disclaimer.
0014  * 2. Redistributions in binary form must reproduce the above copyright
0015  *    notice, this list of conditions and the following disclaimer in the
0016  *    documentation and/or other materials provided with the distribution.
0017  *
0018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0019  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0020  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0021  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0022  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0023  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0024  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0025  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0026  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0027  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0028  * POSSIBILITY OF SUCH DAMAGE.
0029  */
0030 
0031 #ifdef HAVE_CONFIG_H
0032 #include "config.h"
0033 #endif
0034 
0035 #include <sys/stat.h>
0036 #include <stdio.h>
0037 #include <string.h>
0038 #include <errno.h>
0039 #include <fcntl.h>
0040 #include <unistd.h>
0041 
0042 #include <rtems.h>
0043 #include <rtems/io.h>
0044 #include <rtems/bdbuf.h>
0045 #include <rtems/inttypes.h>
0046 #include "bdbuf_tests.h"
0047 
0048 #include <tmacros.h>
0049 
0050 struct bdbuf_test_descr {
0051     void (* main)(void);
0052 } bdbuf_tests[] = {
0053     { bdbuf_test1_1_main },
0054     { bdbuf_test1_2_main },
0055     { bdbuf_test1_3_main },
0056     { bdbuf_test1_4_main },
0057     { bdbuf_test1_5_main },
0058 
0059     { bdbuf_test2_1_main },
0060     { bdbuf_test2_2_main },
0061 
0062     { bdbuf_test3_1_main },
0063     { bdbuf_test3_2_main },
0064     { bdbuf_test3_3_main },
0065 
0066     { bdbuf_test4_1_main },
0067     { bdbuf_test4_2_main },
0068     { bdbuf_test4_3_main },
0069 };
0070 
0071 #define TEST_SEM_ATTRIBS RTEMS_DEFAULT_ATTRIBUTES
0072 
0073 /** Device ID used for testing */
0074 rtems_disk_device *test_dd = NULL;
0075 
0076 /** Test result variable */
0077 bool       good_test_result = true;
0078 
0079 test_ctx g_test_ctx;
0080 
0081 const char *test_name = "NO TEST";
0082 
0083 bdbuf_test_msg test_drv_msg;
0084 
0085 /** Count of messages in RX message queue used on disk driver side. */
0086 #define TEST_DRV_RX_MQUEUE_COUNT 10
0087 /** Name of disk driver RX message queue. */
0088 #define TEST_DRV_RX_MQUEUE_NAME  (rtems_build_name( 'M', 'Q', 'D', ' ' ))
0089 
0090 /** Count of messages in Test task RX message queue */
0091 #define TEST_TASK_RX_MQUEUE_COUNT 10
0092 /** Name of Test task RX message queue */
0093 #define TEST_TASK_RX_MQUEUE_NAME  (rtems_build_name( 'M', 'Q', 'T', ' ' ))
0094 
0095 rtems_status_code
0096 bdbuf_test_start_aux_task(rtems_name name,
0097                           rtems_task_entry entry_point,
0098                           rtems_task_argument arg,
0099                           Objects_Id *id)
0100 {
0101     rtems_status_code rc;
0102     Objects_Id        task_id;
0103 
0104     rc = rtems_task_create(name, BDBUF_TEST_THREAD_PRIO_NORMAL, 1024 * 2,
0105                            RTEMS_PREEMPT | RTEMS_NO_TIMESLICE | RTEMS_NO_ASR,
0106                            RTEMS_LOCAL | RTEMS_NO_FLOATING_POINT,
0107                            &task_id);
0108     if (rc != RTEMS_SUCCESSFUL)
0109     {
0110         printf("Failed to create task\n");
0111         return rc;
0112     }
0113 
0114     rc = rtems_task_start(task_id, entry_point, arg);
0115     if (rc != RTEMS_SUCCESSFUL)
0116     {
0117         printf("Failed to start task\n");
0118     }
0119     else
0120     {
0121         if (id != NULL)
0122             *id = task_id;
0123     }
0124     return rc;
0125 }
0126 
0127 void
0128 run_bdbuf_tests()
0129 {
0130     rtems_status_code sc;
0131     unsigned int      i;
0132     int               fd;
0133     int               rv;
0134 
0135     /* Create a message queue to get events from disk driver. */
0136     sc = rtems_message_queue_create(TEST_TASK_RX_MQUEUE_NAME,
0137                                     TEST_TASK_RX_MQUEUE_COUNT,
0138                                     sizeof(bdbuf_test_msg),
0139                                     RTEMS_DEFAULT_ATTRIBUTES,
0140                                     &g_test_ctx.test_qid);
0141 
0142     if (sc != RTEMS_SUCCESSFUL)
0143     {
0144         printf("Failed to create message queue for test task: %u\n", sc);
0145         return;
0146     }
0147 
0148     sc = test_disk_initialize();
0149     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0150 
0151     fd = open(TEST_DISK_NAME, O_RDWR);
0152     rtems_test_assert(fd >= 0);
0153 
0154     rv = rtems_disk_fd_get_disk_device(fd, &test_dd);
0155     rtems_test_assert(rv == 0);
0156 
0157     rv = close(fd);
0158     rtems_test_assert(rv == 0);
0159 
0160     /*
0161      * On initialization test disk device driver registers
0162      * its RX message queue, so we just need to locate it.
0163      */
0164     sc = rtems_message_queue_ident(TEST_DRV_RX_MQUEUE_NAME,
0165                                    RTEMS_SEARCH_ALL_NODES,
0166                                    &g_test_ctx.test_drv_qid);
0167     if (sc != RTEMS_SUCCESSFUL)
0168     {
0169         printf("Failed to find Test Driver Queue: %u\n", sc);
0170         return;
0171     }
0172 
0173     for (i = 0; i < ARRAY_NUM(g_test_ctx.test_sync_main); i++)
0174     {
0175         sc = rtems_semaphore_create(rtems_build_name('T', 'S', 'M', '0' + i),
0176                                     0, TEST_SEM_ATTRIBS, 0,
0177                                     &g_test_ctx.test_sync_main[i]);
0178         if (sc != RTEMS_SUCCESSFUL)
0179         {
0180             printf("Failed to create sync sem for test task: %u\n", sc);
0181             return;
0182         }
0183     }
0184 
0185     for (i = 0; i < ARRAY_NUM(g_test_ctx.test_sync); i++)
0186     {
0187         sc = rtems_semaphore_create(rtems_build_name('T', 'S', 'T', '0' + i),
0188                                     0, TEST_SEM_ATTRIBS, 0,
0189                                     &g_test_ctx.test_sync[i]);
0190         if (sc != RTEMS_SUCCESSFUL)
0191         {
0192             printf("Failed to create sync sem for test task #%d: %u\n", i + 1, sc);
0193             return;
0194         }
0195     }
0196 
0197     sc = rtems_semaphore_create(rtems_build_name('T', 'S', 'M', 'E'),
0198                                 0, TEST_SEM_ATTRIBS, 0,
0199                                 &g_test_ctx.test_end_main);
0200     if (sc != RTEMS_SUCCESSFUL)
0201     {
0202         printf("Failed to create end sync sem for test task: %u\n", sc);
0203         return;
0204     }
0205 
0206     for (i = 0; i < ARRAY_NUM(g_test_ctx.test_task); i++)
0207         g_test_ctx.test_task[i] = OBJECTS_ID_NONE;
0208 
0209     for (i = 0; i < sizeof(bdbuf_tests) / sizeof(bdbuf_tests[0]); i++)
0210     {
0211         bdbuf_tests[i].main();
0212     }
0213 }
0214 
0215 
0216 rtems_status_code
0217 bdbuf_test_create_drv_rx_queue(Objects_Id *id)
0218 {
0219     return rtems_message_queue_create(TEST_DRV_RX_MQUEUE_NAME,
0220                                       TEST_DRV_RX_MQUEUE_COUNT,
0221                                       sizeof(bdbuf_test_msg),
0222                                       RTEMS_DEFAULT_ATTRIBUTES,
0223                                       id);
0224 }
0225 
0226 rtems_status_code
0227 bdbuf_test_create_drv_tx_queue(Objects_Id *id)
0228 {
0229     return  rtems_message_queue_ident(TEST_TASK_RX_MQUEUE_NAME,
0230                                       RTEMS_SEARCH_ALL_NODES,
0231                                       id);
0232 }
0233 
0234 rtems_status_code
0235 bdbuf_test_start_thread(unsigned int idx, rtems_task_entry func)
0236 {
0237     rtems_status_code sc;
0238 
0239     if (g_test_ctx.test_task[idx] != OBJECTS_ID_NONE)
0240     {
0241         sc = rtems_task_delete(g_test_ctx.test_task[idx]);
0242         if (sc != RTEMS_SUCCESSFUL)
0243         {
0244             printf("Failed to delete test thread %u in test %s\n",
0245                    idx + 1, g_test_ctx.test_name);
0246             return sc;
0247         }
0248     }
0249     sc = bdbuf_test_start_aux_task(
0250             rtems_build_name('T', 'S', '.', '0' + idx),
0251             func, (rtems_task_argument)(NULL),
0252             &g_test_ctx.test_task[idx]);
0253     return sc;
0254 }
0255 
0256 rtems_status_code
0257 bdbuf_test_end()
0258 {
0259     rtems_status_code sc;
0260     unsigned int      i;
0261 
0262     for (i = 0; i < ARRAY_NUM(g_test_ctx.test_task); i++)
0263     {
0264         if (g_test_ctx.test_task[i] != OBJECTS_ID_NONE)
0265         {
0266             sc = rtems_semaphore_obtain(g_test_ctx.test_end_main,
0267                                         RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0268             if (sc != RTEMS_SUCCESSFUL)
0269             {
0270                 printf("Failed to get a thread stopped\n");
0271             }
0272             g_test_ctx.test_task[i] = OBJECTS_ID_NONE;
0273         }
0274     }
0275     return RTEMS_SUCCESSFUL;
0276 }