source: rtems/testsuites/libtests/block10/init.c @ af43554

5
Last change on this file since af43554 was af43554, checked in by Sebastian Huber <sebastian.huber@…>, on 10/26/17 at 11:59:11

tests: Remove TEST_INIT

The TEST_EXTERN is a used only by the system.h style tests and they use
CONFIGURE_INIT appropriately.

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