From: Lionel Perrin <perrin@domain.hid>
To: xenomai@xenomai.org
Subject: Re: [Xenomai-help] shm_open, ftruncate
Date: Fri, 09 Jun 2006 10:56:05 +0200 [thread overview]
Message-ID: <448937A5.7080701@domain.hid> (raw)
In-Reply-To: <17542.59422.109900.142889@domain.hid>
[-- 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;
}
next prev parent reply other threads:[~2006-06-09 8:56 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=448937A5.7080701@domain.hid \
--to=perrin@domain.hid \
--cc=xenomai@xenomai.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.