source: rtems/testsuites/libtests/rbheap01/init.c @ 4ea97d24

4.115
Last change on this file since 4ea97d24 was 4ea97d24, checked in by Sebastian Huber <sebastian.huber@…>, on 11/19/13 at 15:21:54

score/rbtree: Remove "unprotected" from API

  • Property mode set to 100644
File size: 12.3 KB
Line 
1/*
2 * Copyright (c) 2012 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Obere Lagerstr. 30
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.com/license/LICENSE.
13 */
14
15#ifdef HAVE_CONFIG_H
16  #include "config.h"
17#endif
18
19#include "tmacros.h"
20
21#include <rtems.h>
22#include <rtems/rbheap.h>
23#include <rtems/malloc.h>
24#include <rtems/score/rbtreeimpl.h>
25
26/* forward declarations to avoid warnings */
27static rtems_task Init(rtems_task_argument argument);
28
29#define PAGE_SIZE 1024
30
31#define PAGE_COUNT 8
32
33static char area [PAGE_SIZE * PAGE_COUNT + PAGE_SIZE - 1];
34
35static rtems_rbheap_chunk chunks [PAGE_COUNT];
36
37static void extend_descriptors(rtems_rbheap_control *control)
38{
39  rtems_chain_control *chain =
40    rtems_rbheap_get_spare_descriptor_chain(control);
41
42  rtems_rbheap_set_extend_descriptors(
43    control,
44    rtems_rbheap_extend_descriptors_never
45  );
46
47  rtems_chain_initialize(
48    chain,
49    chunks,
50    PAGE_COUNT,
51    sizeof(chunks [0])
52  );
53}
54
55static uintptr_t idx(const rtems_rbheap_chunk *chunk)
56{
57  uintptr_t base = (uintptr_t) area;
58  uintptr_t excess = base % PAGE_SIZE;
59
60  if (excess > 0) {
61    base += PAGE_SIZE - excess;
62  }
63
64  return (chunk->begin - base) / PAGE_SIZE;
65}
66
67typedef struct {
68  const uintptr_t *index_current;
69  const uintptr_t *index_end;
70  const bool *free_current;
71  const bool *free_end;
72} chunk_visitor_context;
73
74static bool chunk_visitor(
75  const RBTree_Node *node,
76  RBTree_Direction dir,
77  void *visitor_arg
78)
79{
80  rtems_rbheap_chunk *chunk = rtems_rbheap_chunk_of_node(node);
81  chunk_visitor_context *context = visitor_arg;
82
83  rtems_test_assert(context->index_current != context->index_end);
84  rtems_test_assert(context->free_current != context->free_end);
85
86  rtems_test_assert(idx(chunk) == *context->index_current);
87  rtems_test_assert(rtems_rbheap_is_chunk_free(chunk) == *context->free_current);
88
89  ++context->index_current;
90  ++context->free_current;
91
92  return false;
93}
94
95static void test_init_chunk_alignment(void)
96{
97  rtems_status_code sc = RTEMS_SUCCESSFUL;
98  rtems_rbheap_control control;
99
100  sc = rtems_rbheap_initialize(
101    &control,
102    area,
103    sizeof(area),
104    0,
105    extend_descriptors,
106    NULL
107  );
108  rtems_test_assert(sc == RTEMS_INVALID_NUMBER);
109}
110
111static void test_init_begin_greater_than_end(void)
112{
113  rtems_status_code sc = RTEMS_SUCCESSFUL;
114  rtems_rbheap_control control;
115
116  sc = rtems_rbheap_initialize(
117    &control,
118    (void *) PAGE_SIZE,
119    (uintptr_t) -PAGE_SIZE,
120    PAGE_SIZE,
121    extend_descriptors,
122    NULL
123  );
124  rtems_test_assert(sc == RTEMS_INVALID_ADDRESS);
125}
126
127static void test_init_begin_greater_than_aligned_begin(void)
128{
129  rtems_status_code sc = RTEMS_SUCCESSFUL;
130  rtems_rbheap_control control;
131
132  sc = rtems_rbheap_initialize(
133    &control,
134    (void *) -(PAGE_SIZE / 2),
135    PAGE_SIZE,
136    PAGE_SIZE,
137    extend_descriptors,
138    NULL
139  );
140  rtems_test_assert(sc == RTEMS_INVALID_ADDRESS);
141}
142
143static void test_init_aligned_begin_greater_than_aligned_end(void)
144{
145  rtems_status_code sc = RTEMS_SUCCESSFUL;
146  rtems_rbheap_control control;
147
148  sc = rtems_rbheap_initialize(
149    &control,
150    (void *) PAGE_SIZE,
151    PAGE_SIZE / 2,
152    PAGE_SIZE,
153    extend_descriptors,
154    NULL
155  );
156  rtems_test_assert(sc == RTEMS_INVALID_ADDRESS);
157}
158
159static void test_init_empty_descriptors(void)
160{
161  rtems_status_code sc = RTEMS_SUCCESSFUL;
162  rtems_rbheap_control control;
163
164  sc = rtems_rbheap_initialize(
165    &control,
166    (void *) PAGE_SIZE,
167    PAGE_SIZE,
168    PAGE_SIZE,
169    rtems_rbheap_extend_descriptors_never,
170    NULL
171  );
172  rtems_test_assert(sc == RTEMS_NO_MEMORY);
173}
174
175static void test_chunk_tree(
176  const rtems_rbheap_control *control,
177  const uintptr_t *index_begin,
178  const uintptr_t *index_end,
179  const bool *free_begin,
180  const bool *free_end
181)
182{
183  chunk_visitor_context context = {
184    .index_current = index_begin,
185    .index_end = index_end,
186    .free_current = free_begin,
187    .free_end = free_end
188  };
189
190  _RBTree_Iterate(
191    &control->chunk_tree,
192    RBT_RIGHT,
193    chunk_visitor,
194    &context
195  );
196}
197
198#define TEST_PAGE_TREE(control, indices, frees) \
199  test_chunk_tree( \
200    control, \
201    indices, \
202    &indices [sizeof(indices) / sizeof(indices [0])], \
203    frees, \
204    &frees [sizeof(frees) / sizeof(frees [0])] \
205  )
206
207static void test_init_successful(rtems_rbheap_control *control)
208{
209  static const uintptr_t indices [] = {
210    0
211  };
212  static const bool frees [] = {
213    true
214  };
215
216  rtems_status_code sc = RTEMS_SUCCESSFUL;
217
218  sc = rtems_rbheap_initialize(
219    control,
220    area,
221    sizeof(area),
222    PAGE_SIZE,
223    extend_descriptors,
224    NULL
225  );
226  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
227
228  TEST_PAGE_TREE(control, indices, frees);
229}
230
231static void test_alloc_and_free_one(void)
232{
233  static const uintptr_t indices_0 [] = {
234    0,
235    PAGE_COUNT - 1
236  };
237  static const bool frees_0 [] = {
238    true,
239    false
240  };
241  static const uintptr_t indices_1 [] = {
242    0
243  };
244  static const bool frees_1 [] = {
245    true,
246  };
247
248  rtems_status_code sc = RTEMS_SUCCESSFUL;
249  rtems_rbheap_control control;
250  void *ptr = NULL;
251
252  test_init_successful(&control);
253
254  ptr = rtems_rbheap_allocate(&control, PAGE_SIZE);
255  rtems_test_assert(ptr != NULL);
256
257  TEST_PAGE_TREE(&control, indices_0, frees_0);
258
259  sc = rtems_rbheap_free(&control, ptr);
260  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
261
262  TEST_PAGE_TREE(&control, indices_1, frees_1);
263}
264
265static void test_alloc_zero(void)
266{
267  static const uintptr_t indices [] = {
268    0
269  };
270  static const bool frees [] = {
271    true
272  };
273
274  rtems_rbheap_control control;
275  void *ptr = NULL;
276
277  test_init_successful(&control);
278
279  ptr = rtems_rbheap_allocate(&control, 0);
280  rtems_test_assert(ptr == NULL);
281
282  TEST_PAGE_TREE(&control, indices, frees);
283}
284
285static void test_alloc_huge_chunk(void)
286{
287  static const uintptr_t indices [] = {
288    0
289  };
290  static const bool frees [] = {
291    true
292  };
293
294  rtems_rbheap_control control;
295  void *ptr = NULL;
296
297  test_init_successful(&control);
298
299  ptr = rtems_rbheap_allocate(&control, (PAGE_COUNT + 1) * PAGE_SIZE);
300  rtems_test_assert(ptr == NULL);
301
302  TEST_PAGE_TREE(&control, indices, frees);
303}
304
305static void test_alloc_one_chunk(void)
306{
307  static const uintptr_t indices_0 [] = {
308    0
309  };
310  static const bool frees_0 [] = {
311    false
312  };
313  static const uintptr_t indices_1 [] = {
314    0
315  };
316  static const bool frees_1 [] = {
317    true,
318  };
319
320  rtems_status_code sc = RTEMS_SUCCESSFUL;
321  rtems_rbheap_control control;
322  void *ptr = NULL;
323
324  test_init_successful(&control);
325
326  ptr = rtems_rbheap_allocate(&control, PAGE_COUNT * PAGE_SIZE);
327  rtems_test_assert(ptr != NULL);
328
329  TEST_PAGE_TREE(&control, indices_0, frees_0);
330
331  sc = rtems_rbheap_free(&control, ptr);
332  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
333
334  TEST_PAGE_TREE(&control, indices_1, frees_1);
335}
336
337static void test_alloc_many_chunks(void)
338{
339  static const uintptr_t indices_0 [] = {
340    0,
341    1,
342    2,
343    3,
344    4,
345    5,
346    6,
347    7
348  };
349  static const bool frees_0 [] = {
350    false,
351    false,
352    false,
353    false,
354    false,
355    false,
356    false,
357    false
358  };
359  static const uintptr_t indices_1 [] = {
360    0
361  };
362  static const bool frees_1 [] = {
363    true,
364  };
365
366  rtems_status_code sc = RTEMS_SUCCESSFUL;
367  rtems_rbheap_control control;
368  void *ptr [PAGE_COUNT];
369  void *null = NULL;
370  int i = 0;
371
372  test_init_successful(&control);
373
374  for (i = 0; i < PAGE_COUNT; ++i) {
375    ptr [i] = rtems_rbheap_allocate(&control, PAGE_SIZE);
376    rtems_test_assert(ptr [i] != NULL);
377  }
378
379  TEST_PAGE_TREE(&control, indices_0, frees_0);
380
381  null = rtems_rbheap_allocate(&control, PAGE_SIZE);
382  rtems_test_assert(null == NULL);
383
384  TEST_PAGE_TREE(&control, indices_0, frees_0);
385
386  for (i = 0; i < PAGE_COUNT; ++i) {
387    sc = rtems_rbheap_free(&control, ptr [i]);
388    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
389  }
390
391  TEST_PAGE_TREE(&control, indices_1, frees_1);
392}
393
394static void test_alloc_misaligned(void)
395{
396  rtems_rbheap_control control;
397  void *p;
398
399  test_init_successful(&control);
400
401  p = rtems_rbheap_allocate(&control, PAGE_SIZE - 1);
402  rtems_test_assert(p != NULL);
403}
404
405static void test_alloc_with_malloc_extend(void)
406{
407  rtems_status_code sc;
408  rtems_rbheap_control control;
409  void *p;
410  void *opaque;
411
412  sc = rtems_rbheap_initialize(
413    &control,
414    area,
415    sizeof(area),
416    PAGE_SIZE,
417    rtems_rbheap_extend_descriptors_with_malloc,
418    NULL
419  );
420  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
421
422  opaque = rtems_heap_greedy_allocate(NULL, 0);
423
424  p = rtems_rbheap_allocate(&control, PAGE_SIZE);
425  rtems_test_assert(p == NULL);
426
427  rtems_heap_greedy_free(opaque);
428
429  p = rtems_rbheap_allocate(&control, PAGE_SIZE);
430  rtems_test_assert(p != NULL);
431}
432
433static void test_free_null(void)
434{
435  rtems_status_code sc = RTEMS_SUCCESSFUL;
436  rtems_rbheap_control control;
437
438  test_init_successful(&control);
439
440  sc = rtems_rbheap_free(&control, NULL);
441  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
442}
443
444static void test_free_invalid(void)
445{
446  rtems_status_code sc = RTEMS_SUCCESSFUL;
447  rtems_rbheap_control control;
448
449  test_init_successful(&control);
450
451  sc = rtems_rbheap_free(&control, (void *) 1);
452  rtems_test_assert(sc == RTEMS_INVALID_ID);
453}
454
455static void test_free_double(void)
456{
457  rtems_status_code sc = RTEMS_SUCCESSFUL;
458  rtems_rbheap_control control;
459  void *ptr = NULL;
460
461  test_init_successful(&control);
462
463  ptr = rtems_rbheap_allocate(&control, PAGE_COUNT * PAGE_SIZE);
464  rtems_test_assert(ptr != NULL);
465
466  sc = rtems_rbheap_free(&control, ptr);
467  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
468
469  sc = rtems_rbheap_free(&control, ptr);
470  rtems_test_assert(sc == RTEMS_INCORRECT_STATE);
471}
472
473enum {
474  LOW,
475  LEFT,
476  MIDDLE,
477  RIGHT,
478  HIGH
479};
480
481static void test_free_merge_left_or_right(bool left)
482{
483  static const uintptr_t indices_0 [] = {
484    0,
485    3,
486    4,
487    5,
488    6,
489    7
490  };
491  static const bool frees_0 [] = {
492    true,
493    false,
494    false,
495    false,
496    false,
497    false
498  };
499  static const uintptr_t indices_1_left [] = {
500    0,
501    3,
502    4,
503    5,
504    6,
505    7
506  };
507  static const bool frees_1_left [] = {
508    true,
509    false,
510    true,
511    false,
512    false,
513    false
514  };
515  static const uintptr_t indices_1_right [] = {
516    0,
517    3,
518    4,
519    5,
520    6,
521    7
522  };
523  static const bool frees_1_right [] = {
524    true,
525    false,
526    false,
527    false,
528    true,
529    false
530  };
531  static const uintptr_t indices_2_left [] = {
532    0,
533    3,
534    4,
535    6,
536    7
537  };
538  static const bool frees_2_left [] = {
539    true,
540    false,
541    true,
542    false,
543    false
544  };
545  static const uintptr_t indices_2_right [] = {
546    0,
547    3,
548    4,
549    5,
550    7
551  };
552  static const bool frees_2_right [] = {
553    true,
554    false,
555    false,
556    true,
557    false
558  };
559
560  rtems_status_code sc = RTEMS_SUCCESSFUL;
561  rtems_rbheap_control control;
562  void *ptr [HIGH + 1];
563  int dir = left ? LEFT : RIGHT;
564  int i = 0;
565
566  test_init_successful(&control);
567
568  for (i = sizeof(ptr) / sizeof(ptr [0]) - 1; i >= 0; --i) {
569    ptr [i] = rtems_rbheap_allocate(&control, PAGE_SIZE);
570    rtems_test_assert(ptr [i] != NULL);
571  }
572
573  TEST_PAGE_TREE(&control, indices_0, frees_0);
574
575  sc = rtems_rbheap_free(&control, ptr [dir]);
576  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
577
578  if (left) {
579    TEST_PAGE_TREE(&control, indices_1_left, frees_1_left);
580  } else {
581    TEST_PAGE_TREE(&control, indices_1_right, frees_1_right);
582  }
583
584  sc = rtems_rbheap_free(&control, ptr [MIDDLE]);
585  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
586
587  if (left) {
588    TEST_PAGE_TREE(&control, indices_2_left, frees_2_left);
589  } else {
590    TEST_PAGE_TREE(&control, indices_2_right, frees_2_right);
591  }
592}
593
594static void Init(rtems_task_argument arg)
595{
596  puts("\n\n*** TEST RBHEAP 1 ***");
597
598  test_init_chunk_alignment();
599  test_init_begin_greater_than_end();
600  test_init_begin_greater_than_aligned_begin();
601  test_init_aligned_begin_greater_than_aligned_end();
602  test_init_empty_descriptors();
603  test_alloc_and_free_one();
604  test_alloc_zero();
605  test_alloc_huge_chunk();
606  test_alloc_one_chunk();
607  test_alloc_many_chunks();
608  test_alloc_misaligned();
609  test_alloc_with_malloc_extend();
610  test_free_null();
611  test_free_invalid();
612  test_free_double();
613  test_free_merge_left_or_right(true);
614  test_free_merge_left_or_right(false);
615
616  puts("*** END OF TEST RBHEAP 1 ***");
617
618  rtems_test_exit(0);
619}
620
621#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
622#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
623
624#define CONFIGURE_MAXIMUM_TASKS 1
625
626#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
627
628#define CONFIGURE_INIT
629
630#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.