From 716024c94421c7e4dfdb018bc89ae1ec4a053086 Mon Sep 17 00:00:00 2001 From: Evan Ramos Date: Wed, 2 May 2018 15:38:41 -0500 Subject: [PATCH] Feature #1184: Use std::atomic_int for CmiReference / CmiFree Change-Id: I53e944e1b9eb3bc443d94ea06685e882a7bfce9f --- src/arch/gni/machine-persistent.c | 2 +- src/conv-core/convcore.C | 26 +++++++++------------ src/conv-core/converse.h | 49 ++++++++++++++++++++++++++++++++++++--- src/util/pup_cmialloc.C | 4 ++-- 4 files changed, 60 insertions(+), 21 deletions(-) diff --git a/src/arch/gni/machine-persistent.c b/src/arch/gni/machine-persistent.c index 9b246eb97a..d8cbc5cd76 100644 --- a/src/arch/gni/machine-persistent.c +++ b/src/arch/gni/machine-persistent.c @@ -294,7 +294,7 @@ void *PerAlloc(int size) res = mempool_malloc(CpvAccess(persistent_mempool), ALIGNBUF+size-sizeof(mempool_header), 1); if (res) ptr = (char*)res - sizeof(mempool_header) + ALIGNBUF; SIZEFIELD(ptr)=size; - REFFIELD(ptr)= PERSIST_SEQ; + REFFIELDSET(ptr, PERSIST_SEQ); return ptr; #else char *ptr = CmiAlloc(size); diff --git a/src/conv-core/convcore.C b/src/conv-core/convcore.C index 66277d6e0d..9988d11820 100644 --- a/src/conv-core/convcore.C +++ b/src/conv-core/convcore.C @@ -3080,7 +3080,7 @@ void *CmiAlloc(int size) CmiAssert((intptr_t)res % ALIGN_BYTES == 0); SIZEFIELD(res)=size; - REFFIELD(res)=1; + REFFIELDSET(res, 1); return (void *)res; } @@ -3102,7 +3102,7 @@ void *CmiRdmaAlloc(int size) { CmiAssert((intptr_t)res % ALIGN_BYTES == 0); SIZEFIELD(res)=size; - REFFIELD(res)=1; + REFFIELDSET(res, 1); return (void *)res; } @@ -3126,7 +3126,7 @@ int CmiGetReference(void *blk) This call must be matched by an equivalent CmiFree. */ void CmiReference(void *blk) { - REFFIELD(CmiAllocFindEnclosing(blk))++; + REFFIELDINC(CmiAllocFindEnclosing(blk)); } /** Return the size of the user portion of this block. */ @@ -3139,14 +3139,12 @@ int CmiSize(void *blk) void CmiFree(void *blk) { void *parentBlk=CmiAllocFindEnclosing(blk); - int refCount=REFFIELD(parentBlk); + int refCount=REFFIELDDEC(parentBlk); #if CMK_ERROR_CHECKING if(refCount==0) /* Logic error: reference count shouldn't already have been zero */ CmiAbort("CmiFree reference count was zero-- is this a duplicate free?"); #endif - refCount--; - REFFIELD(parentBlk) = refCount; - if(refCount==0) { /* This was the last reference to the block-- free it */ + if(refCount==1) { /* This was the last reference to the block-- free it */ #ifdef MEMMONITOR int size=SIZEFIELD(parentBlk); if (size > 1000000000) /* Absurdly large size field-- warning */ @@ -3187,14 +3185,12 @@ void CmiFree(void *blk) void CmiRdmaFree(void *blk) { void *parentBlk=CmiAllocFindEnclosing(blk); - int refCount=REFFIELD(parentBlk); + int refCount=REFFIELDDEC(parentBlk); #if CMK_ERROR_CHECKING if(refCount==0) /* Logic error: reference count shouldn't already have been zero */ CmiAbort("CmiRdmaFree reference count was zero-- is this a duplicate free?"); #endif - refCount--; - REFFIELD(parentBlk) = refCount; - if(refCount==0) { /* This was the last reference to the block-- free it */ + if(refCount==1) { /* This was the last reference to the block-- free it */ #ifdef MEMMONITOR int size=SIZEFIELD(parentBlk); if (size > 1000000000) /* Absurdly large size field-- warning */ @@ -3433,11 +3429,11 @@ static void _CmiMultipleSend(unsigned int destPE, int len, int sizes[], char *ms for (m=0;mchunkHeader.size; /* Size of user portion of message (plus padding at end) */ - ch->chunkHeader.ref=msgWhole-msg; + ch->chunkHeader.setRef(msgWhole-msg); ch->metaData = registerMultiSendMesg(msg,msgSize); #else CmiChunkHeader *ch=(CmiChunkHeader *)(msgWhole+offset); char *msg=(msgWhole+offset+sizeof(CmiChunkHeader)); int msgSize=ch->size; /* Size of user portion of message (plus padding at end) */ - ch->ref=msgWhole-msg; + ch->setRef(msgWhole-msg); #endif /* Link new message to owner via a negative ref pointer */ CmiReference(msg); /* Follows link & increases reference count of *msgWhole* */ diff --git a/src/conv-core/converse.h b/src/conv-core/converse.h index b15576d74e..805e2555a1 100644 --- a/src/conv-core/converse.h +++ b/src/conv-core/converse.h @@ -98,6 +98,10 @@ #include #include +#if defined __cplusplus +#include +#endif + /* brittle accommodation of libc header internals */ #if defined __cplusplus && defined __THROW # define CMK_THROW __THROW @@ -777,12 +781,19 @@ CpvExtern(int, _curRestartPhase); /* number of restarts */ #define MESSAGE_PHASE_CHECK(msg) #endif +#if defined __cplusplus + /** This header goes before each chunk of memory allocated with CmiAlloc. See the comment in convcore.C for details on the fields. */ -typedef struct { +struct CmiChunkHeader { int size; +private: +#if CMK_SMP + std::atomic ref; +#else int ref; +#endif #if ALIGN_BYTES > 8 char align[ALIGN_BYTES - sizeof(int)*2 @@ -791,7 +802,34 @@ typedef struct { #endif ]; #endif -} CmiChunkHeader; +public: + CmiChunkHeader() = default; + CmiChunkHeader(const CmiChunkHeader & x) + : size{x.size}, ref{x.getRef()} { } +#if CMK_SMP + int getRef() const + { + return ref.load(std::memory_order_acquire); + } + void setRef(int r) + { + return ref.store(r, std::memory_order_release); + } + int incRef() + { + return ref.fetch_add(1, std::memory_order_release); + } + int decRef() + { + return ref.fetch_sub(1, std::memory_order_release); + } +#else + int getRef() const { return ref; } + void setRef(int r) { ref = r; } + int incRef() { return ref++; } + int decRef() { return ref--; } +#endif +}; #if CMK_USE_IBVERBS | CMK_USE_IBUD struct infiCmiChunkMetaDataStruct; @@ -814,7 +852,12 @@ struct infiCmiChunkMetaDataStruct *registerMultiSendMesg(char *msg,int msgSize); /* Given a user chunk m, extract the enclosing chunk header fields: */ #define BLKSTART(m) ((CmiChunkHeader *) (((intptr_t)m) - sizeof(CmiChunkHeader))) #define SIZEFIELD(m) ((BLKSTART(m))->size) -#define REFFIELD(m) ((BLKSTART(m))->ref) +#define REFFIELD(m) ((BLKSTART(m))->getRef()) +#define REFFIELDSET(m, r) ((BLKSTART(m))->setRef(r)) +#define REFFIELDINC(m) ((BLKSTART(m))->incRef()) +#define REFFIELDDEC(m) ((BLKSTART(m))->decRef()) + +#endif CMI_EXTERNC void* malloc_nomigrate(size_t size); CMI_EXTERNC void free_nomigrate(void* ptr); diff --git a/src/util/pup_cmialloc.C b/src/util/pup_cmialloc.C index 7fb95d2dc3..58891f4a06 100644 --- a/src/util/pup_cmialloc.C +++ b/src/util/pup_cmialloc.C @@ -50,7 +50,7 @@ void PUP_toCmiAllocMem::pupCmiAllocBuf(void **msg, size_t msg_size) { buf = origBuf + ALIGN8_LONG(size()); chnk_hdr.size = msg_size; - chnk_hdr.ref = origBuf - (buf + sizeof(CmiChunkHeader)); + chnk_hdr.setRef(origBuf - (buf + sizeof(CmiChunkHeader))); //Copy the Chunk header memcpy(buf, &chnk_hdr, sizeof(CmiChunkHeader)); @@ -80,7 +80,7 @@ void PUP_fromCmiAllocMem::pupCmiAllocBuf(void **msg) { buf += chnk_hdr.size; //update the reference count of the original buf - REFFIELD(origBuf) ++; + REFFIELDINC(origBuf); } -- 2.11.4.GIT