Permalink
Cannot retrieve contributors at this time
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?
dynarrc/dynarrc/dynarr.c
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
139 lines (117 sloc)
3.73 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/**/ | |
#include "common.h" | |
#define EXTERN | |
/* Some global variables used externally */ | |
/* Maximum number of segments allowed to be in the system. Must be a power of 2 */ | |
EXTERN unsigned int MaxSeg; | |
/* Base-2 log */ | |
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 = MAX_SEG_BANKS; | |
// new limit on number of segment banks | |
MAX_SEG_BANKS <<= 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; | |
} |