28 if (!mutex || !mutex->enter(1000))
39 memset(serverHeader, 0, masterSize);
42 serverHeader->lastUpdateTime = serverHeader->createdTime;
43 serverHeader->maxConnectionCount = maxConnectionCount;
45 serverHeader->maxQueueSize = maxQueueSize;
46 serverHeader->maxRequestCount = maxRequestCount;
47 serverHeader->size = masterSize;
52 + (serverHeader->maxConnectionCount * serverHeader->eachConnectionSize);
62 if (!requestCon->connect(memoryName)) {
78 if (!mutex->enter(1000))
90 if (!requestCon)
return NULL;
91 return requestCon->waitForRequest(ms);
95 if (!requestCon)
return false;
96 return requestCon->setRequestStatus(
id, status);
100 if (!requestCon)
return false;
101 return requestCon->replyToRequest(
id, msg);
106bool MemoryRequestServer::maintenance() {
116 uint32 count = 10, queueCount = 10, n, m;
122 if (!server->
init(
"TestServer", 4, 256*1024, 256)) {
128 uint64 createdTime, lastUpdateTime;
130 uint64* reqIDs1 =
new uint64[queueCount];
131 uint64* reqIDs2 =
new uint64[queueCount];
135 uint64 startTime = 0;
136 uint32 totalRequests = 0;
139 if (!con1->
connect(
"TestServer")) {
144 if (!con2->
connect(
"TestServer")) {
157 for (n=0; n<count; n++) {
161 for (m=0; m<queueCount; m++) {
163 unittest::fail(
"Con1 couldn't make request [run %u of %u, entry %u of %u]", n, count, m, queueCount);
168 unittest::fail(
"Con2 couldn't make request [run %u of %u, entry %u of %u]", n, count, m, queueCount);
175 for (m=0; m<queueCount; m++) {
177 unittest::fail(
"Con1 request not submitted [run %u of %u, entry %u of %u]", n, count, m, queueCount);
181 unittest::fail(
"Con2 request not submitted [run %u of %u, entry %u of %u]", n, count, m, queueCount);
186 for (m=0; m<queueCount; m++) {
188 unittest::fail(
"Server didn't receive request from con1 [run %u of %u, entry %u of %u]", n, count, m, queueCount);
193 unittest::fail(
"Server couldn't reply to request from con1 [run %u of %u, entry %u of %u]", n, count, m, queueCount);
200 unittest::fail(
"Server didn't receive request from con2 [run %u of %u, entry %u of %u]", n, count, m, queueCount);
205 unittest::fail(
"Server couldn't reply to request from con2 [run %u of %u, entry %u of %u]", n, count, m, queueCount);
212 for (m=0; m<queueCount; m++) {
214 unittest::fail(
"Con1 request not replied [run %u of %u, entry %u of %u]", n, count, m, queueCount);
218 unittest::fail(
"Con2 request not replied [run %u of %u, entry %u of %u]", n, count, m, queueCount);
223 for (m=0; m<queueCount; m++) {
225 unittest::fail(
"Con1 didn't get reply [run %u of %u, entry %u of %u]", n, count, m, queueCount);
230 unittest::fail(
"Con2 didn't get reply [run %u of %u, entry %u of %u]", n, count, m, queueCount);
236 totalRequests += 2 * queueCount;
237 unittest::detail(
"run %u of %u complete (%u requests so far)", n + 1, count, totalRequests);
238 unittest::progress(25 + (uint32)((uint64)(n + 1) * 65 / count),
"request/reply exchange");
242 double us = (double)(
GetTimeNow() - startTime);
244 unittest::metric(
"request_reply_throughput", (
double)totalRequests / us * 1e6,
"req/s",
true);
267 "Shared-memory request server/connection request-reply round-trip",
"memory");
#define MEMORYREQUESTSERVER_INIT
Server status value: segment initialised and accepting connections.
#define MEMORYREQUEST_SUBMITTED
Placed on the server's queue.
#define MEMORYREQUEST_REPLIED
Reply enqueued to the requester.
Server side of the named shared-memory request/reply service.
#define MEMORYREQUESTSERVERID
CMSDK time: µs-resolution 64-bit timestamps and the Time Mapping Constant (TMC).
Small, dependency-free unit test harness used by all CMSDK object tests.
The central Psyclone data container: a self-contained binary message with typed, named user entries.
uint32 getFrom()
getFrom() Get the sender id
uint64 getReference()
getReference() Get and return message reference id
bool setTo(uint32 to)
setTo(uint32 to)
Client endpoint connected to a named shared-memory request server.
uint16 getRequestStatus(uint64 id, uint64 &createdTime, uint64 &lastUpdateTime)
Query a request's status.
DataMessage * waitForRequestReply(uint32 ms)
Wait for the reply to this connection's most recent request.
bool connect(const char *memoryName)
Attach to the named server segment and claim a connection slot.
uint64 makeRequest(DataMessage *msg)
Submit a request to the server.
static bool InitRequestMap(char *data, uint32 count)
Initialise a status map for count requests.
static bool UnitTest()
Self-test of the request/reply round trip.
bool replyToRequest(uint64 id, DataMessage *msg)
Send the reply for request id (copied; caller keeps ownership).
bool shutdown()
Detach and mark the server stopped.
DataMessage * waitForRequest(uint32 ms)
Block up to ms milliseconds for the next client request.
bool init(const char *memoryName, uint32 maxConnectionCount, uint32 maxQueueSize, uint32 maxRequestCount)
Create the named server segment.
bool setRequestStatus(uint64 id, uint16 status)
Advance request id's MEMORYREQUEST_* status.
static UnitTestRunner & instance()
Access the singleton (created on first use).
void registerTest(const char *name, UnitTestFunc func, const char *description="", const char *category="", bool inDefaultRun=true)
Register a test with the runner.
Recursive mutual-exclusion lock, optionally named for cross-process use.
uint64 GetTimeNow()
Return the current absolute time (µs since year 0) according to the TMC.
char * CreateSharedMemorySegment(const char *name, uint64 size, bool force=false)
Create a named shared memory segment and map it into this process.
bool CloseSharedMemorySegment(char *data, uint64 size)
Unmap a segment previously created/opened here.
std::string StringFormat(const char *format,...)
printf into a std::string.
uint32 strcpyavail(char *dst, const char *src, uint32 maxlen, bool copyAvailable)
Bounded strcpy that always NUL-terminates.
void fail(const char *fmt,...)
Set an explanatory reason shown on the FAIL line.
void metric(const char *name, double value, const char *unit="", bool higherIsBetter=true)
Record a performance metric.
void detail(const char *fmt,...)
Verbose-only indented diagnostic line (shown only when verbose=1).
void progress(int percent, const char *action)
Report progress with a short description of the current action.
void Register_MemoryRequestServer_Tests()
One request transaction's status record.