| /******************************************************************************* |
| * Copyright (c) 2012 protos software gmbh (http://www.protos.de). |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * CONTRIBUTORS: |
| * Henrik Rentz-Reichert (initial contribution) |
| * |
| *******************************************************************************/ |
| |
| #include "TestEtMemory.h" |
| |
| #include <stddef.h> |
| #include <string.h> |
| #include "etUnit/etUnit.h" |
| #include "base/etMemory_FixedSize.h" |
| #include "base/etMemory_FreeList.h" |
| |
| #define KBYTE 1024 |
| #define BUF_SIZE (256*KBYTE) |
| #define BUF_SIZE_SMALL (2*KBYTE) |
| #define BLOCK_SIZE 128 |
| #define TEST_BLOCKS 1024 |
| #define TEST_BLOCK_SIZE 64 |
| |
| #define NOBJ 32 |
| #define NSLOTS 8 |
| #define NSIZES 7 |
| #define SIZE0 64 |
| #define SIZE1 16 |
| #define SIZE2 32 |
| #define SIZE3 48 |
| #define SIZE4 (16*8) |
| #define SIZE5 112 |
| #define SIZE6 96 |
| |
| |
| static void TestEtMemory_testFixedSize(etInt16 id) { |
| etUInt8 buffer[BUF_SIZE]; |
| etUInt8* objects[TEST_BLOCKS]; |
| int i; |
| etMemory* mem = etMemory_FixedSize_init(buffer, BUF_SIZE, BLOCK_SIZE); |
| EXPECT_TRUE(id, "mem!=NULL", mem!=NULL); |
| |
| for (i=0; i<TEST_BLOCKS; ++i) { |
| objects[i] = mem->alloc(mem, TEST_BLOCK_SIZE); |
| if (objects[i]==NULL) |
| EXPECT_TRUE(id, "objects[i]==NULL", ET_FALSE); |
| |
| memset(objects[i], i%4, TEST_BLOCK_SIZE); |
| } |
| for (i=0; i<TEST_BLOCKS/2; ++i) { |
| mem->free(mem, objects[i*2], TEST_BLOCK_SIZE); |
| } |
| for (i=0; i<TEST_BLOCKS/2; ++i) { |
| objects[i*2] = mem->alloc(mem, TEST_BLOCK_SIZE); |
| if (objects[i*2]==NULL) |
| EXPECT_TRUE(id, "objects[i*2]==NULL", ET_FALSE); |
| } |
| } |
| |
| static int local_dump_statistics_line(etMemory* mem, int slot) { |
| int nobj = etMemory_FreeList_nObjects(mem, slot); |
| int size = etMemory_FreeList_sizeObjects(mem, slot); |
| int subtotal = nobj*size; |
| |
| printf(" slot %3d with %4d objects of size %4d totaling to %8d\n", slot, nobj, size, subtotal); |
| |
| return subtotal; |
| } |
| |
| static void local_dump_statistics(etMemory* mem, etUInt16 nSlots) { |
| int slot; |
| int total = 0; |
| printf("memory statistics of free list memory management at %p\n", mem); |
| for (slot=0; slot<nSlots; ++slot) { |
| total += local_dump_statistics_line(mem, slot); |
| } |
| printf(" total %12d\n", total); |
| } |
| |
| static etUInt32 local_alloc(etInt16 id, etMemory* mem, etUInt8* objects[NSIZES][NOBJ], etUInt8 sizes[NSIZES]) { |
| int i, kind; |
| etUInt32 total = 0; |
| |
| for (kind=0; kind<NSIZES; ++kind) { |
| total += sizes[kind] * NOBJ; |
| for (i=0; i<NOBJ; ++i) { |
| objects[kind][i] = mem->alloc(mem, sizes[kind]); |
| if (objects[kind][i]==NULL) |
| EXPECT_TRUE(id, "objects[kind][i]==NULL", ET_FALSE); |
| } |
| } |
| |
| return total; |
| } |
| |
| |
| static void local_free(etInt16 id, etMemory* mem, etUInt8* objects[NSIZES][NOBJ], etUInt8 sizes[NSIZES]) { |
| int i, kind; |
| |
| for (kind=0; kind<NSIZES; ++kind) { |
| for (i=0; i<NOBJ; ++i) { |
| mem->free(mem, objects[kind][i], sizes[kind]); |
| } |
| } |
| } |
| |
| static void TestEtMemory_testFreeList(etInt16 id) { |
| static etUInt8 buffer[BUF_SIZE]; |
| static etUInt8 sizes[NSIZES] = { SIZE0, SIZE1, SIZE2, SIZE3, SIZE4, SIZE5, SIZE6 }; |
| etUInt8* objects[NSIZES][NOBJ]; |
| etMemory* mem = etMemory_FreeList_init(buffer, BUF_SIZE, NSLOTS); |
| etUInt32 free = etMemory_FreeList_freeHeapMem(mem); |
| etUInt32 diff, total; |
| |
| printf("initial free heap is %ld\n", free); |
| |
| EXPECT_TRUE(id, "mem!=NULL", mem!=NULL); |
| |
| total = local_alloc(id, mem, objects, sizes); |
| printf("after alloc\n"); |
| local_dump_statistics(mem, NSLOTS); |
| |
| local_free(id, mem, objects, sizes); |
| printf("after free\n"); |
| local_dump_statistics(mem, NSLOTS); |
| |
| diff = free; |
| free = etMemory_FreeList_freeHeapMem(mem); |
| diff -= free; |
| |
| printf("free heap is %ld\n", free); |
| EXPECT_EQUAL_UINT32(id, "allocated total", total, diff); |
| EXPECT_EQUAL_UINT16(id, "free slots", NSLOTS-NSIZES, etMemory_FreeList_freeSlots(mem)); |
| |
| EXPECT_EQUAL_UINT16(id, "slot 0 size", SIZE0, etMemory_FreeList_sizeObjects(mem, 0)); |
| EXPECT_EQUAL_UINT16(id, "slot 0 nobj", NOBJ, etMemory_FreeList_nObjects(mem, 0)); |
| EXPECT_EQUAL_UINT16(id, "slot 2 size", SIZE4, etMemory_FreeList_sizeObjects(mem, 1)); |
| EXPECT_EQUAL_UINT16(id, "slot 2 nobj", NOBJ, etMemory_FreeList_nObjects(mem, 1)); |
| EXPECT_EQUAL_UINT16(id, "slot 4 size", SIZE1, etMemory_FreeList_sizeObjects(mem, 2)); |
| EXPECT_EQUAL_UINT16(id, "slot 4 nobj", NOBJ, etMemory_FreeList_nObjects(mem, 2)); |
| EXPECT_EQUAL_UINT16(id, "slot 1 size", SIZE2, etMemory_FreeList_sizeObjects(mem, 4)); |
| EXPECT_EQUAL_UINT16(id, "slot 1 nobj", NOBJ, etMemory_FreeList_nObjects(mem, 4)); |
| EXPECT_EQUAL_UINT16(id, "slot 3 size", SIZE6, etMemory_FreeList_sizeObjects(mem, 5)); |
| EXPECT_EQUAL_UINT16(id, "slot 3 nobj", NOBJ, etMemory_FreeList_nObjects(mem, 5)); |
| EXPECT_EQUAL_UINT16(id, "slot 5 size", SIZE3, etMemory_FreeList_sizeObjects(mem, 6)); |
| EXPECT_EQUAL_UINT16(id, "slot 5 nobj", NOBJ, etMemory_FreeList_nObjects(mem, 6)); |
| EXPECT_EQUAL_UINT16(id, "slot 6 size", SIZE5, etMemory_FreeList_sizeObjects(mem, 7)); |
| EXPECT_EQUAL_UINT16(id, "slot 6 nobj", NOBJ, etMemory_FreeList_nObjects(mem, 7)); |
| |
| local_alloc(id, mem, objects, sizes); |
| local_free(id, mem, objects, sizes); |
| |
| EXPECT_EQUAL_UINT32(id, "free unchanged", free, etMemory_FreeList_freeHeapMem(mem)); |
| EXPECT_EQUAL_UINT16(id, "free slots", NSLOTS-NSIZES, etMemory_FreeList_freeSlots(mem)); |
| |
| EXPECT_EQUAL_UINT16(id, "slot 0 size", SIZE0, etMemory_FreeList_sizeObjects(mem, 0)); |
| EXPECT_EQUAL_UINT16(id, "slot 0 nobj", NOBJ, etMemory_FreeList_nObjects(mem, 0)); |
| EXPECT_EQUAL_UINT16(id, "slot 2 size", SIZE4, etMemory_FreeList_sizeObjects(mem, 1)); |
| EXPECT_EQUAL_UINT16(id, "slot 2 nobj", NOBJ, etMemory_FreeList_nObjects(mem, 1)); |
| EXPECT_EQUAL_UINT16(id, "slot 4 size", SIZE1, etMemory_FreeList_sizeObjects(mem, 2)); |
| EXPECT_EQUAL_UINT16(id, "slot 4 nobj", NOBJ, etMemory_FreeList_nObjects(mem, 2)); |
| EXPECT_EQUAL_UINT16(id, "slot 1 size", SIZE2, etMemory_FreeList_sizeObjects(mem, 4)); |
| EXPECT_EQUAL_UINT16(id, "slot 1 nobj", NOBJ, etMemory_FreeList_nObjects(mem, 4)); |
| EXPECT_EQUAL_UINT16(id, "slot 3 size", SIZE6, etMemory_FreeList_sizeObjects(mem, 5)); |
| EXPECT_EQUAL_UINT16(id, "slot 3 nobj", NOBJ, etMemory_FreeList_nObjects(mem, 5)); |
| EXPECT_EQUAL_UINT16(id, "slot 5 size", SIZE3, etMemory_FreeList_sizeObjects(mem, 6)); |
| EXPECT_EQUAL_UINT16(id, "slot 5 nobj", NOBJ, etMemory_FreeList_nObjects(mem, 6)); |
| EXPECT_EQUAL_UINT16(id, "slot 6 size", SIZE5, etMemory_FreeList_sizeObjects(mem, 7)); |
| EXPECT_EQUAL_UINT16(id, "slot 6 nobj", NOBJ, etMemory_FreeList_nObjects(mem, 7)); |
| } |
| |
| static void TestEtMemory_testFreeListOverflow(etInt16 id) { |
| static etUInt8 buffer[BUF_SIZE_SMALL]; |
| etMemory* mem = etMemory_FreeList_init(buffer, BUF_SIZE_SMALL, NSLOTS); |
| void* obj; |
| |
| EXPECT_TRUE(id, "mem!=NULL", mem!=NULL); |
| |
| obj = mem->alloc(mem, BUF_SIZE_SMALL+1); |
| EXPECT_TRUE(id, "insufficient space, expect NULL", NULL==obj); |
| } |
| |
| void TestEtMemory_runSuite(void){ |
| etUnit_openTestSuite("TestMemory"); |
| ADD_TESTCASE(TestEtMemory_testFixedSize); |
| ADD_TESTCASE(TestEtMemory_testFreeList); |
| ADD_TESTCASE(TestEtMemory_testFreeListOverflow); |
| etUnit_closeTestSuite(); |
| } |
| |