Project Home
Project Home
Documents
Documents
Wiki
Wiki
Discussion Forums
Discussions
Project Information
Project Info
Forum Topic - shared memory mapping question: (10 Items)
   
shared memory mapping question  
Hello,

I am running an ARM architecture and trying to use shared memory. I have read the docs on the 'special' cases for ARM 
(specifically ARM9) memory management.

What I would like to do, and I thought the docs indicated this was possible, was to have process #1 create some shared 
memory and map it using the following commands and flags.

fd = shm_open(fileNameArg, O_RDWR | O_CREAT | O_EXCL, 0777);
shm_ctl(fd, SHMCTL_ANON | SHMCTL_GLOBAL | SHMCTL_LOWERPROT, 0, sizeInBytes);

ptr = mmap( NULL, length, prot, flags, fd, offset)

My understanding is that the combination of SHMCTL_ANON | SHMCTL_GLOBAL | SHMCTL_LOWERPROT will place this memory in a 
'global' address pool that will be accessible by other processes

In other words, Can I just pass the 'ptr' to process #2 and have it be able to access the memory at that address without
 the need for process #2 to call mmap() ???

I have tried this in my system, and it doesn't seem to work, so maybe I am misunderstanding the docs.

The OS version is 6.4.0

Thanks for the help.
- Mike
Re: shared memory mapping question  
In what way doesn't this work?

The following (cheesy) program worked for me on an omap5912 (ARM926) board.
Compiling it to generate a 'shm' executable gave me the following output:

# shm &
57353 running shm
# ptr = 0x80100000
setting 0 to 0xdeadbeef
hanging around...

# shm 0x80000000
using ptr=80000000
read deadbeef
#

This is the source:

#include <sys/mman.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>

int
main(int argc, char *argv[])
{
         void    *ptr;
         int             fd;

         if (argc == 2) {
                 ptr = (void *)strtoul(argv[1], 0, 0);
                 printf("using ptr=%x\n", ptr);
                 printf("read %x\n", *(unsigned *)ptr);
                 exit(0);
         }

         fd = shm_open("/shmfile", O_CREAT|O_EXCL|O_RDWR, 0666);
         if (fd == -1) {
                 perror("shm_open");
                 exit(1);
         }
         shm_unlink("/shmfile");
         if (shm_ctl(fd, SHMCTL_ANON|SHMCTL_GLOBAL|SHMCTL_LOWERPROT, 0, 4096) == -1) {
                 perror("shm_ctl");
                 exit(1);
         }
         ptr = mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
         if (ptr == MAP_FAILED) {
                 perror("mmap");
                 exit(1);
         }
         printf("ptr = 0x%x\n", ptr);
         printf("setting %x to 0xdeadbeef\n", *(unsigned *)ptr);
         *(unsigned *)ptr = 0xdeadbeef;
         printf("hanging around...\n");
         while (1)
                 ;
         exit(0);
}

Michael Cranston wrote:
> Hello,
> 
> I am running an ARM architecture and trying to use shared memory. I have read the docs on the 'special' cases for ARM 
(specifically ARM9) memory management.
> 
> What I would like to do, and I thought the docs indicated this was possible, was to have process #1 create some shared
 memory and map it using the following commands and flags.
> 
> fd = shm_open(fileNameArg, O_RDWR | O_CREAT | O_EXCL, 0777);
> shm_ctl(fd, SHMCTL_ANON | SHMCTL_GLOBAL | SHMCTL_LOWERPROT, 0, sizeInBytes);
> 
> ptr = mmap( NULL, length, prot, flags, fd, offset)
> 
> My understanding is that the combination of SHMCTL_ANON | SHMCTL_GLOBAL | SHMCTL_LOWERPROT will place this memory in a
 'global' address pool that will be accessible by other processes
> 
> In other words, Can I just pass the 'ptr' to process #2 and have it be able to access the memory at that address 
without the need for process #2 to call mmap() ???
> 
> I have tried this in my system, and it doesn't seem to work, so maybe I am misunderstanding the docs.
> 
> The OS version is 6.4.0
> 
> Thanks for the help.
> - Mike
> 
> 
> _______________________________________________
> OSTech
> http://community.qnx.com/sf/go/post28982
> 
Re: shared memory mapping question  
Thanks for the response.

The problem I am having is that process #1 gets memory at 0x80100000.  I pass that address to process #2 and process #2 
throws some sort of segmentation fault when it attempts to write to the memory.

Question.  Why did you use 0x80000000 when the original ptr was 0x80000000?

Thanks,
- Mike
Re: shared memory mapping question  
Can you post your source?

The 0x80000000 value I passed is because that is the address returned by
the mmap in the first instance of the program. The second invocation takes
that pointer value and accesses it without having first done an mmap in
that process - ie. the memory object is globally visible without an mmap.

	Sunil.

