![]() |
![]() |
![]() |
Give special attributes to a shared memory object
#include <sys/mman.h> int shm_ctl( int fd, int flags, _uint64 paddr, _uint64 size );
libc
The shm_ctl() function modifies the attributes of the shared memory object identified by the handle, fd. This handle is the value returned by shm_open().
The flags argument is a one or more of the following bits, defined in <sys/mman.h>:
![]() |
The combination SHMCTL_ANON | SHMCTL_PHYS has the same behavior as for mmap(): it indicates that you want physically contiguous RAM to be allocated for the object. |
The following examples go together. Run sharephyscreator, followed by sharephysuser.
The sharephyscreator process maps in an area of physical memory and then overlays it with a shared memory object. The sharephysuser process opens that shared memory object in order to access the physical memory.
/* * sharephyscreator.c * * This maps in an area of physical memory and then * overlays it with a shared memory object. This way, another process * can open that shared memory object in order to access the physical * memory. The other process in this case is sharephysuser. * * Note that the size and address that you pass to shm_ctl() must be * even multiples of the page size (sysconf(_SC_PAGE_SIZE)). * * For VGA color text mode video memory: * sharephyscreator /wally b8000 * Note that for VGA color text mode video memory, each character * is followed by an attribute byte. Here we just use a space. */ #include <errno.h> #include <fcntl.h> #include <inttypes.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/mman.h> #include <sys/neutrino.h> #include <sys/stat.h> char *progname = "sharephyscreator"; main( int argc, char *argv[] ) { char *text = "H e l l o w o r l d ! "; int fd, memsize; char *ptr, *name; uint64_t physaddr; if ( argc != 3 ) { printf( "use: sharephyscreator shared_memory_object_name physical_address_in_hex\n" ); printf( "Example: sharephyscreator wally b8000\n" ); exit( EXIT_FAILURE ); } name = argv[1]; physaddr = atoh(argv[2]); memsize = sysconf( _SC_PAGE_SIZE ); /* this should be enough for our string */ /* map in the physical memory */ ptr = mmap_device_memory( 0, memsize, PROT_READ|PROT_WRITE, 0, physaddr ); if ( ptr == MAP_FAILED ) { printf( "%s: mmap_device_memory for physical address %llx failed: %s\n", progname, physaddr, strerror(errno) ); exit( EXIT_FAILURE ); } /* open the shared memory object, create it if it doesn't exist */ fd = shm_open( name, O_RDWR | O_CREAT, 0 ); if ( fd == -1 ) { printf( "%s: error creating the shared memory object '%s': %s\n", progname, name, strerror(errno) ); exit( EXIT_FAILURE ); } /* overlay the shared memory object onto the physical memory */ if ( shm_ctl( fd, SHMCTL_PHYS, physaddr, memsize ) == -1 ) { printf( "%s: shm_ctl failed: %s\n", progname, strerror(errno) ); close( fd ); munmap( ptr, memsize ); shm_unlink( name ); exit( EXIT_FAILURE ); } strcpy( ptr, text ); /* write to the shared memory */ printf( "\n%s: Physical memory mapped in, shared memory overlayed onto it.\n" "%s: Wrote '%s' to physical memory.\n" "%s: Sleeping for 20 seconds. While this program is sleeping\n" "%s: run 'sharephysuser %s %d'.\n", progname, progname, ptr, progname, progname, name, strlen(text)+1 ); sleep( 20 ); printf( "%s: Woke up. Cleaning up and exiting ...\n", progname ); close( fd ); munmap( ptr, memsize ); shm_unlink( name ); }
The following is meant to be run with sharephyscreator.
/* * sharephysuser.c * * This one is meant to be run in tandem with sharephyscreator. * * Run it as: sharephysuser shared_memory_object_name length * Example: sharephysuser wally 49 * */ #include <errno.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/mman.h> #include <sys/neutrino.h> #include <sys/stat.h> char *progname = "sharephysuser"; main( int argc, char *argv[] ) { int fd, len, i; char *ptr, *name; if ( argc != 3 ) { fprintf( stderr, "use: sharephysuser shared_memory_object_name length\n" ); fprintf( stderr, "Example: sharephysuser wally 49\n" ); exit( EXIT_FAILURE ); } name = argv[1]; len = atoi( argv[2] ); /* open the shared memory object */ fd = shm_open( name, O_RDWR, 0 ); if ( fd == -1 ) { fprintf( stderr, "%s: error opening the shared memory object '%s': %s\n", progname, name, strerror(errno) ); exit( EXIT_FAILURE ); } /* get a pointer to a piece of the shared memory, note that we only map in the amount we need to */ ptr = mmap( 0, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 ); if ( ptr == MAP_FAILED ) { fprintf( stderr, "%s: mmap failed: %s\n", progname, strerror(errno) ); exit( EXIT_FAILURE ); } printf( "%s: reading the text: ", progname ); for ( i = 0; i < len; i++ ) printf( "%c", ptr[i] ); printf( "\n" ); close( fd ); munmap( ptr, len ); }
Safety: | |
---|---|
Cancellation point | Yes |
Interrupt handler | No |
Signal handler | Yes |
Thread | Yes |
mmap(), munmap(), mprotect(), shm_open(), shm_unlink()
![]() |
![]() |
![]() |