Skip to content
Permalink
2f30e5650e
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
241 lines (197 sloc) 7.23 KB
#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.*/
/* Assuming DYNARR_TYPE is defined.
The data type of the array.
Must be a valid one-word type without space, *, etc. (use typedef if necessary)
*/
#ifndef MAXSEG
#pragma message("MAXSEG must be defined before including " __FILE__)
#elif MAXSEG <= 0
#pragma message("MAXSEG has non positive value: " MAXSEG)
#elif !defined(DYNARR_TYPE)
#pragma message("DYNARR_TYPE must be defined before including " __FILE__)
#else
// everything is fine
#include "dynarr_freenodelist.h"
// declarations
// swap two integers, or pointers, without using temporary storage
__inline void int_swap(unsigned int *var1, unsigned int *var2) {
(*var1) = (*var1) ^ (*var2);
(*var2) = (*var1) ^ (*var2);
(*var1) = (*var1) ^ (*var2);
}
// external definitions for allocating/resizing blocks
extern int seg_bank_alloc_next();
extern int seg_bank_increase_max();
#define SEG_ARR_NAME pSegArr
#define SEG_INSERT_POS iInsertPos
#define EMPTY_INDEX 0
#define EMPTY_BYTE 0
#define NULL_SEG emptySeg
#define SEG_INSERT_POS_BEGIN 1
// Node blocks
#if _REGION_
// maximum number of segment banks
// this should be a very big number
// this number should never be reached
#define MAX_SEG_BANKS INT_MAX
// array containing size (# of segments) of each segment bank
#define SEG_BANK_SIZE_ARR pSegBankSizeArr
// array containing last valid index of each segment bank
#define SEG_BANK_INDEX_LIMIT_ARR pSegBankIndexLimitArr
// Number of active segment banks
#define NUM_SEG_BANKS NumSegBanks
#define CURRENT_SEG_BANK (NUM_SEG_BANKS - 1)
// actual segment banks
#define SEG_BANKS_ARR pSegBanksArr
// coordinates in the 2-D segment allocation
#define BANK_INDEX_FROM_SEG_INDEX(index) \
( ((unsigned int)(index)) >> LOG_MAXSEG )
#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)
// 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) )
#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_USE() \
extern int NumSegBanks; \
extern int MaxSegBanks; \
extern real_t** SEG_BANKS_ARR; \
extern int* SEG_BANK_SIZE_ARR; \
extern int* SEG_BANK_INDEX_LIMIT_ARR; \
extern int SegBankAllocViolation; \
#define SEG_BANKS_CREATE() \
/* NumSegBanks must be initialized at once, because it may be needed by GPU */ \
int NumSegBanks = 1; /* Default value */ \
int MaxSegBanks = 1; /* Default value */ \
real_t** SEG_BANKS_ARR; \
int* SEG_BANK_SIZE_ARR; \
int* SEG_BANK_INDEX_LIMIT_ARR; \
int SegBankAllocViolation = 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; \
#endif
/* DynArr methods*/
#define SEG_ARR_USE() \
extern real_t* pSegArr; \
extern real_t* pSegCArr; \
extern real_t* pSegVArr; \
extern real_t* pSegNextArr; \
extern real_t *pFirstSegIndexForPipe, *pLastSegIndexForPipe; \
extern int iInsertPos; \
extern struct FreeSegNode *pFreeSegList, *pFreeSegInvalidList; \
extern int iSizeOfFreeSegList; \
extern struct FreeSegNode* pTempFreeNode1, *pTempFreeNode2; \
extern int iTempIndex1, iTempIndex2; \
extern struct Sseg tempSeg1;\
extern const struct Sseg emptySeg;\
/* multiple segment banks */ \
SEG_BANKS_USE(); \
#define SEG_ARR_CREATE() \
real_t* pSegArr = NULL; \
real_t* pSegCArr = NULL; \
real_t* pSegVArr = NULL; \
real_t* pSegNextArr = NULL; \
real_t *pFirstSegIndexForPipe = NULL; \
real_t *pLastSegIndexForPipe = NULL; \
int iInsertPos = SEG_INSERT_POS_BEGIN; \
struct FreeSegNode *pFreeSegList = NULL, *pFreeSegInvalidList = NULL; \
int iSizeOfFreeSegList = 0; \
struct FreeSegNode* pTempFreeNode1 = NULL, *pTempFreeNode2 = NULL; \
int iTempIndex1 = 0, iTempIndex2 = 0;\
const struct Sseg emptySeg = EMPTY_SSEG;\
struct Sseg tempSeg1; \
/* multiple segment banks */ \
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 \
); \
/*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); \
/* seg-arr management */ \
iInsertPos = SEG_INSERT_POS_BEGIN; \
pFreeSegList = NULL;\
pFreeSegInvalidList = NULL; \
memset(pSegArr, 0, sizeof(real_t) * NUM_SEG_ARR_ITEMS ); \
/* multiple segment banks */ \
SEG_BANKS_INIT(); \
//
// allocated arrays remain to be used by later timesteps
//
#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(); \
#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