Michael Cranston wrote:
> Thanks for the response.
> 
> The problem I am having is that process #1 gets memory at 0x80100000.  I pass that address to process #2 and process #
2 throws some sort of segmentation fault when it attempts to write to the memory.
> 
> Question.  Why did you use 0x80000000 when the original ptr was 0x80000000?
> 
> Thanks,
> - Mike
> 
> 
> _______________________________________________
> OSTech
> http://community.qnx.com/sf/go/post29011
> 
Re: shared memory mapping question  
Thanks again.

I didn't type that last question correctly.  What I wanted to ask was why the address passed to the second process was 
not exactly equal to the address returned by the first process.

0x80100000 for process #1
But you passed 0x80000000 to process #2

Why the difference?

Also, I assume that you cannot unmap the memory from the first process while accessing it in the second.
That would make it invalid memory again. Correct?

I can't post the source, but your example program is exactly what I am trying to do.

Thanks,
- Mike
Re: shared memory mapping question  
Oops - the output I sent you had run the shm process twice, so there were
actually 2 global mappings in place. This meant that the 0x80000000 was
the mapping in the first process.

After a clean boot:

shm &
49160 running shm
# ptr = 0x80000000
setting 0 to 0xdeadbeef
hanging around...

# shm 0x80000000
using ptr=80000000
read deadbeef

You are correct that you cannot unmap the memory and expect it to work.
The memmgr can unmap pages in a global region if there are no remaining
active mmap's of that address range.

If you are doing exactly what my program does, I don't understand why
your code is not working (ie. why it gets a sigsegv).

How big is your mapping?
What processor/board are you running on?

	Sunil.

Michael Cranston wrote:
> Thanks again.
> 
> I didn't type that last question correctly.  What I wanted to ask was why the address passed to the second process was
 not exactly equal to the address returned by the first process.
> 
> 0x80100000 for process #1
> But you passed 0x80000000 to process #2
> 
> Why the difference?
> 
> Also, I assume that you cannot unmap the memory from the first process while accessing it in the second.
> That would make it invalid memory again. Correct?
> 
> I can't post the source, but your example program is exactly what I am trying to do.
> 
> Thanks,
> - Mike
> 
> 
> _______________________________________________
> OSTech
> http://community.qnx.com/sf/go/post29031
> 
Re: shared memory mapping question  
Hi Sunil,

I am currently running this on an i.mx27 development board from Freescale.
The memory mappings are generally 1 to 4 Kbytes.  Some may be as large as 1Mbyte.

The code is written in C++, and the shared memory code used by both processes is in one library.
It originally mapped and unmapped as needed and the shared memory file name was passed between processes via messages.  
It is a client server type application.  I want to avoid the added delay of the map/unmap each time a server gets a 
message.

I suspect my issue is that I may have unmapped the memory somewhere in the process and did not catch that yet.  I will 
keep digging and let you know what I find.

One last question.  This should work the same way on x86 platforms, correct?  
I do some of my development on virtual machines running neutrino natively.

Thanks again,
- Mike



> Oops - the output I sent you had run the shm process twice, so there were
> actually 2 global mappings in place. This meant that the 0x80000000 was
> the mapping in the first process.
> 
> After a clean boot:
> 
> shm &
> 49160 running shm
> # ptr = 0x80000000
> setting 0 to 0xdeadbeef
> hanging around...
> 
> # shm 0x80000000
> using ptr=80000000
> read deadbeef
> 
> You are correct that you cannot unmap the memory and expect it to work.
> The memmgr can unmap pages in a global region if there are no remaining
> active mmap's of that address range.
> 
> If you are doing exactly what my program does, I don't understand why
> your code is not working (ie. why it gets a sigsegv).
> 
> How big is your mapping?
> What processor/board are you running on?
> 
> 	Sunil.
> 
> Michael Cranston wrote:
> > Thanks again.
> > 
> > I didn't type that last question correctly.  What I wanted to ask was why 
> the address passed to the second process was not exactly equal to the address 
> returned by the first process.
> > 
> > 0x80100000 for process #1
> > But you passed 0x80000000 to process #2
> > 
> > Why the difference?
> > 
> > Also, I assume that you cannot unmap the memory from the first process while
>  accessing it in the second.
> > That would make it invalid memory again. Correct?
> > 
> > I can't post the source, but your example program is exactly what I am 
> trying to do.
> > 
> > Thanks,
> > - Mike
> > 
> > 
> > _______________________________________________
> > OSTech
> > http://community.qnx.com/sf/go/post29031
> > 


Re: shared memory mapping question  
I am pretty sure that this doesn't work on X86.  The global address space thing, is (I think) unique to ARM...
Re: shared memory mapping question  
Can someone confirm? I also think it's only working on ARM9, no where else, because actually, it should NOT work at all.
.. ;-)


- Malte
Re: shared memory mapping question  
Thanks for all the help.

I ran the test app provided here and it does work on my i.mx27 ARM9.

It does not work on x86.

- Mike