I just had a quick look at my RTEMS5 implementation of the Message Queue.
I use the Posix-mq there. Maybe one could switch the default mq story to posix in general?
Just an idea. I don't want to complicate things.
Heinz
RTEMS-posix/osdMessageQueue.h
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* Author W. Eric Norum
* norume at aps.anl.gov
* 630 252 4793
*/
/*
* Very thin shims around RTEMS routines
*/
#include <rtems.h>
#include <mqueue.h>
struct epicsMessageQueueOSD {
mqd_t id;
char name[24];
int idCnt;
};
#define epicsMessageQueueSend(q,m,l) (mq_send((q)->id, (const char*)(m), (l), 0))
#define epicsMessageQueueReceive(q,m,s) (mq_receive((q)->id, (char*)(m), (s), N
RTEMS-posix/osdMessageQueue.c
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* Author W. Eric Norum
* norume at aps.anl.gov
* 630 252 4793
*/
/*
* We want to access information which is
* normally hidden from application programs.
*/
#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1
#define epicsExportSharedSymbols
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rtems.h>
#include <rtems/error.h>
#include "epicsMessageQueue.h"
#include "errlog.h"
#include <epicsAtomic.h>
#include <errno.h>
#include <mqueue.h>
#include <fcntl.h>
epicsShareFunc epicsMessageQueueId epicsShareAPI
epicsMessageQueueCreate(unsigned int capacity, unsigned int maximumMessageSize)
{
struct mq_attr the_attr;
epicsMessageQueueId id = (epicsMessageQueueId)calloc(1, sizeof(*id));
epicsAtomicIncrIntT(&id->idCnt);
sprintf(id->name, "MQ_%01d", epicsAtomicGetIntT(&id->idCnt));
the_attr.mq_maxmsg = capacity;
the_attr.mq_msgsize = maximumMessageSize;
id->id = mq_open(id->name, O_RDWR | O_CREAT | O_EXCL, 0644, &the_attr);
if (id->id <0) {
fprintf (stderr, "Can't create message queue: %s\n", strerror (errno));
return NULL;
}
return id;
}
epicsShareFunc void epicsShareAPI epicsMessageQueueDestroy(
epicsMessageQueueId id)
{
int rv;
rv = mq_close(id->id);
if( rv ) {
fprintf(stderr, "epicsMessageQueueDestroy mq_close failed: %s\n",
strerror(rv));
}
rv = mq_unlink(id->name);
if( rv ) {
fprintf(stderr,"epicsMessageQueueDestroy mq_unlink %s failed: %s\n",
id->name, strerror(rv));
}
free(id);
}
epicsShareFunc int epicsShareAPI epicsMessageQueueTrySend(
epicsMessageQueueId id,
void *message,
unsigned int messageSize)
{
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
return mq_timedsend(id->id, (char const *)message, messageSize, 0, &ts);
}
epicsShareFunc int epicsShareAPI epicsMessageQueueSendWithTimeout(
epicsMessageQueueId id,
void *message,
unsigned int messageSize,
double timeout)
{
struct timespec ts;
unsigned long micros;
// assume timeout in sec
micros = (unsigned long)(timeout * 1000000.0);
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += micros / 1000000L;
ts.tv_nsec += (micros % 1000000L) * 1000L;
return mq_timedsend (id->id, (const char *)message, messageSize, 0, &ts);
}
epicsShareFunc int epicsShareAPI epicsMessageQueueTryReceive(
epicsMessageQueueId id,
void *message,
unsigned int size)
{
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
return mq_timedreceive(id->id, (char *)message, size, NULL, &ts);
}
epicsShareFunc int epicsShareAPI epicsMessageQueueReceiveWithTimeout(
epicsMessageQueueId id,
void *message,
unsigned int size,
double timeout)
{
unsigned long micros;
struct timespec ts;
micros = (unsigned long)(timeout * 1000000.0);
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += micros / 1000000L;
ts.tv_nsec += (micros % 1000000L) * 1000L;
return mq_timedreceive(id->id, (char *)message, size, NULL, &ts);
}
epicsShareFunc int epicsShareAPI epicsMessageQueuePending(
epicsMessageQueueId id)
{
int rv;
struct mq_attr the_attr;
rv = mq_getattr(id->id, &the_attr);
if (rv) {
fprintf(stderr, "Epics Message queue %x (%s) get attr failed: %s\n",
(unsigned int)id->id, id->name, strerror(rv));
return -1;
}
return the_attr.mq_curmsgs;
}
epicsShareFunc void epicsShareAPI epicsMessageQueueShow(
epicsMessageQueueId id,
int level)
{
int rv;
struct mq_attr the_attr;
rv = mq_getattr(id->id, &the_attr);
if (rv) {
fprintf(stderr, "Epics Message queue %x (%s) get attr failed: %s\n",
(unsigned int)id->id, id->name, strerror(rv));
}
printf("Message Queue Used:%ld Max Msg:%lu", the_attr.mq_curmsgs, the_attr.mq_maxmsg);
if (level >= 1)
printf(" Maximum size:%lu", the_attr.mq_msgsize);
printf("\n");
}
------------------------------------------------------------------------------
Fritz-Haber-Institut | Phone: (+49 30) 8413-4270
Heinz Junkes | Fax (G3+G4): (+49 30) 8413-5900
Faradayweg 4-6 | VC: 102220181216 at bjn.vc
D - 14195 Berlin | E-Mail: junkes at fhi-berlin.mpg.de
------------------------------------------------------------------------------
> On 25. May 2020, at 20:37, Michael Davidsaver via Core-talk <core-talk at aps.anl.gov> wrote:
>
> A couple of things.
>
> It looks like the switch to ci-scripts for Base added TEST=NO for the RTEMS builds.
> This needs to be removed.
>
> On 5/25/20 10:49 AM, Johnson, Andrew N. via Core-talk wrote:
>> tl;dr: I propose that we delete the RTEMS implementation of osdMessageQueue before making the 7.0.3.2 release, it has bugs which the default implementation doesn’t show.
>
> I don't have a strong objection to this. Although, I'm not enthused to be
> making this change days before a release, when it will go out the door with
> very little testing. Whatever is going on, I suspect that it isn't a
> regression (the bugs in the default impl weren't).
>
> How about marking your new test as a skip until after the release?
>
>
>> The long version:
>>
>> While merging 3.15 into 7.0 last night I ran the tests on RTEMS (qemu) and discovered that the implementation of the epicsMessageQueue fails the additional tests that I wrote for this API. I was expecting the Travis-CI builds to fail but
>
>> I forgot that they don’t actually run the tests at all.
>
> I guess there is something to be said for developing on the development branch.
>
>
>> In the RTEMS implementation of the epicsMessageQueue Eric added an rtems_message_queue_send_timeout() routine which the rtems_message_queue type doesn’t come with. These were the results I saw for these tests:
>>
>>> # 6 Single receiver single sender 'Sleepy timeout' tests,
>>> # these should take about 5.00 seconds each:
>>> # sleepySender: sending every 0.009 seconds
>>> ok 57 - Sent 500 (should be 500)
>>> ok 58 - Received 500 (should be 500)
>>> # sleepySender: sending every 0.010 seconds
>>> ok 59 - Sent 500 (should be 500)
>>> ok 60 - Received 500 (should be 500)
>>> # sleepySender: sending every 0.011 seconds
>>> ok 61 - Sent 500 (should be 500)
>>> ok 62 - Received 500 (should be 500)
>>> # sleepyReceiver: acquiring every 0.009 seconds
>>> not ok 63 - Sent 420 (should be 500)
>>> ok 64 - Received 500 (should be 500)
>>> # sleepyReceiver: acquiring every 0.010 seconds
>>> not ok 65 - Sent 420 (should be 500)
>>> ok 66 - Received 500 (should be 500)
>>> # sleepyReceiver: acquiring every 0.011 seconds
>>> not ok 67 - Sent 420 (should be 500)
>>> ok 68 - Received 500 (should be 500)
>>
>> So far every time I have run this test the numSent counter has always come back as 420 instead of 500. The fastSender() code looks like this:
>>
>>> extern"C"void
>>> fastSender(void*arg)
>>> {
>>> epicsMessageQueue *q = (epicsMessageQueue *)arg;
>>> numSent= 0;
>>>
>>> // Send first without 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);
>>> }
>>
>> The epicsMessageQueueSendWithTimeout() routine must sometimes be returning an error (non-zero value) even though it has successfully queued the message; I confirmed that by incrementing a local numFailed counter on the else branch, which always counted to 580. This was the output from a normal run on linux, which is about what I would expect:
>>
>>> # sleepyReceiver: acquiring every 0.009 seconds
>>> ok 63 - Sent 500 (should be 500)
>>> ok 64 - Received 500 (should be 500)
>>> # numFailed = 0
>>> # sleepyReceiver: acquiring every 0.010 seconds
>>> ok 65 - Sent 500 (should be 500)
>>> ok 66 - Received 500 (should be 500)
>>> # numFailed = 204
>>> # sleepyReceiver: acquiring every 0.011 seconds
>>> ok 67 - Sent 500 (should be 500)
>>> ok 68 - Received 500 (should be 500)
>>> # numFailed = 500
>>
>> Instead of trying to fix the RTEMS code I propose that we delete the RTEMS implementation completely, causing RTEMS to use the default implementation which gives me these test results when run on qemu:
>>
>>> # 6 Single receiver single sender 'Sleepy timeout' tests,
>>> # these should take about 5.00 seconds each:
>>> # sleepySender: sending every 0.009 seconds
>>> ok 57 - Sent 500 (should be 500)
>>> ok 58 - Received 500 (should be 500)
>>> # sleepySender: sending every 0.010 seconds
>>> ok 59 - Sent 500 (should be 500)
>>> ok 60 - Received 500 (should be 500)
>>> # sleepySender: sending every 0.011 seconds
>>> ok 61 - Sent 500 (should be 500)
>>> ok 62 - Received 500 (should be 500)
>>> # sleepyReceiver: acquiring every 0.009 seconds
>>> ok 63 - Sent 500 (should be 500)
>>> ok 64 - Received 500 (should be 500)
>>> # numFailed = 80
>>> # sleepyReceiver: acquiring every 0.010 seconds
>>> ok 65 - Sent 500 (should be 500)
>>> ok 66 - Received 500 (should be 500)
>>> # numFailed = 80
>>> # sleepyReceiver: acquiring every 0.011 seconds
>>> ok 67 - Sent 500 (should be 500)
>>> ok 68 - Received 500 (should be 500)
>>> # numFailed = 80
>>
>> Any objections? Discussion?
>>
>> - Andrew
>>
>> --
>> Complexity comes for free, simplicity you have to work for.
>>
>
Attachment:
smime.p7s
Description: S/MIME cryptographic signature
- References:
- RTEMS/osdMessageQueue.c Johnson, Andrew N. via Core-talk
- Re: RTEMS/osdMessageQueue.c Michael Davidsaver via Core-talk
- Navigate by Date:
- Prev:
Re: RTEMS/osdMessageQueue.c Michael Davidsaver via Core-talk
- Next:
Re: RTEMS/osdMessageQueue.c Michael Davidsaver via Core-talk
- Index:
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
<2020>
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
Re: RTEMS/osdMessageQueue.c Michael Davidsaver via Core-talk
- Next:
Re: RTEMS/osdMessageQueue.c Michael Davidsaver via Core-talk
- Index:
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
<2020>
2021
2022
2023
2024
|