93#if !defined(_MEMORYMANAGER_H_)
94#define _MEMORYMANAGER_H_
105#define PSYCLONE_STATUS_NONE 0
106#define PSYCLONE_STATUS_ENDED 1
107#define PSYCLONE_STATUS_INIT 2
108#define PSYCLONE_STATUS_READY 3
113#define DRAFTMSGSIZE 4096
139#define PSYCLONE_INDEX_MAXCOUNT 128
141#define PSYCLONE_INDEX_SIZE (sizeof(PsycloneIndexStruct) + (PSYCLONE_INDEX_MAXCOUNT * sizeof(PsycloneIndexEntry)))
158 static bool GetStatus(uint16 port, uint8& status, uint64& heartbeat);
165 bool init(uint16 port, uint64 instID);
242 return utils::StringFormat(
"<performance time=\"%llu\" ms1=\"%u\" ms2=\"%u\" ms3=\"%u\" maxmemory=\"%llu\" "
243 "percentofsystemcpu1=\"%f\" percentofsystemcpu2=\"%f\" percentofsystemcpu3=\"%f\" "
244 "percentofoscpu1=\"%f\" percentofoscpu2=\"%f\" percentofoscpu3=\"%f\" "
245 "memorybytesaverage1=\"%f\" memorybytesaverage2=\"%f\" memorybytesaverage3=\"%f\" "
246 "datainputbytespersec1=\"%f\" datainputbytespersec2=\"%f\" datainputbytespersec3=\"%f\" "
247 "datainputcountpersec1=\"%f\" datainputcountpersec2=\"%f\" datainputcountpersec3=\"%f\" "
248 "dataoutputbytespersec1=\"%f\" dataoutputbytespersec2=\"%f\" dataoutputbytespersec3=\"%f\" "
249 "dataoutputcountpersec1=\"%f\" dataoutputcountpersec2=\"%f\" dataoutputcountpersec3=\"%f\" "
250 "dataqueuebytesaverage1=\"%f\" dataqueuebytesaverage2=\"%f\" dataqueuebytesaverage3=\"%f\" "
251 "dataqueuecountaverage1=\"%f\" dataqueuecountaverage2=\"%f\" dataqueuecountaverage3=\"%f\" "
252 "cyclecountpersec1=\"%f\" cyclecountpersec2=\"%f\" cyclecountpersec3=\"%f\" "
253 "localsystemcpuusage1=\"%f\" localsystemcpuusage2=\"%f\" localsystemcpuusage3=\"%f\" "
254 "localsystemmemoryusage1=\"%f\" localsystemmemoryusage2=\"%f\" localsystemmemoryusage3=\"%f\" "
255 "computercpuusage1=\"%f\" computercpuusage2=\"%f\" computercpuusage3=\"%f\" "
256 "computermemoryusage1=\"%f\" computermemoryusage2=\"%f\" computermemoryusage3=\"%f\" "
372 bool setID(uint16
id);
439 bool getMemoryUsage(uint64& sysAlloc, uint64& sysUsage, uint64& dataAlloc, uint64& dataUsage);
452 bool connect(uint16 sysID,
bool isMaster);
466 bool create(uint16 sysID, uint32 slotCount = 100000, uint16 binCount = 2, uint32 minBlockSize = 1024, uint32 maxBlockSize = 64*1024, uint64 initSize = 50000000L, uint64 maxSize = 1000000000L,
bool force =
false);
517 bool resizeEOLPage(uint32 slotCount, uint32 pagesPerSlot, uint32 slotDuration);
526 uint32 managementThreadID;
544#define MAXREGISTERCOUNT 64
561#define NODE_PROCESS_ID 1
563#define MAXINSTANCES 256
623#define MP_GetBlockIndexStartLoc(p) ((char*)p + sizeof(MemoryPage))
624#define MP_GetBlockDataStartLoc(p) (MP_GetBlockIndexStartLoc(p) + (p->blockTableSize*sizeof(uint32)) )
679#define MP_SYSMEMID MP_CalcID(0, 0, pageMaster->nodeID)
680#define MP_CalcID(pid,bid,nid) ((uint64)pid | (((uint64)bid) << 32) | (((uint64)nid) << 48))
681#define MP_SetBlockID(id,var) var |= (((uint64)id) << 32)
682#define MP_SetNodeID(id,var) var |= (((uint64)id) << 48)
683#define MP_SetPageID(id,var) var |= ((uint64)id)
684#define MP_GetBlockID(id) (*(uint16*)((char*)&id + sizeof(uint32)))
685#define MP_GetNodeID(id) (*(uint16*)((char*)&id + sizeof(uint32) + sizeof(uint16)))
686#define MP_GetPageID(id) (*(uint32*)(char*)&id)
687#define MP_GetBitFieldLoc(m) ((char*)m + sizeof(MemoryPageMaster))
688#define MP_GetPageTableLoc(m) (MP_GetBitFieldLoc(m) + m->bitFieldSize )
689#define MP_GetPageEntryLoc(m,pid) (MP_GetPageTableLoc(m) + (pid * sizeof(MemoryPageEntry)) )
690#define MP_GetPageLoc(m,pid) ((MemoryPageEntry*)MP_GetPageEntryLoc(m,pid))->page
695#define MP_SYSTEMPAGE 0
696#define MP_STATICPAGE 1
697#define MP_DYNAMICPAGE 2
699#define MP_GetPageType(id,eol) ( ((id < RESERVEDPAGECOUNT) ? MP_SYSTEMPAGE : (eol > 0 ? MP_DYNAMICPAGE : MP_STATICPAGE) ) )
750 static bool GetMemoryUsage(uint32& total, uint32& usage, uint32& sysTotal, uint32& sysUsage, uint32& staticTotal, uint32& staticUsage, uint32& dynamicTotal, uint32& dynamicUsage);
780 bool create(uint16 sysID, uint32 staticPageTableSize = 100, uint32 slotCount = 360, uint32 slotDuration = 60000000, uint32 pagesPerSlot = 10,
bool force =
false);
814 MemoryPage* createPage(uint32 size, uint16 tableSize, uint64 eol, uint32& pageID);
817 bool insertMemoryBlockIntoPage(uint32 pageID,
const char* data, uint32 size, uint64 eol, uint64&
id);
829 bool lockPage(uint32 pageID);
830 bool unlockPage(uint32 pageID);
837 MemoryPage* findPageForBlock(uint32 size, uint64 eol, uint32&
id);
840 bool freePageIntoPool(uint32 pageID);
843 bool removePageFromStats(uint32 pageID, uint32& dataSize);
846 bool insertPageIntoPool(uint32 pageID, uint32 dataSize);
849 bool getPageFromPool(uint32 size, uint32& pageID);
852 bool destroyAllPages();
855 bool destroyPage(uint32 pageID,
bool updateStats =
true);
861 char* getBitFieldAsString(uint32& size);
863 bool printBitFieldAsString(
char* title);
866 bool getPageUsage(uint32 pageID,
double& val);
868 double getPageUsage(uint32 pageID);
870 bool getPageFree(uint32 pageID, uint32& bytes);
872 bool getPageSize(uint32 pageID, uint32& bytes);
875 char* createSystemPage(uint32
id, uint32 size, uint64& memID);
878 bool createSystemPages();
881 bool initSystemPage(
char* data, uint32 size);
884 bool initPagePool(
char* data, uint32 size);
887 bool resizeEOLPage(uint32 slotCount, uint32 pagesPerSlot, uint32 slotDuration, uint32 bufferSlots);
890 bool insertPageIntoEOL(uint32 pageID, uint64 eol, uint64& slotEOL);
893 bool initQueuePage(
char* data, uint32 size);
896 static uint16 CalcBlockTableSize(uint32 size);
908 uint32 managementThreadID;
Shared-memory component registry: identity, location, parameters, private data and statistics for eve...
Shared-memory name/id maps: message types, contexts, tags, cranks and cross-process requests.
The binary DataMessage container — the central data-exchange object of Psyclone/CMSDK.
Abstract interface that lets subsystem memories query/update their segment's id, size and resize seri...
Shared-memory process ("space") table plus per-process message queues.
Slot/bin shared-memory store for time-limited DataMessages (the node's "dynamic" memory).
Process-wide thread registry and lifecycle manager: the concurrency core of CMSDK.
Cross-platform utility toolbox for CMSDK: threading, synchronization, shared memory,...
#define THREAD_FUNCTION_CALL
Accessor for the shared component registry.
Accessor for the shared name/id maps and the request map.
The central Psyclone data container: a self-contained binary message with typed, named user entries.
Handle to the node's master shared-memory segment (MemoryMasterStruct).
uint32 incrementDynamicShmemSerial()
Bump the dynamic segment serial after resize.
uint64 getProcessShmemSize()
bool create(uint16 port)
Create the master segment for the node instance listening on port.
uint32 getDataMapsShmemSerial()
uint32 incrementDataMapsShmemSerial()
Bump the data-maps segment serial after resize.
uint16 getID()
MemoryController interface:
uint64 getComponentShmemSize()
bool setComponentShmemSize(uint64 size)
Record a new component segment size.
bool setID(uint16 id)
MemoryController interface: set the node id.
uint16 port
Node port this master segment belongs to (names all related segments).
bool setDataMapsShmemSize(uint64 size)
Record a new data-maps segment size.
uint32 incrementProcessShmemSerial()
Bump the process segment serial after resize.
friend class MemoryManager
uint32 incrementComponentShmemSerial()
Bump the component segment serial after resize.
uint32 getComponentShmemSerial()
uint32 getProcessShmemSerial()
uint64 getDynamicShmemSize()
uint32 getDynamicShmemSerial()
bool setDynamicShmemSize(uint64 size)
Record a new dynamic segment size.
bool setNodeID(uint16 id)
Set the cluster-wide node id.
bool setProcessShmemSize(uint64 size)
Record a new process segment size.
bool open(uint16 port)
Attach to an existing master segment created by another process.
uint64 getDataMapsShmemSize()
Top-level facade of the shared-memory subsystem for one process.
ProcessMemory * processMemory
Accessor for the process table and per-process queues.
DataMessage * getCopyOfMessage(uint64 id)
Fetch a private copy of a previously published message.
ComponentMemory * componentMemory
Accessor for the component registry.
bool create(uint16 sysID, uint32 slotCount=100000, uint16 binCount=2, uint32 minBlockSize=1024, uint32 maxBlockSize=64 *1024, uint64 initSize=50000000L, uint64 maxSize=1000000000L, bool force=false)
Create all shared segments for a new node instance (master process only).
static bool UnitTest()
Self-test of the shared-memory manager.
std::string subTypeToText(uint16 subtype)
Resolve a subtype id to its registered name.
DataMessage * retrieveAllSystemIDs()
Enumerate all live Psyclone system ids/ports on this machine (via the PsycloneIndex).
uint8 getNodeStatus(uint64 &lastseen, uint64 &createdTime)
Get the node status from the master segment.
bool setNodeID(uint16 id)
Set this node's cluster-wide id.
static MemoryManager * Singleton
Per-process singleton instance, set by the constructor.
static bool ShmUnitTest()
Self-test of the raw shared-memory primitives.
bool insertMessage(DataMessage *msg, uint64 &id)
Publish a DataMessage into shared (temporal) memory.
std::string getComponentName(uint32 compID)
Resolve a component id to its name.
std::string subContextToText(uint16 subcontext)
Resolve a subcontext id to its registered name.
std::string typeToText(PsyType type)
Resolve a type id to its registered name.
bool getTimeSyncData(uint64 &tmc, int64 &adjust)
Read the cluster time-sync values from the master segment.
bool getMemoryUsage(uint64 &sysAlloc, uint64 &sysUsage, uint64 &dataAlloc, uint64 &dataUsage)
Report allocation/usage figures for the system and data segments.
DataMapsMemory * dataMapsMemory
Accessor for the type/context/tag/crank/request maps.
bool connect(uint16 sysID, bool isMaster)
Attach this process to an existing node's shared segments.
TemporalMemory * temporalMemory
Accessor for time-limited message storage.
friend THREAD_RET THREAD_FUNCTION_CALL MemoryManagement(THREAD_ARG arg)
Background maintenance thread entry point for MemoryManager / MemoryManagerX.
std::string contextToText(PsyContext context)
Resolve a context id to its registered name.
bool setTimeSyncData(uint64 tmc, int64 adjust)
Write the cluster time-sync values into the master segment.
char * getLockedSystemBlock(MemoryPage *page, uint32 &size)
static bool UnitTest()
Self-test of the legacy page allocator.
static char * CreateAndLockNewSystemPage(uint32 size, uint32 &id)
bool unlockSystemBlock(uint32 pageID)
static MemoryManagerX * Singleton
Per-process singleton instance.
bool connect(uint16 sysID)
static char * GetAndLockMemoryBlock(uint64 id, uint32 &size, uint64 &eol)
Lock a block and return a pointer into shared memory; pair with UnlockMemoryBlock().
bool unlockMemoryBlock(uint64 id)
bool create(uint16 sysID, uint32 staticPageTableSize=100, uint32 slotCount=360, uint32 slotDuration=60000000, uint32 pagesPerSlot=10, bool force=false)
static char * GetCopyMemoryBlock(uint64 id, uint32 &size, uint64 &eol)
Return a heap copy of a block; caller owns and must free it.
char * getLockedMemoryBlock(MemoryPage *page, uint64 id, uint32 &size, uint64 &eol)
char * getAndLockMemoryBlock(uint64 id, uint32 &size, uint64 &eol)
static char * GetAndLockSystemBlock(uint32 pageID, uint32 &size)
Map and lock the system page pageID; pair with UnlockSystemBlock().
bool overwriteMemoryBlock(uint64 id, const char *data, uint32 size, uint64 eol)
char * getAndLockSystemBlock(uint32 pageID, uint32 &size)
static bool UnlockSystemBlock(uint32 pageID)
Release the lock taken by GetAndLockSystemBlock().
char * createAndLockNewSystemPage(uint32 size, uint32 &id)
static bool UnlockMemoryBlock(uint64 id)
Release the lock taken by GetAndLockMemoryBlock().
char * getSystemBlock(uint32 pageID, uint32 &size)
static bool OverwriteMemoryBlock(uint64 id, const char *data, uint32 size, uint64 eol)
Replace the contents of an existing block.
friend THREAD_RET THREAD_FUNCTION_CALL MemoryManagement(THREAD_ARG arg)
Background maintenance thread entry point for MemoryManager / MemoryManagerX.
static bool InsertMemoryBlock(const char *data, uint32 size, uint64 eol, uint64 &id)
Copy data into a new shared block.
static bool DestroySystemPage(uint32 pageID)
char * getLockedSystemBlock(uint32 pageID, uint32 &size)
bool insertMemoryBlock(const char *data, uint32 size, uint64 eol, uint64 &id)
char * resizeSystemPage(uint32 pageID, uint32 size)
char * getCopyMemoryBlock(uint64 id, uint32 &size, uint64 &eol)
static char * ResizeSystemPage(uint32 pageID, uint32 newSize)
static bool GetMemoryUsage(uint32 &total, uint32 &usage, uint32 &sysTotal, uint32 &sysUsage, uint32 &staticTotal, uint32 &staticUsage, uint32 &dynamicTotal, uint32 &dynamicUsage)
Accessor for the shared process table and per-process queues.
Accessor for the machine-global instance index segment.
bool setStatus(uint8 status)
Update this instance's status and heartbeat in the shared index.
bool init(uint16 port, uint64 instID)
Attach to (or create) the index segment and claim/refresh the slot for this instance.
static bool GetStatus(uint16 port, uint8 &status, uint64 &heartbeat)
Look up the status of the instance registered on port.
Accessor for the temporal (dynamic) message store in shared memory.
Recursive mutual-exclusion lock, optionally named for cross-process use.
std::string StringFormat(const char *format,...)
printf into a std::string.
THREAD_RET THREAD_FUNCTION_CALL MemoryManagement(THREAD_ARG arg)
Background maintenance thread entry point for MemoryManager / MemoryManagerX.
Hierarchical execution-context identifier.
Hierarchical message type identifier — the key used for publish/subscribe matching in Psyclone.
Sliding-window averages derived from successive PerfStats snapshots.
double dataQueueBytesAverage[3]
Average queued bytes, per window.
double cycleCountPerSec[3]
Processing cycles per second, per window.
double dataInputCountPerSec[3]
Input message rate in msgs/s, per window.
uint64 maxMemoryBytes
Peak memory footprint observed.
double percentOfOSCPU[3]
Share of the hosting OS process's CPU use, per window.
uint64 time
Timestamp (µs) of the last update.
double localSystemCPUUsage[3]
CPU usage of the local Psyclone system, per window.
double memoryBytesAverage[3]
Average memory footprint, per window.
double dataOutputCountPerSec[3]
Output message rate in msgs/s, per window.
double computerMemoryUsage[3]
Whole-machine memory usage, per window.
double percentOfSystemCPU[3]
Share of the whole Psyclone system's CPU use, per window.
PerfStats lastStats
Most recent raw snapshot used for delta computation.
double localSystemMemoryUsage[3]
Memory usage of the local Psyclone system, per window.
double dataInputBytesPerSec[3]
Input throughput in bytes/s, per window.
uint32 periodsMS[3]
The three averaging window lengths in milliseconds.
double computerCPUUsage[3]
Whole-machine CPU usage, per window.
std::string toXML()
Render all averaged metrics as a single <performance/> XML element for monitoring.
uint64 dataQueueCountAverage[3]
Average queued message count, per window.
double dataOutputBytesPerSec[3]
Output throughput in bytes/s, per window.
Legacy registry block listing the Psyclone system ids present on this machine.
One page/expiry pair inside an EOL time-wheel slot (legacy allocator).
uint32 pageID
Page scheduled for expiry.
uint64 eol
Absolute end-of-life timestamp (µs).
Size prefix of a raw block inside a MemoryPage (legacy allocator).
Decomposed form of a 64-bit global memory-block id (legacy page allocator).
Root header of the node's master shared-memory segment.
uint64 memAlloc
Total bytes currently allocated across all segments.
uint16 nodeID
Cluster-wide id of this node.
uint64 processShmemSize
Current byte size of the process segment.
uint64 datamapsShmemSize
Current byte size of the data-maps segment.
uint64 currentTMC
Current time-master clock value (µs) for cluster time sync.
uint32 processShmemSerial
Serial of the process segment; bumped on every resize.
uint64 componentShmemSize
Current byte size of the component segment.
uint32 dynamicShmemLocks
Diagnostic lock counter for the dynamic segment.
uint32 dynamicShmemSerial
Serial of the dynamic (temporal) segment; bumped on every resize.
uint64 size
Total size of this segment in bytes.
uint64 memUsage
Total bytes currently in use across all segments.
int64 localSyncAdjustment
Signed offset applied to local clock to match the time master.
uint32 cid
Check/magic id used to validate the segment on attach.
uint64 dynamicShmemSize
Current byte size of the dynamic (temporal) segment.
uint32 componentShmemSerial
Serial of the component segment; bumped on every resize.
uint32 throughputCount
Total messages passed through the node.
uint64 createdTime
Creation timestamp of the segment (µs).
uint64 currentCPUTicks
Aggregate CPU ticks consumed by the node.
uint32 componentShmemLocks
Diagnostic lock counter for the component segment.
uint32 componentCount
Number of registered components.
uint64 throughputSize
Total message bytes passed through the node.
uint32 processShmemLocks
Diagnostic lock counter for the process segment.
uint32 datamapsShmemSerial
Serial of the data-maps segment; bumped on every resize.
uint16 status
Node readiness, 0-10; 10 means fully ready.
One process-local cached page mapping; stale when serials mismatch the page table (legacy allocator).
Header of a process-local (non-shared) cache of mapped page addresses (legacy allocator).
Page-table slot describing one page's identity, size and lock state (legacy allocator).
In-segment header of one memory page holding packed data blocks (legacy allocator).
Root header of the legacy page-allocator segment ("PageMaster").
uint32 lastCreatedStaticPage
One recyclable page recorded in the page pool (legacy allocator).
Raw per-component performance counters sampled inside shared memory.
uint16 spaceID
Id of the space (process slot) hosting the component.
uint32 osID
OS process id of the hosting process.
uint64 totalCycleCount
Total processing cycles across all runs.
uint64 totalQueueBytes
Bytes currently waiting in the component's queues.
uint64 totalInputCount
Total number of input messages.
uint64 currentCPUTicks
Cumulative CPU ticks consumed so far.
uint64 runCount
Number of triggered runs executed.
uint64 totalOutputCount
Total number of output messages.
uint8 type
Component type (Whiteboard, Catalog, Module, ...).
uint64 totalRunCount
Total runs across the component's lifetime.
uint64 currentRunStartTime
Timestamp (µs) the current/last run started.
uint32 migrationCount
How many times the component migrated between spaces/nodes.
uint64 totalOutputBytes
Total bytes posted as output messages.
uint64 currentMemoryBytes
Current memory footprint in bytes.
uint64 totalInputBytes
Total bytes received as input messages.
uint16 nodeID
Id of the node the component runs on.
uint64 firstRunStartTime
Timestamp (µs) of the very first run.
uint32 compID
Component id these stats belong to.
uint32 totalQueueCount
Messages currently waiting in the component's queues.
One slot in the machine-global Psyclone instance index.
uint16 port
TCP port the instance listens on; doubles as the instance key.
uint64 heartbeat
Last heartbeat timestamp (µs since epoch); staleness implies a dead instance.
uint8 status
One of the PSYCLONE_STATUS_* values.
uint64 instanceID
Unique id of the owning instance, used to detect port reuse.
Header of the machine-global Psyclone instance index shared-memory segment.
uint32 count
Number of entry slots that have ever been used.
uint32 cid
Check/magic id used to validate the segment on attach.
uint32 size
Total size of the index segment in bytes (header + entries).