* [Xenomai-help] shm_open, ftruncate
@ 2006-06-02 15:29 Lionel Perrin
2006-06-02 16:29 ` Gilles Chanteperdrix
2006-06-02 17:17 ` Gilles Chanteperdrix
0 siblings, 2 replies; 14+ messages in thread
From: Lionel Perrin @ 2006-06-02 15:29 UTC (permalink / raw)
To: xenomai
Hi,
I got some problems with shared memory.
I started from the shm_open example from opengroup.org.
When I compile it as non real time tasks, it works properly. But since I
tried to compile it with
gcc $(xeno-config --posix-cflags) shm_open.c $(xeno-config
--posix-ldflags) -o xeno_shm_open,
i get an EINVAL error from ftruncate that i can fix.
Does shm under xenomai require particular things ?
Thanks for your help...
Lionel
#include <unistd.h>
#include <sys/mman.h>
...
#define MAX_LEN 10000
struct region { /* Defines "structure" of shared memory */
int len;
char buf[MAX_LEN];
};
struct region *rptr;
int fd;
/* Create shared memory object and set its size */
fd = shm_open("/myregion", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (fd == -1)
/* Handle error */;
if (ftruncate(fd, sizeof(struct region)) == -1)
/* Handle error */;
/* Map shared memory object */
rptr = mmap(NULL, sizeof(struct region),
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (rptr == MAP_FAILED)
/* Handle error */;
/* Now we can refer to mapped region using fields of rptr;
for example, rptr->len */
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Xenomai-help] shm_open, ftruncate
2006-06-02 15:29 [Xenomai-help] shm_open, ftruncate Lionel Perrin
@ 2006-06-02 16:29 ` Gilles Chanteperdrix
2006-06-02 17:17 ` Gilles Chanteperdrix
1 sibling, 0 replies; 14+ messages in thread
From: Gilles Chanteperdrix @ 2006-06-02 16:29 UTC (permalink / raw)
To: Lionel Perrin; +Cc: xenomai
Lionel Perrin wrote:
> Hi,
>
> I got some problems with shared memory.
> I started from the shm_open example from opengroup.org.
> When I compile it as non real time tasks, it works properly. But since I
> tried to compile it with
> gcc $(xeno-config --posix-cflags) shm_open.c $(xeno-config
> --posix-ldflags) -o xeno_shm_open,
> i get an EINVAL error from ftruncate that i can fix.
>
> Does shm under xenomai require particular things ?
The posix skin does not use the new per-process cleanup callback yet, so
you have to clean yourself the mappings, i.e. do not forget to call
munmap before exiting your processes, or unload and reload the POSIX
skin module before running your program.
I tried your program and it did not fail here as it fails for you: mmap
is returning an error of ENXIO, because of some bug that I am currently
fixing.
--
Gilles Chanteperdrix.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Xenomai-help] shm_open, ftruncate
2006-06-02 15:29 [Xenomai-help] shm_open, ftruncate Lionel Perrin
2006-06-02 16:29 ` Gilles Chanteperdrix
@ 2006-06-02 17:17 ` Gilles Chanteperdrix
2006-06-05 13:49 ` Lionel Perrin
1 sibling, 1 reply; 14+ messages in thread
From: Gilles Chanteperdrix @ 2006-06-02 17:17 UTC (permalink / raw)
To: Lionel Perrin; +Cc: xenomai
[-- Attachment #1: message body and .signature --]
[-- Type: text/plain, Size: 645 bytes --]
Lionel Perrin wrote:
> Hi,
>
> I got some problems with shared memory.
> I started from the shm_open example from opengroup.org.
> When I compile it as non real time tasks, it works properly. But since I
> tried to compile it with
> gcc $(xeno-config --posix-cflags) shm_open.c $(xeno-config
> --posix-ldflags) -o xeno_shm_open,
> i get an EINVAL error from ftruncate that i can fix.
>
> Does shm under xenomai require particular things ?
When applying the attached patch to xenomai (do not forget to rebuild
the kernel), the attached program compiled with the attached Makefile
works here.
--
Gilles Chanteperdrix.
[-- Attachment #2: xeno-posix-shm.diff --]
[-- Type: text/plain, Size: 515 bytes --]
Index: ksrc/skins/posix/shm.c
===================================================================
--- ksrc/skins/posix/shm.c (revision 1143)
+++ ksrc/skins/posix/shm.c (working copy)
@@ -516,10 +516,8 @@
is aligned). */
if (len)
{
- len += PAGE_SIZE + xnheap_overhead(len, PAGE_SIZE);
+ len += PAGE_SIZE + PAGE_ALIGN(xnheap_overhead(len, PAGE_SIZE));
len = PAGE_ALIGN(len);
- if (len == 2 * PAGE_SIZE)
- len = 3 * PAGE_SIZE;
}
err = 0;
[-- Attachment #3: test_shm.c --]
[-- Type: text/plain, Size: 1479 bytes --]
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#define MAX_LEN 10000
struct region { /* Defines "structure" of shared memory */
int len;
char buf[MAX_LEN];
};
struct region *rptr;
int fd;
int main(int argc, const char *argv[])
{
int fd, status;
mlockall(MCL_CURRENT|MCL_FUTURE);
/* Create shared memory object and set its size */
fd = shm_open("/myregion", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (fd == -1) {
perror("shm_open");
exit(EXIT_FAILURE);
}
if ((status = ftruncate(fd, sizeof(struct region))) == -1) {
/* Handle error */;
perror("ftruncate");
close(fd);
status = EXIT_FAILURE;
goto close_and_unlink;
}
/* Map shared memory object */
rptr = (struct region *) mmap(NULL,
sizeof(struct region),
PROT_READ | PROT_WRITE,
MAP_SHARED,
fd,
0);
if (rptr == MAP_FAILED) {
/* Handle error */;
perror("mmap");
status = EXIT_FAILURE;
goto close_and_unlink;
}
/* Now we can refer to mapped region using fields of rptr;
for example, rptr->len */
munmap(rptr, sizeof(struct region));
close_and_unlink:
close(fd);
shm_unlink("/myregion");
return status;
}
[-- Attachment #4: Makefile --]
[-- Type: text/plain, Size: 400 bytes --]
DESTDIR=/home/gilles/files/perso/dev/build/nestor/inst
XENO_CONFIG=$(DESTDIR)/usr/xenomai/bin/xeno-config
CFLAGS:=$(shell DESTDIR=$(DESTDIR) $(XENO_CONFIG) --posix-cflags) -g -O2 -Wall -W -Werror-implicit-function-declaration
LDFLAGS:=$(shell DESTDIR=$(DESTDIR) $(XENO_CONFIG) --posix-ldflags)
LOADLIBES=-lpthread_rt
all: test_shm
test_shm: test_shm.o
clean:
$(RM) foo foo.o test_shm.o test_shm
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Xenomai-help] shm_open, ftruncate
2006-06-02 17:17 ` Gilles Chanteperdrix
@ 2006-06-05 13:49 ` Lionel Perrin
2006-06-05 15:55 ` Gilles Chanteperdrix
0 siblings, 1 reply; 14+ messages in thread
From: Lionel Perrin @ 2006-06-05 13:49 UTC (permalink / raw)
To: xenomai
Ok, thanks, i'll try. My old pc will have some job... :)
I still have a few questions :
- How can we load/unload posix skin ?
- Will this shared memory be accessible to non rt-task ?
- What's the simplest way to share information with a non rt-task ?
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Xenomai-help] shm_open, ftruncate
2006-06-05 13:49 ` Lionel Perrin
@ 2006-06-05 15:55 ` Gilles Chanteperdrix
2006-06-06 11:53 ` Lionel Perrin
0 siblings, 1 reply; 14+ messages in thread
From: Gilles Chanteperdrix @ 2006-06-05 15:55 UTC (permalink / raw)
To: Lionel Perrin; +Cc: xenomai
Lionel Perrin wrote:
> Ok, thanks, i'll try. My old pc will have some job... :)
>
> I still have a few questions :
> - How can we load/unload posix skin ?
When configuring your kernel, configure the posix skin as a module. A
module xeno_posix.ko will then be compiled that you may load with
modprobe and unload with modprobe -r.
> - Will this shared memory be accessible to non rt-task ?
> - What's the simplest way to share information with a non rt-task ?
Shared memory are also accessible to non-rt tasks. Since user-space
realtime and non-realtime threads from the same process reside in the
same address space, the simplest way to share information from rt to
non-rt tasks is to create them as threads of the same process.
--
Gilles Chanteperdrix.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Xenomai-help] shm_open, ftruncate
2006-06-05 15:55 ` Gilles Chanteperdrix
@ 2006-06-06 11:53 ` Lionel Perrin
2006-06-06 12:21 ` Gilles Chanteperdrix
2006-06-06 18:08 ` Gilles Chanteperdrix
0 siblings, 2 replies; 14+ messages in thread
From: Lionel Perrin @ 2006-06-06 11:53 UTC (permalink / raw)
Cc: xenomai
[-- Attachment #1: Type: text/plain, Size: 916 bytes --]
> > - Will this shared memory be accessible to non rt-task ?
> > - What's the simplest way to share information with a non rt-task ?
>
> Shared memory are also accessible to non-rt tasks. Since user-space
> realtime and non-realtime threads from the same process reside in the
> same address space, the simplest way to share information from rt to
> non-rt tasks is to create them as threads of the same process.
>
Ok, but I figure out that it's possible to share memory between
processes ? (rt and non rt?)
For the moment, i focus on sharing between two rt tasks, but in vain :(
I still have a ftruncate error (EBADF) when i launch two rt processes...
I explain :
I've tried the attached program. I've added a sleep(1) between mmap and
munmap. I launch this appli twice with
>> shm_test &
>> shm_test &
For the second one, I got "ftruncate: Invalid argument". Am I the only
one to have this problem ?
[-- Attachment #2: test_shm.c --]
[-- Type: text/plain, Size: 1513 bytes --]
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#define MAX_LEN 10000
struct region { /* Defines "structure" of shared memory */
int len;
char buf[MAX_LEN];
};
struct region *rptr;
int fd;
int main(int argc, const char *argv[])
{
int fd, status;
mlockall(MCL_CURRENT|MCL_FUTURE);
/* Create shared memory object and set its size */
fd = shm_open("/myregion", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (fd == -1) {
perror("shm_open");
exit(EXIT_FAILURE);
}
if ((status = ftruncate(fd, sizeof(struct region))) == -1) {
/* Handle error */;
perror("ftruncate");
close(fd);
status = EXIT_FAILURE;
goto close_and_unlink;
}
/* Map shared memory object */
rptr = (struct region *) mmap(NULL,
sizeof(struct region),
PROT_READ | PROT_WRITE,
MAP_SHARED,
fd,
0);
if (rptr == MAP_FAILED) {
/* Handle error */;
perror("mmap");
status = EXIT_FAILURE;
goto close_and_unlink;
}
/* Now we can refer to mapped region using fields of rptr;
for example, rptr->len */
sleep(1);
munmap(rptr, sizeof(struct region));
close_and_unlink:
close(fd);
shm_unlink("/myregion");
return status;
}
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Xenomai-help] shm_open, ftruncate
2006-06-06 11:53 ` Lionel Perrin
@ 2006-06-06 12:21 ` Gilles Chanteperdrix
[not found] ` <44859C28.3090600@domain.hid>
2006-06-06 18:08 ` Gilles Chanteperdrix
1 sibling, 1 reply; 14+ messages in thread
From: Gilles Chanteperdrix @ 2006-06-06 12:21 UTC (permalink / raw)
To: Lionel Perrin; +Cc: xenomai
Lionel Perrin wrote:
>
> > > - Will this shared memory be accessible to non rt-task ?
> > > - What's the simplest way to share information with a non rt-task ?
> >
> > Shared memory are also accessible to non-rt tasks. Since user-space
> > realtime and non-realtime threads from the same process reside in the
> > same address space, the simplest way to share information from rt to
> > non-rt tasks is to create them as threads of the same process.
> >
> Ok, but I figure out that it's possible to share memory between
> processes ? (rt and non rt?)
> For the moment, i focus on sharing between two rt tasks, but in vain :(
> I still have a ftruncate error (EBADF) when i launch two rt processes...
> I explain :
> I've tried the attached program. I've added a sleep(1) between mmap and
> munmap. I launch this appli twice with
> >> shm_test &
> >> shm_test &
> For the second one, I got "ftruncate: Invalid argument". Am I the only
> one to have this problem ?
Using trunk, your example run fine. Which version of Xenomai are you
using ? If not trunk, did you apply the patch I sent ?
--
Gilles Chanteperdrix.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Xenomai-help] shm_open, ftruncate
2006-06-06 11:53 ` Lionel Perrin
2006-06-06 12:21 ` Gilles Chanteperdrix
@ 2006-06-06 18:08 ` Gilles Chanteperdrix
1 sibling, 0 replies; 14+ messages in thread
From: Gilles Chanteperdrix @ 2006-06-06 18:08 UTC (permalink / raw)
To: Lionel Perrin; +Cc: xenomai
Lionel Perrin wrote:
>
> > > - Will this shared memory be accessible to non rt-task ?
> > > - What's the simplest way to share information with a non rt-task ?
> >
> > Shared memory are also accessible to non-rt tasks. Since user-space
> > realtime and non-realtime threads from the same process reside in the
> > same address space, the simplest way to share information from rt to
> > non-rt tasks is to create them as threads of the same process.
> >
> Ok, but I figure out that it's possible to share memory between
> processes ? (rt and non rt?)
> For the moment, i focus on sharing between two rt tasks, but in vain :(
> I still have a ftruncate error (EBADF) when i launch two rt processes...
> I explain :
> I've tried the attached program. I've added a sleep(1) between mmap and
> munmap. I launch this appli twice with
> >> shm_test &
> >> shm_test &
> For the second one, I got "ftruncate: Invalid argument". Am I the only
> one to have this problem ?
No, these errors were due to a few fixes in trunk that had not been
backported to the 2.1 branch. It should now be fixed in the repository.
--
Gilles Chanteperdrix.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Xenomai-help] shm_open, ftruncate
[not found] ` <17541.49945.431732.834139@domain.hid>
@ 2006-06-07 12:55 ` Lionel Perrin
2006-06-07 14:52 ` Gilles Chanteperdrix
0 siblings, 1 reply; 14+ messages in thread
From: Lionel Perrin @ 2006-06-07 12:55 UTC (permalink / raw)
To: xenomai
> I can confirm that a few fixes in v2.1 were missing, so trunk works
> correctly, didn't you forget to rebuild the kernel when building trunk ?
> Attached is a patch to v2.1 that contain the fixes backported from
> trunk. Please try this patch and tell me if this works for you.
>
In fact, I've downloaded the last version of trunk before your mail and
the patch. You're right that works pretty good with this version... :)
Unfortunately, it seem's that we can't share between a real time process
and a non real one ?
I got one task which need to be real time in order to acquire datas, and
another one that plot this datas on screen.
I'd like to give user the choice to launch (or not) the second process,
if he wish (or not) to watch the acquired datas. I'm figure out that
making this second process a xenomai thread with a low priority would
solve my problem but i'd rather prefered a standard linux process...
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Xenomai-help] shm_open, ftruncate
2006-06-07 12:55 ` Lionel Perrin
@ 2006-06-07 14:52 ` Gilles Chanteperdrix
2006-06-09 8:56 ` Lionel Perrin
0 siblings, 1 reply; 14+ messages in thread
From: Gilles Chanteperdrix @ 2006-06-07 14:52 UTC (permalink / raw)
To: Lionel Perrin; +Cc: xenomai
Lionel Perrin wrote:
>
> > I can confirm that a few fixes in v2.1 were missing, so trunk works
> > correctly, didn't you forget to rebuild the kernel when building trunk ?
> > Attached is a patch to v2.1 that contain the fixes backported from
> > trunk. Please try this patch and tell me if this works for you.
> >
> In fact, I've downloaded the last version of trunk before your mail and
> the patch. You're right that works pretty good with this version... :)
>
> Unfortunately, it seem's that we can't share between a real time process
> and a non real one ?
Sharing memory should work, could you explain what happens ? Note that
you may use Linux regular shared memory services in the real-time
process by calling __real_shm_open instead of shm_open.
> I got one task which need to be real time in order to acquire datas, and
> another one that plot this datas on screen.
> I'd like to give user the choice to launch (or not) the second process,
> if he wish (or not) to watch the acquired datas. I'm figure out that
> making this second process a xenomai thread with a low priority would
> solve my problem but i'd rather prefered a standard linux process...
Using Xenomai thread with a low priority would allow you to share
synchronization objects between the real-time and non real-time
activites. You may also create non real-time threads in a
real-time process by calling __real_pthread_create instead of
pthread_create.
--
Gilles Chanteperdrix.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Xenomai-help] shm_open, ftruncate
2006-06-07 14:52 ` Gilles Chanteperdrix
@ 2006-06-09 8:56 ` Lionel Perrin
2006-06-09 11:46 ` Gilles Chanteperdrix
2006-06-09 12:28 ` Gilles Chanteperdrix
0 siblings, 2 replies; 14+ messages in thread
From: Lionel Perrin @ 2006-06-09 8:56 UTC (permalink / raw)
To: xenomai
[-- Attachment #1: Type: text/plain, Size: 1343 bytes --]
> > > I can confirm that a few fixes in v2.1 were missing, so trunk works
> > > correctly, didn't you forget to rebuild the kernel when building trunk ?
> > > Attached is a patch to v2.1 that contain the fixes backported from
> > > trunk. Please try this patch and tell me if this works for you.
> > >
> > In fact, I've downloaded the last version of trunk before your mail and
> > the patch. You're right that works pretty good with this version... :)
> >
> > Unfortunately, it seem's that we can't share between a real time process
> > and a non real one ?
>
> Sharing memory should work, could you explain what happens ? Note that
> you may use Linux regular shared memory services in the real-time
> process by calling __real_shm_open instead of shm_open.
>
Ok,
But I'd like a real time behaviour of shared memory for my real time
task... so I can't use __real_shm_open, etc...
Here is the little code I've developped to access shared memory. May be
there some mistakes...
I compile it with or without xeno-config --posix-cflags, xeno-config
--posix-ldflags to get two executables.
I launch these two executables and the shared_memory seem's to be
different in these two cases.
All Xenomai processes are accessing the same shared_memory while all
non-xenomai processes are accessing another one shared memory.
[-- Attachment #2: rtsharedmem.c --]
[-- Type: text/plain, Size: 5070 bytes --]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <pthread.h>
#include <errno.h>
#include "rtsharedmem.h"
/* **********************************************************************
* Creates a shared memory object protected by a mutex *
* This object is referenced throw its name. If there's no *
* shared memory object with the given name, a new one is created, *
* otherwise, we get an access to the existing shared memory object. *
************************************************************************/
MemMap* RtOpenSharedMem(unsigned int nbvalues, const char * name) {
int shm_exists;
int h_shm;
MemMap* mem;
void * ptr;
int * nbaccess;
char *name_shm;
name_shm = (char *)malloc((strlen(name)+6)*sizeof(char));
mem = (MemMap *)malloc(sizeof(MemMap));
shm_exists = 0;
strcpy(name_shm, name);
sprintf(name_shm, "/%s_shm", name);
/* Here is the clean version to open shm, but for the moment, this doesn't work with xenomai.*/
h_shm = shm_open( name_shm, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH);
if (h_shm < 0)
{
if (errno == EEXIST)
{
/* shm_open has just warned that shm already exists */
/* we shouldn't need O_CREAT here but xenomain failed without */
h_shm = shm_open( name_shm, O_RDWR| O_CREAT, S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH);
if (h_shm<0)
{
printf("shm_open failed to open existing shared mem : %s\n", name_shm);
return NULL;
}
shm_exists = 1;
}
else
{
/* shm_open really failed */
printf("shm_open failed to open %s\n", name_shm);
return NULL;
}
}
// /* the following lines shouldn't be commented but xenomai... */
// else
// {
// /* a new shm_file has been created, we need to truncate it */
// if (ftruncate(h_shm, nbvalues * sizeof(double))==-1)
// {
// printf("truncate failed\n");
// goto close_and_unlink;
// }
// }
if (ftruncate(h_shm, nbvalues * sizeof(double))==-1)
{
printf("truncate failed\n");
goto close_and_unlink;
}
ptr = mmap(NULL, sizeof(int) + nbvalues * sizeof(double), PROT_READ | PROT_WRITE, MAP_SHARED, h_shm, 0);
if( ptr == MAP_FAILED) {
printf("mmap failed\n");
goto close_and_unlink;
}
mem->h_mut = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
pthread_mutex_init(mem->h_mut, NULL);
/* the first sizeof(int) bytes at ptr are reserved to count the number of access to shared mem
in order to be able to unlink cleanly */
nbaccess = (int *)ptr;
if (shm_exists)
*nbaccess = (*nbaccess)+1;
else
*nbaccess = 1;
/* the real data starts at ptr + sizeof(int) */
mem->ptr = (double *)(ptr + sizeof(int));
mem->h_shm = h_shm;
mem->nbvalues = nbvalues;
mem->name_shm = name_shm;
return mem;
close_and_unlink:
close(h_shm);
if (shm_exists==0)
shm_unlink(name_shm);
free(name_shm);
free(mem);
return NULL;
}
/****************************************************************
* Write datas to the shared memory after getting the mutex*
****************************************************************/
int RtWriteSharedMem(MemMap * shared_mem, const double * data) {
if(pthread_mutex_lock(shared_mem->h_mut)!=0)
return -1;
memcpy(shared_mem->ptr, data, shared_mem->nbvalues * (sizeof(double)) );
if (pthread_mutex_unlock(shared_mem->h_mut)!=0)
return -1;
return 0;
}
/****************************************************************
* Read datas from the shared memory and copy it to data *
****************************************************************/
int RtReadSharedMem(double * data, const MemMap * shared_mem) {
if(pthread_mutex_lock(shared_mem->h_mut)!=0)
return -1;
memcpy(data, shared_mem->ptr, shared_mem->nbvalues * (sizeof(double)) );
if (pthread_mutex_unlock(shared_mem->h_mut)!=0)
return -1;
return 0;
}
/****************************************************************
* Close shared memory : no further access can't be done. *
* Memory allocated in RtOpenSharedMem is freed. *
****************************************************************/
int RtCloseSharedMem(MemMap * shared_mem) {
void *ptr;
int *ptr_nbaccess;
int int_nbaccess;
if (shared_mem == NULL)
return -1;
if (pthread_mutex_lock(shared_mem->h_mut)!=0)
return -1;
/* the sizeof(int) bytes before shared_mem->ptr count the number of access to shared memory */
ptr = shared_mem->ptr - sizeof(int);
ptr_nbaccess = (int *)ptr;
*ptr_nbaccess = *ptr_nbaccess - 1;
int_nbaccess = *ptr_nbaccess;
// printf("number of access %d\n", int_nbaccess);
if (munmap(ptr, sizeof(int) + shared_mem->nbvalues * sizeof(double))!=0)
return -1;
if (close(shared_mem->h_shm)!=0)
return -1;
if (pthread_mutex_unlock(shared_mem->h_mut)!=0)
return -1;
if (pthread_mutex_destroy(shared_mem->h_mut)!=0)
return -1;
if (int_nbaccess == 0) /* that was the last process to access this shared mem */
shm_unlink(shared_mem->name_shm);
free(shared_mem->name_shm);
free(shared_mem);
shared_mem = NULL;
return 0;
}
[-- Attachment #3: rtsharedmem.h --]
[-- Type: text/plain, Size: 481 bytes --]
#ifndef __RTSHAREDMEM_H__
#define __RTSHAREDMEM_H__
#include <pthread.h>
typedef struct {
void *ptr;
int h_shm;
pthread_mutex_t *h_mut;
char * name_shm;
char * name_mut;
unsigned int nbvalues;
} MemMap;
MemMap* RtOpenSharedMem(unsigned int nbvalues, const char * name);
int RtWriteSharedMem(MemMap * shared_mem, const double * data);
int RtReadSharedMem(double * data, const MemMap * shared_mem);
int RtCloseSharedMem(MemMap * shared_mem);
#endif // __RTSHAREDMEM_H__
[-- Attachment #4: test_rtsharedmem.c --]
[-- Type: text/plain, Size: 1662 bytes --]
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/mman.h>
#include "rttimer.h"
#include "rtsharedmem.h"
#define NANOCOEF 0.000000001
int RtSetAsPriorityTask()
{
struct sched_param mysched;
mlockall(MCL_CURRENT | MCL_FUTURE);
mysched.sched_priority = sched_get_priority_max(SCHED_FIFO) - 1;
pthread_setschedparam( pthread_self(), SCHED_FIFO, &mysched);
return 0;
}
void RtWaitFor(double time) {
struct timespec rqtp, rmtp;
rqtp.tv_sec = (time_t)time;
rqtp.tv_nsec = (long) ( ( time - (double)(rqtp.tv_sec) ) / NANOCOEF );
nanosleep(&rqtp, &rmtp);
}
int main(int argc, char * argv[])
{
MemMap *mem;
double *data, *val;
RtSetAsPriorityTask();
data = (double *)calloc(1, sizeof(double));
val = (double *)malloc(sizeof(double));
if (argc==1)
*val = 1.0;
else
*val = atof(argv[1]);
//printf("EACCES %d, EFAULT %d, EFBIG %d, EINTR %d, EINVAL %d, EIO %d, EISDIR %d, ELOOP %d, ENAMETOOLONG %d, ENOENT %d, ENOTDIR %d, EROFS %d, ETXTBSY %d, EBADF %d\n", EACCES, EFAULT, EFBIG, EINTR, EINVAL, EIO, EISDIR, ELOOP, ENAMETOOLONG, ENOENT, ENOTDIR, EROFS, ETXTBSY, EBADF);
mem = RtOpenSharedMem(1, "shared1");
if (mem == NULL)
{
printf("ERRNO %d\n", errno);
perror("RtOpenSharedMem");
return -1;
}
printf("data written\t%lf\n", ((double *)(val))[0]);
fflush(stdout);
if (RtWriteSharedMem(mem, (double *)val)<0)
{
perror("RtWriteSharedMem");
return -1;
}
RtWaitFor(1.0);
if (RtReadSharedMem(data, mem)<0)
{
perror("RtReadSharedMem");
return -1;
}
printf("data read\t%lf\n", data[0]);
fflush(stdout);
if (RtCloseSharedMem(mem)<0)
{
perror("RtCloseSharedMem");
return -1;
}
return 0;
}
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Xenomai-help] shm_open, ftruncate
2006-06-09 8:56 ` Lionel Perrin
@ 2006-06-09 11:46 ` Gilles Chanteperdrix
2006-06-09 12:28 ` Gilles Chanteperdrix
1 sibling, 0 replies; 14+ messages in thread
From: Gilles Chanteperdrix @ 2006-06-09 11:46 UTC (permalink / raw)
To: Lionel Perrin; +Cc: xenomai
Lionel Perrin wrote:
>
> > > > I can confirm that a few fixes in v2.1 were missing, so trunk works
> > > > correctly, didn't you forget to rebuild the kernel when building trunk ?
> > > > Attached is a patch to v2.1 that contain the fixes backported from
> > > > trunk. Please try this patch and tell me if this works for you.
> > > >
> > > In fact, I've downloaded the last version of trunk before your mail and
> > > the patch. You're right that works pretty good with this version... :)
> > >
> > > Unfortunately, it seem's that we can't share between a real time process
> > > and a non real one ?
> >
> > Sharing memory should work, could you explain what happens ? Note that
> > you may use Linux regular shared memory services in the real-time
> > process by calling __real_shm_open instead of shm_open.
> >
> Ok,
> But I'd like a real time behaviour of shared memory for my real time
> task... so I can't use __real_shm_open, etc...
>
> Here is the little code I've developped to access shared memory. May be
> there some mistakes...
> I compile it with or without xeno-config --posix-cflags, xeno-config
> --posix-ldflags to get two executables.
> I launch these two executables and the shared_memory seem's to be
> different in these two cases.
> All Xenomai processes are accessing the same shared_memory while all
> non-xenomai processes are accessing another one shared memory.
That is the expected behaviour: xenomai posix skin shared memory is
different from Linux regular shared memory. In the same vein, xenomai
posix skin semaphores are different from Linux regular semaphores.
But there is no problem using Linux regular shared memory in a real-time
thread, providing that you call mlockall. Using a Linux regular
semaphore in a real-time thread is also possible by using
__real_sem_post or __real_sem_wait, but the real-time
thread will migrate to secondary mode.
The alternative is to compile the two processes with the flags given by
xeno-config, and to create non real-time threads in one process using
__real_pthread_create.
--
Gilles Chanteperdrix.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Xenomai-help] shm_open, ftruncate
2006-06-09 8:56 ` Lionel Perrin
2006-06-09 11:46 ` Gilles Chanteperdrix
@ 2006-06-09 12:28 ` Gilles Chanteperdrix
2006-06-09 13:18 ` Lionel Perrin
1 sibling, 1 reply; 14+ messages in thread
From: Gilles Chanteperdrix @ 2006-06-09 12:28 UTC (permalink / raw)
To: Lionel Perrin; +Cc: xenomai
Lionel Perrin wrote:
> // /* the following lines shouldn't be commented but xenomai... */
> // else
> // {
> // /* a new shm_file has been created, we need to truncate it */
> // if (ftruncate(h_shm, nbvalues * sizeof(double))==-1)
> // {
> // printf("truncate failed\n");
> // goto close_and_unlink;
> // }
> // }
Do you still have an issue with ftruncate ?
Note that it is better to always call ftruncate even in a process that
is not creating the shared memory, this avoid the race condition where
the process that created the shared memory is about to truncate it and
is interrupted by the second process which did not create it but want to
mmap it.
> mem->h_mut = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
> pthread_mutex_init(mem->h_mut, NULL);
Note that if you want to share the mem structure between several
processes, you should put the mutex on the shared memory, doing for
example:
typedef struct {
pthread_mutex_t mutex;
int nbaccess;
double values[0]
} myshm_t;
myshm_t *myshm;
myshm = (myshm_t *) mmap(...);
mem->h_mut = &myshm->mutex;
mem->ptr = &myshm->values;
pthread_mutex_init(mem->h_mut, NULL);
Xenomai should detect that you are initializing a mutex that was already
initialized and return EBUSY that you can safely ignore.
--
Gilles Chanteperdrix.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Xenomai-help] shm_open, ftruncate
2006-06-09 12:28 ` Gilles Chanteperdrix
@ 2006-06-09 13:18 ` Lionel Perrin
0 siblings, 0 replies; 14+ messages in thread
From: Lionel Perrin @ 2006-06-09 13:18 UTC (permalink / raw)
Cc: xenomai
Gilles Chanteperdrix a écrit :
> Lionel Perrin wrote:
> > // /* the following lines shouldn't be commented but xenomai... */
> > // else
> > // {
> > // /* a new shm_file has been created, we need to truncate it */
> > // if (ftruncate(h_shm, nbvalues * sizeof(double))==-1)
> > // {
> > // printf("truncate failed\n");
> > // goto close_and_unlink;
> > // }
> > // }
>
> Do you still have an issue with ftruncate ?
>
> Note that it is better to always call ftruncate even in a process that
> is not creating the shared memory, this avoid the race condition where
> the process that created the shared memory is about to truncate it and
> is interrupted by the second process which did not create it but want to
> mmap it.
>
> > mem->h_mut = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
> > pthread_mutex_init(mem->h_mut, NULL);
>
>
> Note that if you want to share the mem structure between several
> processes, you should put the mutex on the shared memory, doing for
> example:
>
> typedef struct {
> pthread_mutex_t mutex;
> int nbaccess;
> double values[0]
> } myshm_t;
>
> myshm_t *myshm;
>
> myshm = (myshm_t *) mmap(...);
>
> mem->h_mut = &myshm->mutex;
> mem->ptr = &myshm->values;
>
> pthread_mutex_init(mem->h_mut, NULL);
>
> Xenomai should detect that you are initializing a mutex that was already
> initialized and return EBUSY that you can safely ignore.
>
Thanks for your help, all work as i wish now...
You're right, i've done a terrible mistake with the mutex... I'm a bit
ashamed ;)
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2006-06-09 13:18 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-06-02 15:29 [Xenomai-help] shm_open, ftruncate Lionel Perrin
2006-06-02 16:29 ` Gilles Chanteperdrix
2006-06-02 17:17 ` Gilles Chanteperdrix
2006-06-05 13:49 ` Lionel Perrin
2006-06-05 15:55 ` Gilles Chanteperdrix
2006-06-06 11:53 ` Lionel Perrin
2006-06-06 12:21 ` Gilles Chanteperdrix
[not found] ` <44859C28.3090600@domain.hid>
[not found] ` <17541.49945.431732.834139@domain.hid>
2006-06-07 12:55 ` Lionel Perrin
2006-06-07 14:52 ` Gilles Chanteperdrix
2006-06-09 8:56 ` Lionel Perrin
2006-06-09 11:46 ` Gilles Chanteperdrix
2006-06-09 12:28 ` Gilles Chanteperdrix
2006-06-09 13:18 ` Lionel Perrin
2006-06-06 18:08 ` Gilles Chanteperdrix
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.