source: rtems/testsuites/libtests/block08/bdbuf_tests.h @ 7f1e6fa

5
Last change on this file since 7f1e6fa was 7f1e6fa, checked in by Sebastian Huber <sebastian.huber@…>, on 07/28/17 at 10:19:05

libtests/block08: Fix format warning

  • Property mode set to 100644
File size: 20.1 KB
Line 
1/*! @file
2 * @brief Common declarations of bdbuf tests.
3 *
4 * Copyright (C) 2010 OKTET Labs, St.-Petersburg, Russia
5 * Author: Oleg Kravtsov <Oleg.Kravtsov@oktetlabs.ru>
6 *
7 * The license and distribution terms for this file may be
8 * found in the file LICENSE in this distribution or at
9 * http://www.rtems.org/license/LICENSE.
10 */
11
12#ifndef BDBUF_TESTS_H
13#define BDBUF_TESTS_H
14
15#include <inttypes.h>
16#include <stdio.h>
17#include <string.h>
18#include <errno.h>
19#include <rtems/bspIo.h>
20#include <rtems/diskdevs.h>
21#include <rtems/bdbuf.h>
22
23#ifdef __cplusplus
24extern "C" {
25#endif
26
27extern void run_bdbuf_tests(void);
28
29extern void bdbuf_test1_1_main(void);
30extern void bdbuf_test1_2_main(void);
31extern void bdbuf_test1_3_main(void);
32extern void bdbuf_test1_4_main(void);
33extern void bdbuf_test1_5_main(void);
34
35extern void bdbuf_test2_1_main(void);
36extern void bdbuf_test2_2_main(void);
37extern void bdbuf_test2_3_main(void);
38extern void bdbuf_test2_4_main(void);
39extern void bdbuf_test2_5_main(void);
40
41extern void bdbuf_test3_1_main(void);
42extern void bdbuf_test3_2_main(void);
43extern void bdbuf_test3_3_main(void);
44
45extern void bdbuf_test4_1_main(void);
46extern void bdbuf_test4_2_main(void);
47extern void bdbuf_test4_3_main(void);
48
49extern rtems_device_driver
50test_disk_initialize(
51    rtems_device_major_number major,
52    rtems_device_minor_number minor,
53    void *arg);
54
55#define ARRAY_NUM(a_) (sizeof(a_) / sizeof(a_[0]))
56
57/**
58 * Configuration parameters of Test disk device.
59 */
60#define TEST_DISK_BLOCK_SIZE   512
61#define TEST_DISK_BLOCK_NUM    1024
62#define TEST_DISK_NAME         "/dev/testdisk"
63
64/** Type of messages between test disk driver and main test task */
65enum bdbuf_test_msg_type {
66    /** Message sent by disk driver to main test task */
67    BDBUF_TEST_MSG_TYPE_DRIVER_REQ,
68    /**
69     * Message sent main test task to disk driver
70     * in reply to request.
71     */
72    BDBUF_TEST_MSG_TYPE_DRIVER_REPLY,
73};
74
75/**
76 * Message used in communication between test disk driver
77 * and main test task.
78 * All R/W requests obtained by driver (from bdbuf library)
79 * are directed to main test task. Then main test task
80 * sends a reply after which test disk driver notifies
81 * bdbuf library about operation complete event.
82 */
83typedef struct bdbuf_test_msg {
84    /** Message type */
85    enum bdbuf_test_msg_type type;
86
87    union {
88        struct driver_req {
89            const rtems_disk_device *dd;
90            uint32_t  req;
91            void     *argp;
92        } driver_req;
93        struct driver_reply {
94            int               ret_val;
95            int               ret_errno;
96            rtems_status_code res_status;
97            int               res_errno;
98        } driver_reply;
99    } val;
100} bdbuf_test_msg;
101
102
103typedef enum bdbuf_rest_thread_prio {
104    BDBUF_TEST_THREAD_PRIO_NORMAL = 3,
105    BDBUF_TEST_THREAD_PRIO_LOW = 7,
106    BDBUF_TEST_THREAD_PRIO_HIGH = 5,
107} bdbuf_rest_thread_prio;
108
109
110typedef struct test_ctx {
111    /**
112     * Message queue used by main task to get messages from
113     * disk device driver.
114     */
115    Objects_Id test_qid;
116
117    /**
118     * Object ID for disk driver queue.
119     * Test task will send messages to this queue in reply
120     * to messages received on @a test_qid.
121     */
122    Objects_Id test_drv_qid;
123
124    /** Test name */
125    const char *test_name;
126
127    /**
128     * Semaphore used for synchronization between test thread
129     * and main test task.
130     * Main test task blocks on one of these semaphores and an auxiliary thread
131     * releases it in order to pass control to main task again.
132     */
133    rtems_id   test_sync_main[3];
134
135    /**
136     * This semaphore is used for synchornization between main test task
137     * and the END of auxiliary threads.
138     */
139    rtems_id   test_end_main;
140
141    /**
142     * Semaphore used for synchronization between test thread
143     * and main test task.
144     * Thread #N blocks on this semaphore and the main task releases it
145     * when it wants to pass control to the auxiliary thread #N.
146     */
147    rtems_id   test_sync[3];
148
149    /** Task Id values of auxiliary threads */
150    Objects_Id test_task[3];
151} test_ctx;
152
153extern test_ctx g_test_ctx;
154
155/** Device ID used for testing */
156extern rtems_disk_device *test_dd;
157
158/**
159 * Create a message queue for test driver that is used for
160 * receiving messages from test task.
161 *
162 * @param[out] id  RTEMS message queue identifier
163 *
164 * @return Status of the operation
165 */
166extern rtems_status_code bdbuf_test_create_drv_rx_queue(Objects_Id *id);
167
168/**
169 * Obtain a message queue for test driver that is used for
170 * sending messages to test task.
171 *
172 * @param[out] id  RTEMS message queue identifier
173 *
174 * @return Status of the operation
175 */
176extern rtems_status_code bdbuf_test_create_drv_tx_queue(Objects_Id *id);
177
178/**
179 * Start a separate test task represented by function @p func
180 * and associated with task index @p idx.
181 *
182 * @param[in] idx   Task index
183 * @param[in] func  Test task function
184 */
185extern rtems_status_code bdbuf_test_start_thread(unsigned int idx,
186                                                 rtems_task_entry func);
187
188/**
189 * Finalize test run.
190 */
191extern rtems_status_code bdbuf_test_end(void);
192
193/** Test result variable */
194extern bool       good_test_result;
195
196#define BDBUF_TEST_BLOCK_TIMEOUT (2 * rtems_clock_get_ticks_per_second())
197
198#define SET_THREAD_PRIORITY(t_num_, prio_) \
199    do {                                                        \
200        rtems_task_priority old_prio;                           \
201        rtems_status_code   rc_;                                \
202                                                                \
203        rc_ = rtems_task_set_priority(                          \
204                g_test_ctx.test_task[(t_num_) - 1],             \
205                BDBUF_TEST_THREAD_PRIO_ ## prio_, &old_prio);   \
206        if (rc_ != RTEMS_SUCCESSFUL)                            \
207        {                                                       \
208            printk("Failed to change priority of test thread #" \
209                   #t_num_ " in test %s\n", g_test_ctx.test_name);         \
210            return;                                             \
211        }                                                       \
212    } while (0)
213
214/**
215 * Start thread number @p t_num_ with @p func_ function
216 * as an entry point of the thread.
217 *
218 * @param t_num_  thread number.
219 * @param func_   thread entry point.
220 */
221#define START_THREAD(t_num_, func_) \
222    do {                                                        \
223        if (bdbuf_test_start_thread((t_num_) - 1, func_) !=     \
224                RTEMS_SUCCESSFUL)                               \
225        {                                                       \
226            return;                                             \
227        }                                                       \
228        printk("Thread #" #t_num_ " started\n");                \
229    } while (0)
230
231/**
232 * Wait for a message from device driver.
233 *
234 * @param[out] msg_  Pointer to a message data structure
235 */
236#define WAIT_DRV_MSG(msg_) \
237    do {                                                        \
238        rtems_status_code rc_;                                  \
239        size_t            msg_size_ = sizeof(*(msg_));          \
240                                                                \
241        rc_ = rtems_message_queue_receive(g_test_ctx.test_qid,  \
242                                          (msg_), &msg_size_,   \
243                                          RTEMS_WAIT,           \
244                                          RTEMS_NO_TIMEOUT);    \
245        if (rc_ != RTEMS_SUCCESSFUL ||                          \
246            msg_size_ != sizeof(*(msg_)))                       \
247        {                                                       \
248            printk("Error at %s:%d\n", __FILE__, __LINE__);     \
249            return;                                             \
250        }                                                       \
251        if ((msg_)->type != BDBUF_TEST_MSG_TYPE_DRIVER_REQ)     \
252        {                                                       \
253            printk("Unexpected message received: %d\n",         \
254                   (msg_)->type);                               \
255            return;                                             \
256        }                                                       \
257    } while (0)
258
259#define WAIT_DRV_MSG_WR(msg_) \
260  do {                                                                     \
261        WAIT_DRV_MSG(msg_);                                                \
262        if ((msg_)->val.driver_req.req != RTEMS_BLKIO_REQUEST ||           \
263            (msg_)->val.driver_req.dd != test_dd ||                        \
264            ((rtems_blkdev_request *)                                      \
265                 ((msg_)->val.driver_req.argp))->req !=                    \
266                 RTEMS_BLKDEV_REQ_WRITE)                                   \
267        {                                                                  \
268            printk("Unexpected message received by disk driver: "          \
269                   "req - 0x%" PRIx32 " (0x%lx), dev - %p (%p)\n", \
270                   (msg_)->val.driver_req.req, RTEMS_BLKIO_REQUEST,        \
271                   (msg_)->val.driver_req.dd, test_dd);                    \
272            return;                                                        \
273        }                                                                  \
274    } while (0)
275
276#define CHECK_NO_DRV_MSG() \
277    do {                                                        \
278        rtems_status_code rc_;                                  \
279        bdbuf_test_msg    msg_;                                 \
280        size_t            msg_size_ = sizeof(msg_);             \
281                                                                \
282        rc_ = rtems_message_queue_receive(g_test_ctx.test_qid,  \
283                  (&msg_), &msg_size_,                          \
284                  RTEMS_WAIT,                                   \
285                  BDBUF_TEST_BLOCK_TIMEOUT);                    \
286        if (rc_ != RTEMS_TIMEOUT)                               \
287        {                                                       \
288            printk("Error at %s:%d\n", __FILE__, __LINE__);     \
289            return;                                             \
290        }                                                       \
291    } while (0)
292
293extern bdbuf_test_msg test_drv_msg;
294
295/**
296 * Send a message to device driver (in order to complete
297 * blocked I/O operation).
298 *
299 * @param ret_val_     Return value to use when returning from
300 *                     ioctl() function.
301 * @param ret_errno_   errno value to set to errno variable.
302 * @param res_status_  In case return value from the ioctl()
303 *                     function is equal to 0, this value
304 *                     is used as status code in asynchronous
305 *                     notification.
306 * @param res_errno_   In case return value from the ioctl()
307 *                     function is equal to 0, this value
308 *                     is used as error value in asynchronous
309 *                     notification.
310 *
311 */
312#define SEND_DRV_MSG(ret_val_, ret_errno_, res_status_, res_errno_) \
313    do {                                                                \
314        rtems_status_code rc_;                                          \
315                                                                        \
316        memset(&test_drv_msg, 0, sizeof(test_drv_msg));                 \
317        test_drv_msg.type = BDBUF_TEST_MSG_TYPE_DRIVER_REPLY;           \
318        test_drv_msg.val.driver_reply.ret_val = (ret_val_);             \
319        test_drv_msg.val.driver_reply.ret_errno = (ret_errno_);         \
320        test_drv_msg.val.driver_reply.res_status = (res_status_);       \
321        test_drv_msg.val.driver_reply.res_errno = (res_errno_);         \
322                                                                        \
323        rc_ = rtems_message_queue_send(g_test_ctx.test_drv_qid,         \
324                                       &test_drv_msg,                   \
325                                       sizeof(test_drv_msg));           \
326        if (rc_ != RTEMS_SUCCESSFUL)                                    \
327        {                                                               \
328            printk("Error while sending a message to "                  \
329                   "disk driver: %u\n", rc_);                           \
330            return;                                                     \
331        }                                                               \
332    } while (0)
333
334/**
335 * Block main test task until a thread passes back control
336 * with CONTINUE_MAIN().
337 *
338 * @param t_num_  thread number from which the main thread
339 *                is waiting for a sync.
340 */
341#define WAIT_THREAD_SYNC(t_num_) \
342    do {                                                                \
343        rtems_status_code rc_;                                          \
344                                                                        \
345        rc_ = rtems_semaphore_obtain(                                   \
346                g_test_ctx.test_sync_main[(t_num_) - 1],                \
347                RTEMS_WAIT, RTEMS_NO_TIMEOUT);                          \
348        if (rc_ != RTEMS_SUCCESSFUL)                                    \
349        {                                                               \
350            printk("Failed to get sync with a thread: %d\n", rc_);      \
351            return;                                                     \
352        }                                                               \
353    } while (0)
354
355/**
356 * Check that a particular thread is blocked.
357 *
358 * @param t_num_  thread number that we want to check for blocking
359 */
360#define CHECK_THREAD_BLOCKED(t_num_) \
361    do {                                                                \
362        rtems_status_code rc_;                                          \
363                                                                        \
364        rc_ = rtems_semaphore_obtain(                                   \
365                g_test_ctx.test_sync_main[(t_num_) - 1],                \
366                RTEMS_WAIT, BDBUF_TEST_BLOCK_TIMEOUT);                  \
367        if (rc_ != RTEMS_TIMEOUT)                                       \
368        {                                                               \
369            printk("Thread %d is not blocked at%s:%d\n",                \
370                   t_num_, __FILE__, __LINE__);                         \
371            return;                                                     \
372        }                                                               \
373    } while (0)
374
375/**
376 * Main test task gives control to the particular thread.
377 *
378 * @param t_num_  thread number to which main test task wants
379 *                to give control.
380 */
381#define CONTINUE_THREAD(t_num_) \
382    do {                                                        \
383        rtems_status_code rc_;                                  \
384                                                                \
385        rc_ = rtems_semaphore_release(                          \
386                g_test_ctx.test_sync[(t_num_) - 1]);            \
387        if (rc_ != RTEMS_SUCCESSFUL)                            \
388        {                                                       \
389            printk("Failed to give control to thread #"         \
390                   #t_num_ ": %d\n", rc_);                      \
391            return;                                             \
392        }                                                       \
393    } while (0)
394
395/**
396 * Passes control back to the main test task from a thread.
397 *
398 * @param t_num_ Current thread number
399 */
400#define CONTINUE_MAIN(t_num_) \
401    do {                                                        \
402        rtems_status_code rc_;                                  \
403                                                                \
404        rc_ = rtems_semaphore_release(                          \
405                g_test_ctx.test_sync_main[(t_num_) - 1]);       \
406        if (rc_ != RTEMS_SUCCESSFUL)                            \
407        {                                                       \
408            printk("Failed to give control to "                 \
409                   "main task: %d", rc_);                       \
410            return;                                             \
411        }                                                       \
412        rc_ = rtems_semaphore_obtain(                           \
413                g_test_ctx.test_sync[(t_num_) - 1],             \
414                RTEMS_WAIT, RTEMS_NO_TIMEOUT);                  \
415        if (rc_ != RTEMS_SUCCESSFUL)                            \
416        {                                                       \
417            printk("Failed to block on thread #"                \
418                   #t_num_ ": %d\n", rc_);                      \
419            return;                                             \
420        }                                                       \
421    } while (0)
422
423#define WAIT_MAIN_SYNC(t_num_) \
424    do {                                                        \
425        rtems_status_code rc_;                                  \
426                                                                \
427        rc_ = rtems_semaphore_obtain(                           \
428                g_test_ctx.test_sync[(t_num_) - 1],             \
429                RTEMS_WAIT, RTEMS_NO_TIMEOUT);                  \
430        if (rc_ != RTEMS_SUCCESSFUL)                            \
431        {                                                       \
432            printk("Failed to block on thread #"                \
433                   #t_num_ ": %d\n", rc_);                      \
434            return;                                             \
435        }                                                       \
436    } while (0)
437
438
439#define TEST_START(test_name_) \
440    do {                                \
441        good_test_result = true;        \
442        g_test_ctx.test_name = test_name_; \
443        printk("%s - STARTED\n",        \
444               g_test_ctx.test_name);              \
445    } while (0)
446
447#define TEST_CHECK_RESULT(step_) \
448    do {                                        \
449        if (!good_test_result)                  \
450        {                                       \
451            printk("TEST FAILED (Step %s)\n",   \
452                   step_);                      \
453            rtems_task_delete(RTEMS_SELF);      \
454        }                                       \
455        else                                    \
456        {                                       \
457            printk("%s: Step %s - OK\n",        \
458                   g_test_ctx.test_name, step_);           \
459        }                                       \
460    } while (0)
461
462#define TEST_STOP() \
463    do {                                 \
464        bdbuf_test_end();                \
465                                         \
466        if (good_test_result)            \
467            printk("TEST PASSED\n");     \
468        else                             \
469            printk("TEST FAILED (END)"); \
470    } while (0)
471
472#define THREAD_END() \
473    do {                                                        \
474        rtems_status_code rc_;                                  \
475                                                                \
476        rc_ = rtems_semaphore_release(g_test_ctx.test_end_main);\
477        if (rc_ != RTEMS_SUCCESSFUL)                            \
478        {                                                       \
479            printk("Failed to give control to "                 \
480                   "main task: %d", rc_);                       \
481            return;                                             \
482        }                                                       \
483        rtems_task_delete(RTEMS_SELF);                          \
484    } while (0)
485
486#define TEST_FAILED() \
487    do {                                \
488        good_test_result = false;       \
489    } while (0)
490
491#define SLEEP() \
492    rtems_task_wake_after(BDBUF_TEST_BLOCK_TIMEOUT)
493
494
495extern rtems_status_code
496bdbuf_test_start_aux_task(rtems_name name,
497                          rtems_task_entry entry_point,
498                          rtems_task_argument arg,
499                          Objects_Id *id);
500#ifdef __cplusplus
501}
502#endif
503
504#endif /* BDBUF_TESTS_H */
Note: See TracBrowser for help on using the repository browser.