diff options
author | Gedare Bloom <gedare@rtems.org> | 2016-08-12 15:25:10 -0400 |
---|---|---|
committer | Gedare Bloom <gedare@rtems.org> | 2017-01-13 11:17:30 -0500 |
commit | ba77628250ae7158db363fc0d7886ebd43e9cb69 (patch) | |
tree | 91a8a5b7d20399c69c5c88223a43ec681451996b /cpukit/posix/src/shmheap.c | |
parent | posix: fix typo in mmap arguments (diff) | |
download | rtems-ba77628250ae7158db363fc0d7886ebd43e9cb69.tar.bz2 |
posix: shared memory support
Add POSIX shared memory manager (Shm). Includes a hook-based
approach for the backing memory storage that defaults to the
Workspace, and a test is provided using the heap. A test is
also provided for the basic use of mmap'ing a shared memory
object. This test currently fails at the mmap stage due to
no support for mmap.
Diffstat (limited to 'cpukit/posix/src/shmheap.c')
-rw-r--r-- | cpukit/posix/src/shmheap.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/cpukit/posix/src/shmheap.c b/cpukit/posix/src/shmheap.c new file mode 100644 index 0000000000..3449c15cca --- /dev/null +++ b/cpukit/posix/src/shmheap.c @@ -0,0 +1,90 @@ +/** + * @file + */ + +/* + * Copyright (c) 2016 Gedare Bloom. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <stdlib.h> +#include <rtems/posix/shmimpl.h> + +int _POSIX_Shm_Object_create_from_heap( + POSIX_Shm_Object *shm_obj, + size_t size +) +{ + void *p = calloc( 1, size ); /* get zero'd memory */ + if ( p != NULL ) { + shm_obj->handle = p; + shm_obj->size = size; + } else { + errno = EIO; + } + return 0; +} + +int _POSIX_Shm_Object_delete_from_heap( POSIX_Shm_Object *shm_obj ) +{ + /* zero out memory before releasing it. */ + memset( shm_obj->handle, 0, shm_obj->size ); + free( shm_obj->handle ); + shm_obj->handle = NULL; + shm_obj->size = 0; + return 0; +} + +int _POSIX_Shm_Object_resize_from_heap( + POSIX_Shm_Object *shm_obj, + size_t size +) +{ + void *p; + int err = 0; + + if ( size < shm_obj->size ) { + /* zero out if shrinking */ + p = (void*)((uintptr_t)shm_obj->handle + (uintptr_t)size); + memset( p, 0, shm_obj->size - size ); + } + p = realloc( shm_obj->handle, size ); + if ( p != NULL ) { + shm_obj->handle = p; + if ( size > shm_obj->size ) { + /* initialize added memory */ + memset( p, 0, size - shm_obj->size ); + } + shm_obj->size = size; + } else { + err = EIO; + } + return err; +} + +int _POSIX_Shm_Object_read_from_heap( + POSIX_Shm_Object *shm_obj, + void *buf, + size_t count +) +{ + if ( shm_obj == NULL || shm_obj->handle == NULL ) + return 0; + + if ( shm_obj->size < count ) { + count = shm_obj->size; + } + + memcpy( buf, shm_obj->handle, count ); + + return count; +} + |