diff --git a/dynarrc/dynarr.h b/dynarrc/dynarr.h index 088daa1..bf7ceeb 100644 --- a/dynarrc/dynarr.h +++ b/dynarrc/dynarr.h @@ -2,6 +2,7 @@ #include "common.h" #include #include +#include //#define MAXSEG 5 //#define DYNARR_DATA_TYPE int @@ -26,21 +27,24 @@ // everything is fine #include "dynarr_freenodelist.h" +#ifndef TYPED_NAME +#define TYPED_NAME(type, name ) TOKEN_PASTE(type, name) +#endif /* The segment structure. These are the nodes of the linked list */ -#define DYNARR_SEG_TYPE TYPED_NAME(Sseg) +#define DYNARR_SEG_TYPE(type) TYPED_NAME(type, Sseg) typedef struct { DYNARR_DATA_TYPE data; int index; // my position int nextIndex; // next node's position -}DYNARR_SEG_TYPE; +}DYNARR_SEG_TYPE(DYNARR_DATA_TYPE); //const DYNARR_SEG_STRUCT TYPED_NAME(EMPTY_SSEG); /* The dynamic array data structure */ -#define DYNARR_STRUCT TYPED_NAME(DynArr) +#define DYNARR_STATE(type) TYPED_NAME(type, DynArr) typedef struct{ ////////// basics ////////// //unsigned int MaxSeg; @@ -49,7 +53,7 @@ typedef struct{ /* MAXSEG-1; MAXSEG must be a power of 2 */ unsigned int MaxSegRemainderBitMask; - DYNARR_SEG_TYPE* pSegArr; + DYNARR_SEG_TYPE(DYNARR_DATA_TYPE)* pSegArr; //real_t* pSegNextArr; int iInsertPos; /////////////////// Free nodes list //////////////// @@ -58,212 +62,188 @@ typedef struct{ struct FreeSegNode* pTempFreeNode1, *pTempFreeNode2; ////////////// temporaries ////////////// int iTempIndex1, iTempIndex2; - DYNARR_SEG_TYPE tempSeg1; - const DYNARR_SEG_TYPE emptySeg; + DYNARR_SEG_TYPE(DYNARR_DATA_TYPE) tempSeg1; + const DYNARR_SEG_TYPE(DYNARR_DATA_TYPE) emptySeg; //////////// Segment banks //////////// - DYNARR_SEG_TYPE** pSegBanksArr; + DYNARR_SEG_TYPE(DYNARR_DATA_TYPE)** pSegBanksArr; int* pSegBankSizeArr; int* pSegBankIndexLimitArr; int NumSegBanks; int MaxSegBanks; int SegBankAllocViolation; -}DYNARR_STRUCT; +} DYNARR_STATE(DYNARR_DATA_TYPE); +#pragma message(TO_STRING(DYNARR_STATE(DYNARR_DATA_TYPE))) // dynarr variable name; contains all state variables -#define DYNARR_VARS TOKEN_PASTE(DYNARR_DATA_TYPE, Vars) -// create a reference -extern DYNARR_STRUCT DYNARR_VARS; +#define DYNARR_VARS(type) TYPED_NAME(type, Vars) /* Shortcuts to important variables */ -#define LOGMAXSEG MEMBER(DYNARR_VARS,.,logMaxSeg) -#define MAXSEG_REMAINDER_BITMASK MEMBER(DYNARR_VARS,.,MaxSegRemainderBitMask) -#define SEG_ARR MEMBER(DYNARR_VARS,.,pSegArr) -#define SEG_INSERT_POS DYNARR_VARS.iInsertPos -#define FREESEG_LIST DYNARR_VARS.pFreeSegList -#define FREESEG_INVALID_LIST DYNARR_VARS.pFreeSegInvalidList -#define FREESEG_LIST_SIZE DYNARR_VARS.iSizeOfFreeSegList -#define TEMP_FREESEGNODE_1 DYNARR_VARS.pTempFreeNode1 -#define TEMP_FREESEGNODE_2 DYNARR_VARS.pTempFreeNode2 -#define TEMP_INDEX_1 DYNARR_VARS.iTempIndex1 -#define TEMP_INDEX_2 DYNARR_VARS.iTempIndex2 -#define TEMP_SEG_1 DYNARR_VARS.iTempIndex1 -#define NULL_SEG DYNARR_VARS.emptySeg -#define SEG_BANK_ALLOC_VIOLATION DYNARR_VARS.SegBankAllocViolation +#define LOGMAXSEG(type) MEMBER(DYNARR_VARS(type),.,LogMaxSeg) +#pragma message(TO_STRING(LOGMAXSEG(DYNARR_DATA_TYPE))) +#define MAXSEG_REMAINDER_BITMASK(type) MEMBER(DYNARR_VARS(type),.,MaxSegRemainderBitMask) +#pragma message(TO_STRING(MAXSEG_REMAINDER_BITMASK(DYNARR_DATA_TYPE))) +#define SEG_ARR(type) MEMBER(DYNARR_VARS(type),.,pSegArr) +#pragma message(TO_STRING(SEG_ARR(DYNARR_DATA_TYPE))) +#define SEG_INSERT_POS(type) MEMBER(DYNARR_VARS(type),.,iInsertPos) +#pragma message(TO_STRING(SEG_INSERT_POS(DYNARR_DATA_TYPE))) +#define FREESEG_LIST(type) DYNARR_VARS(type).pFreeSegList +#pragma message(TO_STRING(FREESEG_LIST(DYNARR_DATA_TYPE))) +#define FREESEG_INVALID_LIST(type) DYNARR_VARS(type).pFreeSegInvalidList +#pragma message(TO_STRING(FREESEG_INVALID_LIST(DYNARR_DATA_TYPE))) +#define FREESEG_LIST_SIZE(type) DYNARR_VARS(type).iSizeOfFreeSegList +#pragma message(TO_STRING(FREESEG_LIST_SIZE(DYNARR_DATA_TYPE))) +#define TEMP_FREESEGNODE_1(type) DYNARR_VARS(type).pTempFreeNode1 +#pragma message(TO_STRING(TEMP_FREESEGNODE_1(DYNARR_DATA_TYPE))) +#define TEMP_FREESEGNODE_2(type) DYNARR_VARS(type).pTempFreeNode2 +#pragma message(TO_STRING(TEMP_FREESEGNODE_2(DYNARR_DATA_TYPE))) +#define TEMP_INDEX_1(type) MEMBER(DYNARR_VARS(type),.,iTempIndex1) +#pragma message(TO_STRING(TEMP_INDEX_1(DYNARR_DATA_TYPE))) +#define TEMP_INDEX_2(type) MEMBER(DYNARR_VARS(type),.,iTempIndex2) +#pragma message(TO_STRING(TEMP_INDEX_2(DYNARR_DATA_TYPE))) +#define TEMP_SEG_1(type) DYNARR_VARS(type).iTempIndex1 +#pragma message(TO_STRING(TEMP_SEG_1(DYNARR_DATA_TYPE))) +#define NULL_SEG(type) DYNARR_VARS(type).emptySeg +#pragma message(TO_STRING(SEG_INSERT_POS(DYNARR_DATA_TYPE))) +#pragma message(TO_STRING(SEG_INSERT_POS(DYNARR_DATA_TYPE))) +#define SEG_BANK_ALLOC_VIOLATION(type) DYNARR_VARS(type).SegBankAllocViolation +#pragma message(TO_STRING(SEG_INSERT_POS(DYNARR_DATA_TYPE))) // maximum number of segment banks // this should be a very big number // this number should never be reached -#define MAX_SEG_BANKS MEMBER(DYNARR_VARS,.,MaxSegBanks) +#define MAX_SEG_BANKS(type) MEMBER(DYNARR_VARS(type),.,MaxSegBanks) // array containing size (# of segments) of each segment bank -#define SEG_BANK_SIZE_ARR MEMBER(DYNARR_VARS,.,pSegBankSizeArr) +#define SEG_BANK_SIZE_ARR(type) MEMBER(DYNARR_VARS(type),.,pSegBankSizeArr) // array containing last valid index of each segment bank -#define SEG_BANK_INDEX_LIMIT_ARR MEMBER(DYNARR_VARS,.,pSegBankIndexLimitArr) +#define SEG_BANK_INDEX_LIMIT_ARR(type) MEMBER(DYNARR_VARS(type),.,pSegBankIndexLimitArr) // Number of active segment banks -#define NUM_SEG_BANKS MEMBER(DYNARR_VARS,.,NumSegBanks) -#define CURRENT_SEG_BANK (NUM_SEG_BANKS - 1) +#define NUM_SEG_BANKS(type) MEMBER(DYNARR_VARS(type),.,NumSegBanks) +#define CURRENT_SEG_BANK(type) (NUM_SEG_BANKS(type) - 1) // actual segment banks -#define SEG_BANKS_ARR MEMBER(DYNARR_VARS,.,pSegBanksArr) +#define SEG_BANKS_ARR(type) MEMBER(DYNARR_VARS(type),.,pSegBanksArr) // declarations // external definitions for allocating/resizing blocks -int TYPED_NAME(seg_bank_alloc_next)(); -int TYPED_NAME(seg_bank_increase_max)(); +#define SEG_ARR_ALLOC_NEXT_FUNC(type) TYPED_NAME(type, _seg_bank_alloc_next) +#define SEG_ARR_INC_MAX_FUNC(type) TYPED_NAME(type, _seg_bank_increase_max) -#if 0 #define EMPTY_INDEX 0 #define EMPTY_BYTE 0 #define SEG_INSERT_POS_BEGIN 1 -// Node blocks +// segment banks #if _REGION_ // coordinates in the 2-D segment allocation -#define BANK_INDEX_FROM_SEG_INDEX(index) \ - ( ((unsigned int)(index)) >> LOG_MAXSEG ) +#define BANK_INDEX_FROM_SEG_INDEX(type, index) \ + ( ((unsigned int)(index)) >> LOG_MAXSEG(type) ) -#define BANK_FROM_SEG_INDEX(index) SEG_BANKS_ARR[BANK_INDEX_FROM_SEG_INDEX(index)] -#define SLOT_FROM_SEG_INDEX(index) (((unsigned int)(index)) & MAXSEG_REMAINDER_BITMASK) +#define BANK_FROM_SEG_INDEX(type, index) SEG_BANKS_ARR[BANK_INDEX_FROM_SEG_INDEX(type, index)] +#define SLOT_FROM_SEG_INDEX(type, index) (((unsigned int)(index)) & MAXSEG_REMAINDER_BITMASK(type)) // pointer to the segment -#define PTR_SEG_FROM_INDEX(index) \ - (BANK_FROM_SEG_INDEX(index) + NUM_SEG_MEMBERS_IN_ARR * SLOT_FROM_SEG_INDEX(index) ) +#define PTR_SEG_FROM_INDEX(type, index) \ + (BANK_FROM_SEG_INDEX(type, index) + SLOT_FROM_SEG_INDEX(type, index) ) #endif -/* Accessor methods */ -#define SEG_ARR_GET_SEG(segIndex) \ - ( (segIndex) != EMPTY_INDEX && \ - (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 -// Region: seg banks use/create/init/cleanup -#ifdef _REGION_ - - - -#define SEG_BANKS_CREATE() \ - /* NumSegBanks must be initialized at once, because it may be needed by GPU */ \ - NUM_SEG_BANKS = 1; /* Default value */ \ - MAX_SEG_BANKS = 1; /* Default value */ \ - SEG_BANK_ALLOC_VIOLATION = 0; \ - - -/* SEG_BANKS_INIT() must be called after/at the end of SEG_ARR_INIT() */ -#define SEG_BANKS_INIT() \ - /* In test mode, do not initalize MaxSegBanks here so that - it can be initialized by other code before calling SEG_BANKS_INIT() */ \ - if (!TestEnabled) MaxSegBanks = 1; \ - SEG_BANKS_ARR = (real_t**)malloc(MaxSegBanks * sizeof(real_t*)); \ - memset(SEG_BANKS_ARR, 0, MaxSegBanks * sizeof(real_t*)); \ - SEG_BANK_SIZE_ARR = (int*)malloc(MaxSegBanks * sizeof(int)); \ - memset(SEG_BANK_SIZE_ARR, 0, MaxSegBanks * sizeof(int)); \ - SEG_BANK_INDEX_LIMIT_ARR = (int*)malloc(MaxSegBanks * sizeof(int)); \ - memset(SEG_BANK_INDEX_LIMIT_ARR, 0, MaxSegBanks * sizeof(int)); \ - SEG_BANKS_ARR[0] = pSegArr + SEG_ARR_SEG_CONTENTS_OFFSET; \ - SEG_BANK_SIZE_ARR[0] = MAXSEG; \ - SEG_BANK_INDEX_LIMIT_ARR[0] = MAXSEG - 1; \ - NumSegBanks = 1; /* one segment bank is already created */ \ - SegBankAllocViolation = 0; \ - -#define SEG_BANKS_CLEANUP() \ - for(iTempIndex1 = 1; iTempIndex1 < NUM_SEG_BANKS; iTempIndex1++){ \ - FREE_SAFE(SEG_BANKS_ARR[iTempIndex1]); \ - } \ - FREE_SAFE(SEG_BANKS_ARR); \ - FREE_SAFE(SEG_BANK_SIZE_ARR); \ - FREE_SAFE(SEG_BANK_INDEX_LIMIT_ARR); \ - SegBankAllocViolation = 0; \ +/* DynArr methods*/ +#if _REGION_ + +// create a global dynarr struct containing all state variables for given type +#define SEG_ARR_CREATE(type) \ + DYNARR_STATE(type) DYNARR_VARS(type); -#endif +// use the global dynarr struct containing all state variables for given type +#define SEG_ARR_USE(type) \ + extern SEG_ARR_CREATE(type); -/* DynArr methods*/ -#define SEG_ARR_USE() \ - extern DYNARR_STRUCT DYNARR_VARS; - -#define SEG_ARR_CREATE() \ - DYNARR_STRUCT DYNARR_VARS; \ - SEG_ARR = NULL; \ - SEG_INSERT_POS = SEG_INSERT_POS_BEGIN; \ - FREESEG_LIST = NULL, FREESEG_INVALID_LIST = NULL; \ - FREESEG_LIST_SIZE = 0; \ - TEMP_FREESEGNODE_1 = NULL, TEMP_FREESEGNODE_2 = NULL; \ - TEMP_INDEX_1 = 0, TEMP_INDEX_2 = 0;\ - /* initialize struct types later */\ - SEG_BANKS_CREATE(); \ - - - -#define SEG_ARR_INIT() \ - printf("maxseg: %d, offsets... fs:%d ls:%d c:%d v:%d n:%d num_seg_arr_items:%d\n", \ - MAXSEG, \ - SEG_ARR_FIRSTSEG_OFFSET, \ - SEG_ARR_LASTSEG_OFFSET, \ - SEG_ARR_C_OFFSET, \ - SEG_ARR_V_OFFSET, \ - SEG_ARR_NEXT_OFFSET, \ - NUM_SEG_ARR_ITEMS \ - ); \ +// initialize all state variables in the global dynarr struct for given type +#define SEG_ARR_INIT(type) \ /*MaxSeg should be already assigned */ \ - assert(MaxSeg > 0 ); \ - LogMaxSeg = (unsigned int) (log(MaxSeg+0.0f)/log(2.0f)); \ - MaxSegRemainderBitMask = (unsigned int) (MaxSeg - 1); \ - pSegArr = (real_t*) malloc(sizeof(real_t) * NUM_SEG_ARR_ITEMS); \ - assert(pSegArr != NULL ); \ - /* seg indexes: first-seg, last-seg */ \ - pFirstSegIndexForPipe = (real_t*)(pSegArr + SEG_ARR_FIRSTSEG_OFFSET); \ - pLastSegIndexForPipe = (real_t*)(pSegArr + SEG_ARR_LASTSEG_OFFSET); \ - /* seg contents: c,v,next */ \ - pSegCArr = (real_t*)(pSegArr + SEG_ARR_C_OFFSET); \ - pSegVArr = (real_t*)(pSegArr + SEG_ARR_V_OFFSET); \ - pSegNextArr = (real_t*)(pSegArr + SEG_ARR_NEXT_OFFSET); \ + assert(MAXSEG > 0 ); \ + LOGMAXSEG(type) = (unsigned int) (log(MAXSEG+0.0f)/log(2.0f)); \ + MAXSEG_REMAINDER_BITMASK(type) = (unsigned int) (MAXSEG - 1); \ + SEG_ARR(type) = ( DYNARR_SEG_TYPE(type) *) malloc( sizeof(DYNARR_SEG_TYPE(type) ) * MAXSEG ); \ + assert(SEG_ARR(type) != NULL ); \ /* seg-arr management */ \ - iInsertPos = SEG_INSERT_POS_BEGIN; \ - pFreeSegList = NULL;\ - pFreeSegInvalidList = NULL; \ - memset(pSegArr, 0, sizeof(real_t) * NUM_SEG_ARR_ITEMS ); \ + memset(SEG_ARR(type), 0, sizeof(DYNARR_SEG_TYPE(type)) * MAXSEG ); \ + SEG_INSERT_POS(type) = SEG_INSERT_POS_BEGIN; \ + /*------------------------------------*/ \ /* multiple segment banks */ \ - SEG_BANKS_INIT(); \ + /* In test mode, do not initalize MaxSegBanks here so that */ \ + /* it can be initialized by other code before calling SEG_BANKS_INIT() */ \ + /*if (!TestEnabled) MAX_SEG_BANKS(type) = 1; */ \ + NUM_SEG_BANKS(type) = 1; /* Default value */ \ + MAX_SEG_BANKS(type) = 1; /* Default value */ \ + SEG_BANK_ALLOC_VIOLATION(type) = 0; \ + /* segment banks*/ \ + SEG_BANKS_ARR(type) = (DYNARR_SEG_TYPE(type)**)malloc(MAX_SEG_BANKS(type) * sizeof(DYNARR_SEG_TYPE(type)*)); \ + memset(SEG_BANKS_ARR(type), 0, MAX_SEG_BANKS(type) * sizeof(DYNARR_SEG_TYPE(type)*)); \ + /* segment bank sizes*/ \ + SEG_BANK_SIZE_ARR(type) = (int*)malloc(MAX_SEG_BANKS(type) * sizeof(int)); \ + memset(SEG_BANK_SIZE_ARR(type), 0, MAX_SEG_BANKS(type) * sizeof(int)); \ + /* segment bank index limits */ \ + SEG_BANK_INDEX_LIMIT_ARR(type) = (int*)malloc(MAX_SEG_BANKS(type) * sizeof(int)); \ + memset(SEG_BANK_INDEX_LIMIT_ARR(type), 0, MAX_SEG_BANKS(type) * sizeof(int)); \ + /* first segment bacnk already allocated */ \ + SEG_BANKS_ARR(type)[0] = SEG_ARR(type); \ + SEG_BANK_SIZE_ARR(type)[0] = MAXSEG; \ + SEG_BANK_INDEX_LIMIT_ARR(type)[0] = MAXSEG - 1; \ + NUM_SEG_BANKS(type) = 1; + + +// cleanup all state variables in the global dynarr struct for given type +#define SEG_ARR_CLEANUP(type) \ + FREE_SAFE( SEG_ARR(type) ); \ + SEG_INSERT_POS(type) = SEG_INSERT_POS_BEGIN; \ + /*-------------------------------*/ \ + /* multiple segment banks */ \ + for(TEMP_INDEX_1(type) = 1; TEMP_INDEX_1(type) < NUM_SEG_BANKS(type); TEMP_INDEX_1(type)++){ \ + FREE_SAFE(SEG_BANKS_ARR(type)[TEMP_INDEX_1(type)]); \ + } \ + FREE_SAFE(SEG_BANKS_ARR(type)); \ + FREE_SAFE(SEG_BANK_SIZE_ARR(type)); \ + FREE_SAFE(SEG_BANK_INDEX_LIMIT_ARR(type)); \ + SEG_BANK_ALLOC_VIOLATION(type) = 0; -// -// allocated arrays remain to be used by later timesteps -// + //_SEG_ARR_FREE_LIST_CLEANUP(); \ -#define SEG_ARR_CLEANUP() \ - FREE_SAFE( pSegArr ); \ - _SEG_ARR_FREE_LIST_CLEANUP(); \ - pSegCArr = pSegVArr = pSegNextArr = NULL; \ - iInsertPos = SEG_INSERT_POS_BEGIN; \ - pFirstSegIndexForPipe = NULL; \ - pLastSegIndexForPipe = NULL; \ - /* multiple segment banks */ \ - SEG_BANKS_CLEANUP(); \ +#endif // _REGION +//#define SEG_ARR_EXISTS() ( pSegArr != NULL ) +//#define SEG_ARR_SIZE NUM_SEG_ARR_ITEMS -#define SEG_ARR_EXISTS() ( pSegArr != NULL ) -#define SEG_ARR_SIZE NUM_SEG_ARR_ITEMS +// segment allocation/free/access +#if 0 //_REGION_ +/* Accessor methods */ +#define SEG_ARR_GET_SEG(type, segIndex) \ + ( (segIndex) != EMPTY_INDEX && \ + (segIndex) >= 0 && \ + (segIndex) < SEG_INSERT_POS(type) )\ + ? ( (tempSeg1).index = (segIndex),\ + tempSeg1.nextIndex = \ + (int) (SEG_ARR_SEG_NEXT_INDEX(type, tempSeg1)),\ + tempSeg1.c = SEG_ARR_SEG_C(tempSeg1), \ + tempSeg1.v = SEG_ARR_SEG_V(tempSeg1), \ + tempSeg1.prev = NULL, \ + tempSeg1)\ + : NULL_SEG -// allocation/free #define SEG_EPANET_FREE_SET(value_seg) \ ( _SEG_ARR_FREE_LIST_ADD((value_seg)), \ - TOTALSEGS_DECR(), \ + /*TOTALSEGS_DECR(), */\ SEG_ARR_SEG_NEXT_INDEX(value_seg) = (real_t) EMPTY_INDEX, \ (value_seg).index = (value_seg).nextIndex = EMPTY_INDEX \ ) @@ -275,7 +255,7 @@ int TYPED_NAME(seg_bank_increase_max)(); ) // should return NULL_SEG if alloc fails -#define SEG_EPANET_ALLOC(value_seg) (\ +#define SEG_EPANET_ALLOC(type, value_seg) (\ (SegBankAllocViolation) \ ? ((value_seg).index = (value_seg).nextIndex = EMPTY_INDEX, (value_seg) ) \ : ( \ @@ -284,7 +264,7 @@ int TYPED_NAME(seg_bank_increase_max)(); TOTALSEGS_INCR(), \ (iInsertPos >= SEG_BANK_INDEX_LIMIT_ARR[NUM_SEG_BANKS-1]) \ ? /* last index filled. allocate more banks. */ \ - seg_bank_alloc_next() \ + SEG_ARR_ALLOC_NEXT_FUNC(type) \ ? /* ok */ (void) 0 \ : /* further alloc not possible */ (\ SegBankAllocViolation = 1, \ @@ -301,27 +281,37 @@ int TYPED_NAME(seg_bank_increase_max)(); ) \ ) \ +#endif // _REGION_ +/*---------------------------------------*/ +/*------- Seg banks methods -------------*/ +SEG_ARR_USE(DYNARR_DATA_TYPE); +#if defined(_MSC_VER) +#define INLINE _inline /* use _inline (VC++ specific) */ +// #define INLINE __forceinline /* use __forceinline (VC++ specific) */ +//#elif __GNUC__ && !__GNUC_STDC_INLINE__ +//#define INLINE inline +#else +#define INLINE inline /* use standard inline */ #endif - - // when maximum number of segment banks is reached, // double MaxSegBanks and // reallocate the bookkeeping machinery // returns 0 if bad, 1 if ok -int TYPED_NAME(seg_bank_increase_max)(){ +INLINE int SEG_ARR_INC_MAX_FUNC(DYNARR_DATA_TYPE)(){ void* pVoid; int bSuccess = 1; - int prevMaxSegBanks = MAX_SEG_BANKS; + int prevMaxSegBanks = MAX_SEG_BANKS(DYNARR_DATA_TYPE); // new limit on number of segment banks - MAX_SEG_BANKS <<= 1; + MAX_SEG_BANKS(DYNARR_DATA_TYPE) <<= 1; // realloc - if (pVoid = realloc(SEG_BANKS_ARR, MAX_SEG_BANKS * sizeof(DYNARR_SEG_TYPE*))){ - SEG_BANKS_ARR = (DYNARR_SEG_TYPE**)pVoid; - memset(SEG_BANKS_ARR + prevMaxSegBanks, 0, (MAX_SEG_BANKS - prevMaxSegBanks) * sizeof(DYNARR_SEG_TYPE*)); + if (pVoid = realloc(SEG_BANKS_ARR(DYNARR_DATA_TYPE), MAX_SEG_BANKS(DYNARR_DATA_TYPE) * sizeof(DYNARR_SEG_TYPE(DYNARR_DATA_TYPE)*))){ + SEG_BANKS_ARR(DYNARR_DATA_TYPE) = (DYNARR_SEG_TYPE(DYNARR_DATA_TYPE)**)pVoid; + memset(SEG_BANKS_ARR(DYNARR_DATA_TYPE) + prevMaxSegBanks, 0, + (MAX_SEG_BANKS(DYNARR_DATA_TYPE) - prevMaxSegBanks) * sizeof(DYNARR_SEG_TYPE(DYNARR_DATA_TYPE)*)); } else { printf("\nFatal error: Failed to increase the Maximum number of segment banks." @@ -330,9 +320,10 @@ int TYPED_NAME(seg_bank_increase_max)(){ return 0; } - if (pVoid = realloc(SEG_BANK_SIZE_ARR, MAX_SEG_BANKS * sizeof(int))){ - SEG_BANK_SIZE_ARR = (int*)pVoid; - memset(SEG_BANK_SIZE_ARR + prevMaxSegBanks, 0, (MAX_SEG_BANKS - prevMaxSegBanks) * sizeof(int)); + if (pVoid = realloc(SEG_BANK_SIZE_ARR(DYNARR_DATA_TYPE), MAX_SEG_BANKS(DYNARR_DATA_TYPE) * sizeof(int))){ + SEG_BANK_SIZE_ARR(DYNARR_DATA_TYPE) = (int*)pVoid; + memset(SEG_BANK_SIZE_ARR(DYNARR_DATA_TYPE) + prevMaxSegBanks, 0, + (MAX_SEG_BANKS(DYNARR_DATA_TYPE) - prevMaxSegBanks) * sizeof(int)); } else { printf("\nFatal error: Failed to increase the Maximum number of segment banks." @@ -341,9 +332,10 @@ int TYPED_NAME(seg_bank_increase_max)(){ return 0; } - if (pVoid = realloc(SEG_BANK_INDEX_LIMIT_ARR, MAX_SEG_BANKS * sizeof(int))){ - SEG_BANK_INDEX_LIMIT_ARR = (int*)pVoid; - memset(SEG_BANK_INDEX_LIMIT_ARR + prevMaxSegBanks, 0, (MAX_SEG_BANKS - prevMaxSegBanks) * sizeof(int)); + if (pVoid = realloc(SEG_BANK_INDEX_LIMIT_ARR(DYNARR_DATA_TYPE), MAX_SEG_BANKS(DYNARR_DATA_TYPE) * sizeof(int))){ + SEG_BANK_INDEX_LIMIT_ARR(DYNARR_DATA_TYPE) = (int*)pVoid; + memset(SEG_BANK_INDEX_LIMIT_ARR(DYNARR_DATA_TYPE) + prevMaxSegBanks, 0, + (MAX_SEG_BANKS(DYNARR_DATA_TYPE) - prevMaxSegBanks) * sizeof(int)); } else { printf("\nFatal error: Failed to increase the Maximum number of segment banks." @@ -359,22 +351,22 @@ int TYPED_NAME(seg_bank_increase_max)(){ // // allocate next segment bank and place iInsertPos in appropriate value // -int TYPED_NAME(seg_bank_alloc_next)(){ +INLINE int SEG_ARR_ALLOC_NEXT_FUNC(DYNARR_DATA_TYPE)(){ // shall we also alloc gpu with cpu? int bAllocGpu = 0; int numElems = MAXSEG, round = 0, iHypotheticalTotalSegsUptoLastActiveBank = 0; - DYNARR_SEG_TYPE* ptr; + DYNARR_SEG_TYPE(DYNARR_DATA_TYPE)* ptr; int bCpuGpuAllocDone = 0; //assert(NumSegBanks < MAX_SEG_BANKS); - if (NUM_SEG_BANKS >= MAX_SEG_BANKS) { + if (NUM_SEG_BANKS(DYNARR_DATA_TYPE) >= MAX_SEG_BANKS(DYNARR_DATA_TYPE)) { // increase limit on the number of segment banks - if (!TYPED_NAME(seg_bank_increase_max)() ){ + if (!SEG_ARR_ALLOC_NEXT_FUNC(DYNARR_DATA_TYPE)()){ // no futher alloc possible - SEG_BANK_ALLOC_VIOLATION = 1; + SEG_BANK_ALLOC_VIOLATION(DYNARR_DATA_TYPE) = 1; printf("\nFatal error: Maximum number of segment banks is reached." "\n\tFile: %s\n\tLine: %d\n", @@ -394,12 +386,12 @@ int TYPED_NAME(seg_bank_alloc_next)(){ numElems >>= (round++); assert(numElems % 4 == 0); // must be a multiple of 4 - ptr = (DYNARR_SEG_TYPE*)malloc(numElems * sizeof(DYNARR_SEG_TYPE)); + ptr = (DYNARR_SEG_TYPE(DYNARR_DATA_TYPE)*)malloc(numElems * sizeof(DYNARR_SEG_TYPE(DYNARR_DATA_TYPE))); } while (numElems > 1 && ptr == NULL); assert(ptr != NULL); if (ptr == NULL){ // no futher alloc possible - SEG_BANK_ALLOC_VIOLATION = 1; + SEG_BANK_ALLOC_VIOLATION(DYNARR_DATA_TYPE) = 1; printf("\nFatal error: Failed to allocate next segment bank" "\n\tFile: %s\n\tLine: %d\n", __FILE__, __LINE__); @@ -407,11 +399,11 @@ int TYPED_NAME(seg_bank_alloc_next)(){ } // ok in cpu - SEG_BANKS_ARR[NUM_SEG_BANKS] = ptr; + SEG_BANKS_ARR(DYNARR_DATA_TYPE)[NUM_SEG_BANKS(DYNARR_DATA_TYPE)] = ptr; // update the size of the bank // it is used when allocating bank in gpu - SEG_BANK_SIZE_ARR[NUM_SEG_BANKS] = numElems; + SEG_BANK_SIZE_ARR(DYNARR_DATA_TYPE)[NUM_SEG_BANKS(DYNARR_DATA_TYPE)] = numElems; // now allocate corresponding bank in gpu bCpuGpuAllocDone = 1; @@ -419,14 +411,14 @@ int TYPED_NAME(seg_bank_alloc_next)(){ // great // initialize everything to zero, this makes all segments initially null - memset(ptr, 0, numElems * sizeof(DYNARR_SEG_TYPE)); - iHypotheticalTotalSegsUptoLastActiveBank = NUM_SEG_BANKS * MAXSEG; + memset(ptr, 0, numElems * sizeof(DYNARR_SEG_TYPE(DYNARR_DATA_TYPE))); + iHypotheticalTotalSegsUptoLastActiveBank = NUM_SEG_BANKS(DYNARR_DATA_TYPE) * MAXSEG; // pretend that each segment bank is of size MaxSeg - SEG_BANK_INDEX_LIMIT_ARR[NUM_SEG_BANKS] = (iHypotheticalTotalSegsUptoLastActiveBank - 1) + numElems; + SEG_BANK_INDEX_LIMIT_ARR(DYNARR_DATA_TYPE)[NUM_SEG_BANKS(DYNARR_DATA_TYPE)] = (iHypotheticalTotalSegsUptoLastActiveBank - 1) + numElems; // finally - SEG_INSERT_POS = iHypotheticalTotalSegsUptoLastActiveBank; - NUM_SEG_BANKS++; + SEG_INSERT_POS(DYNARR_DATA_TYPE) = iHypotheticalTotalSegsUptoLastActiveBank; + NUM_SEG_BANKS(DYNARR_DATA_TYPE)++; return 1; } diff --git a/dynarrc/main.c b/dynarrc/main.c index fa3722c..380d54d 100644 --- a/dynarrc/main.c +++ b/dynarrc/main.c @@ -2,36 +2,39 @@ #include #include -//#define MAXSEG 5 -#define DYNARR_DATA_TYPE int -#define TYPED_NAME( name ) TOKEN_PASTE(DYNARR_DATA_TYPE, name) +typedef struct MyStruct{ + int a; + float b; + char c; +}MyStruct; + +/*------ Allocator for MyStruct ------*/ +// fix the type for this allocator +#define DYNARR_DATA_TYPE MyStruct #include "dynarr.h" -typedef DYNARR_STRUCT IdArr; +SEG_ARR_CREATE(MyStruct); #undef DYNARR_DATA_TYPE - -#define DYNARR_DATA_TYPE float -#define TYPED_NAME( name ) TOKEN_PASTE(DYNARR_DATA_TYPE, name) +/*------ Allocator for MyStruct* ------*/ +typedef struct MyStruct* MyStructPtr; +#define DYNARR_DATA_TYPE MyStructPtr #include "dynarr.h" -typedef DYNARR_STRUCT ValueArr; +SEG_ARR_CREATE(MyStructPtr); #undef DYNARR_DATA_TYPE int main(int argc, char** argv){ MEM_LEAK_CATCH(); + // your code here + SEG_ARR_INIT(MyStruct); + SEG_ARR_CLEANUP(MyStruct); - IdArr *p1; - ValueArr *p2; - - p1 = (IdArr*)malloc(sizeof(IdArr)); - p2 = (ValueArr*)malloc(sizeof(ValueArr)); - + SEG_ARR_INIT(MyStructPtr); + SEG_ARR_CLEANUP(MyStructPtr); // done - FREE_SAFE(p1); - FREE_SAFE(p2); MEM_LEAK_SHOW(); return 0; } \ No newline at end of file