TOC PREV NEXT INDEX

POSIX 1.b Migration Guide


Shared Memory

Introduction

The mmap() function is fundamental to the POSIX.1b changes in the shared memory system. Additional changes affect the way shared memory object sizes are specified upon creation. The mmap() function from POSIX.1b is not specific to shared memory objects. With its full features, it is a powerful function allowing files and devices to be mapped into process address space.

Also, there are persistence-related differences between the Draft 9 and POSIX.1b specification of shared memory. Draft 9 provides persistent and non-persistent shared memory; persistent shared memory had to be requested explicitly with the SHM_PERSIST flag. In contrast, POSIX.1b only provides persistent shared memory and does not require an explicit flag.

Persistence of an object implies that the object and its state (for example, the value of a semaphore, data in a message queue, data for a shared memory object) are preserved once the object is no longer referenced by a process. If the user absolutely needs to migrate non-persistent behavior from Draft 9 to POSIX.1b, here is an alternative method: After all of the processes that wish to use
non-persistent shared memory have opened the shared memory, shm_unlink the shared memory. The shared memory will be deleted when all references to it are removed, simulating non-persistent shared memory.

Creating and Deleting Shared Memory

The interface to create a shared memory object differs between Draft 9 and POSIX.1b. Draft 9 provides a mkshm() function which used a size argument to specify the size of the shared memory object. POSIX.1b shared memory is created with the shm_open() function with the O_CREAT flag. This function does not take a size argument; all shared memory objects are of zero size when created.

To specify size, a new POSIX.1b function, ftruncate(), which is not specific to shared memory, must be used. This function truncates a file to a specified size. If a file is expanded with ftruncate(), the expanded part is initialized to zero. When ftruncate() is used to expand a shared memory object, the expanded part is initialized to zero. The following example demonstrates the comparison.

Note: To delete a shared memory object under POSIX.1b, call shm_unlink(). The object is actually destroyed after the last process unmaps the object.

Draft 9 Code

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/shmmap.h>

#define SIZE 1024

main()
{
int shm;
off_t size = SIZE;
:
mkshm("shmem", SHM_PERSIST | 0666, size);
shm = open("shmem", O_RDWR, SHM_PERSIST | 0666);
:
close(shm);
unlink("shmem");
:
}

Equivalent POSIX.1b Code

#include <sys/mman.h>

#define SIZE 1024

main()
{
int shm;
:
shm = shm_open("shmem", O_CREAT | O_RDWR, 0666);
ftruncate(shm, SIZE);
:
close(shm);
shm_unlink("shmem");
:
}

Mapping and Unmapping Shared Memory

This code compares mapping and unmapping a shared memory object between Draft 9 and POSIX.1b code; refer to "Changes from Draft 9 to POSIX.1b" for flags specific to shared memory.

Draft 9 Code

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/shmmap.h>

#define SIZE 1024

main()
{
int shm;
void *mem_ptr;
:
mkshm("shmem",.....);
shm = open("shmem",.....);
:
mem_ptr = shmmap(shm, NULL, SIZE, 0,
SHM_READ | SHM_WRITE);
:
shmunmap(mem_ptr, 0);
:
close(shm);
unlink("shmem");
:
}

Equivalent POSIX.1b code

#include <sys/mman.h>

#define SIZE 1024

main()
{
int shm;
char *mem_ptr;
:
shm = shm_open("shmem",.....);
ftruncate(shm,.....);
:
mem_ptr = mmap(NULL, SIZE, PROT_READ |
PROT_WRITE, MAP_SHARED, shm, 0);
:
munmap(mem_ptr, SIZE);
:
close(shm);
shm_unlink("shmem");
:
}

Changes from Draft 9 to POSIX.1b

The following table summarizes the shared memory interface changes:

Shared Memory Interface  
Draft 9
POSIX.1b
Shared memory object = Special file
Independent of file system
<sys/shmmap.h>
<sys/mman.h>
SHM_READ
PROT_READ
SHM_WRITE
PROT_WRITE
SHM_EXEC
PROT_EXEC
No Equivalent
PROT_NONE
SHM_EXACT
MAP_FIXED
shmmap()
Done by mmap()
shmunmap()
Done by munmap()
mkshm()
Done by shm_open()
open()
shm_open()
close()
close()
unlink()
shm_unlink()
No Equivalent
ftruncate()
Truncates a file to specified length

Persistence

Draft 9 supports persistent and non-persistent shared memory. POSIX.1b shared memory is persistent.

Size of Shared Memory Object

The interface changed to specify shared memory object size (when it is created). In Draft 9, size was specified as an argument to the mkshm() function. In POSIX.1b, a shared memory object is created with shm_open(), which does not take a size argument. All shared memory objects are of zero size when created. The size is specified with a new ftruncate() function. This function is not specific to shared memory, and can be used to truncate any file to a specified size. When ftruncate() is used to expand a shared memory object, the expanded part is initialized to zero.

Shared/Private Changes

Currently, LynxOS does not support the MAP_PRIVATE flag. The MAP_SHARED flag can be used, and changes to a shared memory object change the underlying object. With the MAP_PRIVATE flag (which will be supported in a subsequent release), changes to a shared memory object change the private copy of that object for that process but not the underlying object.

fork() Behavior

In the absence of MAP_PRIVATE, there are no changes to the fork() behavior with respect to shared memory. Memory mappings created by the parent are retained by the child process. With the MAP_PRIVATE flag (when it is supported), mappings before fork() in the parent also appear in the child. After fork(), the parent and the child are independent with respect to private mappings. The semantics are copy-on-write.

Protection

POSIX.1b supports all protections supported by Draft 9 (read, write, execute). In addition a new PROT_NONE flag is provided to suppress the ability to access data.

msync() and mprotect() Functions

In addition to mmap(), POSIX.1b provides msync() and mprotect(), which are unrelated to shared memory. These functions correspond to the _POSIX_MAPPED_FILES and _POSIX_MEMORY_PROTECTION feature test macros. These functions are only relevant to map files and devices with the mmap() function.

Return Values

A notable difference exists between the return values of shmmap() in Draft 9 and mmap() in POSIX.1b. shmmap() returns NULL upon failure, while mmap() returns MAP_FAILED. All successful mmap() returns are guaranteed not to return MAP_FAILED.

New Utilities

Lynx provides two new utilities, lipcs and lipcrm, to list and remove shared memory objects, respectively; refer to the lipcs and lipcrm man pages for more information.

Inter-Operability

There is no inter-operability between Draft 9 and POSIX.1b shared memory. Two processes, one using Draft 9 shared memory, and the other using POSIX.1b shared memory, cannot access the same underlying object.



LynuxWorks, Inc.
855 Branham Lane East
San Jose, CA 95138
http://www.lynuxworks.com
1.800.255.5969
TOC PREV NEXT INDEX