diff --git a/dynarrc/common.h b/dynarrc/common.h index f4c5c1e..2cdd74a 100644 --- a/dynarrc/common.h +++ b/dynarrc/common.h @@ -60,4 +60,7 @@ #define MAXSEG_REMAINDER_BITMASK MaxSegRemainderBitMask +// types +#define real_t float + #endif // __dynarr_common_h__ \ No newline at end of file diff --git a/dynarrc/dynarr.c b/dynarrc/dynarr.c index 7dc5ae8..2cd1706 100644 --- a/dynarrc/dynarr.c +++ b/dynarrc/dynarr.c @@ -9,3 +9,131 @@ EXTERN unsigned int MaxSeg; EXTERN unsigned int LogMaxSeg; /* MAXSEG-1; MAXSEG must be a power of 2 */ EXTERN unsigned int MaxSegRemainderBitMask; + + +#include "dynarr.h" +#include "dynarr_freenodelist.h" + +SEGALLOC_USE(); + + +// when maximum number of segment banks is reached, +// double MaxSegBanks and +// reallocate the bookkeeping machinery +// returns 0 if bad, 1 if ok +int seg_bank_increase_max(){ + void* pVoid; + int bSuccess = 1; + int prevMaxSegBanks = MaxSegBanks; + // new limit on number of segment banks + MaxSegBanks <<= 1; + + // realloc + if (pVoid = realloc(pSegBanksArr, MaxSegBanks * sizeof(real_t*))){ + pSegBanksArr = (real_t**)pVoid; + memset(pSegBanksArr + prevMaxSegBanks, 0, (MaxSegBanks - prevMaxSegBanks) * sizeof(real_t*)); + } + else { + printf("\nFatal error: Failed to increase the Maximum number of segment banks." + "\n\tFile: %s\n\tLine: %d\n", + __FILE__, __LINE__); + return 0; + } + + if (pVoid = realloc(pSegBankSizeArr, MaxSegBanks * sizeof(int))){ + pSegBankSizeArr = (int*)pVoid; + memset(pSegBankSizeArr + prevMaxSegBanks, 0, (MaxSegBanks - prevMaxSegBanks) * sizeof(int)); + } + else { + printf("\nFatal error: Failed to increase the Maximum number of segment banks." + "\n\tFile: %s\n\tLine: %d\n", + __FILE__, __LINE__); + return 0; + } + + if (pVoid = realloc(pSegBankIndexLimitArr, MaxSegBanks * sizeof(int))){ + pSegBankIndexLimitArr = (int*)pVoid; + memset(pSegBankIndexLimitArr + prevMaxSegBanks, 0, (MaxSegBanks - prevMaxSegBanks) * sizeof(int)); + } + else { + printf("\nFatal error: Failed to increase the Maximum number of segment banks." + "\n\tFile: %s\n\tLine: %d\n", + __FILE__, __LINE__); + return 0; + } + + // ok + return 1; +} + +// +// allocate next segment bank and place iInsertPos in appropriate value +// +int seg_bank_alloc_next(){ + int numElems = MaxSeg, + round = 0, + iHypotheticalTotalSegsUptoLastActiveBank = 0; + real_t* ptr; + int bCpuGpuAllocDone = 0; + + //assert(NumSegBanks < MAX_SEG_BANKS); + if (NumSegBanks >= MAX_SEG_BANKS) { + // increase limit on the number of segment banks + if (!seg_bank_increase_max()){ + // no futher alloc possible + SegBankAllocViolation = 1; + + printf("\nFatal error: Maximum number of segment banks is reached." + "\n\tFile: %s\n\tLine: %d\n", + __FILE__, __LINE__); + return 0; + } + else{ + // great, it is possible to have more segment banks + // continue + } + } + + // ok, lets try to allocate one more segment bank + do{ + // cpu alloc + do{ + numElems >>= (round++); + assert(numElems % 4 == 0); // must be a multiple of 4 + + ptr = (real_t*)malloc(numElems * NUM_SEG_MEMBERS_IN_ARR * sizeof(real_t)); + } while (numElems > 1 && ptr == NULL); + assert(ptr != NULL); + if (ptr == NULL){ + // no futher alloc possible + SegBankAllocViolation = 1; + + printf("\nFatal error: Failed to allocate next segment bank" + "\n\tFile: %s\n\tLine: %d\n", __FILE__, __LINE__); + return 0; + } + + // ok in cpu + pSegBanksArr[NumSegBanks] = ptr; + + // update the size of the bank + // it is used when allocating bank in gpu + pSegBankSizeArr[NumSegBanks] = numElems; + + // now allocate corresponding bank in gpu + bCpuGpuAllocDone = 1; + } while (bCpuGpuAllocDone == 0); + + // great + // initialize everything to zero, this makes all segments initially null + memset(ptr, 0, numElems * NUM_SEG_MEMBERS_IN_ARR * sizeof(real_t)); + iHypotheticalTotalSegsUptoLastActiveBank = NumSegBanks * MaxSeg; + // pretend that each segment bank is of size MaxSeg + pSegBankIndexLimitArr[NumSegBanks] = (iHypotheticalTotalSegsUptoLastActiveBank - 1) + numElems; + + // finally + iInsertPos = iHypotheticalTotalSegsUptoLastActiveBank; + NumSegBanks++; + + return 1; +} diff --git a/dynarrc/dynarr.h b/dynarrc/dynarr.h index 9b8fa8a..a23926d 100644 --- a/dynarrc/dynarr.h +++ b/dynarrc/dynarr.h @@ -1,6 +1,9 @@ #pragma message("touching: "__FILE__) #include "common.h" +//#define MAXSEG 5 +//#define DYNARR_TYPE int +//#define TYPED_NAME(name) TOKEN_PASTE(DYNARR_TYPE, name) /* Assuming MAXSEG is defined. Size of each block of the dynamic array. Must be a positive integer.*/ @@ -71,10 +74,6 @@ extern int seg_bank_increase_max(); #endif -/* The dynamic array data structure */ -struct TYPED_NAME(DynArr){ - int a; -}; /* Accessor methods */ #define SEG_ARR_GET_SEG(segIndex) \ @@ -82,6 +81,11 @@ struct TYPED_NAME(DynArr){ (segIndex) >= 0 && \ (segIndex) < iInsertPos )\ ? ( (tempSeg1).index = (segIndex),\ + tempSeg1.nextIndex = \ + (int) (SEG_ARR_SEG_NEXT_INDEX(tempSeg1)),\ + tempSeg1.c = SEG_ARR_SEG_C(tempSeg1), \ + tempSeg1.v = SEG_ARR_SEG_V(tempSeg1), \ + tempSeg1.prev = NULL, \ tempSeg1)\ : NULL_SEG @@ -223,6 +227,13 @@ struct TYPED_NAME(DynArr){ #define SEG_ARR_EXISTS() ( pSegArr != NULL ) #define SEG_ARR_SIZE NUM_SEG_ARR_ITEMS + +/* The dynamic array data structure */ +struct TYPED_NAME(DynArr){ + int a; +}; + + #endif