From b59ee19e6019577dbc6ce7633281fed9a2b8a432 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Oct 2014 21:08:36 -0400 Subject: [PATCH] Need to check segment allocation/write/read/deallocation. Signed-off-by: unknown --- dynarrc/dynarr.h | 234 ++++++++++++++++++++++++-------- dynarrc/dynarr_freenodelist.h | 102 -------------- dynarrc/dynarrc.vcxproj | 1 - dynarrc/dynarrc.vcxproj.filters | 3 - dynarrc/main.c | 2 + 5 files changed, 177 insertions(+), 165 deletions(-) delete mode 100644 dynarrc/dynarr_freenodelist.h diff --git a/dynarrc/dynarr.h b/dynarrc/dynarr.h index bf7ceeb..68c9467 100644 --- a/dynarrc/dynarr.h +++ b/dynarrc/dynarr.h @@ -26,21 +26,74 @@ // everything is fine -#include "dynarr_freenodelist.h" +#ifndef __dynarr_only_once__ +#define __dynarr_only_once__ + + +// the struct FreeSegNode will be used multiple times, so we do not want to redefine it +struct FreeSegNode{ + int index; + struct FreeSegNode* next; +}; +typedef struct FreeSegNode FreeSegNode; + + + +#define _FreeSegNodeMalloc() \ + ( (struct FreeSegNode*) malloc(sizeof(struct FreeSegNode)) ) +// Swaps two 32-bit intergers without using temporary variables +#define _SEG_ARR_INT_SWAP(var1, var2) (\ + (var1) = (FreeSegNode*) (((int) (void*) var1) ^ ((int) (void*) var2) ), \ + (var2) = (FreeSegNode*) (((int) (void*) var1) ^ ((int) (void*) var2) ), \ + (var1) = (FreeSegNode*) (((int) (void*) var1) ^ ((int) (void*) var2) ) ) +// Given two lists A and B, moves the head of A in front of the +// head of B. Head of A must be non-null. +// +// Before: +// A-->1-2-3-4-5 +// B-->a-b-c-d-e +// After: +// A-->2-3-4-5 +// B-->1-a-b-c-d-e +// +#define _SEG_ARR_MOVE_LIST_HEAD(listFrom, listTo) (\ + _SEG_ARR_INT_SWAP( listFrom->next, listTo), \ + _SEG_ARR_INT_SWAP( listFrom, listTo ) \ + ) + #ifndef TYPED_NAME +// prefix the name with the type #define TYPED_NAME(type, name ) TOKEN_PASTE(type, name) #endif +#if defined(_MSC_VER) + +// inlining +#define INLINE _inline /* use _inline (VC++ specific) */ +// #define INLINE __forceinline /* use __forceinline (VC++ specific) */ +//#elif __GNUC__ && !__GNUC_STDC_INLINE__ +//#define INLINE inline +#else +#define INLINE inline /* use standard inline */ +#endif + +#endif // __dynarr_only_once__ + + /* The segment structure. These are the nodes of the linked list */ #define DYNARR_SEG_TYPE(type) TYPED_NAME(type, Sseg) typedef struct { - DYNARR_DATA_TYPE data; int index; // my position int nextIndex; // next node's position + DYNARR_DATA_TYPE data; }DYNARR_SEG_TYPE(DYNARR_DATA_TYPE); -//const DYNARR_SEG_STRUCT TYPED_NAME(EMPTY_SSEG); + +// true if the index is 0 +#define DYNARR_SEG_NULL(value_seg) ( (value_seg).index == EMPTY_INDEX ) +#define DYNARR_SEG_NOT_NULL(value_seg) ( (value_seg).index != EMPTY_INDEX ) +#define MAKE_DYNARR_SEG_NULL(value_seg) ( (value_seg).index = EMPTY_INDEX ) /* The dynamic array data structure */ @@ -63,7 +116,7 @@ typedef struct{ ////////////// temporaries ////////////// int iTempIndex1, iTempIndex2; DYNARR_SEG_TYPE(DYNARR_DATA_TYPE) tempSeg1; - const DYNARR_SEG_TYPE(DYNARR_DATA_TYPE) emptySeg; + DYNARR_SEG_TYPE(DYNARR_DATA_TYPE) emptySeg; //////////// Segment banks //////////// DYNARR_SEG_TYPE(DYNARR_DATA_TYPE)** pSegBanksArr; int* pSegBankSizeArr; @@ -77,6 +130,18 @@ typedef struct{ // dynarr variable name; contains all state variables #define DYNARR_VARS(type) TYPED_NAME(type, Vars) +// create a global dynarr struct containing all state variables for given type +#define SEG_ARR_CREATE(type) \ + DYNARR_STATE(type) DYNARR_VARS(type); + +// use the global dynarr struct containing all state variables for given type +#define SEG_ARR_USE(type) \ + extern SEG_ARR_CREATE(type); + +/* Declare state variables to be used by functions below */ +SEG_ARR_USE(DYNARR_DATA_TYPE); + + /* Shortcuts to important variables */ #define LOGMAXSEG(type) MEMBER(DYNARR_VARS(type),.,LogMaxSeg) #pragma message(TO_STRING(LOGMAXSEG(DYNARR_DATA_TYPE))) @@ -86,9 +151,9 @@ typedef struct{ #pragma message(TO_STRING(SEG_ARR(DYNARR_DATA_TYPE))) #define SEG_INSERT_POS(type) MEMBER(DYNARR_VARS(type),.,iInsertPos) #pragma message(TO_STRING(SEG_INSERT_POS(DYNARR_DATA_TYPE))) -#define FREESEG_LIST(type) DYNARR_VARS(type).pFreeSegList +#define FREESEG_LIST(type) MEMBER(DYNARR_VARS(type),.,pFreeSegList) #pragma message(TO_STRING(FREESEG_LIST(DYNARR_DATA_TYPE))) -#define FREESEG_INVALID_LIST(type) DYNARR_VARS(type).pFreeSegInvalidList +#define FREESEG_INVALID_LIST(type) MEMBER(DYNARR_VARS(type),.,pFreeSegInvalidList) #pragma message(TO_STRING(FREESEG_INVALID_LIST(DYNARR_DATA_TYPE))) #define FREESEG_LIST_SIZE(type) DYNARR_VARS(type).iSizeOfFreeSegList #pragma message(TO_STRING(FREESEG_LIST_SIZE(DYNARR_DATA_TYPE))) @@ -126,11 +191,12 @@ typedef struct{ -// declarations -// external definitions for allocating/resizing blocks -#define SEG_ARR_ALLOC_NEXT_FUNC(type) TYPED_NAME(type, _seg_bank_alloc_next) -#define SEG_ARR_INC_MAX_FUNC(type) TYPED_NAME(type, _seg_bank_increase_max) - +// external declarations for allocating/resizing blocks +#define SEG_ARR_ALLOC_NEXT_FUNC(type) TYPED_NAME(type, _seg_bank_alloc_next) +#define SEG_ARR_INC_MAX_FUNC(type) TYPED_NAME(type, _seg_bank_increase_max) +// early declarations +extern int SEG_ARR_ALLOC_NEXT_FUNC(DYNARR_DATA_TYPE)(); +extern int SEG_ARR_INC_MAX_FUNC(DYNARR_DATA_TYPE)(); #define EMPTY_INDEX 0 @@ -153,31 +219,94 @@ typedef struct{ (BANK_FROM_SEG_INDEX(type, index) + SLOT_FROM_SEG_INDEX(type, index) ) #endif +// Free segment list methods +#if _REGION_ +// returns index +#define _SEG_ARR_FREE_LIST_ADD_VALIDLIST(type, value_seg) (\ + (!FREESEG_LIST(type))\ + ?(\ + FREESEG_LIST(type) = _FreeSegNodeMalloc(), \ + /*assert(FREESEG_LIST(type) != NULL );*/ \ + FREESEG_LIST(type)->next = NULL, \ + FREESEG_LIST(type)->index = ((value_seg).index) \ + ) : (\ + TEMP_FREESEGNODE_1(type) = _FreeSegNodeMalloc(), \ + /*assert(pTempFreeNode1 != NULL );*/ \ + TEMP_FREESEGNODE_1(type)->next = FREESEG_LIST(type); \ + FREESEG_LIST(type) = TEMP_FREESEGNODE_1(type); \ + FREESEG_LIST(type)->index = ((value_seg).index) \ + ) \ + ) +// Algorithm: +// If (an invalid node exists) Then +// move it to the front of valid list +// set its index as the index of value_seg +// Else +// Allocate new node in the valid list +// +#define _SEG_ARR_FREE_LIST_ADD(type, value_seg) (\ + ( FREESEG_INVALID_LIST(type) ) \ + ? ( \ + _SEG_ARR_MOVE_LIST_HEAD( FREESEG_INVALID_LIST(type), FREESEG_LIST(type) ), \ + FREESEG_LIST(type)->index = ((value_seg).index) \ + ) \ + : ( _SEG_ARR_FREE_LIST_ADD_VALIDLIST_FUNC(type)(value_seg) ) \ + ) -/* DynArr methods*/ -#if _REGION_ +#define _SEG_ARR_REMOVE_LIST_HEAD(type, list) (\ + TEMP_FREESEGNODE_1(type) = list, \ + list = list->next, \ + FREE_SAFE( TEMP_FREESEGNODE_1(type) ) )\ -// create a global dynarr struct containing all state variables for given type -#define SEG_ARR_CREATE(type) \ - DYNARR_STATE(type) DYNARR_VARS(type); +// Algorithm: +// If (a valid node exists) Then +// output its index, and +// move it to the front of invalid list +// Else +// output null index +// +#define _SEG_ARR_FREE_LIST_GRAB_INDEX(type, value_seg) (\ + ( FREESEG_LIST(type) ) ?(\ + (value_seg).index = FREESEG_LIST(type)->index, \ + (value_seg).nextIndex = EMPTY_INDEX, \ + _SEG_ARR_MOVE_LIST_HEAD( type, FREESEG_LIST(type), FREESEG_INVALID_LIST(type) ), \ + (value_seg) \ + ):(\ + MAKE_DYNARR_SEG_NULL(value_seg), \ + (value_seg) \ + ) )\ + + +#define _SEG_ARR_FREE_LIST_CLEANUP(type) {\ + while( FREESEG_LIST(type) ) {\ + _SEG_ARR_REMOVE_LIST_HEAD(type, FREESEG_LIST(type)); \ + } \ + while( FREESEG_INVALID_LIST(type) ) {\ + _SEG_ARR_REMOVE_LIST_HEAD(type, FREESEG_INVALID_LIST(type)); \ + } \ +} \ -// use the global dynarr struct containing all state variables for given type -#define SEG_ARR_USE(type) \ - extern SEG_ARR_CREATE(type); +#endif +/* DynArr methods*/ +#if _REGION_ + +// SEG_ARR_USE() and SEG_ARR_CREATE() has already been defined + // initialize all state variables in the global dynarr struct for given type #define SEG_ARR_INIT(type) \ /*MaxSeg should be already assigned */ \ assert(MAXSEG > 0 ); \ LOGMAXSEG(type) = (unsigned int) (log(MAXSEG+0.0f)/log(2.0f)); \ MAXSEG_REMAINDER_BITMASK(type) = (unsigned int) (MAXSEG - 1); \ + NULL_SEG(type).index = NULL_SEG(type).nextIndex = EMPTY_INDEX; \ + /* seg-arr management */ \ SEG_ARR(type) = ( DYNARR_SEG_TYPE(type) *) malloc( sizeof(DYNARR_SEG_TYPE(type) ) * MAXSEG ); \ assert(SEG_ARR(type) != NULL ); \ - /* seg-arr management */ \ memset(SEG_ARR(type), 0, sizeof(DYNARR_SEG_TYPE(type)) * MAXSEG ); \ SEG_INSERT_POS(type) = SEG_INSERT_POS_BEGIN; \ /*------------------------------------*/ \ @@ -216,67 +345,62 @@ typedef struct{ FREE_SAFE(SEG_BANKS_ARR(type)); \ FREE_SAFE(SEG_BANK_SIZE_ARR(type)); \ FREE_SAFE(SEG_BANK_INDEX_LIMIT_ARR(type)); \ - SEG_BANK_ALLOC_VIOLATION(type) = 0; - - //_SEG_ARR_FREE_LIST_CLEANUP(); \ + SEG_BANK_ALLOC_VIOLATION(type) = 0; \ + _SEG_ARR_FREE_LIST_CLEANUP(type); \ #endif // _REGION //#define SEG_ARR_EXISTS() ( pSegArr != NULL ) //#define SEG_ARR_SIZE NUM_SEG_ARR_ITEMS +#define SEG_ARR_SEG_NEXT_INDEX(type, value_seg) (PTR_SEG_FROM_INDEX(type, (value_seg).index)->nextIndex) // segment allocation/free/access -#if 0 //_REGION_ +#if 1 //_REGION_ /* Accessor methods */ #define SEG_ARR_GET_SEG(type, segIndex) \ ( (segIndex) != EMPTY_INDEX && \ (segIndex) >= 0 && \ (segIndex) < SEG_INSERT_POS(type) )\ - ? ( (tempSeg1).index = (segIndex),\ - tempSeg1.nextIndex = \ - (int) (SEG_ARR_SEG_NEXT_INDEX(type, tempSeg1)),\ - tempSeg1.c = SEG_ARR_SEG_C(tempSeg1), \ - tempSeg1.v = SEG_ARR_SEG_V(tempSeg1), \ - tempSeg1.prev = NULL, \ - tempSeg1)\ - : NULL_SEG - -#define SEG_EPANET_FREE_SET(value_seg) \ - ( _SEG_ARR_FREE_LIST_ADD((value_seg)), \ + ? ( (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_FREE_SET(type, value_seg) \ + ( _SEG_ARR_FREE_LIST_ADD(type, (value_seg)), \ /*TOTALSEGS_DECR(), */\ - SEG_ARR_SEG_NEXT_INDEX(value_seg) = (real_t) EMPTY_INDEX, \ + SEG_ARR_SEG_NEXT_INDEX(type, (value_seg)) = EMPTY_INDEX, \ (value_seg).index = (value_seg).nextIndex = EMPTY_INDEX \ ) -#define SEG_EPANET_FREE_GET(value_seg) (\ - _SEG_ARR_FREE_LIST_GRAB_INDEX((value_seg)), \ - (SEG_EPANET_NOT_NULL(value_seg) ? TOTALSEGS_INCR() : 0), \ +#define SEG_ARR_FREE_GET(type, value_seg) (\ + _SEG_ARR_FREE_LIST_GRAB_INDEX(type, (value_seg)), \ (value_seg) \ ) // should return NULL_SEG if alloc fails -#define SEG_EPANET_ALLOC(type, value_seg) (\ - (SegBankAllocViolation) \ +#define SEG_ARR_ALLOC_SEG(type, value_seg) (\ + (SEG_BANK_ALLOC_VIOLATION(type)) \ ? ((value_seg).index = (value_seg).nextIndex = EMPTY_INDEX, (value_seg) ) \ : ( \ - (value_seg).index = iInsertPos, \ + (value_seg).index = SEG_INSERT_POS(type), \ (value_seg).nextIndex = EMPTY_INDEX, \ - TOTALSEGS_INCR(), \ - (iInsertPos >= SEG_BANK_INDEX_LIMIT_ARR[NUM_SEG_BANKS-1]) \ + (SEG_INSERT_POS(type) >= SEG_BANK_INDEX_LIMIT_ARR(type)[NUM_SEG_BANKS(type)-1]) \ ? /* last index filled. allocate more banks. */ \ SEG_ARR_ALLOC_NEXT_FUNC(type) \ ? /* ok */ (void) 0 \ : /* further alloc not possible */ (\ - SegBankAllocViolation = 1, \ + SEG_BANK_ALLOC_VIOLATION(type) = 1, \ printf("\nFatal error: No more segment allocation possible." \ "\n\tSegment index: %d, Last possible index: %d " \ "NumSegBanks: %d, MaxSegBanks: %d " \ "\n\tFile: %s\n\tLine: %d\n", \ - iInsertPos, SEG_BANK_INDEX_LIMIT_ARR[CURRENT_SEG_BANK], \ - NUM_SEG_BANKS, MAX_SEG_BANKS, \ + SEG_INSERT_POS(type), SEG_BANK_INDEX_LIMIT_ARR(type)[CURRENT_SEG_BANK(type)], \ + NUM_SEG_BANKS(type), MAX_SEG_BANKS(type), \ __FILE__, __LINE__) \ ) \ - : /* last index not filled */ iInsertPos++, \ + : /* last index not filled */ SEG_INSERT_POS(type)++, \ (value_seg)\ ) \ ) \ @@ -286,21 +410,13 @@ typedef struct{ /*---------------------------------------*/ /*------- Seg banks methods -------------*/ -SEG_ARR_USE(DYNARR_DATA_TYPE); -#if defined(_MSC_VER) -#define INLINE _inline /* use _inline (VC++ specific) */ -// #define INLINE __forceinline /* use __forceinline (VC++ specific) */ -//#elif __GNUC__ && !__GNUC_STDC_INLINE__ -//#define INLINE inline -#else -#define INLINE inline /* use standard inline */ -#endif + // when maximum number of segment banks is reached, // double MaxSegBanks and // reallocate the bookkeeping machinery // returns 0 if bad, 1 if ok -INLINE int SEG_ARR_INC_MAX_FUNC(DYNARR_DATA_TYPE)(){ +static INLINE int SEG_ARR_INC_MAX_FUNC(DYNARR_DATA_TYPE)(){ void* pVoid; int bSuccess = 1; int prevMaxSegBanks = MAX_SEG_BANKS(DYNARR_DATA_TYPE); @@ -351,7 +467,7 @@ INLINE int SEG_ARR_INC_MAX_FUNC(DYNARR_DATA_TYPE)(){ // // allocate next segment bank and place iInsertPos in appropriate value // -INLINE int SEG_ARR_ALLOC_NEXT_FUNC(DYNARR_DATA_TYPE)(){ +static INLINE int SEG_ARR_ALLOC_NEXT_FUNC(DYNARR_DATA_TYPE)(){ // shall we also alloc gpu with cpu? int bAllocGpu = 0; diff --git a/dynarrc/dynarr_freenodelist.h b/dynarrc/dynarr_freenodelist.h deleted file mode 100644 index 8212da8..0000000 --- a/dynarrc/dynarr_freenodelist.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef __dynarr_free_node_list_h__ -#define __dynarr_free_node_list_h__ - -// the struct FreeSegNode will be used multiple times, so we do not want to redefine it -struct FreeSegNode{ - int index; - struct FreeSegNode* next; -}; -typedef struct FreeSegNode FreeSegNode; - -// name of variables -#define FREESEG_LIST_NAME pFreeSegList -#define FREESEG_INVALID_LIST_NAME pFreeSegInvalidList - - -#define _FreeSegNodeMalloc() \ - ( (struct FreeSegNode*) malloc(sizeof(struct FreeSegNode)) ) -// Swaps two 32-bit intergers without using temporary variables -#define _SEG_ARR_INT_SWAP(var1, var2) (\ - (var1) = (FreeSegNode*) (((int) (void*) var1) ^ ((int) (void*) var2) ), \ - (var2) = (FreeSegNode*) (((int) (void*) var1) ^ ((int) (void*) var2) ), \ - (var1) = (FreeSegNode*) (((int) (void*) var1) ^ ((int) (void*) var2) ) ) -// Given two lists A and B, moves the head of A in front of the -// head of B. Head of A must be non-null. -// -// Before: -// A-->1-2-3-4-5 -// B-->a-b-c-d-e -// After: -// A-->2-3-4-5 -// B-->1-a-b-c-d-e -// -#define _SEG_ARR_MOVE_LIST_HEAD(listFrom, listTo) (\ - _SEG_ARR_INT_SWAP( listFrom->next, listTo), \ - _SEG_ARR_INT_SWAP( listFrom, listTo ) \ - ) - - -#define _SEG_ARR_FREE_LIST_ADD_VALIDLIST(value_seg) \ - ( ( !FREESEG_LIST_NAME ) \ - ?( \ - FREESEG_LIST_NAME = _FreeSegNodeMalloc(), \ - /*assert(FREESEG_LIST_NAME != NULL ),*/ \ - FREESEG_LIST_NAME->next = NULL, \ - FREESEG_LIST_NAME->index = ((value_seg).index) \ - ) \ - :( \ - pTempFreeNode1 = _FreeSegNodeMalloc(), \ - /*assert(pTempFreeNode1 != NULL ),*/ \ - pTempFreeNode1->next = FREESEG_LIST_NAME, \ - FREESEG_LIST_NAME = pTempFreeNode1, \ - FREESEG_LIST_NAME->index = ((value_seg).index) \ - )\ - ) - -// Algorithm: -// If (an invalid node exists) Then -// move it to the front of valid list -// set its index as the index of value_seg -// Else -// Allocate new node in the valid list -// -#define _SEG_ARR_FREE_LIST_ADD(value_seg) (\ - ( FREESEG_INVALID_LIST_NAME ) \ - ? ( \ - _SEG_ARR_MOVE_LIST_HEAD( FREESEG_INVALID_LIST_NAME, FREESEG_LIST_NAME ), \ - FREESEG_LIST_NAME->index = ((value_seg).index) \ - ) \ - : ( _SEG_ARR_FREE_LIST_ADD_VALIDLIST(value_seg) ) \ - ) - - -#define _SEG_ARR_REMOVE_LIST_HEAD(list) (\ - pTempFreeNode1 = list, \ - list = list->next, \ - FREE_SAFE( pTempFreeNode1 ) )\ - -// Algorithm: -// If (a valid node exists) Then -// output its index, and -// move it to the front of invalid list -// Else -// output null index -// -#define _SEG_ARR_FREE_LIST_GRAB_INDEX(value_seg) (\ - ( FREESEG_LIST_NAME ) ?(\ - (value_seg).index = FREESEG_LIST_NAME->index, \ - (value_seg).nextIndex = EMPTY_INDEX, \ - _SEG_ARR_MOVE_LIST_HEAD( FREESEG_LIST_NAME, FREESEG_INVALID_LIST_NAME ), \ - (value_seg) \ - ):(\ - ( (value_seg) = NULL_SEG ) \ - ) )\ - - -#define _SEG_ARR_FREE_LIST_CLEANUP() {\ - while( FREESEG_LIST_NAME ) _SEG_ARR_REMOVE_LIST_HEAD(FREESEG_LIST_NAME); \ - while( FREESEG_INVALID_LIST_NAME ) _SEG_ARR_REMOVE_LIST_HEAD(FREESEG_INVALID_LIST_NAME); \ - } \ - - -#endif \ No newline at end of file diff --git a/dynarrc/dynarrc.vcxproj b/dynarrc/dynarrc.vcxproj index e31e8ad..f1eac40 100644 --- a/dynarrc/dynarrc.vcxproj +++ b/dynarrc/dynarrc.vcxproj @@ -66,7 +66,6 @@ - diff --git a/dynarrc/dynarrc.vcxproj.filters b/dynarrc/dynarrc.vcxproj.filters index a683cab..924c3f3 100644 --- a/dynarrc/dynarrc.vcxproj.filters +++ b/dynarrc/dynarrc.vcxproj.filters @@ -21,9 +21,6 @@ Header Files - - Header Files - diff --git a/dynarrc/main.c b/dynarrc/main.c index 380d54d..29e9dac 100644 --- a/dynarrc/main.c +++ b/dynarrc/main.c @@ -29,6 +29,8 @@ int main(int argc, char** argv){ MEM_LEAK_CATCH(); // your code here SEG_ARR_INIT(MyStruct); + DYNARR_SEG_TYPE(MyStruct) seg = NULL_SEG(MyStruct); + SEG_ARR_ALLOC_SEG(MyStruct, seg); SEG_ARR_CLEANUP(MyStruct); SEG_ARR_INIT(MyStructPtr);