embb_mtapi_test_id_pool.cc 4.17 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
/*
 * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <embb_mtapi_test_id_pool.h>

IdPoolTest::IdPoolTest() {
  CreateUnit("mtapi id pool test single threaded").
    Add(&IdPoolTest::TestBasic, this, 1, 1000).
    Pre(&IdPoolTest::TestBasicPre, this).
    Post(&IdPoolTest::TestBasicPost, this);

  CreateUnit("mtapi id pool test concurrent").
36
    Add(&IdPoolTest::TestParallel, this, concurrent_accessors_id_pool_2
37 38 39 40 41 42 43 44 45
    , 20).
    Post(&IdPoolTest::TestParallelPost, this).
    Pre(&IdPoolTest::TestParallelPre, this);
}

void IdPoolTest::TestParallel() {
  // allocate ID_ELEMENTS_PER_ACCESSOR elements. Each test thread is
  // guaranteed to be able to allocate this amount of elements.
  TestAllocateDeallocateNElementsFromPool(id_pool_parallel,
46
    id_elements_per_accessor);
47 48 49 50 51 52
}

void IdPoolTest::TestParallelPre() {
  // create second id pool with CONCURRENT_ACCESSORS_ID_POOL_2*
  // ID_ELEMENTS_PER_ACCESSOR elements
  embb_mtapi_id_pool_initialize(&id_pool_parallel,
53
    concurrent_accessors_id_pool_2*id_elements_per_accessor);
54 55 56 57 58 59
}

void IdPoolTest::TestParallelPost() {
  // after the parallel tests, try to again allocate and deallocate all
  // elements sequentially.
  TestAllocateDeallocateNElementsFromPool(id_pool_parallel,
60
    concurrent_accessors_id_pool_2*id_elements_per_accessor, true);
61 62 63 64 65 66
  
  // finalize pool
  embb_mtapi_id_pool_finalize(&id_pool_parallel);
}

void IdPoolTest::TestBasic() {
67
  TestAllocateDeallocateNElementsFromPool(id_pool, id_pool_size_1, true);
68 69 70 71
}

void IdPoolTest::TestBasicPre() {
  // create id pool with ID_POOL_SIZE_1 elements
72
  embb_mtapi_id_pool_initialize(&id_pool, id_pool_size_1);
73 74 75 76 77 78 79 80 81 82 83
}

void IdPoolTest::TestBasicPost() {
  // finalize pool
  embb_mtapi_id_pool_finalize(&id_pool);
}

void IdPoolTest::TestAllocateDeallocateNElementsFromPool(
  embb_mtapi_id_pool_t &pool,
  int count_elements, 
  bool empty_check) {
84
  std::vector<unsigned int> allocated;
85 86 87 88 89 90

  for (int i = 0; i != count_elements; ++i) {
    allocated.push_back(embb_mtapi_id_pool_allocate(&pool));
  }

  // the allocated elements should be disjunctive, and never invalid element
91
  for (unsigned int x = 0; x != allocated.size(); ++x) {
92
    PT_ASSERT(allocated[x] != EMBB_MTAPI_IDPOOL_INVALID_ID);
93
    for (unsigned int y = 0; y != allocated.size(); ++y) {
94 95 96 97 98 99 100 101 102 103 104 105
      if (x == y) {
        continue;
      }
      PT_ASSERT(allocated[x] != allocated[y]);
    }
  }

  // now the id pool should be empty... try ten times to get an id,
  // we should always get the invalid element
  if (empty_check) {
    for (int i = 0; i != 10; ++i) {
      PT_ASSERT_EQ(embb_mtapi_id_pool_allocate(&pool),
106
        static_cast<unsigned int>(EMBB_MTAPI_IDPOOL_INVALID_ID)
107 108 109 110 111 112 113 114
        )
    }
  }

  // now return allocated elements in a shuffled manner.
  ::std::random_shuffle(allocated.begin(), allocated.end());

  for (int i = 0; i != count_elements; ++i) {
115 116
    embb_mtapi_id_pool_deallocate(&pool, 
      allocated[static_cast<unsigned int>(i)]);
117 118 119
  }
}