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/dynarrc.segbankmethods.h
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
135 lines (117 sloc)
4.49 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
#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; | |
} |