* data modified by second NRT write with same memory location
[not found] <DM6PR14MB3871876E6E078D3BE974ADCBA30AA@DM6PR14MB3871.namprd14.prod.outlook.com>
@ 2023-08-01 9:18 ` yo sang
2023-08-01 17:29 ` Philippe Gerum
0 siblings, 1 reply; 10+ messages in thread
From: yo sang @ 2023-08-01 9:18 UTC (permalink / raw)
To: xenomai@lists.linux.dev
Hi,
I was playing with xddp recently, and found a strange situation.
I modified official example xddp-echo to test my case:
Main()
* => get socket
* => bind socket to port 0
* => open /dev/rtp0
* => create data buf with “first”
* => write buf to RT domain via write()
* => modify data buf to “second”
* => write buf to RT domain via write()
* Start realtime_thread-------------------------------------->----------+
* => read from NRT domain via recvfrom()
* => print output: “second"
* => read from NRT domain via recvfrom()
* => print output: “second”
If I write twice with same data location, the RT-end will receive “second” twice.
Any comments?
Thanks
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: data modified by second NRT write with same memory location
2023-08-01 9:18 ` data modified by second NRT write with same memory location yo sang
@ 2023-08-01 17:29 ` Philippe Gerum
2023-08-02 1:19 ` yo sang
0 siblings, 1 reply; 10+ messages in thread
From: Philippe Gerum @ 2023-08-01 17:29 UTC (permalink / raw)
To: yo sang; +Cc: xenomai@lists.linux.dev
yo sang <stlfatboy@hotmail.com> writes:
> Hi,
>
> I was playing with xddp recently, and found a strange situation.
> I modified official example xddp-echo to test my case:
>
> Main()
> * => get socket
> * => bind socket to port 0
> * => open /dev/rtp0
>
> * => create data buf with “first”
> * => write buf to RT domain via write()
> * => modify data buf to “second”
> * => write buf to RT domain via write()
>
> * Start realtime_thread-------------------------------------->----------+
> * => read from NRT domain via recvfrom()
> * => print output: “second"
> * => read from NRT domain via recvfrom()
> * => print output: “second”
>
> If I write twice with same data location, the RT-end will receive “second” twice.
>
> Any comments?
> Thanks
>
>
Please send the shortest possible piece of code illustrating the issue.
--
Philippe.
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: data modified by second NRT write with same memory location
2023-08-01 17:29 ` Philippe Gerum
@ 2023-08-02 1:19 ` yo sang
2023-08-02 6:04 ` yo sang
0 siblings, 1 reply; 10+ messages in thread
From: yo sang @ 2023-08-02 1:19 UTC (permalink / raw)
To: Philippe Gerum; +Cc: xenomai@lists.linux.dev
#define XDDP_PORT (6)
enum RTMemType
{
RTMEM_NONE = 0,
RTMEM_1,
RTMEM_2
};
class RTMem
{
public:
RTMem() {}
RTMem(const char* data, int size, RTMemType type) {
memcpy(Data, data, size);
Size = size;
Type = type;
}
int Size{};
RTMemType Type{};
char Data[256]{};
};
static void *realtime_thread(void *arg)
{
struct timespec ts;
int ret;
RTMem buf;
for (;;) {
ret = recvfrom(s, &buf, sizeof(buf), 0, NULL, 0);
if (ret <= 0)
fail("recvfrom");
printf(" => %s \n", buf.Data);
ts.tv_sec = 0;
ts.tv_nsec = 100000000; /* 100 ms */
clock_nanosleep(CLOCK_REALTIME, 0, &ts, NULL);
}
return NULL;
}
int main()
{
sigset_t set;
int sig;
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigaddset(&set, SIGTERM);
sigaddset(&set, SIGHUP);
pthread_sigmask(SIG_BLOCK, &set, NULL);
struct sockaddr_ipc saddr;
int ret, n = 0, len;
size_t poolsz;
/*
* Get a datagram socket to bind to the RT endpoint. Each
* endpoint is represented by a port number within the XDDP
* protocol namespace.
*/
s = socket(AF_RTIPC, SOCK_DGRAM, IPCPROTO_XDDP);
if (s < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
/*
* Set a local 16k pool for the RT endpoint. Memory needed to
* convey datagrams will be pulled from this pool, instead of
* Xenomai's system pool.
*/
poolsz = sizeof(RTMem) * 128; /* bytes */
ret = setsockopt(s, SOL_XDDP, XDDP_POOLSZ,
&poolsz, sizeof(poolsz));
if (ret)
fail("setsockopt");
/*
* Bind the socket to the port, to setup a proxy to channel
* traffic to/from the Linux domain.
*
* saddr.sipc_port specifies the port number to use.
*/
memset(&saddr, 0, sizeof(saddr));
saddr.sipc_family = AF_RTIPC;
saddr.sipc_port = XDDP_PORT;
ret = bind(s, (struct sockaddr *)&saddr, sizeof(saddr));
if (ret)
fail("bind");
char *devname;
int fd;
if (asprintf(&devname, "/dev/rtp%d", XDDP_PORT) < 0)
fail("asprintf");
fd = open(devname, O_WRONLY | O_APPEND);
free(devname);
if (fd < 0)
fail("open");
RTMem data("data1", 6, RTMEM_1);
ret = write(fd, &data, sizeof(data));
if (ret != sizeof(data))
fail("write");
memcpy(data.Data, "datadata", 9);
data.Size = 9;
data.Type = RTMEM_2;
ret = write(fd, &data, sizeof(data));
if (ret != sizeof(data))
fail("write");
struct sched_param rtparam = { .sched_priority = 42 };
pthread_attr_t rtattr;
pthread_attr_init(&rtattr);
pthread_attr_setdetachstate(&rtattr, PTHREAD_CREATE_JOINABLE);
pthread_attr_setinheritsched(&rtattr, PTHREAD_EXPLICIT_SCHED);
pthread_attr_setschedpolicy(&rtattr, SCHED_FIFO);
pthread_attr_setschedparam(&rtattr, &rtparam);
errno = pthread_create(&rt, &rtattr, &realtime_thread, NULL);
if (errno)
fail("pthread_create");
sigwait(&set, &sig);
pthread_cancel(rt);
pthread_join(rt, NULL);
close(s);
close(fd);
return 0;
}
==============================================
I'm expecting result to be
=> data1
=> datadata
However it will be
=> datadata
=> datadata
-----Original Message-----
From: Philippe Gerum <rpm@xenomai.org>
Sent: Wednesday, August 2, 2023 1:29 AM
To: yo sang <stlfatboy@hotmail.com>
Cc: xenomai@lists.linux.dev
Subject: Re: data modified by second NRT write with same memory location
yo sang <stlfatboy@hotmail.com> writes:
> Hi,
>
> I was playing with xddp recently, and found a strange situation.
> I modified official example xddp-echo to test my case:
>
> Main()
> * => get socket
> * => bind socket to port 0
> * => open /dev/rtp0
>
> * => create data buf with “first”
> * => write buf to RT domain via write()
> * => modify data buf to “second”
> * => write buf to RT domain via write()
>
> * Start realtime_thread-------------------------------------->----------+
> * => read from NRT domain via recvfrom()
> * => print output: “second"
> * => read from NRT domain via recvfrom()
> * => print output: “second”
>
> If I write twice with same data location, the RT-end will receive “second” twice.
>
> Any comments?
> Thanks
>
>
Please send the shortest possible piece of code illustrating the issue.
--
Philippe.
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: data modified by second NRT write with same memory location
2023-08-02 1:19 ` yo sang
@ 2023-08-02 6:04 ` yo sang
2023-08-02 7:30 ` Philippe Gerum
0 siblings, 1 reply; 10+ messages in thread
From: yo sang @ 2023-08-02 6:04 UTC (permalink / raw)
To: Philippe Gerum; +Cc: xenomai@lists.linux.dev
**********Please ignore previous code sample*********
#define XDDP_PORT (6)
enum RTMemType
{
RTMEM_NONE = 0,
RTMEM_1,
RTMEM_2
};
class RTMem
{
public:
RTMem() {}
RTMem(const char* data, int size, RTMemType type) {
Data = Buf;
memcpy(Data, data, size);
Size = size;
Type = type;
}
int Size{};
RTMemType Type{};
char* Data{};
char Buf[256]{};
};
static void *realtime_thread(void *arg)
{
struct timespec ts;
int ret;
RTMem buf;
for (;;) {
ret = recvfrom(s, &buf, sizeof(buf), 0, NULL, 0);
if (ret <= 0)
fail("recvfrom");
printf(" => %s \n", buf.Data);
ts.tv_sec = 0;
ts.tv_nsec = 100000000; /* 100 ms */
clock_nanosleep(CLOCK_REALTIME, 0, &ts, NULL);
}
return NULL;
}
int main()
{
sigset_t set;
int sig;
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigaddset(&set, SIGTERM);
sigaddset(&set, SIGHUP);
pthread_sigmask(SIG_BLOCK, &set, NULL);
struct sockaddr_ipc saddr;
int ret, n = 0, len;
size_t poolsz;
/*
* Get a datagram socket to bind to the RT endpoint. Each
* endpoint is represented by a port number within the XDDP
* protocol namespace.
*/
s = socket(AF_RTIPC, SOCK_DGRAM, IPCPROTO_XDDP);
if (s < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
/*
* Set a local 16k pool for the RT endpoint. Memory needed to
* convey datagrams will be pulled from this pool, instead of
* Xenomai's system pool.
*/
poolsz = sizeof(RTMem) * 128; /* bytes */
ret = setsockopt(s, SOL_XDDP, XDDP_POOLSZ,
&poolsz, sizeof(poolsz));
if (ret)
fail("setsockopt");
/*
* Bind the socket to the port, to setup a proxy to channel
* traffic to/from the Linux domain.
*
* saddr.sipc_port specifies the port number to use.
*/
memset(&saddr, 0, sizeof(saddr));
saddr.sipc_family = AF_RTIPC;
saddr.sipc_port = XDDP_PORT;
ret = bind(s, (struct sockaddr *)&saddr, sizeof(saddr));
if (ret)
fail("bind");
char *devname;
int fd;
if (asprintf(&devname, "/dev/rtp%d", XDDP_PORT) < 0)
fail("asprintf");
fd = open(devname, O_WRONLY | O_APPEND);
free(devname);
if (fd < 0)
fail("open");
RTMem data("data1", 6, RTMEM_1);
ret = write(fd, &data, sizeof(data));
if (ret != sizeof(data))
fail("write");
memcpy(data.Data, "datadata", 9);
data.Size = 9;
data.Type = RTMEM_2;
ret = write(fd, &data, sizeof(data));
if (ret != sizeof(data))
fail("write");
struct sched_param rtparam = { .sched_priority = 42 };
pthread_attr_t rtattr;
pthread_attr_init(&rtattr);
pthread_attr_setdetachstate(&rtattr, PTHREAD_CREATE_JOINABLE);
pthread_attr_setinheritsched(&rtattr, PTHREAD_EXPLICIT_SCHED);
pthread_attr_setschedpolicy(&rtattr, SCHED_FIFO);
pthread_attr_setschedparam(&rtattr, &rtparam);
errno = pthread_create(&rt, &rtattr, &realtime_thread, NULL);
if (errno)
fail("pthread_create");
sigwait(&set, &sig);
pthread_cancel(rt);
pthread_join(rt, NULL);
close(s);
close(fd);
return 0;
}
==============================================
I'm expecting result to be
=> data1
=> datadata
However it will be
=> datadata
=> datadata
-----Original Message-----
From: Philippe Gerum <rpm@xenomai.org>
Sent: Wednesday, August 2, 2023 1:29 AM
To: yo sang <stlfatboy@hotmail.com>
Cc: xenomai@lists.linux.dev
Subject: Re: data modified by second NRT write with same memory location
yo sang <stlfatboy@hotmail.com> writes:
> Hi,
>
> I was playing with xddp recently, and found a strange situation.
> I modified official example xddp-echo to test my case:
>
> Main()
> * => get socket
> * => bind socket to port 0
> * => open /dev/rtp0
>
> * => create data buf with “first”
> * => write buf to RT domain via write()
> * => modify data buf to “second”
> * => write buf to RT domain via write()
>
> * Start realtime_thread-------------------------------------->----------+
> * => read from NRT domain via recvfrom()
> * => print output: “second"
> * => read from NRT domain via recvfrom()
> * => print output: “second”
>
> If I write twice with same data location, the RT-end will receive “second” twice.
>
> Any comments?
> Thanks
>
>
Please send the shortest possible piece of code illustrating the issue.
--
Philippe.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: data modified by second NRT write with same memory location
2023-08-02 6:04 ` yo sang
@ 2023-08-02 7:30 ` Philippe Gerum
2023-08-02 8:14 ` dietmar.schindler
2023-08-02 8:32 ` yo sang
0 siblings, 2 replies; 10+ messages in thread
From: Philippe Gerum @ 2023-08-02 7:30 UTC (permalink / raw)
To: yo sang; +Cc: xenomai@lists.linux.dev
yo sang <stlfatboy@hotmail.com> writes:
> class RTMem
> {
> public:
> RTMem() {}
>
> RTMem(const char* data, int size, RTMemType type) {
> Data = Buf;
> memcpy(Data, data, size);
> Size = size;
> Type = type;
> }
>
> int Size{};
> RTMemType Type{};
> char* Data{};
> char Buf[256]{};
>
> };
<snip>
> static void *realtime_thread(void *arg)
> {
> struct timespec ts;
> int ret;
> RTMem buf;
> for (;;) {
> ret = recvfrom(s, &buf, sizeof(buf), 0, NULL, 0);
> if (ret <= 0)
> fail("recvfrom");
> printf(" => %s \n", buf.Data);
<snip>
>
> RTMem data("data1", 6, RTMEM_1);
> ret = write(fd, &data, sizeof(data));
> if (ret != sizeof(data))
> fail("write");
> memcpy(data.Data, "datadata", 9);
> data.Size = 9;
> data.Type = RTMEM_2;
> ret = write(fd, &data, sizeof(data));
> if (ret != sizeof(data))
> fail("write");
This example code is broken, badly. Please consider what the reader
thread actually reads, which is definitely not a value, but a descriptor
containing a pointer to some value, which the writer thread will
overwrite before realtime_thread() runs. Which explains the outcome.
At the very least, you should have a distinct RTMem instance to feed
each write() with. This said, since XDDP is by design an inter-stage,
inter-process IPC, passing process-private pointers in messages looks
wrong in the first place.
--
Philippe.
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: data modified by second NRT write with same memory location
2023-08-02 7:30 ` Philippe Gerum
@ 2023-08-02 8:14 ` dietmar.schindler
2023-08-02 9:01 ` Philippe Gerum
2023-08-02 8:32 ` yo sang
1 sibling, 1 reply; 10+ messages in thread
From: dietmar.schindler @ 2023-08-02 8:14 UTC (permalink / raw)
Cc: xenomai
> From: Philippe Gerum <rpm@xenomai.org>
> Sent: Wednesday, August 2, 2023 9:31 AM
> ...
> yo sang <stlfatboy@hotmail.com> writes:
>
> > class RTMem
> > {
> > public:
> > RTMem() {}
> >
> > RTMem(const char* data, int size, RTMemType type) {
> > Data = Buf;
> > memcpy(Data, data, size);
> > Size = size;
> > Type = type;
> > }
> >
> > intSize{};
> > RTMemTypeType{};
> > char*Data{};
> > charBuf[256]{};
> >
> > };
>
> <snip>
>
> > static void *realtime_thread(void *arg)
> > {
> > struct timespec ts;
> > int ret;
> > RTMem buf;
> > for (;;) {
> > ret = recvfrom(s, &buf, sizeof(buf), 0, NULL, 0);
> > if (ret <= 0)
> >fail("recvfrom");
> > printf(" => %s \n", buf.Data);
>
> <snip>
>
> >
> > RTMem data("data1", 6, RTMEM_1);
> > ret = write(fd, &data, sizeof(data));
> > if (ret != sizeof(data))
> > fail("write");
> > memcpy(data.Data, "datadata", 9);
> > data.Size = 9;
> > data.Type = RTMEM_2;
> > ret = write(fd, &data, sizeof(data));
> > if (ret != sizeof(data))
> > fail("write");
>
> This example code is broken, badly. Please consider what the reader
> thread actually reads, which is definitely not a value, but a descriptor
> containing a pointer to some value, which the writer thread will
> overwrite before realtime_thread() runs. Which explains the outcome.
>
> At the very least, you should have a distinct RTMem instance to feed
> each write() with. This said, since XDDP is by design an inter-stage,
> inter-process IPC, passing process-private pointers in messages looks
> wrong in the first place.
I think it would also work if only the reader used buf.Buf rather than buf.Data, i. e.
printf(" => %s \n", buf.Buf);
since buf.Buf is copied and remains meaningful, unlike the pointer.
--
Best regards,
Dietmar Schindler
________________________________
manroland Goss web systems GmbH | Managing Director: Franz Kriechbaum
Registered Office: Augsburg | Trade Register: AG Augsburg | HRB-No.: 32609 | VAT: DE815764857
Confidentiality note:
This message and any attached documents may contain confidential or proprietary information of manroland|Goss. These materials are intended only for the use of the intended recipient. If you are not the intended recipient of this transmission, you are hereby notified that any distribution, disclosure, printing, copying, storage, modification or the taking of any action in reliance upon this transmission is strictly prohibited. Delivery of this message to any person other than the intended recipient shall not compromise or waive such confidentiality, privilege or exemption from disclosure as to this communication. If you have received this communication in error, please immediately notify the sender and delete the message from your system. All liability for viruses is excluded to the fullest extent permitted by law.
________________________________
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: data modified by second NRT write with same memory location
2023-08-02 7:30 ` Philippe Gerum
2023-08-02 8:14 ` dietmar.schindler
@ 2023-08-02 8:32 ` yo sang
2023-08-02 8:56 ` Philippe Gerum
1 sibling, 1 reply; 10+ messages in thread
From: yo sang @ 2023-08-02 8:32 UTC (permalink / raw)
To: Philippe Gerum; +Cc: xenomai@lists.linux.dev
Thanks for the reply.
I still have several doubts:
1. it's very common to delete data right after calling write(). Data should be completely copied to ensure a successful write() call.
2. The fd opened for nrt is blocking by default. If I'm using un-blocking way of write(), it's reasonable to maintain several distinct RTMem instances at write end.
3. If I modify the RTMem class as below, the result is correct then:
class RTMem
{
public:
RTMem() {}
RTMem(const char* data, int size, RTMemType type) {
//Data = Buf;
memcpy(Data, data, size);
Size = size;
Type = type;
}
int Size{};
RTMemType Type{};
//char* Data{};
char Data[256]{};
};
-----Original Message-----
From: Philippe Gerum <rpm@xenomai.org>
Sent: Wednesday, August 2, 2023 3:31 PM
To: yo sang <stlfatboy@hotmail.com>
Cc: xenomai@lists.linux.dev
Subject: Re: data modified by second NRT write with same memory location
yo sang <stlfatboy@hotmail.com> writes:
> class RTMem
> {
> public:
> RTMem() {}
>
> RTMem(const char* data, int size, RTMemType type) {
> Data = Buf;
> memcpy(Data, data, size);
> Size = size;
> Type = type;
> }
>
> int Size{};
> RTMemType Type{};
> char* Data{};
> char Buf[256]{};
>
> };
<snip>
> static void *realtime_thread(void *arg) {
> struct timespec ts;
> int ret;
> RTMem buf;
> for (;;) {
> ret = recvfrom(s, &buf, sizeof(buf), 0, NULL, 0);
> if (ret <= 0)
> fail("recvfrom");
> printf(" => %s \n", buf.Data);
<snip>
>
> RTMem data("data1", 6, RTMEM_1);
> ret = write(fd, &data, sizeof(data));
> if (ret != sizeof(data))
> fail("write");
> memcpy(data.Data, "datadata", 9);
> data.Size = 9;
> data.Type = RTMEM_2;
> ret = write(fd, &data, sizeof(data));
> if (ret != sizeof(data))
> fail("write");
This example code is broken, badly. Please consider what the reader thread actually reads, which is definitely not a value, but a descriptor containing a pointer to some value, which the writer thread will overwrite before realtime_thread() runs. Which explains the outcome.
At the very least, you should have a distinct RTMem instance to feed each write() with. This said, since XDDP is by design an inter-stage, inter-process IPC, passing process-private pointers in messages looks wrong in the first place.
--
Philippe.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: data modified by second NRT write with same memory location
2023-08-02 8:32 ` yo sang
@ 2023-08-02 8:56 ` Philippe Gerum
2023-08-03 1:03 ` yo sang
0 siblings, 1 reply; 10+ messages in thread
From: Philippe Gerum @ 2023-08-02 8:56 UTC (permalink / raw)
To: yo sang; +Cc: xenomai@lists.linux.dev
yo sang <stlfatboy@hotmail.com> writes:
> Thanks for the reply.
>
> I still have several doubts:
> 1. it's very common to delete data right after calling write(). Data should be completely copied to ensure a successful write() call.
>
Except that your code is simply not doing that. Please read it
again. Hint: this implementation introduces sharing by mean of a
pointer.
> 2. The fd opened for nrt is blocking by default. If I'm using un-blocking way of write(), it's reasonable to maintain several distinct RTMem instances at write end.
>
This is not the point in discussion. The issue is with the broken
indirection the pointer adds.
> 3. If I modify the RTMem class as below, the result is correct then:
>
> class RTMem
> {
> public:
> RTMem() {}
>
> RTMem(const char* data, int size, RTMemType type) {
> //Data = Buf;
> memcpy(Data, data, size);
> Size = size;
> Type = type;
> }
>
> int Size{};
> RTMemType Type{};
> //char* Data{};
> char Data[256]{};
>
> };
Obviously it is, indeed.
--
Philippe.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: data modified by second NRT write with same memory location
2023-08-02 8:14 ` dietmar.schindler
@ 2023-08-02 9:01 ` Philippe Gerum
0 siblings, 0 replies; 10+ messages in thread
From: Philippe Gerum @ 2023-08-02 9:01 UTC (permalink / raw)
To: dietmar.schindler; +Cc: xenomai
<dietmar.schindler@manrolandgoss.com> writes:
>> From: Philippe Gerum <rpm@xenomai.org>
>> Sent: Wednesday, August 2, 2023 9:31 AM
>> ...
>> yo sang <stlfatboy@hotmail.com> writes:
>>
>> > class RTMem
>> > {
>> > public:
>> > RTMem() {}
>> >
>> > RTMem(const char* data, int size, RTMemType type) {
>> > Data = Buf;
>> > memcpy(Data, data, size);
>> > Size = size;
>> > Type = type;
>> > }
>> >
>> > intSize{};
>> > RTMemTypeType{};
>> > char*Data{};
>> > charBuf[256]{};
>> >
>> > };
>>
>> <snip>
>>
>> > static void *realtime_thread(void *arg)
>> > {
>> > struct timespec ts;
>> > int ret;
>> > RTMem buf;
>> > for (;;) {
>> > ret = recvfrom(s, &buf, sizeof(buf), 0, NULL, 0);
>> > if (ret <= 0)
>> >fail("recvfrom");
>> > printf(" => %s \n", buf.Data);
>>
>> <snip>
>>
>> >
>> > RTMem data("data1", 6, RTMEM_1);
>> > ret = write(fd, &data, sizeof(data));
>> > if (ret != sizeof(data))
>> > fail("write");
>> > memcpy(data.Data, "datadata", 9);
>> > data.Size = 9;
>> > data.Type = RTMEM_2;
>> > ret = write(fd, &data, sizeof(data));
>> > if (ret != sizeof(data))
>> > fail("write");
>>
>> This example code is broken, badly. Please consider what the reader
>> thread actually reads, which is definitely not a value, but a descriptor
>> containing a pointer to some value, which the writer thread will
>> overwrite before realtime_thread() runs. Which explains the outcome.
>>
>> At the very least, you should have a distinct RTMem instance to feed
>> each write() with. This said, since XDDP is by design an inter-stage,
>> inter-process IPC, passing process-private pointers in messages looks
>> wrong in the first place.
>
> I think it would also work if only the reader used buf.Buf rather than buf.Data, i. e.
>
> printf(" => %s \n", buf.Buf);
>
> since buf.Buf is copied and remains meaningful, unlike the pointer.
Agreed. I'm giving the original implementation the benefit of the doubt
assuming that such pointer would in fact mimic some kind of read cursor
on the receiver end in the actual application, unfortunately initialized
by the send site in the example.
--
Philippe.
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: data modified by second NRT write with same memory location
2023-08-02 8:56 ` Philippe Gerum
@ 2023-08-03 1:03 ` yo sang
0 siblings, 0 replies; 10+ messages in thread
From: yo sang @ 2023-08-03 1:03 UTC (permalink / raw)
To: Philippe Gerum; +Cc: xenomai@lists.linux.dev
Thank you again for the detailed explanation, it really help.
It's my mistake for using private pointer for XDDP. ^-^
-----Original Message-----
From: Philippe Gerum <rpm@xenomai.org>
Sent: Wednesday, August 2, 2023 4:57 PM
To: yo sang <stlfatboy@hotmail.com>
Cc: xenomai@lists.linux.dev
Subject: Re: data modified by second NRT write with same memory location
yo sang <stlfatboy@hotmail.com> writes:
> Thanks for the reply.
>
> I still have several doubts:
> 1. it's very common to delete data right after calling write(). Data should be completely copied to ensure a successful write() call.
>
Except that your code is simply not doing that. Please read it again. Hint: this implementation introduces sharing by mean of a pointer.
> 2. The fd opened for nrt is blocking by default. If I'm using un-blocking way of write(), it's reasonable to maintain several distinct RTMem instances at write end.
>
This is not the point in discussion. The issue is with the broken indirection the pointer adds.
> 3. If I modify the RTMem class as below, the result is correct then:
>
> class RTMem
> {
> public:
> RTMem() {}
>
> RTMem(const char* data, int size, RTMemType type) {
> //Data = Buf;
> memcpy(Data, data, size);
> Size = size;
> Type = type;
> }
>
> int Size{};
> RTMemType Type{};
> //char* Data{};
> char Data[256]{};
>
> };
Obviously it is, indeed.
--
Philippe.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2023-08-03 1:03 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <DM6PR14MB3871876E6E078D3BE974ADCBA30AA@DM6PR14MB3871.namprd14.prod.outlook.com>
2023-08-01 9:18 ` data modified by second NRT write with same memory location yo sang
2023-08-01 17:29 ` Philippe Gerum
2023-08-02 1:19 ` yo sang
2023-08-02 6:04 ` yo sang
2023-08-02 7:30 ` Philippe Gerum
2023-08-02 8:14 ` dietmar.schindler
2023-08-02 9:01 ` Philippe Gerum
2023-08-02 8:32 ` yo sang
2023-08-02 8:56 ` Philippe Gerum
2023-08-03 1:03 ` yo sang
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.