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
#ifndef DYNARR_DATA_TYPE
#pragma message("Error: DYNARR_DATA_TYPE not defined. " __FILE__)
#endif
// when maximum number of segment banks is reached,
// double MaxSegBanks and
// reallocate the bookkeeping machinery
// returns 0 if bad, 1 if ok
static INLINE int SEG_ARR_INC_MAX_FUNC(DYNARR_DATA_TYPE)(){
SEG_ARR_USE(DYNARR_DATA_TYPE);
void* pVoid;
int bSuccess = 1;
int prevMaxSegBanks = MAX_SEG_BANKS(DYNARR_DATA_TYPE);
// new limit on number of segment banks
// double from previous number
MAX_SEG_BANKS(DYNARR_DATA_TYPE) <<= 1;
// realloc
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."
"\n\tFile: %s\n\tLine: %d\n",
__FILE__, __LINE__);
return 0;
}
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."
"\n\tFile: %s\n\tLine: %d\n",
__FILE__, __LINE__);
return 0;
}
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."
"\n\tFile: %s\n\tLine: %d\n",
__FILE__, __LINE__);
return 0;
}
// ok
return 1;
}
//
// allocate next segment bank and place iInsertPos in appropriate value
//
static INLINE int SEG_ARR_ALLOC_NEXT_FUNC(DYNARR_DATA_TYPE)(){
SEG_ARR_USE(DYNARR_DATA_TYPE);
// shall we also alloc gpu with cpu?
int bAllocGpu = 0;
int numElems = MAXSEG,
round = 0,
iHypotheticalTotalSegsUptoLastActiveBank = 0;
DYNARR_SEG_TYPE(DYNARR_DATA_TYPE)* ptr;
int bCpuGpuAllocDone = 0;
//assert(NumSegBanks < 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 (!SEG_ARR_INC_MAX_FUNC(DYNARR_DATA_TYPE)()){
// no futher alloc possible
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",
__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
// try allocating numElems segments
// if it fails, in next trial, try allocating half as many segments
do{
numElems >>= (round++);
assert(numElems % 4 == 0); // must be a multiple of 4
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(DYNARR_DATA_TYPE) = 1;
printf("\nFatal error: Failed to allocate next segment bank"
"\n\tFile: %s\n\tLine: %d\n", __FILE__, __LINE__);
return 0;
}
// ok in cpu
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(DYNARR_DATA_TYPE)[NUM_SEG_BANKS(DYNARR_DATA_TYPE)] = 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 * 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(DYNARR_DATA_TYPE)[NUM_SEG_BANKS(DYNARR_DATA_TYPE)] = (iHypotheticalTotalSegsUptoLastActiveBank - 1) + numElems;
// finally
SEG_INSERT_POS(DYNARR_DATA_TYPE) = iHypotheticalTotalSegsUptoLastActiveBank;
NUM_SEG_BANKS(DYNARR_DATA_TYPE)++;
return 1;
}