From 298c8706ece05c977e3db080330d155ef341735b Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 30 Apr 2020 22:59:58 -0500 Subject: [PATCH 01/10] osdMessageQueue: Rename freeEventNode() -> destroyEventNode() --- src/libCom/osi/os/default/osdMessageQueue.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libCom/osi/os/default/osdMessageQueue.cpp b/src/libCom/osi/os/default/osdMessageQueue.cpp index fc50a36b7..81d0fa015 100644 --- a/src/libCom/osi/os/default/osdMessageQueue.cpp +++ b/src/libCom/osi/os/default/osdMessageQueue.cpp @@ -106,7 +106,7 @@ epicsShareFunc epicsMessageQueueId epicsShareAPI epicsMessageQueueCreate( } static void -freeEventNode(struct eventNode *enode) +destroyEventNode(struct eventNode *enode) { epicsEventDestroy(enode->event); free(enode); @@ -119,7 +119,7 @@ epicsMessageQueueDestroy(epicsMessageQueueId pmsg) while ((evp = reinterpret_cast < struct eventNode * > ( ellGet(&pmsg->eventFreeList) ) ) != NULL) { - freeEventNode(evp); + destroyEventNode(evp); } epicsMutexDestroy(pmsg->mutex); free(pmsg->buf); From cf2fef2405aee3469fd4f9d82ccebc77bd4454e6 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 30 Apr 2020 23:27:43 -0500 Subject: [PATCH 02/10] osdMessageQueue: Return sooner on -ve timeout It appears that previously a negative timeout actually implemented a 'wait forever', but the VxWorks and RTEMS implementations both check for (timeout <= 0) and return immediately if nothing can be done without waiting. --- src/libCom/osi/os/default/osdMessageQueue.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/libCom/osi/os/default/osdMessageQueue.cpp b/src/libCom/osi/os/default/osdMessageQueue.cpp index 81d0fa015..c93be4d97 100644 --- a/src/libCom/osi/os/default/osdMessageQueue.cpp +++ b/src/libCom/osi/os/default/osdMessageQueue.cpp @@ -165,7 +165,7 @@ mySend(epicsMessageQueueId pmsg, void *message, unsigned int size, /* * Return if not allowed to wait */ - if (timeout == 0) { + if (timeout <= 0) { epicsMutexUnlock(pmsg->mutex); return -1; } @@ -186,11 +186,8 @@ mySend(epicsMessageQueueId pmsg, void *message, unsigned int size, epicsMutexUnlock(pmsg->mutex); - epicsEventStatus status; - if (timeout > 0) - status = epicsEventWaitWithTimeout(threadNode.evp->event, timeout); - else - status = epicsEventWait(threadNode.evp->event); + epicsEventStatus status = + epicsEventWaitWithTimeout(threadNode.evp->event, timeout); epicsMutexMustLock(pmsg->mutex); @@ -304,7 +301,7 @@ myReceive(epicsMessageQueueId pmsg, void *message, unsigned int size, /* * Return if not allowed to wait */ - if (timeout == 0) { + if (timeout <= 0) { epicsMutexUnlock(pmsg->mutex); return -1; } @@ -335,10 +332,11 @@ myReceive(epicsMessageQueueId pmsg, void *message, unsigned int size, ellAdd(&pmsg->receiveQueue, &threadNode.link); epicsMutexUnlock(pmsg->mutex); - if (timeout > 0) + /* + * Wait for a message to arrive + */ + epicsEventStatus status = epicsEventWaitWithTimeout(threadNode.evp->event, timeout); - else - epicsEventWait(threadNode.evp->event); epicsMutexMustLock(pmsg->mutex); From 183c3b2a3e1fa2a55cd918b94ef4d7c486e11bf4 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 30 Apr 2020 23:38:51 -0500 Subject: [PATCH 03/10] osdMessageQueue: Clear eventNode before returning it Introduced freeEventNode() which ensures eventNodes don't have a signalled event in them before returning the node to the freeList. Callers pass the status from epicsEventWaitWithTimeout() to indicate whether it was signalled or not. If it timed out we must trigger it and Wait to clear the event state. --- src/libCom/osi/os/default/osdMessageQueue.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/libCom/osi/os/default/osdMessageQueue.cpp b/src/libCom/osi/os/default/osdMessageQueue.cpp index c93be4d97..0e1d1fc22 100644 --- a/src/libCom/osi/os/default/osdMessageQueue.cpp +++ b/src/libCom/osi/os/default/osdMessageQueue.cpp @@ -145,6 +145,16 @@ getEventNode(epicsMessageQueueId pmsg) return evp; } +static void +freeEventNode(epicsMessageQueueId pmsg, eventNode *evp, epicsEventStatus status) +{ + if (status == epicsEventWaitTimeout) { + epicsEventSignal(evp->event); + epicsEventWait(evp->event); + } + ellAdd(&pmsg->eventFreeList, &evp->link); +} + static int mySend(epicsMessageQueueId pmsg, void *message, unsigned int size, double timeout) @@ -195,7 +205,7 @@ mySend(epicsMessageQueueId pmsg, void *message, unsigned int size, ellDelete(&pmsg->sendQueue, &threadNode.link); pmsg->numberOfSendersWaiting--; - ellAdd(&pmsg->eventFreeList, &threadNode.evp->link); + freeEventNode(pmsg, threadNode.evp, status); if ((pmsg->full && (ellFirst(&pmsg->receiveQueue) == NULL)) || status != epicsEventOK) { @@ -342,7 +352,8 @@ myReceive(epicsMessageQueueId pmsg, void *message, unsigned int size, if (!threadNode.eventSent) ellDelete(&pmsg->receiveQueue, &threadNode.link); - ellAdd(&pmsg->eventFreeList, &threadNode.evp->link); + + freeEventNode(pmsg, threadNode.evp, status); epicsMutexUnlock(pmsg->mutex); From aeed7cfbddc979c5bc668d668052ef96cb5d84c5 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 30 Apr 2020 23:55:30 -0500 Subject: [PATCH 04/10] osdMessageQueue: This is the mirror of Heinz Junkes' earlier fix When sending a message, if the queue is full so we have to wait, we create a threadNode with an eventNode in it and stick it on the sendQueue, then wait for a receiver to signal that event, waking us. If we awoke due to a timeout but a receiver was actually waking us up anyway (i.e. eventSent was set), we shouldn't give up. --- src/libCom/osi/os/default/osdMessageQueue.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libCom/osi/os/default/osdMessageQueue.cpp b/src/libCom/osi/os/default/osdMessageQueue.cpp index 0e1d1fc22..cdb3afba9 100644 --- a/src/libCom/osi/os/default/osdMessageQueue.cpp +++ b/src/libCom/osi/os/default/osdMessageQueue.cpp @@ -207,8 +207,7 @@ mySend(epicsMessageQueueId pmsg, void *message, unsigned int size, freeEventNode(pmsg, threadNode.evp, status); - if ((pmsg->full && (ellFirst(&pmsg->receiveQueue) == NULL)) || - status != epicsEventOK) { + if (pmsg->full && (ellFirst(&pmsg->receiveQueue) == NULL)) { epicsMutexUnlock(pmsg->mutex); return -1; } From 084557bd3e6de8795f65b0f6cff7914fa4ec930b Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 1 May 2020 00:12:32 -0500 Subject: [PATCH 05/10] osdMessageQueue: Don't wake our sender until we're ready for it Move the code that wakes up the next sending task to after we've added our threadNode to the receiveQueue. He still has to wait for us to release the Mutex though, so this might make no difference. This commit also changes when we decrement the number of waiting senders so it always happens immediately after a threadNode gets taken off the sendQueue by the code that removed it. --- src/libCom/osi/os/default/osdMessageQueue.cpp | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/libCom/osi/os/default/osdMessageQueue.cpp b/src/libCom/osi/os/default/osdMessageQueue.cpp index cdb3afba9..38e4f764d 100644 --- a/src/libCom/osi/os/default/osdMessageQueue.cpp +++ b/src/libCom/osi/os/default/osdMessageQueue.cpp @@ -201,9 +201,10 @@ mySend(epicsMessageQueueId pmsg, void *message, unsigned int size, epicsMutexMustLock(pmsg->mutex); - if(!threadNode.eventSent) + if (!threadNode.eventSent) { ellDelete(&pmsg->sendQueue, &threadNode.link); - pmsg->numberOfSendersWaiting--; + pmsg->numberOfSendersWaiting--; + } freeEventNode(pmsg, threadNode.evp, status); @@ -300,6 +301,7 @@ myReceive(epicsMessageQueueId pmsg, void *message, unsigned int size, */ if ((pthr = reinterpret_cast < struct threadNode * > ( ellGet(&pmsg->sendQueue) ) ) != NULL) { + pmsg->numberOfSendersWaiting--; pthr->eventSent = true; epicsEventSignal(pthr->evp->event); } @@ -316,16 +318,7 @@ myReceive(epicsMessageQueueId pmsg, void *message, unsigned int size, } /* - * Wake up the oldest task waiting to send - */ - if ((pthr = reinterpret_cast < struct threadNode * > - ( ellGet(&pmsg->sendQueue) ) ) != NULL) { - pthr->eventSent = true; - epicsEventSignal(pthr->evp->event); - } - - /* - * Wait for message to arrive + * Indicate that we're waiting */ struct threadNode threadNode; threadNode.evp = getEventNode(pmsg); @@ -339,6 +332,17 @@ myReceive(epicsMessageQueueId pmsg, void *message, unsigned int size, } ellAdd(&pmsg->receiveQueue, &threadNode.link); + + /* + * Wake up the oldest task waiting to send + */ + if ((pthr = reinterpret_cast < struct threadNode * > + ( ellGet(&pmsg->sendQueue) ) ) != NULL) { + pmsg->numberOfSendersWaiting--; + pthr->eventSent = true; + epicsEventSignal(pthr->evp->event); + } + epicsMutexUnlock(pmsg->mutex); /* From ceb13797a600da82bd73d52dded14fd6ee35d423 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 1 May 2020 00:13:02 -0500 Subject: [PATCH 06/10] Cosmetic --- src/libCom/osi/os/default/osdMessageQueue.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libCom/osi/os/default/osdMessageQueue.cpp b/src/libCom/osi/os/default/osdMessageQueue.cpp index 38e4f764d..3f95c4f40 100644 --- a/src/libCom/osi/os/default/osdMessageQueue.cpp +++ b/src/libCom/osi/os/default/osdMessageQueue.cpp @@ -408,7 +408,8 @@ epicsMessageQueuePending(epicsMessageQueueId pmsg) epicsShareFunc void epicsShareAPI epicsMessageQueueShow(epicsMessageQueueId pmsg, int level) { - printf("Message Queue Used:%d Slots:%lu", epicsMessageQueuePending(pmsg), pmsg->capacity); + printf("Message Queue Used:%d Slots:%lu", + epicsMessageQueuePending(pmsg), pmsg->capacity); if (level >= 1) printf(" Maximum size:%lu", pmsg->maxMessageSize); printf("\n"); From 34e0b2f305ecef38f699d150086a76ee962a52cb Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Mon, 4 May 2020 11:56:14 -0500 Subject: [PATCH 07/10] osdMessageQueue: Undo change to -ve timeout handling The internal mySend() and myReceive() routines do expect a timeout of -1 to mean wait forever, see the epicsMessageQueueSend() and epicsMessageQueueReceive() API routines. --- src/libCom/osi/os/default/osdMessageQueue.cpp | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/libCom/osi/os/default/osdMessageQueue.cpp b/src/libCom/osi/os/default/osdMessageQueue.cpp index 3f95c4f40..d99e23b70 100644 --- a/src/libCom/osi/os/default/osdMessageQueue.cpp +++ b/src/libCom/osi/os/default/osdMessageQueue.cpp @@ -173,15 +173,15 @@ mySend(epicsMessageQueueId pmsg, void *message, unsigned int size, if ((pmsg->numberOfSendersWaiting > 0) || (pmsg->full && (ellFirst(&pmsg->receiveQueue) == NULL))) { /* - * Return if not allowed to wait + * Return if not allowed to wait. NB -1 means wait forever. */ - if (timeout <= 0) { + if (timeout == 0) { epicsMutexUnlock(pmsg->mutex); return -1; } /* - * Wait + * Indicate that we're waiting */ struct threadNode threadNode; threadNode.evp = getEventNode(pmsg); @@ -196,12 +196,17 @@ mySend(epicsMessageQueueId pmsg, void *message, unsigned int size, epicsMutexUnlock(pmsg->mutex); - epicsEventStatus status = + /* + * Wait for receiver to wake us + */ + epicsEventStatus status = timeout < 0 ? + epicsEventWait(threadNode.evp->event) : epicsEventWaitWithTimeout(threadNode.evp->event, timeout); epicsMutexMustLock(pmsg->mutex); if (!threadNode.eventSent) { + /* Receiver didn't take us off the sendQueue, do it ourselves */ ellDelete(&pmsg->sendQueue, &threadNode.link); pmsg->numberOfSendersWaiting--; } @@ -209,6 +214,7 @@ mySend(epicsMessageQueueId pmsg, void *message, unsigned int size, freeEventNode(pmsg, threadNode.evp, status); if (pmsg->full && (ellFirst(&pmsg->receiveQueue) == NULL)) { + /* State of the queue didn't change, exit */ epicsMutexUnlock(pmsg->mutex); return -1; } @@ -310,9 +316,9 @@ myReceive(epicsMessageQueueId pmsg, void *message, unsigned int size, } /* - * Return if not allowed to wait + * Return if not allowed to wait. NB -1 means wait forever. */ - if (timeout <= 0) { + if (timeout == 0) { epicsMutexUnlock(pmsg->mutex); return -1; } @@ -348,7 +354,8 @@ myReceive(epicsMessageQueueId pmsg, void *message, unsigned int size, /* * Wait for a message to arrive */ - epicsEventStatus status = + epicsEventStatus status = timeout < 0 ? + epicsEventWait(threadNode.evp->event) : epicsEventWaitWithTimeout(threadNode.evp->event, timeout); epicsMutexMustLock(pmsg->mutex); From 089954aaab0ef6c43da77305bc28b807f1686930 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 7 May 2020 13:12:12 -0500 Subject: [PATCH 08/10] MessageQueue Tests: Extend Mark's sleep tests --- src/libCom/test/epicsMessageQueueTest.cpp | 133 ++++++++++++++++------ 1 file changed, 101 insertions(+), 32 deletions(-) diff --git a/src/libCom/test/epicsMessageQueueTest.cpp b/src/libCom/test/epicsMessageQueueTest.cpp index 1bee13c36..b793ce2cd 100644 --- a/src/libCom/test/epicsMessageQueueTest.cpp +++ b/src/libCom/test/epicsMessageQueueTest.cpp @@ -27,7 +27,10 @@ static volatile int sendExit = 0; static volatile int recvExit = 0; static epicsEventId finished; static unsigned int mediumStack; -static int numReceived; + +#define SLEEPY_TESTS 500 +static int numSent, numReceived; +static epicsEventId complete; /* * In Numerical Recipes in C: The Art of Scientific Computing (William H. @@ -124,11 +127,95 @@ fastReceiver(void *arg) int len; numReceived = 0; while (!recvExit) { - len = q->receive(cbuf, sizeof cbuf, 0.01); + len = q->receive(cbuf, sizeof cbuf, 0.010); if (len > 0) { numReceived++; } } + recvExit = 0; + epicsEventSignal(complete); +} + +void sleepySender(epicsMessageQueue *q, double delay) +{ + testDiag("sleepySender: sending every %.3f seconds", delay); + epicsThreadCreate("Fast Receiver", epicsThreadPriorityMedium, + mediumStack, fastReceiver, q); + + numSent = 0; + numReceived = 0; + for (int i = 0 ; i < SLEEPY_TESTS ; i++) { + if (q->send((void *)msg1, 4) == 0) { + numSent++; + } + epicsThreadSleep(delay); + } + epicsThreadSleep(1.0); + testOk(numSent == SLEEPY_TESTS, "Sent %d (should be %d)", + numSent, SLEEPY_TESTS); + testOk(numReceived == SLEEPY_TESTS, "Received %d (should be %d)", + numReceived, SLEEPY_TESTS); + + recvExit = 1; + while (q->send((void *)msg1, 4) != 0) + epicsThreadSleep(0.01); + epicsEventMustWait(complete); +} + +extern "C" void +fastSender(void *arg) +{ + epicsMessageQueue *q = (epicsMessageQueue *)arg; + numSent = 0; + + // Send first withough timeout + q->send((void *)msg1, 4); + numSent++; + + // The rest have a timeout + while (!sendExit) { + if (q->send((void *)msg1, 4, 0.010) == 0) { + numSent++; + } + } + sendExit = 0; + epicsEventSignal(complete); +} + +void sleepyReceiver(epicsMessageQueue *q, double delay) +{ + testDiag("sleepyReceiver: acquiring every %.3f seconds", delay); + + // Fill the queue + for (int i = q->pending(); i < 4 ;i++) { + q->send((void *)msg1, 4); + } + + epicsThreadCreate("Fast Sender", epicsThreadPriorityMedium, + mediumStack, fastSender, q); + epicsThreadSleep(0.5); + + char cbuf[80]; + int len; + numReceived = 0; + + for (int i = 0 ; i < SLEEPY_TESTS ; i++) { + len = q->receive(cbuf, sizeof cbuf); + if (len > 0) { + numReceived++; + } + epicsThreadSleep(delay); + } + + testOk(numSent == SLEEPY_TESTS, "Sent %d (should be %d)", + numSent, SLEEPY_TESTS); + testOk(numReceived == SLEEPY_TESTS, "Received %d (should be %d)", + numReceived, SLEEPY_TESTS); + + sendExit = 1; + while (q->receive(cbuf, sizeof cbuf) <= 0) + epicsThreadSleep(0.01); + epicsEventMustWait(complete); } extern "C" void @@ -156,7 +243,6 @@ extern "C" void messageQueueTest(void *parm) int len; int pass; int want; - int numSent = 0; epicsMessageQueue *q1 = new epicsMessageQueue(4, 20); epicsMessageQueue *q2 = new epicsMessageQueue(4, 20); @@ -269,34 +355,17 @@ extern "C" void messageQueueTest(void *parm) testOk(q1->send((void *)msg1, 10) == 0, "Send with no receiver"); epicsThreadSleep(2.0); - testDiag("Single receiver with timeout, single sender with sleep tests:"); - testDiag("These tests last 20 seconds ..."); - epicsThreadCreate("Fast Receiver", epicsThreadPriorityMedium, - mediumStack, fastReceiver, q2); - numSent = 0; - numReceived = 0; - for (i = 0 ; i < 1000 ; i++) { - if (q2->send((void *)msg1, 4) == 0) { - numSent++; - } - epicsThreadSleep(0.011); - } - epicsThreadSleep(1.0); - if (!testOk(numSent == 1000 && numReceived == 1000, "sleep=0.011")) { - testDiag("numSent should be 1000, actual=%d, numReceived should be 1000, actual=%d", numSent, numReceived); - } - numSent = 0; - numReceived = 0; - for (i = 0 ; i < 1000 ; i++) { - if (q2->send((void *)msg1, 4) == 0) { - numSent++; - } - epicsThreadSleep(0.010); - } - epicsThreadSleep(1.0); - if (!testOk(numSent == 1000 && numReceived == 1000, "sleep=0.010")) { - testDiag("numSent should be 1000, actual=%d, numReceived should be 1000, actual=%d", numSent, numReceived); - } + testDiag("6 Single receiver single sender 'Sleepy timeout' tests,"); + testDiag(" these should take about %.2f seconds each:", + SLEEPY_TESTS * 0.010); + + complete = epicsEventMustCreate(epicsEventEmpty); + sleepySender(q2, 0.009); + sleepySender(q2, 0.010); + sleepySender(q2, 0.011); + sleepyReceiver(q2, 0.009); + sleepyReceiver(q2, 0.010); + sleepyReceiver(q2, 0.011); testDiag("Single receiver, single sender tests:"); epicsThreadSetPriority(myThreadId, epicsThreadPriorityHigh); @@ -359,7 +428,7 @@ extern "C" void messageQueueTest(void *parm) MAIN(epicsMessageQueueTest) { - testPlan(64); + testPlan(74); finished = epicsEventMustCreate(epicsEventEmpty); mediumStack = epicsThreadGetStackSize(epicsThreadStackMedium); From 2e7ed02a606bbebe3cf961670a8b782fd6915705 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 7 May 2020 13:13:26 -0500 Subject: [PATCH 09/10] Allow/expect MinGW to fail epicsStackTraceTest #5 --- src/libCom/test/epicsStackTraceTest.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/libCom/test/epicsStackTraceTest.c b/src/libCom/test/epicsStackTraceTest.c index 69cb499f2..246abe4d8 100644 --- a/src/libCom/test/epicsStackTraceTest.c +++ b/src/libCom/test/epicsStackTraceTest.c @@ -1,11 +1,11 @@ -/* +/* * Copyright: Stanford University / SLAC National Laboratory. * * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. + * in file LICENSE that is included with this distribution. * * Author: Till Straumann , 2014 - */ + */ /* * Check stack trace functionality @@ -135,14 +135,14 @@ findNumOcc(const char *buf) } /* We should find an address close to epicsStackTraceRecurseGbl twice */ for (i=0; i= (char*)epicsStackTraceRecurseGbl && (char*)ptrs[i] < (char*)epicsStackTraceRecurseGbl + WINDOW_SZ ) { - rval ++; + rval ++; if ( test_debug ) testDiag("found address %p again\n", ptrs[i]); } @@ -167,7 +167,7 @@ MAIN(epicsStackTraceTest) testPlan(5); - features = epicsStackTraceGetFeatures(); + features = epicsStackTraceGetFeatures(); all_features = EPICS_STACKTRACE_LCL_SYMBOLS | EPICS_STACKTRACE_GBL_SYMBOLS @@ -217,7 +217,13 @@ MAIN(epicsStackTraceTest) } if ( (features & EPICS_STACKTRACE_ADDRESSES) ) { +#ifdef _MINGW + testTodoBegin("MinGW, might fail"); +#endif testOk( numFound > 0, "dumping addresses" ); +#ifdef _MINGW + testTodoEnd(); +#endif } else { testSkip(1 , "no support for dumping addresses on this platform"); } From b03e2f376bf8bd126dacc684b34afc35c309fd92 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 13 May 2020 16:11:31 -0500 Subject: [PATCH 10/10] eMQTest: Start each test with a new (empty) queue If fastReceiver() took more than 0.01 seconds to exit, sleepySender() might have pushed a second message onto the queue after setting recvExit, so there would be an extra message in the queue for the next test, which I was seeing on Appveyor. That's my current theory... --- src/libCom/test/epicsMessageQueueTest.cpp | 36 +++++++++++------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/libCom/test/epicsMessageQueueTest.cpp b/src/libCom/test/epicsMessageQueueTest.cpp index b793ce2cd..f23683c84 100644 --- a/src/libCom/test/epicsMessageQueueTest.cpp +++ b/src/libCom/test/epicsMessageQueueTest.cpp @@ -136,16 +136,16 @@ fastReceiver(void *arg) epicsEventSignal(complete); } -void sleepySender(epicsMessageQueue *q, double delay) +void sleepySender(double delay) { testDiag("sleepySender: sending every %.3f seconds", delay); + epicsMessageQueue q(4, 20); epicsThreadCreate("Fast Receiver", epicsThreadPriorityMedium, - mediumStack, fastReceiver, q); + mediumStack, fastReceiver, &q); numSent = 0; - numReceived = 0; for (int i = 0 ; i < SLEEPY_TESTS ; i++) { - if (q->send((void *)msg1, 4) == 0) { + if (q.send((void *)msg1, 4) == 0) { numSent++; } epicsThreadSleep(delay); @@ -157,7 +157,7 @@ void sleepySender(epicsMessageQueue *q, double delay) numReceived, SLEEPY_TESTS); recvExit = 1; - while (q->send((void *)msg1, 4) != 0) + while (q.send((void *)msg1, 4) != 0) epicsThreadSleep(0.01); epicsEventMustWait(complete); } @@ -182,17 +182,18 @@ fastSender(void *arg) epicsEventSignal(complete); } -void sleepyReceiver(epicsMessageQueue *q, double delay) +void sleepyReceiver(double delay) { testDiag("sleepyReceiver: acquiring every %.3f seconds", delay); + epicsMessageQueue q(4, 20); // Fill the queue - for (int i = q->pending(); i < 4 ;i++) { - q->send((void *)msg1, 4); + for (int i = q.pending(); i < 4 ;i++) { + q.send((void *)msg1, 4); } epicsThreadCreate("Fast Sender", epicsThreadPriorityMedium, - mediumStack, fastSender, q); + mediumStack, fastSender, &q); epicsThreadSleep(0.5); char cbuf[80]; @@ -200,7 +201,7 @@ void sleepyReceiver(epicsMessageQueue *q, double delay) numReceived = 0; for (int i = 0 ; i < SLEEPY_TESTS ; i++) { - len = q->receive(cbuf, sizeof cbuf); + len = q.receive(cbuf, sizeof cbuf); if (len > 0) { numReceived++; } @@ -213,7 +214,7 @@ void sleepyReceiver(epicsMessageQueue *q, double delay) numReceived, SLEEPY_TESTS); sendExit = 1; - while (q->receive(cbuf, sizeof cbuf) <= 0) + while (q.receive(cbuf, sizeof cbuf) <= 0) epicsThreadSleep(0.01); epicsEventMustWait(complete); } @@ -245,7 +246,6 @@ extern "C" void messageQueueTest(void *parm) int want; epicsMessageQueue *q1 = new epicsMessageQueue(4, 20); - epicsMessageQueue *q2 = new epicsMessageQueue(4, 20); testDiag("Simple single-thread tests:"); i = 0; @@ -360,12 +360,12 @@ extern "C" void messageQueueTest(void *parm) SLEEPY_TESTS * 0.010); complete = epicsEventMustCreate(epicsEventEmpty); - sleepySender(q2, 0.009); - sleepySender(q2, 0.010); - sleepySender(q2, 0.011); - sleepyReceiver(q2, 0.009); - sleepyReceiver(q2, 0.010); - sleepyReceiver(q2, 0.011); + sleepySender(0.009); + sleepySender(0.010); + sleepySender(0.011); + sleepyReceiver(0.009); + sleepyReceiver(0.010); + sleepyReceiver(0.011); testDiag("Single receiver, single sender tests:"); epicsThreadSetPriority(myThreadId, epicsThreadPriorityHigh);