source: rtems/testsuites/libtests/block05/init.c @ c499856

4.115
Last change on this file since c499856 was c499856, checked in by Chris Johns <chrisj@…>, on 03/20/14 at 21:10:47

Change all references of rtems.com to rtems.org.

  • Property mode set to 100644
File size: 10.6 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup test_bdbuf
5 *
6 * @brief Bdbuf test.
7 */
8
9/*
10 * Copyright (c) 2009-2012 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Obere Lagerstr. 30
14 *  82178 Puchheim
15 *  Germany
16 *  <rtems@embedded-brains.de>
17 *
18 * The license and distribution terms for this file may be
19 * found in the file LICENSE in this distribution or at
20 * http://www.rtems.org/license/LICENSE.
21 */
22
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26
27#include "tmacros.h"
28#include <stdarg.h>
29#include <errno.h>
30
31#include <rtems.h>
32#include <rtems/bdbuf.h>
33#include <rtems/diskdevs.h>
34
35const char rtems_test_name[] = "BLOCK 5";
36
37/* forward declarations to avoid warnings */
38static rtems_task Init(rtems_task_argument argument);
39
40#define ASSERT_SC(sc) rtems_test_assert((sc) == RTEMS_SUCCESSFUL)
41
42#define PRIORITY_INIT 1
43
44#define PRIORITY_HIGH 2
45
46#define PRIORITY_LOW_ALT 3
47
48#define PRIORITY_SWAPOUT 4
49
50#define PRIORITY_LOW 5
51
52#define PRIORITY_RESUME 6
53
54#define BLOCK_SIZE_A 1
55
56#define BLOCK_COUNT_A 2
57
58#define BLOCK_SIZE_B 2
59
60#define BLOCK_COUNT_B 1
61
62/* In case of trouble change this to 1 or 2 for more output */
63static unsigned output_level = 0;
64
65static rtems_disk_device *dd_a;
66
67static rtems_disk_device *dd_b;
68
69static rtems_id task_id_init;
70
71static rtems_id task_id_low;
72
73static rtems_id task_id_high;
74
75static rtems_id task_id_resume;
76
77static volatile bool finish_low;
78
79static volatile bool finish_high;
80
81static volatile enum resume_style {
82  RESUME_IMMEDIATE,
83  RESUME_FINISH
84} resume;
85
86static volatile enum trig_style {
87  SUSP = 0,
88  CONT
89} trig;
90
91static volatile enum get_type {
92  GET = 0,
93  READ
94} trig_get, low_get, high_get;
95
96static volatile enum blk_kind {
97  BLK_A0 = 0,
98  BLK_A1,
99  BLK_B0
100} trig_blk, low_blk, high_blk;
101
102static volatile enum rel_type {
103  REL = 0,
104  REL_MOD,
105  SYNC
106} trig_rel, low_rel, high_rel;
107
108static const char trig_style_desc [] = {
109  'S',
110  'C'
111};
112
113static const char get_type_desc [] = {
114  'G',
115  'R'
116};
117
118static const char *blk_kind_desc [] = {
119  "A0",
120  "A1",
121  "B0"
122};
123
124static const char rel_type_desc [] = {
125  'R',
126  'M',
127  'S'
128};
129
130static void print(unsigned level, const char *fmt, ...)
131{
132  if (level <= output_level) {
133    va_list ap;
134
135    va_start(ap, fmt);
136    vprintk(fmt, ap);
137    va_end(ap);
138  }
139}
140
141static void set_task_prio(rtems_id task, rtems_task_priority prio)
142{
143  rtems_status_code sc = RTEMS_SUCCESSFUL;
144  rtems_task_priority cur = 0;
145
146  sc = rtems_task_set_priority(task, prio, &cur);
147  ASSERT_SC(sc);
148}
149
150static rtems_bdbuf_buffer *get(enum get_type type, enum blk_kind kind)
151{
152  rtems_status_code sc = RTEMS_SUCCESSFUL;
153  rtems_bdbuf_buffer *bd = NULL;
154  rtems_blkdev_bnum blk_index = 0;
155  rtems_status_code (*get_bd)(
156    rtems_disk_device *,
157    rtems_blkdev_bnum,
158    rtems_bdbuf_buffer **
159  ) = NULL;
160  rtems_disk_device *dd = NULL;
161  size_t bds_per_group = 0;
162
163  switch (kind) {
164    case BLK_A0:
165      dd = dd_a;
166      blk_index = 0;
167      bds_per_group = 2;
168      break;
169    case BLK_A1:
170      dd = dd_a;
171      blk_index = 1;
172      bds_per_group = 2;
173      break;
174    case BLK_B0:
175      dd = dd_b;
176      blk_index = 0;
177      bds_per_group = 1;
178      break;
179    default:
180      rtems_test_assert(false);
181      break;
182  }
183
184  switch (type) {
185    case GET:
186      get_bd = rtems_bdbuf_get;
187      break;
188    case READ:
189      get_bd = rtems_bdbuf_read;
190      break;
191    default:
192      rtems_test_assert(false);
193      break;
194  }
195
196  sc = (*get_bd)(dd, blk_index, &bd);
197  rtems_test_assert(
198    sc == RTEMS_SUCCESSFUL
199      && bd->dd == dd
200      && bd->block == blk_index
201      && bd->group->bds_per_group == bds_per_group
202   );
203
204  return bd;
205}
206
207static void rel(rtems_bdbuf_buffer *bd, enum rel_type type)
208{
209  rtems_status_code sc = RTEMS_SUCCESSFUL;
210  rtems_status_code (*rel_bd)(rtems_bdbuf_buffer *) = NULL;
211
212  switch (type) {
213    case REL:
214      rel_bd = rtems_bdbuf_release;
215      break;
216    case REL_MOD:
217      rel_bd = rtems_bdbuf_release_modified;
218      break;
219    case SYNC:
220      rel_bd = rtems_bdbuf_sync;
221      break;
222    default:
223      rtems_test_assert(false);
224      break;
225  }
226
227  sc = (*rel_bd)(bd);
228  ASSERT_SC(sc);
229}
230
231static void task_low(rtems_task_argument arg)
232{
233  rtems_status_code sc = RTEMS_SUCCESSFUL;
234
235  while (true) {
236    print(2, "LG\n");
237    rtems_bdbuf_buffer *bd = get(low_get, low_blk);
238
239    print(2, "LR\n");
240    rel(bd, low_rel);
241
242    finish_low = true;
243
244    sc = rtems_task_suspend(RTEMS_SELF);
245    ASSERT_SC(sc);
246  }
247}
248
249static void task_high(rtems_task_argument arg)
250{
251  rtems_status_code sc = RTEMS_SUCCESSFUL;
252
253  while (true) {
254    print(2, "HG\n");
255    rtems_bdbuf_buffer *bd = get(high_get, high_blk);
256
257    print(2, "HR\n");
258    rel(bd, high_rel);
259
260    finish_high = true;
261
262    sc = rtems_task_suspend(RTEMS_SELF);
263    ASSERT_SC(sc);
264  }
265}
266
267static void task_resume(rtems_task_argument arg)
268{
269  while (true) {
270    bool do_resume = false;
271
272    switch (resume) {
273      case RESUME_IMMEDIATE:
274        print(2, "RI\n");
275        do_resume = true;
276        break;
277      case RESUME_FINISH:
278        print(2, "RF\n");
279        do_resume = finish_low && finish_high;
280        break;
281      default:
282        rtems_test_assert(false);
283        break;
284    }
285
286    if (do_resume) {
287      rtems_task_resume(task_id_init);
288    }
289  }
290}
291
292static void execute_test(unsigned i)
293{
294  rtems_status_code sc = RTEMS_SUCCESSFUL;
295  rtems_bdbuf_buffer *bd = NULL;
296  bool suspend = false;
297
298  print(
299    1,
300    "[%05u]T(%c,%c,%s,%c)L(%c,%s,%c)H(%c,%s,%c)\n",
301    i,
302    trig_style_desc [trig],
303    get_type_desc [trig_get],
304    blk_kind_desc [trig_blk],
305    rel_type_desc [trig_rel],
306    get_type_desc [low_get],
307    blk_kind_desc [low_blk],
308    rel_type_desc [low_rel],
309    get_type_desc [high_get],
310    blk_kind_desc [high_blk],
311    rel_type_desc [high_rel]
312  );
313
314  set_task_prio(task_id_low, PRIORITY_LOW);
315
316  finish_low = false;
317  finish_high = false;
318
319  sc = rtems_task_resume(task_id_low);
320  ASSERT_SC(sc);
321
322  sc = rtems_task_resume(task_id_high);
323  ASSERT_SC(sc);
324
325  sc = rtems_bdbuf_get(dd_b, 0, &bd);
326  rtems_test_assert(sc == RTEMS_SUCCESSFUL && bd->dd == dd_b && bd->block == 0);
327
328  sc = rtems_bdbuf_release(bd);
329  ASSERT_SC(sc);
330
331  switch (trig) {
332    case SUSP:
333      suspend = true;
334      break;
335    case CONT:
336      suspend = false;
337      break;
338    default:
339      rtems_test_assert(false);
340      break;
341  }
342
343  print(2, "TG\n");
344  bd = get(trig_get, trig_blk);
345
346  if (suspend) {
347    print(2, "S\n");
348    resume = RESUME_IMMEDIATE;
349    sc = rtems_task_suspend(RTEMS_SELF);
350    ASSERT_SC(sc);
351  }
352  resume = RESUME_FINISH;
353
354  print(2, "TR\n");
355  rel(bd, trig_rel);
356
357  sc = rtems_task_suspend(RTEMS_SELF);
358  ASSERT_SC(sc);
359
360  print(2, "F\n");
361
362  sc = rtems_bdbuf_syncdev(dd_a);
363  ASSERT_SC(sc);
364
365  sc = rtems_bdbuf_syncdev(dd_b);
366  ASSERT_SC(sc);
367}
368
369static const rtems_driver_address_table disk_ops = {
370  .initialization_entry = NULL,
371  RTEMS_GENERIC_BLOCK_DEVICE_DRIVER_ENTRIES
372};
373
374static int disk_ioctl(rtems_disk_device *dd, uint32_t req, void *argp)
375{
376  if (req == RTEMS_BLKIO_REQUEST) {
377    rtems_blkdev_request *r = argp;
378
379    set_task_prio(task_id_low, PRIORITY_LOW_ALT);
380
381    switch (r->req) {
382      case RTEMS_BLKDEV_REQ_READ:
383      case RTEMS_BLKDEV_REQ_WRITE:
384        rtems_blkdev_request_done(r, RTEMS_SUCCESSFUL);
385        return 0;
386      default:
387        errno = EINVAL;
388        return -1;
389    }
390  } else {
391    return rtems_blkdev_ioctl(dd, req, argp);
392  }
393}
394
395static void disk_register(
396  uint32_t block_size,
397  rtems_blkdev_bnum block_count,
398  rtems_disk_device **dd_ptr
399)
400{
401  rtems_status_code sc = RTEMS_SUCCESSFUL;
402  rtems_device_major_number major = 0;
403  dev_t dev = 0;
404
405  sc = rtems_io_register_driver(0, &disk_ops, &major);
406  ASSERT_SC(sc);
407
408  dev = rtems_filesystem_make_dev_t(major, 0);
409
410  sc = rtems_disk_create_phys(
411    dev,
412    block_size,
413    block_count,
414    disk_ioctl,
415    NULL,
416    NULL
417  );
418  ASSERT_SC(sc);
419
420  *dd_ptr = rtems_disk_obtain(dev);
421  rtems_test_assert(*dd_ptr!= NULL);
422}
423
424static rtems_task Init(rtems_task_argument argument)
425{
426  rtems_status_code sc = RTEMS_SUCCESSFUL;
427  unsigned i = 0;
428
429  rtems_test_begink();
430
431  task_id_init = rtems_task_self();
432
433  sc = rtems_disk_io_initialize();
434  ASSERT_SC(sc);
435
436  disk_register(BLOCK_SIZE_A, BLOCK_COUNT_A, &dd_a);
437
438  disk_register(BLOCK_SIZE_B, BLOCK_COUNT_B, &dd_b);
439
440  sc = rtems_task_create(
441    rtems_build_name(' ', 'L', 'O', 'W'),
442    PRIORITY_LOW,
443    0,
444    RTEMS_DEFAULT_MODES,
445    RTEMS_DEFAULT_ATTRIBUTES,
446    &task_id_low
447  );
448  ASSERT_SC(sc);
449
450  sc = rtems_task_start(task_id_low, task_low, 0);
451  ASSERT_SC(sc);
452
453  sc = rtems_task_create(
454    rtems_build_name('H', 'I', 'G', 'H'),
455    PRIORITY_HIGH,
456    0,
457    RTEMS_DEFAULT_MODES,
458    RTEMS_DEFAULT_ATTRIBUTES,
459    &task_id_high
460  );
461  ASSERT_SC(sc);
462
463  sc = rtems_task_start(task_id_high, task_high, 0);
464  ASSERT_SC(sc);
465
466  sc = rtems_task_create(
467    rtems_build_name('R', 'E', 'S', 'U'),
468    PRIORITY_RESUME,
469    0,
470    RTEMS_DEFAULT_MODES,
471    RTEMS_DEFAULT_ATTRIBUTES,
472    &task_id_resume
473  );
474  ASSERT_SC(sc);
475
476  sc = rtems_task_start(task_id_resume, task_resume, 0);
477  ASSERT_SC(sc);
478
479  sc = rtems_task_suspend(task_id_low);
480  ASSERT_SC(sc);
481
482  sc = rtems_task_suspend(task_id_high);
483  ASSERT_SC(sc);
484
485  for (trig = SUSP; trig <= CONT; ++trig) {
486    for (trig_get = GET; trig_get <= READ; ++trig_get) {
487      for (low_get = GET; low_get <= READ; ++low_get) {
488        for (high_get = GET; high_get <= READ; ++high_get) {
489          for (trig_blk = BLK_A0; trig_blk <= BLK_B0; ++trig_blk) {
490            for (low_blk = BLK_A0; low_blk <= BLK_B0; ++low_blk) {
491              for (high_blk = BLK_A0; high_blk <= BLK_B0; ++high_blk) {
492                for (trig_rel = REL; trig_rel <= SYNC; ++trig_rel) {
493                  for (low_rel = REL; low_rel <= SYNC; ++low_rel) {
494                    for (high_rel = REL; high_rel <= SYNC; ++high_rel) {
495                      execute_test(i);
496                      ++i;
497                    }
498                  }
499                }
500              }
501            }
502          }
503        }
504      }
505    }
506  }
507
508  rtems_test_endk();
509
510  exit(0);
511}
512
513#define CONFIGURE_INIT
514
515#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
516#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
517#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
518
519#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
520
521#define CONFIGURE_MAXIMUM_TASKS 4
522#define CONFIGURE_MAXIMUM_DRIVERS 4
523
524#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
525
526#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
527
528#define CONFIGURE_INIT_TASK_PRIORITY PRIORITY_INIT
529#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_DEFAULT_ATTRIBUTES
530#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
531
532#define CONFIGURE_SWAPOUT_TASK_PRIORITY PRIORITY_SWAPOUT
533
534#define CONFIGURE_BDBUF_BUFFER_MIN_SIZE BLOCK_SIZE_A
535#define CONFIGURE_BDBUF_BUFFER_MAX_SIZE BLOCK_SIZE_B
536#define CONFIGURE_BDBUF_CACHE_MEMORY_SIZE BLOCK_SIZE_B
537
538#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.