Solved

mmap() disk file to shared memory

Posted on 1997-04-21
10
209 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
Comment Utility
I meant to say that my environment was Solaris 2.5
0
 
LVL 2

Accepted Solution

by:
mlev earned 100 total points
Comment Utility
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
Comment Utility
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
 
LVL 2

Expert Comment

by:mlev
Comment Utility
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
Comment Utility
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
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 2

Expert Comment

by:mlev
Comment Utility
You have to use mmap() in both processes.
0
 

Author Comment

by:SatComm
Comment Utility
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
Comment Utility
Any further suggestions???
0
 
LVL 2

Expert Comment

by:mlev
Comment Utility
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
Comment Utility
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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

This is to be the first in a series of articles demonstrating the development of a complete windows based application using the MFC classes.  I’ll try to keep each article focused on one (or a couple) of the tasks that one may meet.   Introductio…
Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
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.
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

771 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now