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.segmentmethods.h
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
96 lines (83 sloc)
3.24 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
#define SEG_INSERT_POS_BEGIN 1 | |
#define EMPTY_INDEX 0 | |
// coordinates in the 2-D segment allocation | |
#define BANK_INDEX_FROM_SEG_INDEX(type, index) \ | |
( ((unsigned int)(index)) >> LOGMAXSEG(type) ) | |
#define BANK_FROM_SEG_INDEX(type, index) \ | |
SEG_BANKS_ARR(type)[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(type, index) \ | |
(BANK_FROM_SEG_INDEX(type, index) + SLOT_FROM_SEG_INDEX(type, index) ) | |
#define SEG_ARR_SEG_NEXT_INDEX(type, value_seg) \ | |
(PTR_SEG_FROM_INDEX(type, (value_seg).index )->nextIndex) | |
// segment allocation/free/access | |
/* Accessor methods */ | |
#define SEG_ARR_GET_SEG(type, segIndex) \ | |
( (segIndex) != EMPTY_INDEX && \ | |
(segIndex) >= 0 && \ | |
(segIndex) < SEG_INSERT_POS(type) )\ | |
? ( (TEMP_SEG_1(type)).index = (segIndex),\ | |
TEMP_SEG_1(type).nextIndex = \ | |
(int) (SEG_ARR_SEG_NEXT_INDEX(type, TEMP_SEG_1(type))),\ | |
TEMP_SEG_1(type))\ | |
: NULL_SEG(type) | |
#define SEG_ARR_SEG_FREE_SET(type, value_seg) \ | |
do{ \ | |
_SEG_ARR_FREE_LIST_ADD(type, value_seg ); \ | |
TOTAL_SEGS(type)--; \ | |
SEG_ARR_SEG_NEXT_INDEX(type, value_seg ) = EMPTY_INDEX; \ | |
(value_seg).index = (value_seg).nextIndex = EMPTY_INDEX ; \ | |
}while(0); | |
// returns an available slot | |
// possibly recycled from a previously deleted segment | |
// returns NULL_SEG if alloc fails | |
static INLINE DYNARR_SEG_TYPE(DYNARR_DATA_TYPE) SEG_ARR_ALLOC_SEG_FUNC(DYNARR_DATA_TYPE)() { | |
SEG_ARR_USE(DYNARR_DATA_TYPE); | |
DYNARR_SEG_TYPE(DYNARR_DATA_TYPE) seg; | |
// if there is a free segment available, take it | |
_SEG_ARR_FREE_LIST_GRAB_INDEX(DYNARR_DATA_TYPE, seg); | |
if (DYNARR_SEG_NOT_NULL(seg)){ | |
// valid seg | |
TOTAL_SEGS(DYNARR_DATA_TYPE)++; | |
return seg; | |
} | |
// no free segments available | |
if (SEG_BANK_ALLOC_VIOLATION(DYNARR_DATA_TYPE)){ | |
/* Something bad happened */ | |
(TEMP_SEG_1(DYNARR_DATA_TYPE) = NULL_SEG(DYNARR_DATA_TYPE)); | |
return TEMP_SEG_1(DYNARR_DATA_TYPE); | |
} | |
else{ | |
/* do we need to allocate more banks? */ | |
if (SEG_INSERT_POS(DYNARR_DATA_TYPE) > SEG_BANK_INDEX_LIMIT_ARR(DYNARR_DATA_TYPE)[NUM_SEG_BANKS(DYNARR_DATA_TYPE) - 1]) { | |
/* Yes: alloc a new bank */ | |
/* call function, and see return value */ | |
if (SEG_ARR_ALLOC_NEXT_FUNC(DYNARR_DATA_TYPE)() == 0){ | |
/* next-bank-allocation failed */ | |
SEG_BANK_ALLOC_VIOLATION(DYNARR_DATA_TYPE) = 1; | |
printf("nFatal error: No more segment allocation possible." | |
"ntSegment index: %d, Last possible index: %d " | |
"NumSegBanks: %d, MaxSegBanks: %d " | |
"ntFile: %sntLine: %dn", | |
SEG_INSERT_POS(DYNARR_DATA_TYPE), | |
SEG_BANK_INDEX_LIMIT_ARR(DYNARR_DATA_TYPE)[CURRENT_SEG_BANK(DYNARR_DATA_TYPE)], | |
NUM_SEG_BANKS(DYNARR_DATA_TYPE), | |
MAX_SEG_BANKS(DYNARR_DATA_TYPE), | |
__FILE__, __LINE__); | |
TEMP_SEG_1(DYNARR_DATA_TYPE) = NULL_SEG(DYNARR_DATA_TYPE); | |
} | |
} | |
/* ready for insert, see if the coast is clear */ | |
if (SEG_BANK_ALLOC_VIOLATION(DYNARR_DATA_TYPE) == 0){ | |
/* insert a new segment in the current bank */ | |
TEMP_SEG_1(DYNARR_DATA_TYPE).index = SEG_INSERT_POS(DYNARR_DATA_TYPE); | |
TEMP_SEG_1(DYNARR_DATA_TYPE).nextIndex = EMPTY_INDEX; | |
SEG_INSERT_POS(DYNARR_DATA_TYPE)++; | |
TOTAL_SEGS(DYNARR_DATA_TYPE)++; | |
} | |
/* finally, return*/ | |
return TEMP_SEG_1(DYNARR_DATA_TYPE); | |
} | |
} | |