66#ifdef __cplusplus
77#include < atomic>
88#include < queue>
9+ #include < utility>
910#else
1011#include < stdatomic.h>
1112#endif
@@ -54,6 +55,8 @@ extern CmiNodeLock CmiMemLock_lock;
5455
5556#define CmiMemUnlock () do {if (CmiMemLock_lock) CmiUnlock (CmiMemLock_lock);} while (0 )
5657
58+ #define CmiInCommThread () (0 )
59+
5760#define CMK_TAG (x, y ) x##y##_
5861#define CMK_CONCAT (x, y ) x##y
5962
@@ -279,6 +282,8 @@ void CthFree(CthThread t);
279282
280283void CthResume (CthThread t);
281284
285+ int CthIsSuspendable (CthThread t);
286+
282287void CthSuspend (void );
283288
284289void CthAwaken (CthThread th);
@@ -536,7 +541,11 @@ int CmiGetArgc(char **argv);
536541int CmiScanf (const char *format, ...);
537542int CmiError (const char *format, ...);
538543
539- #define ConverseExit (...) CmiExit(__VA_ARGS__ + 0 )
544+ #ifdef __cplusplus
545+ void ConverseExit (int status=0 );
546+ #else
547+ void ConverseExit (int status);
548+ #endif
540549#define CmiMemcpy (dest, src, size ) memcpy((dest), (src), (size))
541550
542551#define setMemoryTypeChare (p ) /* empty memory debugging method */
@@ -546,15 +555,25 @@ void CmiInitCPUTopology(char **argv);
546555void CmiInitCPUAffinity (char **argv);
547556int CmiOnCore (void );
548557
549- void __CmiEnforceMsgHelper ( const char *expr, const char *fileName, int lineNum,
550- const char *msg, ...);
558+ # define __CMK_STRING ( x ) #x
559+ # define __CMK_XSTRING ( x ) __CMK_STRING(x)
551560
552- #define CmiEnforce (condition ) \
553- do { \
554- if (!(condition)) { \
555- __CmiEnforceMsgHelper (#condition, __FILE__, __LINE__, " " ); \
556- } \
557- } while (0 )
561+ void __CmiEnforceHelper (const char * expr, const char * fileName, const char * lineNum);
562+ void __CmiEnforceMsgHelper (const char * expr, const char * fileName,
563+ const char * lineNum, const char * msg, ...);
564+
565+ #define CmiEnforce (expr ) \
566+ ((void )(CMI_LIKELY(expr) ? 0 \
567+ : (__CmiEnforceHelper(__CMK_STRING(expr), __FILE__, \
568+ __CMK_XSTRING (__LINE__)), \
569+ 0)))
570+
571+ #define CmiEnforceMsg (expr, ...) \
572+ ((void )(CMI_LIKELY(expr) \
573+ ? 0 \
574+ : (__CmiEnforceMsgHelper(__CMK_STRING(expr), __FILE__, \
575+ __CMK_XSTRING (__LINE__), __VA_ARGS__), \
576+ 0)))
558577
559578double getCurrentTime(void );
560579double CmiWallTimer (void );
@@ -1196,4 +1215,109 @@ void CmiInterSyncNodeSendAndFreeFn(int destNode, int partition, int messageSize,
11961215
11971216/* end of variables and functions for partition */
11981217
1218+ #define CMI_IPC_CUTOFF_ARG " ipccutoff"
1219+ #define CMI_IPC_CUTOFF_DESC " max message size for cmi-shmem (in bytes)"
1220+ #define CMI_IPC_POOL_SIZE_ARG " ipcpoolsize"
1221+ #define CMI_IPC_POOL_SIZE_DESC " size of cmi-shmem pool (in bytes)"
1222+
1223+ struct CmiIpcManager ;
1224+
1225+ #ifndef __cplusplus
1226+ typedef struct CmiIpcManager CmiIpcManager;
1227+ #endif
1228+
1229+ #ifdef __cplusplus
1230+ namespace cmi {
1231+ namespace ipc {
1232+ // recommended cutoff for block sizes
1233+ CpvExtern (size_t , kRecommendedCutoff );
1234+ // used to represent an empty linked list
1235+ constexpr auto nil = uintptr_t (0 );
1236+ // used to represent the tail of a linked list
1237+ constexpr auto max = UINTPTR_MAX;
1238+ // used to indicate a message bound for a node
1239+ constexpr auto nodeDatagram = UINT16_MAX;
1240+ // default number of attempts to alloc before timing out
1241+ constexpr auto defaultTimeout = 4 ;
1242+ } // namespace ipc
1243+ } // namespace cmi
1244+
1245+ // alignas is used for padding here, rather than for alignment of the
1246+ // CmiIpcBlock itself.
1247+ struct alignas (ALIGN_BYTES) CmiIpcBlock {
1248+ public:
1249+ // "home" rank of the block
1250+ int src;
1251+ int dst;
1252+ uintptr_t orig;
1253+ uintptr_t next;
1254+ size_t size;
1255+
1256+ CmiIpcBlock (size_t size_, uintptr_t orig_)
1257+ : orig (orig_), next (cmi::ipc::nil), size (size_) {}
1258+ };
1259+
1260+ enum CmiIpcAllocStatus {
1261+ CMI_IPC_OUT_OF_MEMORY,
1262+ CMI_IPC_REMOTE_DESTINATION,
1263+ CMI_IPC_SUCCESS,
1264+ CMI_IPC_TIMEOUT
1265+ };
1266+
1267+ // sets up ipc environment
1268+ void CmiIpcInit (char ** argv);
1269+
1270+ // creates an ipc manager, waking the thread when it's done
1271+ // ( this must be called in the same order on all pes! )
1272+ CmiIpcManager* CmiMakeIpcManager (CthThread th);
1273+
1274+ // push/pop blocks from the manager's send/recv queue
1275+ bool CmiPushIpcBlock (CmiIpcManager*, CmiIpcBlock*);
1276+ CmiIpcBlock* CmiPopIpcBlock (CmiIpcManager*);
1277+
1278+ // tries to allocate a block, returning null if unsucessful
1279+ // (fails when other PEs are contending resources)
1280+ // second value of pair indicates failure cause
1281+ std::pair<CmiIpcBlock*, CmiIpcAllocStatus> CmiAllocIpcBlock (CmiIpcManager*, int node, std::size_t size);
1282+
1283+ // frees a block -- enabling it to be used again
1284+ void CmiFreeIpcBlock (CmiIpcManager*, CmiIpcBlock*);
1285+
1286+ // currently a no-op but may be eventually usable
1287+ // intended to "capture" blocks from remote pes
1288+ inline void CmiCacheIpcBlock (CmiIpcBlock*) { return ; }
1289+
1290+ // identifies whether a void* is the payload of a block
1291+ // belonging to the given node
1292+ CmiIpcBlock* CmiIsIpcBlock (CmiIpcManager*, void *, int node);
1293+
1294+ // if (init) is true -- initializes the
1295+ // memory segment for use as a message
1296+ void * CmiIpcBlockToMsg (CmiIpcBlock*, bool init);
1297+
1298+ // equivalent to calling above with (init = false)
1299+ inline void * CmiIpcBlockToMsg (CmiIpcBlock* block) {
1300+ auto res = (char *)block + sizeof (CmiIpcBlock) + sizeof (CmiChunkHeader);
1301+ return (void *)res;
1302+ }
1303+
1304+ inline CmiIpcBlock* CmiMsgToIpcBlock (CmiIpcManager* manager, void * msg) {
1305+ return CmiIsIpcBlock (manager, (char *)msg - sizeof (CmiChunkHeader), CmiMyNode ());
1306+ }
1307+
1308+ CmiIpcBlock* CmiMsgToIpcBlock (CmiIpcManager*, char * msg, std::size_t len, int node,
1309+ int rank = cmi::ipc::nodeDatagram,
1310+ int timeout = cmi::ipc::defaultTimeout);
1311+
1312+ // deliver a block as a message
1313+ void CmiDeliverIpcBlockMsg (CmiIpcBlock*);
1314+
1315+ inline const std::size_t & CmiRecommendedIpcBlockCutoff (void ) {
1316+ using namespace cmi ::ipc;
1317+ return CpvAccess (kRecommendedCutoff );
1318+ }
1319+ #endif /* __cplusplus */
1320+
1321+ CsvExtern (CmiIpcManager*, coreIpcManager_);
1322+
11991323#endif // CONVERSE_H
0 commit comments