I'm contemplating adapting the mmap support from https://git.rtems.org/chrisj/rtl.git/tree/mmap.c
This patch adds most of the plumbing necessary so that the libc calls used there should work correctly. So far that code implicitly only supports MAP_PRIVATE. On Fri, Aug 26, 2016 at 4:17 PM, Gedare Bloom <ged...@rtems.org> wrote: > --- > cpukit/posix/include/rtems/posix/shm.h | 8 +-- > cpukit/posix/include/rtems/posix/shmimpl.h | 12 ++++ > cpukit/posix/src/shmheap.c | 19 ++++-- > cpukit/posix/src/shmopen.c | 92 > ++++++++++++++++++++++++++---- > cpukit/posix/src/shmunlink.c | 30 +++++++++- > cpukit/posix/src/shmwkspace.c | 19 ++++-- > 6 files changed, 151 insertions(+), 29 deletions(-) > > diff --git a/cpukit/posix/include/rtems/posix/shm.h > b/cpukit/posix/include/rtems/posix/shm.h > index eae0dcf..33d59f8 100644 > --- a/cpukit/posix/include/rtems/posix/shm.h > +++ b/cpukit/posix/include/rtems/posix/shm.h > @@ -56,10 +56,10 @@ typedef struct { > } POSIX_Shm_Control; > > struct POSIX_Shm_Object_operations { > - int ( *object_create ) ( POSIX_Shm_Control *shm, size_t size ); > - int ( *object_resize ) ( POSIX_Shm_Control *shm, size_t size ); > - int ( *object_delete ) ( POSIX_Shm_Control *shm ); > - void *( *object_mmap ) ( POSIX_Shm_Control *shm, size_t len, int prot, > int flags, off_t off ); > + int ( *object_create ) ( POSIX_Shm_Control *shm, size_t size ); > + int ( *object_resize ) ( POSIX_Shm_Control *shm, size_t size ); > + int ( *object_delete ) ( POSIX_Shm_Control *shm ); > + int ( *object_read ) ( POSIX_Shm_Control *shm, void *buf, size_t count ); > }; > > extern int _POSIX_Shm_Object_create_from_workspace( > diff --git a/cpukit/posix/include/rtems/posix/shmimpl.h > b/cpukit/posix/include/rtems/posix/shmimpl.h > index c012771..97a7442 100644 > --- a/cpukit/posix/include/rtems/posix/shmimpl.h > +++ b/cpukit/posix/include/rtems/posix/shmimpl.h > @@ -92,6 +92,18 @@ RTEMS_INLINE_ROUTINE void _POSIX_Shm_Update_mtime_ctime( > shm->ctime = now.tv_sec; > } > > +static inline POSIX_Shm_Control* iop_to_shm( rtems_libio_t *iop ) > +{ > + return (POSIX_Shm_Control*) iop->data1; > +} > + > +static inline POSIX_Shm_Control* loc_to_shm( > + const rtems_filesystem_location_info_t *loc > +) > +{ > + return (POSIX_Shm_Control*) loc->node_access; > +} > + > /** @} */ > > #ifdef __cplusplus > diff --git a/cpukit/posix/src/shmheap.c b/cpukit/posix/src/shmheap.c > index 5896445..cd56e5f 100644 > --- a/cpukit/posix/src/shmheap.c > +++ b/cpukit/posix/src/shmheap.c > @@ -65,15 +65,22 @@ int _POSIX_Shm_Object_resize_from_heap( > return err; > } > > -void *_POSIX_Shm_Object_mmap_from_heap( > +int _POSIX_Shm_Object_read_from_heap( > POSIX_Shm_Control *shm, > - size_t len, > - int prot, > - int flags, > - off_t off > + void *buf, > + size_t count > ) > { > - return NULL; > + if ( shm == NULL || shm->shm_object.handle == NULL ) > + return 0; > + > + if ( shm->shm_object.size < count ) { > + count = shm->shm_object.size; > + } > + > + memcpy( buf, shm->shm_object.handle, count ); > + > + return count; > } > > > diff --git a/cpukit/posix/src/shmopen.c b/cpukit/posix/src/shmopen.c > index cbea88c..7c92194 100644 > --- a/cpukit/posix/src/shmopen.c > +++ b/cpukit/posix/src/shmopen.c > @@ -28,11 +28,49 @@ > > static const rtems_filesystem_file_handlers_r shm_handlers; > > +static int shm_fstat( > + const rtems_filesystem_location_info_t *loc, > + struct stat *buf > +) > +{ > + POSIX_Shm_Control *shm = loc_to_shm( loc ); > + > + if ( shm == NULL ) > + rtems_set_errno_and_return_minus_one( EIO ); > + > + /* mandatory for shm objects */ > + buf->st_uid = shm->uid; > + buf->st_gid = shm->gid; > + buf->st_size = shm->shm_object.size; > + buf->st_mode = shm->mode; > + > + /* optional for shm objects */ > + buf->st_atim = shm->atime; > + buf->st_mtim = shm->mtime; > + buf->st_ctim = shm->ctime; > + > + return 0; > +} > + > +/* read() is unspecified for shared memory objects */ > +static int shm_read( rtems_libio_t *iop, void *buffer, size_t count ) > +{ > + Thread_queue_Context queue_context; > + int bytes_read; > + POSIX_Shm_Control *shm = iop_to_shm( iop ); > + > + _POSIX_Shm_Acquire_critical( shm, &queue_context ); > + bytes_read = (*shm->shm_object.ops->object_read)( shm, buffer, count ); > + _POSIX_Shm_Release( shm, &queue_context ); > + > + return bytes_read; > +} > + > static int shm_ftruncate( rtems_libio_t *iop, off_t length ) > { > - Thread_queue_Context queue_context; > - POSIX_Shm_Control *shm = (POSIX_Shm_Control *) iop->data1; > + Thread_queue_Context queue_context; > int err; > + POSIX_Shm_Control *shm = iop_to_shm( iop ); > > _POSIX_Shm_Acquire_critical( shm, &queue_context ); > > @@ -42,13 +80,48 @@ static int shm_ftruncate( rtems_libio_t *iop, off_t > length ) > _POSIX_Shm_Release( shm, &queue_context ); > rtems_set_errno_and_return_minus_one( err ); > } > - > + > _POSIX_Shm_Update_mtime_ctime( shm ); > > _POSIX_Shm_Release( shm, &queue_context ); > return 0; > } > > +static int shm_close( rtems_libio_t *iop ) > +{ > + POSIX_Shm_Control *shm = iop_to_shm( iop ); > + Objects_Control *the_object; > + ISR_lock_Context lock_ctx; > + int err; > + > + _Objects_Allocator_lock(); > + > + --shm->reference_count; > + if ( shm->reference_count == 0 ) { > + /* TODO: need to make sure this counts mmaps too! */ > + if ( (*shm->shm_object.ops->object_delete)( shm ) != 0 ) { > + err = EIO; > + } > + /* check if the object has been unlinked yet. */ > + obj = _Objects_Get( shm->Object.id, &lock_ctx, &_POSIX_Shm_Information ); > + if ( obj == NULL ) { > + /* if it was unlinked, then it can be freed. */ > + _POSIX_Shm_Free( shm ); > + } else { > + /* it will be freed when it is unlinked. */ > + _ISR_lock_ISR_enable( &lock_context ); > + } > + } > + iop->pathinfo.node_access = NULL; > + > + _Objects_Allocator_unlock(); > + > + if ( err != 0 ) { > + rtems_set_errno_and_return_minus_one( err ); > + } > + return 0; > +} > + > static inline POSIX_Shm_Control *shm_allocate( > const char *name_arg, > size_t name_len, > @@ -145,7 +218,6 @@ int shm_open( const char *name, int oflag, mode_t mode ) > return -1; > } > > - /* TODO see if the object exists, shms available */ > iop = rtems_libio_allocate(); > if ( iop == NULL ) { > rtems_set_errno_and_return_minus_one( EMFILE ); > @@ -169,20 +241,17 @@ int shm_open( const char *name, int oflag, mode_t mode ) > shm = shm_allocate(name, len, oflag, mode, &err); > break; > } > - _Objects_Allocator_unlock(); > } else { /* shm exists */ > - _Objects_Allocator_unlock(); > if ( ( oflag & ( O_EXCL | O_CREAT ) ) == ( O_EXCL | O_CREAT ) ) { > /* Request to create failed. */ > err = EEXIST; > } else if ( !shm_access_ok( shm, oflag ) ) { > err = EACCES; > } else { > - _POSIX_Shm_Acquire_critical( shm, &queue_context ); > ++shm->reference_count; > - _POSIX_Shm_Release( shm, &queue_context ); > } > } > + _Objects_Allocator_unlock(); > if ( err != 0 ) { > rtems_libio_free( iop ); > rtems_set_errno_and_return_minus_one( err ); > @@ -202,6 +271,7 @@ int shm_open( const char *name, int oflag, mode_t mode ) > } > iop->data0 = fd; > iop->data1 = shm; > + iop->pathinfo.node_access = shm; > iop->pathinfo.handlers = &shm_handlers; > iop->pathinfo.mt_entry = &rtems_filesystem_null_mt_entry; > rtems_filesystem_location_add_to_mt_entry( &iop->pathinfo ); > @@ -211,12 +281,12 @@ int shm_open( const char *name, int oflag, mode_t mode ) > > static const rtems_filesystem_file_handlers_r shm_handlers = { > .open_h = rtems_filesystem_default_open, > - .close_h = rtems_filesystem_default_close, > - .read_h = rtems_filesystem_default_read, > + .close_h = shm_close, > + .read_h = shm_read, > .write_h = rtems_filesystem_default_write, > .ioctl_h = rtems_filesystem_default_ioctl, > .lseek_h = rtems_filesystem_default_lseek, > - .fstat_h = rtems_filesystem_default_fstat, > + .fstat_h = shm_fstat, > .ftruncate_h = shm_ftruncate, > .fsync_h = rtems_filesystem_default_fsync_or_fdatasync, > .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, > diff --git a/cpukit/posix/src/shmunlink.c b/cpukit/posix/src/shmunlink.c > index f559922..c4f4b4e 100644 > --- a/cpukit/posix/src/shmunlink.c > +++ b/cpukit/posix/src/shmunlink.c > @@ -18,9 +18,35 @@ > #include <errno.h> > #include <rtems/seterr.h> > > +#include <rtems/posix/shmimpl.h> > + > int shm_unlink( const char *name ) > { > - (void) name; > + Objects_Get_by_name_error obj_err; > + int err; > + POSIX_Shm_Control *shm; > + > + shm = _POSIX_Shm_Get_by_name( name, 0, &obj_err ); > + switch ( obj_err ) { > + case OBJECTS_GET_BY_NAME_INVALID_NAME: > + err = ENOENT; > + break; > + > + case OBJECTS_GET_BY_NAME_NAME_TOO_LONG: > + err = ENAMETOOLONG; > + break; > > - rtems_set_errno_and_return_minus_one( ENOENT ); > + case OBJECTS_GET_BY_NAME_NO_OBJECT: > + default: > + _Objects_Close( &_POSIX_Shm_Information, &shm->Object ); > + if ( shm->reference_count == 0 ) { > + /* TODO: need to make sure this counts mmaps too! */ > + /* only remove the shm object if no references exist to it. */ > + _POSIX_Shm_Free( shm ); > + } > + break; > + } > + if ( err != 0 ) > + rtems_set_errno_and_return_minus_one( err ); > + return 0; > } > diff --git a/cpukit/posix/src/shmwkspace.c b/cpukit/posix/src/shmwkspace.c > index 59573dd..54df9c5 100644 > --- a/cpukit/posix/src/shmwkspace.c > +++ b/cpukit/posix/src/shmwkspace.c > @@ -57,15 +57,22 @@ int _POSIX_Shm_Object_resize_from_workspace( > return err; > } > > -void *_POSIX_Shm_Object_mmap_from_workspace( > +int _POSIX_Shm_Object_read_from_workspace( > POSIX_Shm_Control *shm, > - size_t len, > - int prot, > - int flags, > - off_t off > + void *buf, > + size_t count > ) > { > - return NULL; > + if ( shm == NULL || shm->shm_object.handle == NULL ) > + return 0; > + > + if ( shm->shm_object.size < count ) { > + count = shm->shm_object.size; > + } > + > + memcpy( buf, shm->shm_object.handle, count ); > + > + return count; > } > > > -- > 1.9.1 > _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel