Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
#include "common.h"
#include <stdio.h>
#include <stdlib.h>
#include "CuTest.h"
typedef struct MyStruct{
int a;
float b;
char c;
}MyStruct;
#define MAXSEG 16
/*------ Allocator for MyStruct ------*/
// fix the type for this allocator
#define DYNARR_DATA_TYPE MyStruct
#include "dynarr.h"
/*------ Allocator for MyStruct* ------*/
typedef struct MyStruct* MyStructPtr;
#define DYNARR_DATA_TYPE MyStructPtr
#include "dynarr.h"
// create, init, cleanup
void test_createInitCleanup(CuTest* tc){
int i;
// init
initLLArr(MyStruct);
CuAssert(tc, "LogMaxSeg not 4", 4 == LOGMAXSEG(MyStruct));
CuAssert(tc, "MaxSegRemainderBitMask not 15", 15 == MAXSEG_REMAINDER_BITMASK(MyStruct));
CuAssert(tc, "insertPos not 1", 1 == SEG_INSERT_POS(MyStruct));
CuAssert(tc, "TotalSegs not 0", 0 == TOTAL_SEGS(MyStruct));
CuAssert(tc, "NULLSEG.index not 0", 0 == NULL_SEG(MyStruct).index);
CuAssert(tc, "NULLSEG not NULL", 1 == DYNARR_SEG_NULL(NULL_SEG(MyStruct)));
CuAssert(tc, "NULLSEG not NULL", 0 == DYNARR_SEG_NOT_NULL(NULL_SEG(MyStruct)));
CuAssert(tc, "SEGARR NULL", NULL != SEG_ARR(MyStruct));
CuAssert(tc, "NUM_SEG_BANKS not 1", 1 == NUM_SEG_BANKS(MyStruct));
CuAssert(tc, "MAX_SEG_BANKS not 1", 1 == MAX_SEG_BANKS(MyStruct));
CuAssert(tc, "SEG_BANK_ALLOC_VIOLATION not 0", 0 == SEG_BANK_ALLOC_VIOLATION(MyStruct));
CuAssert(tc, "SEG_BANKS_ARR NULL", NULL != SEG_BANKS_ARR(MyStruct));
CuAssert(tc, "SEG_BANK_SIZE_ARR NULL", NULL != SEG_BANK_SIZE_ARR(MyStruct));
CuAssert(tc, "SEG_BANK_INDEX_LIMIT_ARR NULL", NULL != SEG_BANK_INDEX_LIMIT_ARR(MyStruct));
CuAssert(tc, "SEG_BANK_SIZE_ARR[0] not MAXSEG", MAXSEG == SEG_BANK_SIZE_ARR(MyStruct)[0]);
CuAssert(tc, "SEG_BANK_INDEX_LIMIT_ARR[0] not MAXSEG-1", (MAXSEG-1) == SEG_BANK_INDEX_LIMIT_ARR(MyStruct)[0]);
// cleanup
clearLLArr(MyStruct);
CuAssert(tc, "SEGARR not NULL", NULL == SEG_ARR(MyStruct));
for (i = 1; i < NUM_SEG_BANKS(MyStruct); i++){
CuAssert(tc, "SEG_BANKS_ARR[i] not NULL", NULL == SEG_BANKS_ARR(MyStruct)[i]);
}
CuAssert(tc, "SEG_BANKS_ARR not NULL", NULL == SEG_BANKS_ARR(MyStruct));
CuAssert(tc, "SEG_BANK_INDEX_LIMIT_ARR not NULL", NULL == SEG_BANK_INDEX_LIMIT_ARR(MyStruct));
CuAssert(tc, "SEG_BANK_SIZE_ARR not NULL", NULL == SEG_BANK_SIZE_ARR(MyStruct));
CuAssert(tc, "TotalSegs not 0", 0 == TOTAL_SEGS(MyStruct));
CuAssert(tc, "NUM_SEG_BANKS not 0", 0 == NUM_SEG_BANKS(MyStruct));
}
// allocate segment
void test_allocSeg(CuTest* tc){
int i;
DYNARR_SEG_TYPE(MyStruct) seg1, seg2, seg, tempSeg;
// init
initLLArr(MyStruct);
/* Allocate one segment */
seg1 = allocSeg(MyStruct);
CuAssert(tc, "first index not " TO_STRING(SEG_INSERT_POS_BEGIN),
SEG_INSERT_POS_BEGIN == seg1.index);
CuAssert(tc, "TotalSegs not 1", 1 == TOTAL_SEGS(MyStruct));
CuAssert(tc, "NumSegBanks not 1", 1 == NUM_SEG_BANKS(MyStruct));
CuAssert(tc, "free seg list not NULL",
NULL == FREESEG_LIST(MyStruct));
CuAssert(tc, "free seg invalid-list not NULL",
NULL == FREESEG_INVALID_LIST(MyStruct));
// Allocate one more. this should go at index 2
seg2 = allocSeg(MyStruct);
CuAssert(tc, "index not 2", 2 == seg2.index);
CuAssert(tc, "TotalSegs not 2", 2 == TOTAL_SEGS(MyStruct));
// now delete the first seg; it should go to the free list
freeSeg(MyStruct, seg1);
CuAssert(tc, "TotalSegs not 1", 1 == TOTAL_SEGS(MyStruct));
CuAssert(tc, "deleted seg not in free list",
1 == FREESEG_LIST(MyStruct)->index);
CuAssert(tc, "free seg invalid-list not NULL",
NULL == FREESEG_INVALID_LIST(MyStruct));
// Allocate one more. this should go at index 1
// because that segment was previously deleted
// after this, the freeseg list should be empty
seg = allocSeg(MyStruct);
CuAssert(tc, "index not 1", 1 == seg.index);
CuAssert(tc, "TotalSegs not 2", 2 == TOTAL_SEGS(MyStruct));
CuAssert(tc, "free seg list not NULL",
NULL == FREESEG_LIST(MyStruct));
CuAssert(tc, "free seg invalid-list NULL",
NULL != FREESEG_INVALID_LIST(MyStruct));
// so far 3 slots are taken from first segment bank
// first one empty by design
// next two allocated
// Allocate more (MAXSEG-3) segments. Should still occupy only the first bank
// all allocations must succeed
for (i = 0; i < MAXSEG - 3; i++){
tempSeg = allocSeg(MyStruct);
CuAssert(tc, "alloc failed", 0 == segNull(tempSeg));
CuAssert(tc, "alloc violation", 0 == isAllocError(MyStruct));
}
CuAssert(tc, "NumSegBanks not 1", 1 == NUM_SEG_BANKS(MyStruct));
CuAssert(tc, "MaxSegBanks not 1", 1 == MAX_SEG_BANKS(MyStruct));
// now allocate one more segment. This should cause segment bank allocation
CuAssert(tc, "SEG_INSERT_POS not indexLimit[0]+1", (SEG_BANK_INDEX_LIMIT_ARR(MyStruct)[0] + 1) == SEG_INSERT_POS(MyStruct));
seg = allocSeg(MyStruct);
CuAssert(tc, "alloc failed", 0 == segNull(tempSeg));
CuAssert(tc, "alloc violation", 0 == isAllocError(MyStruct));
CuAssert(tc, "NumSegBanks not 2", 2 == NUM_SEG_BANKS(MyStruct));
CuAssert(tc, "MaxSegBanks not 2", 2 == MAX_SEG_BANKS(MyStruct));
CuAssert(tc, "index not indexLimit[0]+1", (SEG_BANK_INDEX_LIMIT_ARR(MyStruct)[0]+1) == seg.index);
// Allocate more (MAXSEG-1) segments. Should still occupy only the first bank
// all allocations must succeed
for (i = 0; i < MAXSEG - 1; i++){
tempSeg = allocSeg(MyStruct);
CuAssert(tc, "alloc failed", 0 == segNull(tempSeg));
CuAssert(tc, "alloc violation", 0 == isAllocError(MyStruct));
}
CuAssert(tc, "NumSegBanks not 2", 2 == NUM_SEG_BANKS(MyStruct));
CuAssert(tc, "MaxSegBanks not 2", 2 == MAX_SEG_BANKS(MyStruct));
CuAssert(tc, "SEG_INSERT_POS not indexLimit[1]+1", (SEG_BANK_INDEX_LIMIT_ARR(MyStruct)[1] + 1) == SEG_INSERT_POS(MyStruct));
// now allocate one more segment. This should cause segment bank allocation
seg = allocSeg(MyStruct);
CuAssert(tc, "alloc failed", 0 == segNull(tempSeg));
CuAssert(tc, "alloc violation", 0 == isAllocError(MyStruct));
CuAssert(tc, "NumSegBanks not 3", 3 == NUM_SEG_BANKS(MyStruct));
CuAssert(tc, "MaxSegBanks not 4", 4 == MAX_SEG_BANKS(MyStruct));
CuAssert(tc, "index not indexLimit[1]+1", (SEG_BANK_INDEX_LIMIT_ARR(MyStruct)[1] + 1) == seg.index);
// delete a particular segment,
// and see if next alloc gives that index
i = 5;
seg = getSegAt(MyStruct, i);
CuAssert(tc, "index not i", i == seg.index);
// delete it, then get one more segment
freeSeg(MyStruct, seg);
seg1 = allocSeg(MyStruct);
CuAssert(tc, "new index not deleted index", i == seg1.index);
// cleanup
clearLLArr(MyStruct);
}
// prevent repeated initialization
// if it is already initialized, init() should do nothing more
void test_issue1(CuTest* tc){
int i;
int numSegs, numSegBanks;
CuAssert(tc, "initialized flag not 0", 0 == INITIALIZED_FLAG(MyStruct));
initLLArr(MyStruct);
CuAssert(tc, "initialized flag not 1", 1 == INITIALIZED_FLAG(MyStruct));
// add some segments
for (i = 0; i < MAXSEG+1; i++){
allocSeg(MyStruct);
}
numSegs = TOTAL_SEGS(MyStruct);
numSegBanks = NUM_SEG_BANKS(MyStruct);
CuAssert(tc, "numsegbanks not 2", 2 == numSegBanks);
// now init again
initLLArr(MyStruct);
// totalsegs and numsegs should stay the same
CuAssert(tc, "numsegbanks changed", numSegBanks == NUM_SEG_BANKS(MyStruct));
CuAssert(tc, "totalsegs changed", numSegs == TOTAL_SEGS(MyStruct));
// now cleanup
clearLLArr(MyStruct);
CuAssert(tc, "initialized flag not 0", 0 == INITIALIZED_FLAG(MyStruct));
}
CuSuite* getBasicTestSuite(void)
{
CuSuite* suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_createInitCleanup);
SUITE_ADD_TEST(suite, test_allocSeg);
SUITE_ADD_TEST(suite, test_issue1);
return suite;
}
void runAllTests(void)
{
CuString *output = CuStringNew();
CuSuite* suite = getBasicTestSuite();
//CuSuiteAddSuite(suite, auxSuite);
CuSuiteRun(suite);
CuSuiteSummary(suite, output);
CuSuiteDetails(suite, output);
printf("%s\n", output->buffer);
//
CuSuiteDelete(suite);
CuStringDelete(output);
}
int main(int argc, char** argv){
MEM_LEAK_CATCH();
// your code here
runAllTests();
// done
MEM_LEAK_SHOW();
printf("\nPress any key...");
getchar();
return 0;
}