![]() |
![]() 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; }
|