[Previous] [Contents] [Next]

shm_ctl()

Give special attributes to a shared memory object

Synopsis:

#include <sys/mman.h>

int shm_ctl( int fd,
             int flags,
             _uint64 paddr,
             _uint64 size );

Library:

libc

Description:

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>:

SHMCTL_ANON
Grow the object to be size bytes.
SHMCTL_PHYS
Assign the physical address, paddr, to the object.
SHMCTL_GLOBAL
A hint that any mapping to the object could be global across all processes.
SHMCTL_PRIV
A hint that a mapping of this object may require privileged access.
SHMCTL_LOWERPROT
A hint that the system may map this object in such a way that it trades lower memory protection for better performance.

Note: 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.

Returns:

0
Success.
-1
An error occurred (errno is set).

Errors:

EINVAL
An invalid combination of flags was specified, or the shared memory object is already "special."

Examples:

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 );
}

Classification:

QNX 6

Safety:
Cancellation point Yes
Interrupt handler No
Signal handler Yes
Thread Yes

See also:

mmap(), munmap(), mprotect(), shm_open(), shm_unlink()


[Previous] [Contents] [Next]