Solved

mmap() disk file to shared memory

Posted on 1997-04-21
10
214 Views
Last Modified: 2013-12-26
I am trying to do the following in the Solaris environment.

Problem Statement
-----------------
My basic problem is that I would like to mmap() a disk file into *shared* memory. Or does this not make any sense at all?

Background
----------
I have been able to mmap() a disk file into memory.
I have been able to create a shared memory segment and attached/detached to it.
Now, what I would like is to mmap() the disk file into the shared memory segment I create in the previous step. I tried this by passing the address returned by the creation of the shared memory segment, to the mmap() call. But all mmap() did was to map the file in a memory location "close to" the shared memory segment.

Thanks in advance.
0
Comment
Question by:SatComm
  • 6
  • 4
10 Comments
 

Author Comment

by:SatComm
ID: 1292616
I meant to say that my environment was Solaris 2.5
0
 
LVL 2

Accepted Solution

by:
mlev earned 100 total points
ID: 1292617
The optional start address you specify as a parameter to mmap() call, is only a "hint". If you want mmap() to use the exact address, pass MAP_FIXED in the flags parameter.
On the other hand, you can pass NULL for start address and MAP_SHARED for flags. mmap() will then allocate memory on its own. You won't need to use either shmget() or shmat(). The memory
will be shared in the sense that if several processes call mmap() with start=NULL and flags=MAP_SHARED for the same file, they will all map to the same memory address. It will be different from the shared memory segments you create with shmget() in the sense that you cannot access it with a key or id.
Hope this helps.
0
 

Author Comment

by:SatComm
ID: 1292618
I liked the second approach and have gotten it to work.
Thanks for providing the missing link in my understanding of mmap()!

Unfortunately, I need to also use the first approach. When I changed the flags parameter to MAP_FIXED, and passed the address returned by shmat() to mmap() as the start address, mmap() fails with errno set to EINVAL. My offset parameter is still 0. Any hints on what could be going wrong? Could it be a page alignment problem? If you have some sample code handy, could you please provide that.

Thanks!
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
LVL 2

Expert Comment

by:mlev
ID: 1292619
In principle, page alignment could be a problem, but your
address comes from shmat() and is thus always page-aligned.
Your problem comes from invalid flags parameter.
Either MAP_PRIVATE or MAP_SHARED always has to be specified.
MAP_FIXED is an "add-on". That is, you have to use MAP_SHARED|MAP_FIXED.

Here is a sample program that works for me (Linux 2.0.18)

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/fcntl.h>
#include <sys/mman.h>

main()
{
        key_t key;
        int shmid;
        char *shmaddr;
        int fd;

        if ((key = ftok("/bin/cat", 'A')) == -1) { perror("ftok"); exit(1); }
        if ((shmid = shmget(key, 100000, IPC_CREAT|0600)) == -1) { perror("smget"); exit(1); }
        if ((shmaddr = shmat(shmid, NULL, 0)) == NULL) { perror("shmat"); exit(1); }

        if ((fd = open("shm.c", O_RDONLY)) == -1) { perror("open"); exit(1); }
        if (mmap(shmaddr, 500, PROT_READ, MAP_SHARED|MAP_FIXED, fd, 0) == -1) { perror("mmap"); exit(1); }
}

(I checked return values with strace.)

0
 

Author Comment

by:SatComm
ID: 1292620
Well, I got the "writer" side of things to work, i.e. if I can call the process that creates the shared memory and maps a file to that location as the writer, as you have indicated in your example above.

But now, another process, the "reader", needs to read that file in the shared memory created by the writer. I did an shmget() to get the shmId from the key (used by the writer); and then did an shmat(), using the  id. shmat() returns the same address as the start of the shared memory, but then I dont see the contents of the mapped file in the reader process! Am I missing something here?
0
 
LVL 2

Expert Comment

by:mlev
ID: 1292621
You have to use mmap() in both processes.
0
 

Author Comment

by:SatComm
ID: 1292622
If we use mmap() of the same file in the reader process also, then we are, in essence, back to the second option you had originally suggested, and I dont really need to use shmget() and shmat().
To use mmap() to map the *shared memory* to the specific location in the reader process, requires the shared memory file descriptor. shmget(), etc. dont return file descriptors, but rather IDs. Solaris 2.5 does not support the POSIX interface yet, i.e., shm_open() etc. that work with file descriptors...

I guess, at this point, I'm stuck.
0
 

Author Comment

by:SatComm
ID: 1292623
Any further suggestions???
0
 
LVL 2

Expert Comment

by:mlev
ID: 1292624
I don't think there is any way to use mmap() without opening the file in both processes.
You are right - there is no need to use shmget() and shmat() when you use mmap(). And shm_open() wouldn't help you, either. Below is the closest possible, to my understanding, analogy between shared memory segments and memory-mapped files:
shared memory segment <---> file
shmget()              <---> open()
shmid                 <---> fd
shmat()               <---> mmap()
shmdt()               <---> munmap()
N/A                   <---> close()
shmctl()              <---> fcntl()

You cannot map a file to a shared memory segment, same as you cannot map one file to another. The best you can do is make them share a common logical memory address in a process' paging space (which you did, with MAP_FIXED), but that doesn't help much.

Is there any special reason why you are reluctant to open the file in the second process?
0
 

Author Comment

by:SatComm
ID: 1292625
Thanks for your input.

The reason is that, I didn't want the second process to have to deal with files and filenames, but just memory and shared memory.  In our system, the files arrive on disk via FTP from a different location, and the files names might contain some type of timestamp for identification purposes. I wanted the first process to be the front end that opens the file, maps it to shared memory, makes some changes in memory, and then sends a notification to the second process to pick up the info from shared memory, and not worry about dynamically changing filenames, etc. Now, I could do other things to get around the name changes, I suppose, but I wanted to see if I could avoid that.

As a first step workaround, in my first process, after mapping the file to some other location in memory, I am doing a memcpy() into shared memory for the second process to be able to see the file...
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
sumNumber challenge 16 139
wordmultiple challenge 12 141
Problem to event 3 102
SQUD PROXY SERVER, UNIX, SLL/HTTPS 5 104
Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

860 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question