HP OpenVMS Systemsask the wizard |
The Question is: Where can I find programming examples using the Compaq C 6.4 rtl function mmap? Ideally I'd like to see how a cooperating process maps to an existing memory region. The Answer is :
An OpenVMS example of shared memory access based on COMMONs is
available in Ask The Wizard topic (2486), and an example based
on system services is available via a link at the top level of
the Ask The Wizard area. Here is a Compaq C example of mmap:
--
/*
// Copyright 2001 Compaq Computer Corporation
//
// This program is an example of using the C RTL routine mmap, and
// which allows sharing of memory (global sections) in a relatively
// portable manner.
*/
#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#define MAXSIZE 10
#define VMSSHROPT
#ifdef __vms
#undef VMSSHROPT
#define VMSSHROPT ,"shr=put"
#endif
int main()
{
char *filename = tmpnam(NULL);
int FileChan1, FileChan2;
int i;
int RetStat;
struct
{
int DataArray[MAXSIZE];
} Mmap0, *MmapPtr1, *MmapPtr2;
// Initialize the data in the array
//
for ( i = 0; i < MAXSIZE; i++ )
Mmap0.DataArray[i] = i;
// create the file. Permit write sharing.
//
FileChan1 = open( filename, O_RDWR | O_CREAT, 0777 VMSSHROPT );
if ( FileChan1 == -1 ) perror("1? open");
// Open another channel to the same file, using the write-sharing.
//
FileChan2 = open( filename, O_RDWR, 0777 VMSSHROPT );
if ( FileChan2 == -1 ) perror("2? open");
// write the data into the file
//
RetStat = write( FileChan1, &Mmap0, sizeof ( Mmap0 ) );
if ( RetStat != sizeof ( Mmap0 ))
perror( "error writing initial data to file..." );
// flush the data out of the cache, and into the file.
//
if ( fsync ( FileChan1 ) )
perror( "error flushing the file..." );
// Map the file to a shared memory section.
//
// By specifying NULL as the first parameter and by using the MAP_VARIABLE
// flag, we let the operating system pick the virtual address range where
// the section will be mapped.
//
// In OpenVMS, the equivalent of this option on the $crmpsc and $mgblsc
// calls is the SEC$M_EXPREG expand-region flag.
//
MmapPtr1 = mmap( NULL, // let the OS pick the address
sizeof( Mmap0 ), // size of the data
PROT_WRITE, // permit write sharing
MAP_VARIABLE | MAP_SHARED,
FileChan1, // file id
0 ); // offset into the file
if ( MmapPtr1 == MAP_FAILED )
perror("1? mmap");
// Map the file again.
//
MmapPtr2 = mmap( NULL,
sizeof( *MmapPtr2 ),
PROT_WRITE,
MAP_VARIABLE | MAP_SHARED,
FileChan2, 0 );
if ( MmapPtr2 == MAP_FAILED )
perror("1? mmap");
// Now use both windows to demonstrate shared access into the data.
//
printf( "++ The view through the first window...\n");
for ( i = 0; i < MAXSIZE; i++ )
printf ( " DataArray[%d] = %d\n", i, MmapPtr1->DataArray[i] );
printf( "++ The view through the second window...\n");
for ( i = 0; i < MAXSIZE; i++ )
printf ( " DataArray[%d] = %d\n", i, MmapPtr2->DataArray[i] );
printf( "++ Increment the data via the second window...\n");
for ( i = 0; i < MAXSIZE; i++ )
MmapPtr2->DataArray[i]++;
printf( "++ The view through the first window...\n");
for ( i = 0; i < MAXSIZE; i++ )
printf ( " DataArray[%d] = %d\n", i, MmapPtr1->DataArray[i] );
printf( "Cleaning up for exit...\n");
// Close and unmap the file.
//
if ( close( FileChan1 ) ) perror("1? close");
if ( close( FileChan2 ) ) perror("2? close");
if ( munmap( MmapPtr1, sizeof( *MmapPtr1 )) ) perror("1? munmap");
if ( munmap( MmapPtr2, sizeof( *MmapPtr2 )) ) perror("2? munmap");
if ( remove( filename ) ) perror("remove");
printf( "Done...\n");
return EXIT_SUCCESS;
}
|