diff options
| author | Giovanni Di Sirio <gdisirio@gmail.com> | 2018-09-30 05:38:03 +0000 | 
|---|---|---|
| committer | Giovanni Di Sirio <gdisirio@gmail.com> | 2018-09-30 05:38:03 +0000 | 
| commit | 8fa2bcdad9edb41d01c9ccf1ebbbe135713bf9c0 (patch) | |
| tree | 0810a1752b0312c1ce321281d4fa8a0225e16daf /test/oslib/source | |
| parent | f562ee4948dd1e2b9175dfa3f2a2c071023c6167 (diff) | |
| download | ChibiOS-8fa2bcdad9edb41d01c9ccf1ebbbe135713bf9c0.tar.gz ChibiOS-8fa2bcdad9edb41d01c9ccf1ebbbe135713bf9c0.tar.bz2 ChibiOS-8fa2bcdad9edb41d01c9ccf1ebbbe135713bf9c0.zip  | |
Fixed small errors in pipes and pipes factory.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12307 110e8d01-0319-4d1e-a829-52ad28d1bb01
Diffstat (limited to 'test/oslib/source')
| -rw-r--r-- | test/oslib/source/test/oslib_test_root.c | 10 | ||||
| -rw-r--r-- | test/oslib/source/test/oslib_test_root.h | 1 | ||||
| -rw-r--r-- | test/oslib/source/test/oslib_test_sequence_001.c | 2 | ||||
| -rw-r--r-- | test/oslib/source/test/oslib_test_sequence_002.c | 234 | ||||
| -rw-r--r-- | test/oslib/source/test/oslib_test_sequence_003.c | 299 | ||||
| -rw-r--r-- | test/oslib/source/test/oslib_test_sequence_004.c | 773 | 
6 files changed, 351 insertions, 968 deletions
diff --git a/test/oslib/source/test/oslib_test_root.c b/test/oslib/source/test/oslib_test_root.c index e222dcd06..9f65ccc68 100644 --- a/test/oslib/source/test/oslib_test_root.c +++ b/test/oslib/source/test/oslib_test_root.c @@ -25,6 +25,7 @@   * - @subpage oslib_test_sequence_002
   * - @subpage oslib_test_sequence_003
   * - @subpage oslib_test_sequence_004
 + * - @subpage oslib_test_sequence_005
   * .
   */
 @@ -49,15 +50,18 @@ const testsequence_t * const oslib_test_suite_array[] = {  #if (CH_CFG_USE_MAILBOXES) || defined(__DOXYGEN__)
    &oslib_test_sequence_001,
  #endif
 -#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
 +#if (CH_CFG_USE_PIPES) || defined(__DOXYGEN__)
    &oslib_test_sequence_002,
  #endif
 -#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
 +#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
    &oslib_test_sequence_003,
  #endif
 -#if ((CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE)) || defined(__DOXYGEN__)
 +#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
    &oslib_test_sequence_004,
  #endif
 +#if ((CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE)) || defined(__DOXYGEN__)
 +  &oslib_test_sequence_005,
 +#endif
    NULL
  };
 diff --git a/test/oslib/source/test/oslib_test_root.h b/test/oslib/source/test/oslib_test_root.h index 760ccddc8..01b6eefe9 100644 --- a/test/oslib/source/test/oslib_test_root.h +++ b/test/oslib/source/test/oslib_test_root.h @@ -28,6 +28,7 @@  #include "oslib_test_sequence_002.h"
  #include "oslib_test_sequence_003.h"
  #include "oslib_test_sequence_004.h"
 +#include "oslib_test_sequence_005.h"
  #if !defined(__DOXYGEN__)
 diff --git a/test/oslib/source/test/oslib_test_sequence_001.c b/test/oslib/source/test/oslib_test_sequence_001.c index 74672a242..076efa102 100644 --- a/test/oslib/source/test/oslib_test_sequence_001.c +++ b/test/oslib/source/test/oslib_test_sequence_001.c @@ -26,7 +26,7 @@   * File: @ref oslib_test_sequence_001.c
   *
   * <h2>Description</h2>
 - * This sequence tests the ChibiOS libraryfunctionalities related to
 + * This sequence tests the ChibiOS library functionalities related to
   * mailboxes.
   *
   * <h2>Conditions</h2>
 diff --git a/test/oslib/source/test/oslib_test_sequence_002.c b/test/oslib/source/test/oslib_test_sequence_002.c index bd661ce13..406b4f21d 100644 --- a/test/oslib/source/test/oslib_test_sequence_002.c +++ b/test/oslib/source/test/oslib_test_sequence_002.c @@ -21,259 +21,121 @@   * @file    oslib_test_sequence_002.c
   * @brief   Test Sequence 002 code.
   *
 - * @page oslib_test_sequence_002 [2] Memory Pools
 + * @page oslib_test_sequence_002 [2] Pipes
   *
   * File: @ref oslib_test_sequence_002.c
   *
   * <h2>Description</h2>
   * This sequence tests the ChibiOS library functionalities related to
 - * memory pools.
 + * pipes.
   *
   * <h2>Conditions</h2>
   * This sequence is only executed if the following preprocessor condition
   * evaluates to true:
 - * - CH_CFG_USE_MEMPOOLS
 + * - CH_CFG_USE_PIPES
   * .
   *
   * <h2>Test Cases</h2>
   * - @subpage oslib_test_002_001
 - * - @subpage oslib_test_002_002
 - * - @subpage oslib_test_002_003
   * .
   */
 -#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
 +#if (CH_CFG_USE_PIPES) || defined(__DOXYGEN__)
  /****************************************************************************
   * Shared code.
   ****************************************************************************/
 -#define MEMORY_POOL_SIZE 4
 +#define PIPE_SIZE 16
 -static uint32_t objects[MEMORY_POOL_SIZE];
 -static MEMORYPOOL_DECL(mp1, sizeof (uint32_t), PORT_NATURAL_ALIGN, NULL);
 +static uint8_t buffer[PIPE_SIZE];
 +static PIPE_DECL(pipe1, buffer, PIPE_SIZE);
 -#if CH_CFG_USE_SEMAPHORES
 -static GUARDEDMEMORYPOOL_DECL(gmp1, sizeof (uint32_t), PORT_NATURAL_ALIGN);
 -#endif
 -
 -static void *null_provider(size_t size, unsigned align) {
 -
 -  (void)size;
 -  (void)align;
 -
 -  return NULL;
 -}
 +static const uint8_t pipe_pattern[] = "0123456789ABCDEF";
  /****************************************************************************
   * Test cases.
   ****************************************************************************/
  /**
 - * @page oslib_test_002_001 [2.1] Loading and emptying a memory pool
 + * @page oslib_test_002_001 [2.1] Loading and emptying a pipe, non blocking
   *
   * <h2>Description</h2>
 - * The memory pool functionality is tested by loading and emptying it,
 - * all conditions are tested.
 + * The pipe functionality is tested by loading and emptying it, all
 + * conditions are tested.
   *
   * <h2>Test Steps</h2>
 - * - [2.1.1] Adding the objects to the pool using chPoolLoadArray().
 - * - [2.1.2] Emptying the pool using chPoolAlloc().
 - * - [2.1.3] Now must be empty.
 - * - [2.1.4] Adding the objects to the pool using chPoolFree().
 - * - [2.1.5] Emptying the pool using chPoolAlloc() again.
 - * - [2.1.6] Now must be empty again.
 - * - [2.1.7] Covering the case where a provider is unable to return
 - *   more memory.
 + * - [2.1.1] Filling whole pipe.
 + * - [2.1.2] Emptying pipe.
 + * - [2.1.3].
 + * - [2.1.4].
 + * - [2.1.5].
 + * - [2.1.6].
   * .
   */
  static void oslib_test_002_001_setup(void) {
 -  chPoolObjectInit(&mp1, sizeof (uint32_t), NULL);
 +  chPipeObjectInit(&pipe1, buffer, PIPE_SIZE);
  }
  static void oslib_test_002_001_execute(void) {
    unsigned i;
 -  /* [2.1.1] Adding the objects to the pool using chPoolLoadArray().*/
 +  /* [2.1.1] Filling whole pipe.*/
    test_set_step(1);
    {
 -    chPoolLoadArray(&mp1, objects, MEMORY_POOL_SIZE);
 +    msg_t msg;
 +
 +    msg = chPipeWriteTimeout(&pipe1, pipe_pattern, PIPE_SIZE, TIME_IMMEDIATE);
 +    test_assert(msg == PIPE_SIZE, "wrong size");
 +    test_assert((pipe1.rdptr == pipe1.buffer) &&
 +                (pipe1.wrptr == pipe1.buffer) &&
 +                (pipe1.cnt == PIPE_SIZE),
 +                "invalid pipe state");
    }
 -  /* [2.1.2] Emptying the pool using chPoolAlloc().*/
 +  /* [2.1.2] Emptying pipe.*/
    test_set_step(2);
    {
 -    for (i = 0; i < MEMORY_POOL_SIZE; i++)
 -      test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
 +    msg_t msg;
 +    uint8_t buf[PIPE_SIZE];
 +
 +    msg = chPipeReadTimeout(&pipe1, buf, PIPE_SIZE, TIME_IMMEDIATE);
 +    test_assert(msg == PIPE_SIZE, "wrong size");
 +    test_assert((pipe1.rdptr == pipe1.buffer) &&
 +                (pipe1.wrptr == pipe1.buffer) &&
 +                (pipe1.cnt == 0),
 +                "invalid pipe state");
    }
 -  /* [2.1.3] Now must be empty.*/
 +  /* [2.1.3].*/
    test_set_step(3);
    {
 -    test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
    }
 -  /* [2.1.4] Adding the objects to the pool using chPoolFree().*/
 +  /* [2.1.4].*/
    test_set_step(4);
    {
 -    for (i = 0; i < MEMORY_POOL_SIZE; i++)
 -      chPoolFree(&mp1, &objects[i]);
    }
 -  /* [2.1.5] Emptying the pool using chPoolAlloc() again.*/
 +  /* [2.1.5].*/
    test_set_step(5);
    {
 -    for (i = 0; i < MEMORY_POOL_SIZE; i++)
 -      test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
    }
 -  /* [2.1.6] Now must be empty again.*/
 +  /* [2.1.6].*/
    test_set_step(6);
    {
 -    test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
 -  }
 -
 -  /* [2.1.7] Covering the case where a provider is unable to return
 -     more memory.*/
 -  test_set_step(7);
 -  {
 -    chPoolObjectInit(&mp1, sizeof (uint32_t), null_provider);
 -    test_assert(chPoolAlloc(&mp1) == NULL, "provider returned memory");
    }
  }
  static const testcase_t oslib_test_002_001 = {
 -  "Loading and emptying a memory pool",
 +  "Loading and emptying a pipe, non blocking",
    oslib_test_002_001_setup,
    NULL,
    oslib_test_002_001_execute
  };
 -#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
 -/**
 - * @page oslib_test_002_002 [2.2] Loading and emptying a guarded memory pool without waiting
 - *
 - * <h2>Description</h2>
 - * The memory pool functionality is tested by loading and emptying it,
 - * all conditions are tested.
 - *
 - * <h2>Conditions</h2>
 - * This test is only executed if the following preprocessor condition
 - * evaluates to true:
 - * - CH_CFG_USE_SEMAPHORES
 - * .
 - *
 - * <h2>Test Steps</h2>
 - * - [2.2.1] Adding the objects to the pool using
 - *   chGuardedPoolLoadArray().
 - * - [2.2.2] Emptying the pool using chGuardedPoolAllocTimeout().
 - * - [2.2.3] Now must be empty.
 - * - [2.2.4] Adding the objects to the pool using chGuardedPoolFree().
 - * - [2.2.5] Emptying the pool using chGuardedPoolAllocTimeout() again.
 - * - [2.2.6] Now must be empty again.
 - * .
 - */
 -
 -static void oslib_test_002_002_setup(void) {
 -  chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
 -}
 -
 -static void oslib_test_002_002_execute(void) {
 -  unsigned i;
 -
 -  /* [2.2.1] Adding the objects to the pool using
 -     chGuardedPoolLoadArray().*/
 -  test_set_step(1);
 -  {
 -    chGuardedPoolLoadArray(&gmp1, objects, MEMORY_POOL_SIZE);
 -  }
 -
 -  /* [2.2.2] Emptying the pool using chGuardedPoolAllocTimeout().*/
 -  test_set_step(2);
 -  {
 -    for (i = 0; i < MEMORY_POOL_SIZE; i++)
 -      test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty");
 -  }
 -
 -  /* [2.2.3] Now must be empty.*/
 -  test_set_step(3);
 -  {
 -    test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty");
 -  }
 -
 -  /* [2.2.4] Adding the objects to the pool using
 -     chGuardedPoolFree().*/
 -  test_set_step(4);
 -  {
 -    for (i = 0; i < MEMORY_POOL_SIZE; i++)
 -      chGuardedPoolFree(&gmp1, &objects[i]);
 -  }
 -
 -  /* [2.2.5] Emptying the pool using chGuardedPoolAllocTimeout()
 -     again.*/
 -  test_set_step(5);
 -  {
 -    for (i = 0; i < MEMORY_POOL_SIZE; i++)
 -      test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty");
 -  }
 -
 -  /* [2.2.6] Now must be empty again.*/
 -  test_set_step(6);
 -  {
 -    test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty");
 -  }
 -}
 -
 -static const testcase_t oslib_test_002_002 = {
 -  "Loading and emptying a guarded memory pool without waiting",
 -  oslib_test_002_002_setup,
 -  NULL,
 -  oslib_test_002_002_execute
 -};
 -#endif /* CH_CFG_USE_SEMAPHORES */
 -
 -#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
 -/**
 - * @page oslib_test_002_003 [2.3] Guarded Memory Pools timeout
 - *
 - * <h2>Description</h2>
 - * The timeout features for the Guarded Memory Pools is tested.
 - *
 - * <h2>Conditions</h2>
 - * This test is only executed if the following preprocessor condition
 - * evaluates to true:
 - * - CH_CFG_USE_SEMAPHORES
 - * .
 - *
 - * <h2>Test Steps</h2>
 - * - [2.3.1] Trying to allocate with 100mS timeout, must fail because
 - *   the pool is empty.
 - * .
 - */
 -
 -static void oslib_test_002_003_setup(void) {
 -  chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
 -}
 -
 -static void oslib_test_002_003_execute(void) {
 -
 -  /* [2.3.1] Trying to allocate with 100mS timeout, must fail because
 -     the pool is empty.*/
 -  test_set_step(1);
 -  {
 -    test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_MS2I(100)) == NULL, "list not empty");
 -  }
 -}
 -
 -static const testcase_t oslib_test_002_003 = {
 -  "Guarded Memory Pools timeout",
 -  oslib_test_002_003_setup,
 -  NULL,
 -  oslib_test_002_003_execute
 -};
 -#endif /* CH_CFG_USE_SEMAPHORES */
 -
  /****************************************************************************
   * Exported data.
   ****************************************************************************/
 @@ -283,21 +145,15 @@ static const testcase_t oslib_test_002_003 = {   */
  const testcase_t * const oslib_test_sequence_002_array[] = {
    &oslib_test_002_001,
 -#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
 -  &oslib_test_002_002,
 -#endif
 -#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
 -  &oslib_test_002_003,
 -#endif
    NULL
  };
  /**
 - * @brief   Memory Pools.
 + * @brief   Pipes.
   */
  const testsequence_t oslib_test_sequence_002 = {
 -  "Memory Pools",
 +  "Pipes",
    oslib_test_sequence_002_array
  };
 -#endif /* CH_CFG_USE_MEMPOOLS */
 +#endif /* CH_CFG_USE_PIPES */
 diff --git a/test/oslib/source/test/oslib_test_sequence_003.c b/test/oslib/source/test/oslib_test_sequence_003.c index 9f623e9db..7bfd208e0 100644 --- a/test/oslib/source/test/oslib_test_sequence_003.c +++ b/test/oslib/source/test/oslib_test_sequence_003.c @@ -21,240 +21,258 @@   * @file    oslib_test_sequence_003.c
   * @brief   Test Sequence 003 code.
   *
 - * @page oslib_test_sequence_003 [3] Memory Heaps
 + * @page oslib_test_sequence_003 [3] Memory Pools
   *
   * File: @ref oslib_test_sequence_003.c
   *
   * <h2>Description</h2>
   * This sequence tests the ChibiOS library functionalities related to
 - * memory heaps.
 + * memory pools.
   *
   * <h2>Conditions</h2>
   * This sequence is only executed if the following preprocessor condition
   * evaluates to true:
 - * - CH_CFG_USE_HEAP
 + * - CH_CFG_USE_MEMPOOLS
   * .
   *
   * <h2>Test Cases</h2>
   * - @subpage oslib_test_003_001
   * - @subpage oslib_test_003_002
 + * - @subpage oslib_test_003_003
   * .
   */
 -#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
 +#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
  /****************************************************************************
   * Shared code.
   ****************************************************************************/
 -#define ALLOC_SIZE 16
 -#define HEAP_SIZE (ALLOC_SIZE * 8)
 +#define MEMORY_POOL_SIZE 4
 -static memory_heap_t test_heap;
 -static uint8_t test_heap_buffer[HEAP_SIZE];
 +static uint32_t objects[MEMORY_POOL_SIZE];
 +static MEMORYPOOL_DECL(mp1, sizeof (uint32_t), PORT_NATURAL_ALIGN, NULL);
 +
 +#if CH_CFG_USE_SEMAPHORES
 +static GUARDEDMEMORYPOOL_DECL(gmp1, sizeof (uint32_t), PORT_NATURAL_ALIGN);
 +#endif
 +
 +static void *null_provider(size_t size, unsigned align) {
 +
 +  (void)size;
 +  (void)align;
 +
 +  return NULL;
 +}
  /****************************************************************************
   * Test cases.
   ****************************************************************************/
  /**
 - * @page oslib_test_003_001 [3.1] Allocation and fragmentation
 + * @page oslib_test_003_001 [3.1] Loading and emptying a memory pool
   *
   * <h2>Description</h2>
 - * Series of allocations/deallocations are performed in carefully
 - * designed sequences in order to stimulate all the possible code paths
 - * inside the allocator. The test expects to find the heap back to the
 - * initial status after each sequence.
 + * The memory pool functionality is tested by loading and emptying it,
 + * all conditions are tested.
   *
   * <h2>Test Steps</h2>
 - * - [3.1.1] Testing initial conditions, the heap must not be
 - *   fragmented and one free block present.
 - * - [3.1.2] Trying to allocate an block bigger than available space,
 - *   an error is expected.
 - * - [3.1.3] Single block allocation using chHeapAlloc() then the block
 - *   is freed using chHeapFree(), must not fail.
 - * - [3.1.4] Using chHeapStatus() to assess the heap state. There must
 - *   be at least one free block of sufficient size.
 - * - [3.1.5] Allocating then freeing in the same order.
 - * - [3.1.6] Allocating then freeing in reverse order.
 - * - [3.1.7] Small fragments handling. Checking the behavior when
 - *   allocating blocks with size not multiple of alignment unit.
 - * - [3.1.8] Skipping a fragment, the first fragment in the list is too
 - *   small so the allocator must pick the second one.
 - * - [3.1.9] Allocating the whole available space.
 - * - [3.1.10] Testing final conditions. The heap geometry must be the
 - *   same than the one registered at beginning.
 + * - [3.1.1] Adding the objects to the pool using chPoolLoadArray().
 + * - [3.1.2] Emptying the pool using chPoolAlloc().
 + * - [3.1.3] Now must be empty.
 + * - [3.1.4] Adding the objects to the pool using chPoolFree().
 + * - [3.1.5] Emptying the pool using chPoolAlloc() again.
 + * - [3.1.6] Now must be empty again.
 + * - [3.1.7] Covering the case where a provider is unable to return
 + *   more memory.
   * .
   */
  static void oslib_test_003_001_setup(void) {
 -  chHeapObjectInit(&test_heap, test_heap_buffer, sizeof(test_heap_buffer));
 +  chPoolObjectInit(&mp1, sizeof (uint32_t), NULL);
  }
  static void oslib_test_003_001_execute(void) {
 -  void *p1, *p2, *p3;
 -  size_t n, sz;
 +  unsigned i;
 -  /* [3.1.1] Testing initial conditions, the heap must not be
 -     fragmented and one free block present.*/
 +  /* [3.1.1] Adding the objects to the pool using chPoolLoadArray().*/
    test_set_step(1);
    {
 -    test_assert(chHeapStatus(&test_heap, &sz, NULL) == 1, "heap fragmented");
 +    chPoolLoadArray(&mp1, objects, MEMORY_POOL_SIZE);
    }
 -  /* [3.1.2] Trying to allocate an block bigger than available space,
 -     an error is expected.*/
 +  /* [3.1.2] Emptying the pool using chPoolAlloc().*/
    test_set_step(2);
    {
 -    p1 = chHeapAlloc(&test_heap, sizeof test_heap_buffer * 2);
 -    test_assert(p1 == NULL, "allocation not failed");
 +    for (i = 0; i < MEMORY_POOL_SIZE; i++)
 +      test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
    }
 -  /* [3.1.3] Single block allocation using chHeapAlloc() then the block
 -     is freed using chHeapFree(), must not fail.*/
 +  /* [3.1.3] Now must be empty.*/
    test_set_step(3);
    {
 -    p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
 -    test_assert(p1 != NULL, "allocation failed");
 -    chHeapFree(p1);
 +    test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
    }
 -  /* [3.1.4] Using chHeapStatus() to assess the heap state. There must
 -     be at least one free block of sufficient size.*/
 +  /* [3.1.4] Adding the objects to the pool using chPoolFree().*/
    test_set_step(4);
    {
 -    size_t total_size, largest_size;
 -
 -    n = chHeapStatus(&test_heap, &total_size, &largest_size);
 -    test_assert(n == 1, "missing free block");
 -    test_assert(total_size >= ALLOC_SIZE, "unexpected heap state");
 -    test_assert(total_size == largest_size, "unexpected heap state");
 +    for (i = 0; i < MEMORY_POOL_SIZE; i++)
 +      chPoolFree(&mp1, &objects[i]);
    }
 -  /* [3.1.5] Allocating then freeing in the same order.*/
 +  /* [3.1.5] Emptying the pool using chPoolAlloc() again.*/
    test_set_step(5);
    {
 -    p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
 -    p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
 -    p3 = chHeapAlloc(&test_heap, ALLOC_SIZE);
 -    chHeapFree(p1);                                 /* Does not merge.*/
 -    chHeapFree(p2);                                 /* Merges backward.*/
 -    chHeapFree(p3);                                 /* Merges both sides.*/
 -    test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
 +    for (i = 0; i < MEMORY_POOL_SIZE; i++)
 +      test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
    }
 -  /* [3.1.6] Allocating then freeing in reverse order.*/
 +  /* [3.1.6] Now must be empty again.*/
    test_set_step(6);
    {
 -    p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
 -    p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
 -    p3 = chHeapAlloc(&test_heap, ALLOC_SIZE);
 -    chHeapFree(p3);                                 /* Merges forward.*/
 -    chHeapFree(p2);                                 /* Merges forward.*/
 -    chHeapFree(p1);                                 /* Merges forward.*/
 -    test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
 +    test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
    }
 -  /* [3.1.7] Small fragments handling. Checking the behavior when
 -     allocating blocks with size not multiple of alignment unit.*/
 +  /* [3.1.7] Covering the case where a provider is unable to return
 +     more memory.*/
    test_set_step(7);
    {
 -    p1 = chHeapAlloc(&test_heap, ALLOC_SIZE + 1);
 -    p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
 -    chHeapFree(p1);
 -    test_assert(chHeapStatus(&test_heap, &n, NULL) == 2, "invalid state");
 -    p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
 -    /* Note, the first situation happens when the alignment size is smaller
 -       than the header size, the second in the other cases.*/
 -    test_assert((chHeapStatus(&test_heap, &n, NULL) == 1) ||
 -                (chHeapStatus(&test_heap, &n, NULL) == 2), "heap fragmented");
 -    chHeapFree(p2);
 -    chHeapFree(p1);
 -    test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
 -  }
 -
 -  /* [3.1.8] Skipping a fragment, the first fragment in the list is too
 -     small so the allocator must pick the second one.*/
 -  test_set_step(8);
 -  {
 -    p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
 -    p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
 -    chHeapFree(p1);
 -    test_assert( chHeapStatus(&test_heap, &n, NULL) == 2, "invalid state");
 -    p1 = chHeapAlloc(&test_heap, ALLOC_SIZE * 2); /* Skips first fragment.*/
 -    chHeapFree(p1);
 -    chHeapFree(p2);
 -    test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
 -  }
 -
 -  /* [3.1.9] Allocating the whole available space.*/
 -  test_set_step(9);
 -  {
 -    (void)chHeapStatus(&test_heap, &n, NULL);
 -    p1 = chHeapAlloc(&test_heap, n);
 -    test_assert(p1 != NULL, "allocation failed");
 -    test_assert(chHeapStatus(&test_heap, NULL, NULL) == 0, "not empty");
 -    chHeapFree(p1);
 -  }
 -
 -  /* [3.1.10] Testing final conditions. The heap geometry must be the
 -     same than the one registered at beginning.*/
 -  test_set_step(10);
 -  {
 -    test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
 -    test_assert(n == sz, "size changed");
 +    chPoolObjectInit(&mp1, sizeof (uint32_t), null_provider);
 +    test_assert(chPoolAlloc(&mp1) == NULL, "provider returned memory");
    }
  }
  static const testcase_t oslib_test_003_001 = {
 -  "Allocation and fragmentation",
 +  "Loading and emptying a memory pool",
    oslib_test_003_001_setup,
    NULL,
    oslib_test_003_001_execute
  };
 +#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
  /**
 - * @page oslib_test_003_002 [3.2] Default Heap
 + * @page oslib_test_003_002 [3.2] Loading and emptying a guarded memory pool without waiting
   *
   * <h2>Description</h2>
 - * The default heap is pre-allocated in the system. We test base
 - * functionality.
 + * The memory pool functionality is tested by loading and emptying it,
 + * all conditions are tested.
 + *
 + * <h2>Conditions</h2>
 + * This test is only executed if the following preprocessor condition
 + * evaluates to true:
 + * - CH_CFG_USE_SEMAPHORES
 + * .
   *
   * <h2>Test Steps</h2>
 - * - [3.2.1] Single block allocation using chHeapAlloc() then the block
 - *   is freed using chHeapFree(), must not fail.
 - * - [3.2.2] Testing allocation failure.
 + * - [3.2.1] Adding the objects to the pool using
 + *   chGuardedPoolLoadArray().
 + * - [3.2.2] Emptying the pool using chGuardedPoolAllocTimeout().
 + * - [3.2.3] Now must be empty.
 + * - [3.2.4] Adding the objects to the pool using chGuardedPoolFree().
 + * - [3.2.5] Emptying the pool using chGuardedPoolAllocTimeout() again.
 + * - [3.2.6] Now must be empty again.
   * .
   */
 +static void oslib_test_003_002_setup(void) {
 +  chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
 +}
 +
  static void oslib_test_003_002_execute(void) {
 -  void *p1;
 -  size_t total_size, largest_size;
 +  unsigned i;
 -  /* [3.2.1] Single block allocation using chHeapAlloc() then the block
 -     is freed using chHeapFree(), must not fail.*/
 +  /* [3.2.1] Adding the objects to the pool using
 +     chGuardedPoolLoadArray().*/
    test_set_step(1);
    {
 -    (void)chHeapStatus(NULL, &total_size, &largest_size);
 -    p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
 -    test_assert(p1 != NULL, "allocation failed");
 -    chHeapFree(p1);
 +    chGuardedPoolLoadArray(&gmp1, objects, MEMORY_POOL_SIZE);
    }
 -  /* [3.2.2] Testing allocation failure.*/
 +  /* [3.2.2] Emptying the pool using chGuardedPoolAllocTimeout().*/
    test_set_step(2);
    {
 -    p1 = chHeapAlloc(NULL, (size_t)-256);
 -    test_assert(p1 == NULL, "allocation not failed");
 +    for (i = 0; i < MEMORY_POOL_SIZE; i++)
 +      test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty");
 +  }
 +
 +  /* [3.2.3] Now must be empty.*/
 +  test_set_step(3);
 +  {
 +    test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty");
 +  }
 +
 +  /* [3.2.4] Adding the objects to the pool using
 +     chGuardedPoolFree().*/
 +  test_set_step(4);
 +  {
 +    for (i = 0; i < MEMORY_POOL_SIZE; i++)
 +      chGuardedPoolFree(&gmp1, &objects[i]);
 +  }
 +
 +  /* [3.2.5] Emptying the pool using chGuardedPoolAllocTimeout()
 +     again.*/
 +  test_set_step(5);
 +  {
 +    for (i = 0; i < MEMORY_POOL_SIZE; i++)
 +      test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty");
 +  }
 +
 +  /* [3.2.6] Now must be empty again.*/
 +  test_set_step(6);
 +  {
 +    test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty");
    }
  }
  static const testcase_t oslib_test_003_002 = {
 -  "Default Heap",
 -  NULL,
 +  "Loading and emptying a guarded memory pool without waiting",
 +  oslib_test_003_002_setup,
    NULL,
    oslib_test_003_002_execute
  };
 +#endif /* CH_CFG_USE_SEMAPHORES */
 +
 +#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
 +/**
 + * @page oslib_test_003_003 [3.3] Guarded Memory Pools timeout
 + *
 + * <h2>Description</h2>
 + * The timeout features for the Guarded Memory Pools is tested.
 + *
 + * <h2>Conditions</h2>
 + * This test is only executed if the following preprocessor condition
 + * evaluates to true:
 + * - CH_CFG_USE_SEMAPHORES
 + * .
 + *
 + * <h2>Test Steps</h2>
 + * - [3.3.1] Trying to allocate with 100mS timeout, must fail because
 + *   the pool is empty.
 + * .
 + */
 +
 +static void oslib_test_003_003_setup(void) {
 +  chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
 +}
 +
 +static void oslib_test_003_003_execute(void) {
 +
 +  /* [3.3.1] Trying to allocate with 100mS timeout, must fail because
 +     the pool is empty.*/
 +  test_set_step(1);
 +  {
 +    test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_MS2I(100)) == NULL, "list not empty");
 +  }
 +}
 +
 +static const testcase_t oslib_test_003_003 = {
 +  "Guarded Memory Pools timeout",
 +  oslib_test_003_003_setup,
 +  NULL,
 +  oslib_test_003_003_execute
 +};
 +#endif /* CH_CFG_USE_SEMAPHORES */
  /****************************************************************************
   * Exported data.
 @@ -265,16 +283,21 @@ static const testcase_t oslib_test_003_002 = {   */
  const testcase_t * const oslib_test_sequence_003_array[] = {
    &oslib_test_003_001,
 +#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
    &oslib_test_003_002,
 +#endif
 +#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
 +  &oslib_test_003_003,
 +#endif
    NULL
  };
  /**
 - * @brief   Memory Heaps.
 + * @brief   Memory Pools.
   */
  const testsequence_t oslib_test_sequence_003 = {
 -  "Memory Heaps",
 +  "Memory Pools",
    oslib_test_sequence_003_array
  };
 -#endif /* CH_CFG_USE_HEAP */
 +#endif /* CH_CFG_USE_MEMPOOLS */
 diff --git a/test/oslib/source/test/oslib_test_sequence_004.c b/test/oslib/source/test/oslib_test_sequence_004.c index a053008d8..84b466a64 100644 --- a/test/oslib/source/test/oslib_test_sequence_004.c +++ b/test/oslib/source/test/oslib_test_sequence_004.c @@ -21,725 +21,240 @@   * @file    oslib_test_sequence_004.c
   * @brief   Test Sequence 004 code.
   *
 - * @page oslib_test_sequence_004 [4] Objects Factory
 + * @page oslib_test_sequence_004 [4] Memory Heaps
   *
   * File: @ref oslib_test_sequence_004.c
   *
   * <h2>Description</h2>
   * This sequence tests the ChibiOS library functionalities related to
 - * the object factory.
 + * memory heaps.
   *
   * <h2>Conditions</h2>
   * This sequence is only executed if the following preprocessor condition
   * evaluates to true:
 - * - (CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE)
 + * - CH_CFG_USE_HEAP
   * .
   *
   * <h2>Test Cases</h2>
   * - @subpage oslib_test_004_001
   * - @subpage oslib_test_004_002
 - * - @subpage oslib_test_004_003
 - * - @subpage oslib_test_004_004
 - * - @subpage oslib_test_004_005
 - * - @subpage oslib_test_004_006
   * .
   */
 -#if ((CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE)) || defined(__DOXYGEN__)
 +#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
  /****************************************************************************
   * Shared code.
   ****************************************************************************/
 +#define ALLOC_SIZE 16
 +#define HEAP_SIZE (ALLOC_SIZE * 8)
 +
 +static memory_heap_t test_heap;
 +static uint8_t test_heap_buffer[HEAP_SIZE];
  /****************************************************************************
   * Test cases.
   ****************************************************************************/
 -#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXYGEN__)
  /**
 - * @page oslib_test_004_001 [4.1] Objects Registry
 + * @page oslib_test_004_001 [4.1] Allocation and fragmentation
   *
   * <h2>Description</h2>
 - * This test case verifies the static objects registry.
 - *
 - * <h2>Conditions</h2>
 - * This test is only executed if the following preprocessor condition
 - * evaluates to true:
 - * - CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE
 - * .
 + * Series of allocations/deallocations are performed in carefully
 + * designed sequences in order to stimulate all the possible code paths
 + * inside the allocator. The test expects to find the heap back to the
 + * initial status after each sequence.
   *
   * <h2>Test Steps</h2>
 - * - [4.1.1] Retrieving a registered object by name, must not exist.
 - * - [4.1.2] Registering an object, it must not exists, must succeed.
 - * - [4.1.3] Registering an object with the same name, must fail.
 - * - [4.1.4] Retrieving the registered object by name, must exist, then
 - *   increasing the reference counter, finally releasing both
 - *   references.
 - * - [4.1.5] Releasing the first reference to the object, must not
 - *   trigger an assertion.
 - * - [4.1.6] Retrieving the registered object by name again, must not
 - *   exist.
 + * - [4.1.1] Testing initial conditions, the heap must not be
 + *   fragmented and one free block present.
 + * - [4.1.2] Trying to allocate an block bigger than available space,
 + *   an error is expected.
 + * - [4.1.3] Single block allocation using chHeapAlloc() then the block
 + *   is freed using chHeapFree(), must not fail.
 + * - [4.1.4] Using chHeapStatus() to assess the heap state. There must
 + *   be at least one free block of sufficient size.
 + * - [4.1.5] Allocating then freeing in the same order.
 + * - [4.1.6] Allocating then freeing in reverse order.
 + * - [4.1.7] Small fragments handling. Checking the behavior when
 + *   allocating blocks with size not multiple of alignment unit.
 + * - [4.1.8] Skipping a fragment, the first fragment in the list is too
 + *   small so the allocator must pick the second one.
 + * - [4.1.9] Allocating the whole available space.
 + * - [4.1.10] Testing final conditions. The heap geometry must be the
 + *   same than the one registered at beginning.
   * .
   */
 -static void oslib_test_004_001_teardown(void) {
 -  registered_object_t *rop;
 -
 -  rop = chFactoryFindObject("myobj");
 -  if (rop != NULL) {
 -    while (rop->element.refs > 0U) {
 -      chFactoryReleaseObject(rop);
 -    }
 -  }
 +static void oslib_test_004_001_setup(void) {
 +  chHeapObjectInit(&test_heap, test_heap_buffer, sizeof(test_heap_buffer));
  }
  static void oslib_test_004_001_execute(void) {
 -  registered_object_t *rop;
 +  void *p1, *p2, *p3;
 +  size_t n, sz;
 -  /* [4.1.1] Retrieving a registered object by name, must not exist.*/
 +  /* [4.1.1] Testing initial conditions, the heap must not be
 +     fragmented and one free block present.*/
    test_set_step(1);
    {
 -    rop = chFactoryFindObject("myobj");
 -    test_assert(rop == NULL, "found");
 +    test_assert(chHeapStatus(&test_heap, &sz, NULL) == 1, "heap fragmented");
    }
 -  /* [4.1.2] Registering an object, it must not exists, must succeed.*/
 +  /* [4.1.2] Trying to allocate an block bigger than available space,
 +     an error is expected.*/
    test_set_step(2);
    {
 -    static uint32_t myobj = 0x55aa;
 -
 -    rop = chFactoryRegisterObject("myobj", (void *)&myobj);
 -    test_assert(rop != NULL, "cannot register");
 +    p1 = chHeapAlloc(&test_heap, sizeof test_heap_buffer * 2);
 +    test_assert(p1 == NULL, "allocation not failed");
    }
 -  /* [4.1.3] Registering an object with the same name, must fail.*/
 +  /* [4.1.3] Single block allocation using chHeapAlloc() then the block
 +     is freed using chHeapFree(), must not fail.*/
    test_set_step(3);
    {
 -    registered_object_t *rop1;
 -    static uint32_t myobj = 0x55aa;
 -
 -    rop1 = chFactoryRegisterObject("myobj", (void *)&myobj);
 -    test_assert(rop1 == NULL, "can register");
 +    p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
 +    test_assert(p1 != NULL, "allocation failed");
 +    chHeapFree(p1);
    }
 -  /* [4.1.4] Retrieving the registered object by name, must exist, then
 -     increasing the reference counter, finally releasing both
 -     references.*/
 +  /* [4.1.4] Using chHeapStatus() to assess the heap state. There must
 +     be at least one free block of sufficient size.*/
    test_set_step(4);
    {
 -    registered_object_t *rop1, *rop2;
 -
 -    rop1 = chFactoryFindObject("myobj");
 -    test_assert(rop1 != NULL, "not found");
 -    test_assert(*(uint32_t *)(rop1->objp) == 0x55aa, "object mismatch");
 -    test_assert(rop == rop1, "object reference mismatch");
 -    test_assert(rop1->element.refs == 2, "object reference mismatch");
 -
 -    rop2 = (registered_object_t *)chFactoryDuplicateReference(&rop1->element);
 -    test_assert(rop1 == rop2, "object reference mismatch");
 -    test_assert(*(uint32_t *)(rop2->objp) == 0x55aa, "object mismatch");
 -    test_assert(rop2->element.refs == 3, "object reference mismatch");
 -
 -    chFactoryReleaseObject(rop2);
 -    test_assert(rop1->element.refs == 2, "references mismatch");
 +    size_t total_size, largest_size;
 -    chFactoryReleaseObject(rop1);
 -    test_assert(rop->element.refs == 1, "references mismatch");
 +    n = chHeapStatus(&test_heap, &total_size, &largest_size);
 +    test_assert(n == 1, "missing free block");
 +    test_assert(total_size >= ALLOC_SIZE, "unexpected heap state");
 +    test_assert(total_size == largest_size, "unexpected heap state");
    }
 -  /* [4.1.5] Releasing the first reference to the object, must not
 -     trigger an assertion.*/
 +  /* [4.1.5] Allocating then freeing in the same order.*/
    test_set_step(5);
    {
 -    chFactoryReleaseObject(rop);
 +    p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
 +    p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
 +    p3 = chHeapAlloc(&test_heap, ALLOC_SIZE);
 +    chHeapFree(p1);                                 /* Does not merge.*/
 +    chHeapFree(p2);                                 /* Merges backward.*/
 +    chHeapFree(p3);                                 /* Merges both sides.*/
 +    test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
    }
 -  /* [4.1.6] Retrieving the registered object by name again, must not
 -     exist.*/
 +  /* [4.1.6] Allocating then freeing in reverse order.*/
    test_set_step(6);
    {
 -    rop = chFactoryFindObject("myobj");
 -    test_assert(rop == NULL, "found");
 -  }
 -}
 -
 -static const testcase_t oslib_test_004_001 = {
 -  "Objects Registry",
 -  NULL,
 -  oslib_test_004_001_teardown,
 -  oslib_test_004_001_execute
 -};
 -#endif /* CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE */
 -
 -#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXYGEN__)
 -/**
 - * @page oslib_test_004_002 [4.2] Dynamic Buffers Factory
 - *
 - * <h2>Description</h2>
 - * This test case verifies the dynamic buffers factory.
 - *
 - * <h2>Conditions</h2>
 - * This test is only executed if the following preprocessor condition
 - * evaluates to true:
 - * - CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE
 - * .
 - *
 - * <h2>Test Steps</h2>
 - * - [4.2.1] Retrieving a dynamic buffer by name, must not exist.
 - * - [4.2.2] Creating a dynamic buffer it must not exists, must
 - *   succeed.
 - * - [4.2.3] Creating a dynamic buffer with the same name, must fail.
 - * - [4.2.4] Retrieving the dynamic buffer by name, must exist, then
 - *   increasing the reference counter, finally releasing both
 - *   references.
 - * - [4.2.5] Releasing the first reference to the dynamic buffer, must
 - *   not trigger an assertion.
 - * - [4.2.6] Retrieving the dynamic buffer by name again, must not
 - *   exist.
 - * .
 - */
 -
 -static void oslib_test_004_002_teardown(void) {
 -  dyn_buffer_t *dbp;
 -
 -  dbp = chFactoryFindBuffer("mybuf");
 -  if (dbp != NULL) {
 -    while (dbp->element.refs > 0U) {
 -      chFactoryReleaseBuffer(dbp);
 -    }
 -  }
 -}
 -
 -static void oslib_test_004_002_execute(void) {
 -  dyn_buffer_t *dbp;
 -
 -  /* [4.2.1] Retrieving a dynamic buffer by name, must not exist.*/
 -  test_set_step(1);
 -  {
 -    dbp = chFactoryFindBuffer("mybuf");
 -    test_assert(dbp == NULL, "found");
 -  }
 -
 -  /* [4.2.2] Creating a dynamic buffer it must not exists, must
 -     succeed.*/
 -  test_set_step(2);
 -  {
 -    dbp = chFactoryCreateBuffer("mybuf", 128U);
 -    test_assert(dbp != NULL, "cannot create");
 -  }
 -
 -  /* [4.2.3] Creating a dynamic buffer with the same name, must fail.*/
 -  test_set_step(3);
 -  {
 -    dyn_buffer_t *dbp1;
 -
 -    dbp1 = chFactoryCreateBuffer("mybuf", 128U);
 -    test_assert(dbp1 == NULL, "can create");
 -  }
 -
 -  /* [4.2.4] Retrieving the dynamic buffer by name, must exist, then
 -     increasing the reference counter, finally releasing both
 -     references.*/
 -  test_set_step(4);
 -  {
 -    dyn_buffer_t *dbp1, *dbp2;
 -
 -    dbp1 = chFactoryFindBuffer("mybuf");
 -    test_assert(dbp1 != NULL, "not found");
 -    test_assert(dbp == dbp1, "object reference mismatch");
 -    test_assert(dbp1->element.refs == 2, "object reference mismatch");
 -
 -    dbp2 = (dyn_buffer_t *)chFactoryDuplicateReference(&dbp1->element);
 -    test_assert(dbp1 == dbp2, "object reference mismatch");
 -    test_assert(dbp2->element.refs == 3, "object reference mismatch");
 -
 -    chFactoryReleaseBuffer(dbp2);
 -    test_assert(dbp1->element.refs == 2, "references mismatch");
 -
 -    chFactoryReleaseBuffer(dbp1);
 -    test_assert(dbp->element.refs == 1, "references mismatch");
 -  }
 -
 -  /* [4.2.5] Releasing the first reference to the dynamic buffer, must
 -     not trigger an assertion.*/
 -  test_set_step(5);
 -  {
 -    chFactoryReleaseBuffer(dbp);
 -  }
 -
 -  /* [4.2.6] Retrieving the dynamic buffer by name again, must not
 -     exist.*/
 -  test_set_step(6);
 -  {
 -    dbp = chFactoryFindBuffer("mybuf");
 -    test_assert(dbp == NULL, "found");
 -  }
 -}
 -
 -static const testcase_t oslib_test_004_002 = {
 -  "Dynamic Buffers Factory",
 -  NULL,
 -  oslib_test_004_002_teardown,
 -  oslib_test_004_002_execute
 -};
 -#endif /* CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE */
 -
 -#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
 -/**
 - * @page oslib_test_004_003 [4.3] Dynamic Semaphores Factory
 - *
 - * <h2>Description</h2>
 - * This test case verifies the dynamic semaphores factory.
 - *
 - * <h2>Conditions</h2>
 - * This test is only executed if the following preprocessor condition
 - * evaluates to true:
 - * - CH_CFG_FACTORY_SEMAPHORES == TRUE
 - * .
 - *
 - * <h2>Test Steps</h2>
 - * - [4.3.1] Retrieving a dynamic semaphore by name, must not exist.
 - * - [4.3.2] Creating a dynamic semaphore it must not exists, must
 - *   succeed.
 - * - [4.3.3] Creating a dynamic semaphore with the same name, must
 - *   fail.
 - * - [4.3.4] Retrieving the dynamic semaphore by name, must exist, then
 - *   increasing the reference counter, finally releasing both
 - *   references.
 - * - [4.3.5] Releasing the first reference to the dynamic semaphore
 - *   must not trigger an assertion.
 - * - [4.3.6] Retrieving the dynamic semaphore by name again, must not
 - *   exist.
 - * .
 - */
 -
 -static void oslib_test_004_003_teardown(void) {
 -  dyn_semaphore_t *dsp;
 -
 -  dsp = chFactoryFindSemaphore("mysem");
 -  if (dsp != NULL) {
 -    while (dsp->element.refs > 0U) {
 -      chFactoryReleaseSemaphore(dsp);
 -    }
 -  }
 -}
 -
 -static void oslib_test_004_003_execute(void) {
 -  dyn_semaphore_t *dsp;
 -
 -  /* [4.3.1] Retrieving a dynamic semaphore by name, must not exist.*/
 -  test_set_step(1);
 -  {
 -    dsp = chFactoryFindSemaphore("mysem");
 -    test_assert(dsp == NULL, "found");
 -  }
 -
 -  /* [4.3.2] Creating a dynamic semaphore it must not exists, must
 -     succeed.*/
 -  test_set_step(2);
 -  {
 -    dsp = chFactoryCreateSemaphore("mysem", 0);
 -    test_assert(dsp != NULL, "cannot create");
 -  }
 -
 -  /* [4.3.3] Creating a dynamic semaphore with the same name, must
 -     fail.*/
 -  test_set_step(3);
 -  {
 -    dyn_semaphore_t *dsp1;
 -
 -    dsp1 = chFactoryCreateSemaphore("mysem", 0);
 -    test_assert(dsp1 == NULL, "can create");
 -  }
 -
 -  /* [4.3.4] Retrieving the dynamic semaphore by name, must exist, then
 -     increasing the reference counter, finally releasing both
 -     references.*/
 -  test_set_step(4);
 -  {
 -    dyn_semaphore_t *dsp1, *dsp2;
 -
 -    dsp1 = chFactoryFindSemaphore("mysem");
 -    test_assert(dsp1 != NULL, "not found");
 -    test_assert(dsp == dsp1, "object reference mismatch");
 -    test_assert(dsp1->element.refs == 2, "object reference mismatch");
 -
 -    dsp2 = (dyn_semaphore_t *)chFactoryDuplicateReference(&dsp1->element);
 -    test_assert(dsp1 == dsp2, "object reference mismatch");
 -    test_assert(dsp2->element.refs == 3, "object reference mismatch");
 -
 -    chFactoryReleaseSemaphore(dsp2);
 -    test_assert(dsp1->element.refs == 2, "references mismatch");
 -
 -    chFactoryReleaseSemaphore(dsp1);
 -    test_assert(dsp->element.refs == 1, "references mismatch");
 -  }
 -
 -  /* [4.3.5] Releasing the first reference to the dynamic semaphore
 -     must not trigger an assertion.*/
 -  test_set_step(5);
 -  {
 -    chFactoryReleaseSemaphore(dsp);
 -  }
 -
 -  /* [4.3.6] Retrieving the dynamic semaphore by name again, must not
 -     exist.*/
 -  test_set_step(6);
 -  {
 -    dsp = chFactoryFindSemaphore("mysem");
 -    test_assert(dsp == NULL, "found");
 -  }
 -}
 -
 -static const testcase_t oslib_test_004_003 = {
 -  "Dynamic Semaphores Factory",
 -  NULL,
 -  oslib_test_004_003_teardown,
 -  oslib_test_004_003_execute
 -};
 -#endif /* CH_CFG_FACTORY_SEMAPHORES == TRUE */
 -
 -#if (CH_CFG_FACTORY_MAILBOXES == TRUE) || defined(__DOXYGEN__)
 -/**
 - * @page oslib_test_004_004 [4.4] Dynamic Mailboxes Factory
 - *
 - * <h2>Description</h2>
 - * This test case verifies the dynamic mailboxes factory.
 - *
 - * <h2>Conditions</h2>
 - * This test is only executed if the following preprocessor condition
 - * evaluates to true:
 - * - CH_CFG_FACTORY_MAILBOXES == TRUE
 - * .
 - *
 - * <h2>Test Steps</h2>
 - * - [4.4.1] Retrieving a dynamic mailbox by name, must not exist.
 - * - [4.4.2] Creating a dynamic mailbox it must not exists, must
 - *   succeed.
 - * - [4.4.3] Creating a dynamic mailbox with the same name, must fail.
 - * - [4.4.4] Retrieving the dynamic mailbox by name, must exist, then
 - *   increasing the reference counter, finally releasing both
 - *   references.
 - * - [4.4.5] Releasing the first reference to the dynamic mailbox must
 - *   not trigger an assertion.
 - * - [4.4.6] Retrieving the dynamic mailbox by name again, must not
 - *   exist.
 - * .
 - */
 -
 -static void oslib_test_004_004_teardown(void) {
 -  dyn_mailbox_t *dmp;
 -
 -  dmp = chFactoryFindMailbox("mymbx");
 -  if (dmp != NULL) {
 -    while (dmp->element.refs > 0U) {
 -      chFactoryReleaseMailbox(dmp);
 -    }
 -  }
 -}
 -
 -static void oslib_test_004_004_execute(void) {
 -  dyn_mailbox_t *dmp;
 -
 -  /* [4.4.1] Retrieving a dynamic mailbox by name, must not exist.*/
 -  test_set_step(1);
 -  {
 -    dmp = chFactoryFindMailbox("mymbx");
 -    test_assert(dmp == NULL, "found");
 +    p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
 +    p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
 +    p3 = chHeapAlloc(&test_heap, ALLOC_SIZE);
 +    chHeapFree(p3);                                 /* Merges forward.*/
 +    chHeapFree(p2);                                 /* Merges forward.*/
 +    chHeapFree(p1);                                 /* Merges forward.*/
 +    test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
    }
 -  /* [4.4.2] Creating a dynamic mailbox it must not exists, must
 -     succeed.*/
 -  test_set_step(2);
 +  /* [4.1.7] Small fragments handling. Checking the behavior when
 +     allocating blocks with size not multiple of alignment unit.*/
 +  test_set_step(7);
    {
 -    dmp = chFactoryCreateMailbox("mymbx", 16U);
 -    test_assert(dmp != NULL, "cannot create");
 +    p1 = chHeapAlloc(&test_heap, ALLOC_SIZE + 1);
 +    p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
 +    chHeapFree(p1);
 +    test_assert(chHeapStatus(&test_heap, &n, NULL) == 2, "invalid state");
 +    p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
 +    /* Note, the first situation happens when the alignment size is smaller
 +       than the header size, the second in the other cases.*/
 +    test_assert((chHeapStatus(&test_heap, &n, NULL) == 1) ||
 +                (chHeapStatus(&test_heap, &n, NULL) == 2), "heap fragmented");
 +    chHeapFree(p2);
 +    chHeapFree(p1);
 +    test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
    }
 -  /* [4.4.3] Creating a dynamic mailbox with the same name, must
 -     fail.*/
 -  test_set_step(3);
 -  {
 -    dyn_mailbox_t *dmp1;
 -
 -    dmp1 = chFactoryCreateMailbox("mymbx", 16U);
 -    test_assert(dmp1 == NULL, "can create");
 -  }
 -
 -  /* [4.4.4] Retrieving the dynamic mailbox by name, must exist, then
 -     increasing the reference counter, finally releasing both
 -     references.*/
 -  test_set_step(4);
 +  /* [4.1.8] Skipping a fragment, the first fragment in the list is too
 +     small so the allocator must pick the second one.*/
 +  test_set_step(8);
    {
 -    dyn_mailbox_t *dmp1, *dmp2;
 -
 -    dmp1 = chFactoryFindMailbox("mymbx");
 -    test_assert(dmp1 != NULL, "not found");
 -    test_assert(dmp == dmp1, "object reference mismatch");
 -    test_assert(dmp1->element.refs == 2, "object reference mismatch");
 -
 -    dmp2 = (dyn_mailbox_t *)chFactoryDuplicateReference(&dmp1->element);
 -    test_assert(dmp1 == dmp2, "object reference mismatch");
 -    test_assert(dmp2->element.refs == 3, "object reference mismatch");
 -
 -    chFactoryReleaseMailbox(dmp2);
 -    test_assert(dmp1->element.refs == 2, "references mismatch");
 -
 -    chFactoryReleaseMailbox(dmp1);
 -    test_assert(dmp->element.refs == 1, "references mismatch");
 +    p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
 +    p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
 +    chHeapFree(p1);
 +    test_assert( chHeapStatus(&test_heap, &n, NULL) == 2, "invalid state");
 +    p1 = chHeapAlloc(&test_heap, ALLOC_SIZE * 2); /* Skips first fragment.*/
 +    chHeapFree(p1);
 +    chHeapFree(p2);
 +    test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
    }
 -  /* [4.4.5] Releasing the first reference to the dynamic mailbox must
 -     not trigger an assertion.*/
 -  test_set_step(5);
 +  /* [4.1.9] Allocating the whole available space.*/
 +  test_set_step(9);
    {
 -    chFactoryReleaseMailbox(dmp);
 +    (void)chHeapStatus(&test_heap, &n, NULL);
 +    p1 = chHeapAlloc(&test_heap, n);
 +    test_assert(p1 != NULL, "allocation failed");
 +    test_assert(chHeapStatus(&test_heap, NULL, NULL) == 0, "not empty");
 +    chHeapFree(p1);
    }
 -  /* [4.4.6] Retrieving the dynamic mailbox by name again, must not
 -     exist.*/
 -  test_set_step(6);
 +  /* [4.1.10] Testing final conditions. The heap geometry must be the
 +     same than the one registered at beginning.*/
 +  test_set_step(10);
    {
 -    dmp = chFactoryFindMailbox("mymbx");
 -    test_assert(dmp == NULL, "found");
 +    test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
 +    test_assert(n == sz, "size changed");
    }
  }
 -static const testcase_t oslib_test_004_004 = {
 -  "Dynamic Mailboxes Factory",
 +static const testcase_t oslib_test_004_001 = {
 +  "Allocation and fragmentation",
 +  oslib_test_004_001_setup,
    NULL,
 -  oslib_test_004_004_teardown,
 -  oslib_test_004_004_execute
 +  oslib_test_004_001_execute
  };
 -#endif /* CH_CFG_FACTORY_MAILBOXES == TRUE */
 -#if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__)
  /**
 - * @page oslib_test_004_005 [4.5] Dynamic Objects FIFOs Factory
 + * @page oslib_test_004_002 [4.2] Default Heap
   *
   * <h2>Description</h2>
 - * This test case verifies the dynamic objects FIFOs factory.
 - *
 - * <h2>Conditions</h2>
 - * This test is only executed if the following preprocessor condition
 - * evaluates to true:
 - * - CH_CFG_FACTORY_OBJ_FIFOS == TRUE
 - * .
 + * The default heap is pre-allocated in the system. We test base
 + * functionality.
   *
   * <h2>Test Steps</h2>
 - * - [4.5.1] Retrieving a dynamic objects FIFO by name, must not exist.
 - * - [4.5.2] Creating a dynamic objects FIFO it must not exists, must
 - *   succeed.
 - * - [4.5.3] Creating a dynamic objects FIFO with the same name, must
 - *   fail.
 - * - [4.5.4] Retrieving the dynamic objects FIFO by name, must exist,
 - *   then increasing the reference counter, finally releasing both
 - *   references.
 - * - [4.5.5] Releasing the first reference to the dynamic objects FIFO
 - *   must not trigger an assertion.
 - * - [4.5.6] Retrieving the dynamic objects FIFO by name again, must
 - *   not exist.
 + * - [4.2.1] Single block allocation using chHeapAlloc() then the block
 + *   is freed using chHeapFree(), must not fail.
 + * - [4.2.2] Testing allocation failure.
   * .
   */
 -static void oslib_test_004_005_teardown(void) {
 -  dyn_objects_fifo_t *dofp;
 -
 -  dofp = chFactoryFindObjectsFIFO("myfifo");
 -  if (dofp != NULL) {
 -    while (dofp->element.refs > 0U) {
 -      chFactoryReleaseObjectsFIFO(dofp);
 -    }
 -  }
 -}
 -
 -static void oslib_test_004_005_execute(void) {
 -  dyn_objects_fifo_t *dofp;
 +static void oslib_test_004_002_execute(void) {
 +  void *p1;
 +  size_t total_size, largest_size;
 -  /* [4.5.1] Retrieving a dynamic objects FIFO by name, must not
 -     exist.*/
 +  /* [4.2.1] Single block allocation using chHeapAlloc() then the block
 +     is freed using chHeapFree(), must not fail.*/
    test_set_step(1);
    {
 -    dofp = chFactoryFindObjectsFIFO("myfifo");
 -    test_assert(dofp == NULL, "found");
 +    (void)chHeapStatus(NULL, &total_size, &largest_size);
 +    p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
 +    test_assert(p1 != NULL, "allocation failed");
 +    chHeapFree(p1);
    }
 -  /* [4.5.2] Creating a dynamic objects FIFO it must not exists, must
 -     succeed.*/
 +  /* [4.2.2] Testing allocation failure.*/
    test_set_step(2);
    {
 -    dofp = chFactoryCreateObjectsFIFO("myfifo", 16U, 16U, PORT_NATURAL_ALIGN);
 -    test_assert(dofp != NULL, "cannot create");
 -  }
 -
 -  /* [4.5.3] Creating a dynamic objects FIFO with the same name, must
 -     fail.*/
 -  test_set_step(3);
 -  {
 -    dyn_objects_fifo_t *dofp1;
 -
 -    dofp1 = chFactoryCreateObjectsFIFO("myfifo", 16U, 16U, PORT_NATURAL_ALIGN);
 -    test_assert(dofp1 == NULL, "can create");
 -  }
 -
 -  /* [4.5.4] Retrieving the dynamic objects FIFO by name, must exist,
 -     then increasing the reference counter, finally releasing both
 -     references.*/
 -  test_set_step(4);
 -  {
 -    dyn_objects_fifo_t *dofp1, *dofp2;
 -
 -    dofp1 = chFactoryFindObjectsFIFO("myfifo");
 -    test_assert(dofp1 != NULL, "not found");
 -    test_assert(dofp == dofp1, "object reference mismatch");
 -    test_assert(dofp1->element.refs == 2, "object reference mismatch");
 -
 -    dofp2 = (dyn_objects_fifo_t *)chFactoryDuplicateReference(&dofp1->element);
 -    test_assert(dofp1 == dofp2, "object reference mismatch");
 -    test_assert(dofp2->element.refs == 3, "object reference mismatch");
 -
 -    chFactoryReleaseObjectsFIFO(dofp2);
 -    test_assert(dofp1->element.refs == 2, "references mismatch");
 -
 -    chFactoryReleaseObjectsFIFO(dofp1);
 -    test_assert(dofp->element.refs == 1, "references mismatch");
 -  }
 -
 -  /* [4.5.5] Releasing the first reference to the dynamic objects FIFO
 -     must not trigger an assertion.*/
 -  test_set_step(5);
 -  {
 -    chFactoryReleaseObjectsFIFO(dofp);
 -  }
 -
 -  /* [4.5.6] Retrieving the dynamic objects FIFO by name again, must
 -     not exist.*/
 -  test_set_step(6);
 -  {
 -    dofp = chFactoryFindObjectsFIFO("myfifo");
 -    test_assert(dofp == NULL, "found");
 +    p1 = chHeapAlloc(NULL, (size_t)-256);
 +    test_assert(p1 == NULL, "allocation not failed");
    }
  }
 -static const testcase_t oslib_test_004_005 = {
 -  "Dynamic Objects FIFOs Factory",
 +static const testcase_t oslib_test_004_002 = {
 +  "Default Heap",
    NULL,
 -  oslib_test_004_005_teardown,
 -  oslib_test_004_005_execute
 -};
 -#endif /* CH_CFG_FACTORY_OBJ_FIFOS == TRUE */
 -
 -#if (CH_CFG_FACTORY_PIPES == TRUE) || defined(__DOXYGEN__)
 -/**
 - * @page oslib_test_004_006 [4.6] Dynamic Pipes Factory
 - *
 - * <h2>Description</h2>
 - * This test case verifies the dynamic pipes factory.
 - *
 - * <h2>Conditions</h2>
 - * This test is only executed if the following preprocessor condition
 - * evaluates to true:
 - * - CH_CFG_FACTORY_PIPES == TRUE
 - * .
 - *
 - * <h2>Test Steps</h2>
 - * - [4.6.1] Retrieving a dynamic pipe by name, must not exist.
 - * - [4.6.2] Creating a dynamic pipe it must not exists, must succeed.
 - * - [4.6.3] Creating a dynamic pipe with the same name, must fail.
 - * - [4.6.4] Retrieving the dynamic pipe by name, must exist, then
 - *   increasing the reference counter, finally releasing both
 - *   references.
 - * - [4.6.5] Releasing the first reference to the dynamic pipe must not
 - *   trigger an assertion.
 - * - [4.6.6] Retrieving the dynamic pipe by name again, must not exist.
 - * .
 - */
 -
 -static void oslib_test_004_006_teardown(void) {
 -  dyn_pipe_t *dpp;
 -
 -  dpp = chFactoryFindPipe("mypipe");
 -  if (dpp != NULL) {
 -    while (dpp->element.refs > 0U) {
 -      chFactoryReleasePipe(dpp);
 -    }
 -  }
 -}
 -
 -static void oslib_test_004_006_execute(void) {
 -  dyn_pipe_t *dpp;
 -
 -  /* [4.6.1] Retrieving a dynamic pipe by name, must not exist.*/
 -  test_set_step(1);
 -  {
 -    dpp = chFactoryFindPipe("mypipe");
 -    test_assert(dpp == NULL, "found");
 -  }
 -
 -  /* [4.6.2] Creating a dynamic pipe it must not exists, must
 -     succeed.*/
 -  test_set_step(2);
 -  {
 -    dpp = chFactoryCreatePipe("mypipe", 16U);
 -    test_assert(dpp != NULL, "cannot create");
 -  }
 -
 -  /* [4.6.3] Creating a dynamic pipe with the same name, must fail.*/
 -  test_set_step(3);
 -  {
 -    dyn_pipe_t *dpp1;
 -
 -    dpp1 = chFactoryCreatePipe("mypipe", 16U);
 -    test_assert(dpp1 == NULL, "can create");
 -  }
 -
 -  /* [4.6.4] Retrieving the dynamic pipe by name, must exist, then
 -     increasing the reference counter, finally releasing both
 -     references.*/
 -  test_set_step(4);
 -  {
 -    dyn_pipe_t *dpp1, *dpp2;
 -
 -    dpp1 = chFactoryFindPipe("mypipe");
 -    test_assert(dpp1 != NULL, "not found");
 -    test_assert(dpp == dpp1, "object reference mismatch");
 -    test_assert(dpp1->element.refs == 2, "object reference mismatch");
 -
 -    dpp2 = (dyn_pipe_t *)chFactoryDuplicateReference(&dpp1->element);
 -    test_assert(dpp1 == dpp2, "object reference mismatch");
 -    test_assert(dpp2->element.refs == 3, "object reference mismatch");
 -
 -    chFactoryReleasePipe(dpp2);
 -    test_assert(dpp1->element.refs == 2, "references mismatch");
 -
 -    chFactoryReleasePipe(dpp1);
 -    test_assert(dpp->element.refs == 1, "references mismatch");
 -  }
 -
 -  /* [4.6.5] Releasing the first reference to the dynamic pipe must not
 -     trigger an assertion.*/
 -  test_set_step(5);
 -  {
 -    chFactoryReleasePipe(dpp);
 -  }
 -
 -  /* [4.6.6] Retrieving the dynamic pipe by name again, must not
 -     exist.*/
 -  test_set_step(6);
 -  {
 -    dpp = chFactoryFindPipe("mypipe");
 -    test_assert(dpp == NULL, "found");
 -  }
 -}
 -
 -static const testcase_t oslib_test_004_006 = {
 -  "Dynamic Pipes Factory",
    NULL,
 -  oslib_test_004_006_teardown,
 -  oslib_test_004_006_execute
 +  oslib_test_004_002_execute
  };
 -#endif /* CH_CFG_FACTORY_PIPES == TRUE */
  /****************************************************************************
   * Exported data.
 @@ -749,33 +264,17 @@ static const testcase_t oslib_test_004_006 = {   * @brief   Array of test cases.
   */
  const testcase_t * const oslib_test_sequence_004_array[] = {
 -#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXYGEN__)
    &oslib_test_004_001,
 -#endif
 -#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXYGEN__)
    &oslib_test_004_002,
 -#endif
 -#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
 -  &oslib_test_004_003,
 -#endif
 -#if (CH_CFG_FACTORY_MAILBOXES == TRUE) || defined(__DOXYGEN__)
 -  &oslib_test_004_004,
 -#endif
 -#if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__)
 -  &oslib_test_004_005,
 -#endif
 -#if (CH_CFG_FACTORY_PIPES == TRUE) || defined(__DOXYGEN__)
 -  &oslib_test_004_006,
 -#endif
    NULL
  };
  /**
 - * @brief   Objects Factory.
 + * @brief   Memory Heaps.
   */
  const testsequence_t oslib_test_sequence_004 = {
 -  "Objects Factory",
 +  "Memory Heaps",
    oslib_test_sequence_004_array
  };
 -#endif /* (CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE) */
 +#endif /* CH_CFG_USE_HEAP */
  | 
