source: rtems/testsuites/libtests/block10/init.c @ 4c86e3d

4.115
Last change on this file since 4c86e3d was 4c86e3d, checked in by Joel Sherrill <joel.sherrill@…>, on 05/11/12 at 17:20:47

libtmtests - Eliminate missing prototype warnings

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