Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Need to check segment allocation/write/read/deallocation.
Signed-off-by: unknown <saq10002@iteb-219.ad.engr.uconn.edu>
  • Loading branch information
unknown committed Oct 4, 2014
1 parent 33b0c18 commit b59ee19
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 165 deletions.
234 changes: 175 additions & 59 deletions dynarrc/dynarr.h
Expand Up @@ -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 */
Expand All @@ -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;
Expand All @@ -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)))
Expand All @@ -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)))
Expand Down Expand Up @@ -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
Expand All @@ -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; \
/*------------------------------------*/ \
Expand Down Expand Up @@ -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)\
) \
) \
Expand All @@ -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);
Expand Down Expand Up @@ -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;

Expand Down

0 comments on commit b59ee19

Please sign in to comment.