source: rtems/testsuites/libtests/block10/init.c @ 0d796d6

Last change on this file since 0d796d6 was 0d796d6, checked in by Sebastian Huber <sebastian.huber@…>, on Nov 2, 2017 at 1:08:02 PM

tests: Delete obsolete TESTS_USE_PRINTF

Update #3170.
Update #3199.

  • Property mode set to 100644
File size: 9.5 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup test_bdbuf
5 *
6 * @brief Bdbuf test for purge.
7 */
8
9/*
10 * Copyright (c) 2010
11 * embedded brains GmbH
12 * Obere Lagerstr. 30
13 * D-82178 Puchheim
14 * Germany
15 * <rtems@embedded-brains.de>
16 *
17 * The license and distribution terms for this file may be
18 * found in the file LICENSE in this distribution or at
19 * http://www.rtems.org/license/LICENSE.
20 */
21
22#ifdef HAVE_CONFIG_H
23#include "config.h"
24#endif
25
26#include "tmacros.h"
27
28#include <assert.h>
29#include <errno.h>
30#include <stdlib.h>
31
32#include <rtems.h>
33#include <rtems/bdbuf.h>
34#include <rtems/diskdevs.h>
35#include <rtems/test.h>
36
37#include <bsp.h>
38
39const char rtems_test_name[] = "BLOCK 10";
40
41/* forward declarations to avoid warnings */
42static rtems_task Init(rtems_task_argument argument);
43
44#define ASSERT_SC(sc) assert((sc) == RTEMS_SUCCESSFUL)
45
46#define PRIORITY_HIGH 1
47
48#define PRIORITY_INIT 2
49
50#define PRIORITY_MID 3
51
52#define PRIORITY_SWAPOUT 4
53
54#define PRIORITY_LOW 5
55
56#define PRIORITY_IDLE 6
57
58#define BLOCK_SIZE 1
59
60#define BLOCK_COUNT 1
61
62typedef rtems_bdbuf_buffer *(*access_func)(char task);
63
64typedef void (*release_func)(char task, rtems_bdbuf_buffer *bd);
65
66static rtems_disk_device *dd;
67
68static rtems_id task_id_init;
69
70static rtems_id task_id_purger;
71
72static rtems_id task_id_waiter;
73
74static const rtems_driver_address_table disk_ops = {
75  .initialization_entry = NULL,
76  RTEMS_GENERIC_BLOCK_DEVICE_DRIVER_ENTRIES
77};
78
79static void set_task_prio(rtems_id task, rtems_task_priority prio)
80{
81  rtems_status_code sc = RTEMS_SUCCESSFUL;
82  rtems_task_priority cur = 0;
83
84  sc = rtems_task_set_priority(task, prio, &cur);
85  ASSERT_SC(sc);
86}
87
88static void suspend(rtems_id task)
89{
90  rtems_status_code sc = RTEMS_SUCCESSFUL;
91
92  sc = rtems_task_suspend(task);
93  ASSERT_SC(sc);
94}
95
96static void resume(rtems_id task)
97{
98  rtems_status_code sc = RTEMS_SUCCESSFUL;
99
100  sc = rtems_task_resume(task);
101  ASSERT_SC(sc);
102}
103
104static int disk_ioctl(rtems_disk_device *dd, uint32_t req, void *arg)
105{
106  rtems_status_code sc = RTEMS_SUCCESSFUL;
107
108  if (req == RTEMS_BLKIO_REQUEST) {
109    rtems_blkdev_request *r = arg;
110
111    if (r->req == RTEMS_BLKDEV_REQ_WRITE) {
112      set_task_prio(RTEMS_SELF, PRIORITY_IDLE);
113      set_task_prio(RTEMS_SELF, PRIORITY_SWAPOUT);
114    }
115
116    rtems_blkdev_request_done(r, sc);
117
118    return 0;
119  } else {
120    return rtems_blkdev_ioctl(dd, req, arg);
121  }
122}
123
124static rtems_status_code disk_register(
125  uint32_t block_size,
126  rtems_blkdev_bnum block_count,
127  dev_t *dev_ptr
128)
129{
130  rtems_status_code sc = RTEMS_SUCCESSFUL;
131  rtems_device_major_number major = 0;
132  dev_t dev = 0;
133
134  sc = rtems_io_register_driver(0, &disk_ops, &major);
135  ASSERT_SC(sc);
136
137  dev = rtems_filesystem_make_dev_t(major, 0);
138
139  sc = rtems_disk_create_phys(
140    dev,
141    block_size,
142    block_count,
143    disk_ioctl,
144    NULL,
145    NULL
146  );
147  ASSERT_SC(sc);
148
149  *dev_ptr = dev;
150
151  return RTEMS_SUCCESSFUL;
152}
153
154static rtems_bdbuf_buffer *do_get(char task)
155{
156  rtems_status_code sc = RTEMS_SUCCESSFUL;
157  rtems_bdbuf_buffer *bd = NULL;
158
159  printf("%c: try get\n", task);
160
161  sc = rtems_bdbuf_get(dd, 0, &bd);
162  ASSERT_SC(sc);
163
164  printf("%c: get\n", task);
165
166  return bd;
167}
168
169static rtems_bdbuf_buffer *do_get_mod(char task)
170{
171  rtems_status_code sc = RTEMS_SUCCESSFUL;
172  rtems_bdbuf_buffer *bd = NULL;
173
174  printf("%c: try get modified\n", task);
175
176  sc = rtems_bdbuf_get(dd, 0, &bd);
177  ASSERT_SC(sc);
178
179  sc = rtems_bdbuf_release_modified(bd);
180  ASSERT_SC(sc);
181
182  sc = rtems_bdbuf_get(dd, 0, &bd);
183  ASSERT_SC(sc);
184
185  printf("%c: get modified\n", task);
186
187  return bd;
188}
189
190static rtems_bdbuf_buffer *do_read(char task)
191{
192  rtems_status_code sc = RTEMS_SUCCESSFUL;
193  rtems_bdbuf_buffer *bd = NULL;
194
195  printf("%c: try read\n", task);
196
197  sc = rtems_bdbuf_read(dd, 0, &bd);
198  ASSERT_SC(sc);
199
200  printf("%c: read\n", task);
201
202  return bd;
203}
204
205static void do_rel(char task, rtems_bdbuf_buffer *bd)
206{
207  rtems_status_code sc = RTEMS_SUCCESSFUL;
208
209  printf("%c: release\n", task);
210
211  sc = rtems_bdbuf_release(bd);
212  ASSERT_SC(sc);
213
214  printf("%c: release done\n", task);
215}
216
217static void do_rel_mod(char task, rtems_bdbuf_buffer *bd)
218{
219  rtems_status_code sc = RTEMS_SUCCESSFUL;
220
221  printf("%c: release modified\n", task);
222
223  sc = rtems_bdbuf_release_modified(bd);
224  ASSERT_SC(sc);
225
226  printf("%c: release modified done\n", task);
227}
228
229static void do_sync(char task, rtems_bdbuf_buffer *bd)
230{
231  rtems_status_code sc = RTEMS_SUCCESSFUL;
232
233  printf("%c: sync\n", task);
234
235  sc = rtems_bdbuf_sync(bd);
236  ASSERT_SC(sc);
237
238  printf("%c: sync done\n", task);
239}
240
241static void purge(char task)
242{
243  printf("%c: purge\n", task);
244
245  rtems_bdbuf_purge_dev(dd);
246}
247
248static void task_purger(rtems_task_argument arg)
249{
250  while (true) {
251    suspend(RTEMS_SELF);
252
253    set_task_prio(RTEMS_SELF, PRIORITY_HIGH);
254
255    purge('P');
256  }
257
258  rtems_task_delete(RTEMS_SELF);
259}
260
261static void activate_purger(rtems_task_priority prio)
262{
263  set_task_prio(task_id_purger, prio);
264  resume(task_id_purger);
265}
266
267static void task_waiter(rtems_task_argument arg)
268{
269  while (true) {
270    rtems_bdbuf_buffer *bd = NULL;
271
272    suspend(RTEMS_SELF);
273
274    bd = do_get('W');
275
276    do_rel('W', bd);
277  }
278
279  rtems_task_delete(RTEMS_SELF);
280}
281
282static void create_waiter(void)
283{
284  resume(task_id_waiter);
285  set_task_prio(task_id_waiter, PRIORITY_IDLE);
286}
287
288static void restore_waiter(void)
289{
290  set_task_prio(task_id_waiter, PRIORITY_HIGH);
291}
292
293static void check_access(access_func ac, release_func rel, bool waiter)
294{
295  rtems_bdbuf_buffer *bd = (*ac)('I');
296
297  if (waiter) {
298    create_waiter();
299  }
300
301  purge('I');
302
303  (*rel)('I', bd);
304
305  if (waiter) {
306    restore_waiter();
307  }
308}
309
310static void check_intermediate(release_func rel, bool waiter)
311{
312  rtems_bdbuf_buffer *bd = do_read('I');
313
314  if (waiter) {
315    create_waiter();
316  }
317
318  (*rel)('I', bd);
319
320  purge('I');
321
322  if (waiter) {
323    restore_waiter();
324  }
325}
326
327static void check_transfer(rtems_task_priority prio, bool waiter)
328{
329  rtems_bdbuf_buffer *bd = do_read('I');
330
331  if (waiter) {
332    create_waiter();
333  }
334
335  activate_purger(prio);
336
337  do_sync('I', bd);
338
339  if (waiter) {
340    restore_waiter();
341  }
342}
343
344static const bool waiter_table [] = {
345  true,
346  false
347};
348
349static const access_func access_table [] = {
350  do_get,
351  do_get_mod,
352  do_read
353};
354
355static const release_func release_table [] = {
356  do_rel,
357  do_rel_mod,
358  do_sync
359};
360
361static const rtems_task_priority purger_table [] = {
362  PRIORITY_MID,
363  PRIORITY_LOW
364};
365
366#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array [0]))
367
368#define WAITER_COUNT ARRAY_COUNT(waiter_table)
369
370#define ACCESS_COUNT ARRAY_COUNT(access_table)
371
372#define RELEASE_COUNT ARRAY_COUNT(release_table)
373
374#define PURGER_COUNT ARRAY_COUNT(purger_table)
375
376static const char *waiter_assoc_table [WAITER_COUNT] = {
377  "with waiter",
378  "without waiter"
379};
380
381static const char *access_assoc_table [ACCESS_COUNT] = {
382  "get",
383  "access modified",
384  "read"
385};
386
387static const char *release_assoc_table [RELEASE_COUNT] = {
388  "release",
389  "release modified",
390  "sync"
391};
392
393static const char *purger_assoc_table [PURGER_COUNT] = {
394  "sync",
395  "transfer"
396};
397
398static rtems_task Init(rtems_task_argument argument)
399{
400  rtems_status_code sc = RTEMS_SUCCESSFUL;
401  dev_t dev = 0;
402  size_t i_w = 0;
403  size_t i_ac = 0;
404  size_t i_rel = 0;
405  size_t i_p = 0;
406
407  TEST_BEGIN();
408
409  task_id_init = rtems_task_self();
410
411  sc = rtems_disk_io_initialize();
412  ASSERT_SC(sc);
413
414  sc = disk_register(BLOCK_SIZE, BLOCK_COUNT, &dev);
415  ASSERT_SC(sc);
416
417  dd = rtems_disk_obtain(dev);
418  assert(dd != NULL);
419
420  sc = rtems_task_create(
421    rtems_build_name('P', 'U', 'R', 'G'),
422    PRIORITY_HIGH,
423    0,
424    RTEMS_DEFAULT_MODES,
425    RTEMS_DEFAULT_ATTRIBUTES,
426    &task_id_purger
427  );
428  ASSERT_SC(sc);
429
430  sc = rtems_task_start(task_id_purger, task_purger, 0);
431  ASSERT_SC(sc);
432
433  set_task_prio(task_id_purger, PRIORITY_LOW);
434
435  sc = rtems_task_create(
436    rtems_build_name('W', 'A', 'I', 'T'),
437    PRIORITY_HIGH,
438    0,
439    RTEMS_DEFAULT_MODES,
440    RTEMS_DEFAULT_ATTRIBUTES,
441    &task_id_waiter
442  );
443  ASSERT_SC(sc);
444
445  sc = rtems_task_start(task_id_waiter, task_waiter, 0);
446  ASSERT_SC(sc);
447
448  for (i_ac = 0; i_ac < ACCESS_COUNT; ++i_ac) {
449    for (i_rel = 0; i_rel < RELEASE_COUNT; ++i_rel) {
450      for (i_w = 0; i_w < WAITER_COUNT; ++i_w) {
451        printf("test case [access]: %s and %s %s\n", access_assoc_table [i_ac], release_assoc_table [i_rel], waiter_assoc_table [i_w]);
452        check_access(access_table [i_ac], release_table [i_rel], waiter_table [i_w]);
453      }
454    }
455  }
456
457  for (i_rel = 0; i_rel < RELEASE_COUNT; ++i_rel) {
458    for (i_w = 0; i_w < WAITER_COUNT; ++i_w) {
459      printf("test case [intermediate]: %s %s\n", release_assoc_table [i_rel], waiter_assoc_table [i_w]);
460      check_intermediate(release_table [i_rel], waiter_table [i_w]);
461    }
462  }
463
464  for (i_p = 0; i_p < PURGER_COUNT; ++i_p) {
465    for (i_w = 0; i_w < WAITER_COUNT; ++i_w) {
466      printf("test case [transfer]: %s %s\n", purger_assoc_table [i_p], waiter_assoc_table [i_w]);
467      check_transfer(purger_table [i_p], waiter_table [i_w]);
468    }
469  }
470
471  TEST_END();
472
473  exit(0);
474}
475
476#define CONFIGURE_INIT
477
478#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
479#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
480#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
481
482#define CONFIGURE_MAXIMUM_TASKS 3
483#define CONFIGURE_MAXIMUM_DRIVERS 4
484
485#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
486
487#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
488
489#define CONFIGURE_INIT_TASK_PRIORITY PRIORITY_INIT
490#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_DEFAULT_ATTRIBUTES
491#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
492
493#define CONFIGURE_SWAPOUT_TASK_PRIORITY PRIORITY_SWAPOUT
494
495#define CONFIGURE_BDBUF_BUFFER_MIN_SIZE BLOCK_SIZE
496#define CONFIGURE_BDBUF_BUFFER_MAX_SIZE BLOCK_SIZE
497#define CONFIGURE_BDBUF_CACHE_MEMORY_SIZE (BLOCK_SIZE * BLOCK_COUNT)
498
499#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.