[lttng-dev] [Babeltrace RFC PATCH 08/28] Add MinGW implementation of mmap and munmap

Jérémie Galarneau jeremie.galarneau at efficios.com
Mon May 13 16:20:23 EDT 2013


On Thu, May 2, 2013 at 7:49 AM, Ikaheimonen, JP
<jp_ikaheimonen at mentor.com> wrote:
> Implementations of mmap and munmap using Windows API.
> The header file sys/mman.h is now indirectly included by
> include/babeltrace/compat/mman.h .
> For MinGW, PAGE_SIZE is defined as a constant instead of
> using a sysconf() setting.
> ---
>  compat/Makefile.am                  |   4 +-
>  compat/compat_mman.c                | 128 ++++++++++++++++++++++++++++++++++++
>  converter/babeltrace-log.c          |   2 +-
>  formats/bt-dummy/bt-dummy.c         |   2 +-
>  formats/ctf-metadata/ctf-metadata.c |   2 +-
>  formats/ctf-text/ctf-text.c         |   2 +-
>  formats/ctf/ctf.c                   |   2 +-
>  include/babeltrace/align.h          |   5 ++
>  include/babeltrace/compat/mman.h    |  24 +++++++
>  include/babeltrace/ctf-text/types.h |   2 +-
>  include/babeltrace/mmap-align.h     |   2 +-
>  11 files changed, 166 insertions(+), 9 deletions(-)
>  create mode 100644 compat/compat_mman.c
>  create mode 100644 include/babeltrace/compat/mman.h
>
> diff --git a/compat/Makefile.am b/compat/Makefile.am
> index e624a79..e573854 100644
> --- a/compat/Makefile.am
> +++ b/compat/Makefile.am
> @@ -9,5 +9,5 @@ libcompat_la_LDFLAGS = \
>         -Wl,--no-as-needed
>
>  if BABELTRACE_BUILD_WITH_MINGW
> -libcompat_la_SOURCES += compat_uuid.c
> -endif
> \ No newline at end of file
> +libcompat_la_SOURCES += compat_mman.c compat_uuid.c
> +endif
> diff --git a/compat/compat_mman.c b/compat/compat_mman.c
> new file mode 100644
> index 0000000..0e45260
> --- /dev/null
> +++ b/compat/compat_mman.c
> @@ -0,0 +1,128 @@
> +/* This file is only built under MINGW32 */
> +
> +#include <windows.h>
> +#include <stdlib.h>
> +#include <babeltrace/compat/mman.h>
> +
> +#define HAS_FLAG( BITSET, FLAG ) ( ( BITSET & FLAG ) == FLAG )
> +
> +typedef struct
> +{
> +    HANDLE hFile;
> +    HANDLE hFileMappingObject;
> +    unsigned char *start_addr;
> +    long offset;
> +} mmap_data;
> +
> +mmap_data *arr_mmap_data = NULL;
> +size_t arr_mmap_data_size = 0;
> +DWORD allocationGranularity = 0;
> +
> +void mmap_data_add( mmap_data data )
> +{
> +    arr_mmap_data = (mmap_data *) realloc( arr_mmap_data, ( arr_mmap_data_size + 1 ) * sizeof( mmap_data ) );
> +    arr_mmap_data[ arr_mmap_data_size ] = data;
> +    arr_mmap_data_size += 1;
> +}
> +
> +mmap_data *mmap_data_find_addr( unsigned char *start_addr )
> +{
> +    size_t i;
> +    for( i = 0; i < arr_mmap_data_size; ++i )
> +       if( arr_mmap_data[i].start_addr + arr_mmap_data[i].offset == start_addr )
> +           return arr_mmap_data + i;
> +
> +    return NULL;
> +}
> +
> +/* mmap for mingw32 */
> +void *mmap( void *ptr, long size, long prot, long type, long handle, long arg )
> +{
> +    //__builtin_printf( "mmap: %p, %d, %d, %d, %d, %d\n", ptr, size, prot, type, handle, arg );
> +    mmap_data data_entry;
> +    long offset;
> +
> +    if (allocationGranularity == 0)
> +    {
> +        SYSTEM_INFO sysinfo;
> +        GetSystemInfo(&sysinfo);
> +        allocationGranularity = sysinfo.dwAllocationGranularity;
> +    }
> +
> +    if( prot == PROT_NONE || HAS_FLAG( prot, PROT_EXEC ) )
> +       return MAP_FAILED; /* not supported - fail safe */
> +
> +    data_entry.hFile = (HANDLE) _get_osfhandle( handle );
> +    if( data_entry.hFile != INVALID_HANDLE_VALUE )
> +    {
> +
> +       /* There is no 1:1 mapping, best effort strategy */
> +       DWORD flProtect = PAGE_READONLY;
> +       DWORD dwDesiredAccess = FILE_MAP_READ;
> +
> +       if( HAS_FLAG( prot, PROT_WRITE ) )
> +       {
> +           flProtect = PAGE_READWRITE;
> +           if( HAS_FLAG( prot, PROT_READ ) )
> +               dwDesiredAccess = FILE_MAP_ALL_ACCESS;
> +           else
> +               dwDesiredAccess = FILE_MAP_WRITE;
> +       }
> +
> +       if( HAS_FLAG( type, MAP_PRIVATE ) )
> +       {
> +           flProtect = PAGE_WRITECOPY;
> +           dwDesiredAccess = FILE_MAP_COPY;
> +       }
> +
> +       data_entry.hFileMappingObject = CreateFileMapping( data_entry.hFile, NULL, flProtect, 0, 0, NULL );
> +       if( data_entry.hFileMappingObject != NULL )
> +       {
> +            DWORD filesizelow;
> +            DWORD filesizehigh;
> +           filesizelow = GetFileSize(data_entry.hFile, &filesizehigh);
> +           offset = 0;
> +            while (arg > allocationGranularity)
> +            {
> +                if (filesizelow < allocationGranularity)
> +                {
> +                       filesizehigh--;
> +               }
> +               filesizelow -= allocationGranularity;
> +
> +                arg -= allocationGranularity;
> +                offset += allocationGranularity;
> +            }
> +            data_entry.offset = arg;
> +            size = size + arg;
> +            if ((size > filesizelow) && (filesizehigh == 0))
> +            {
> +                size = filesizelow;
> +            }
> +           data_entry.start_addr = MapViewOfFile( data_entry.hFileMappingObject, dwDesiredAccess, 0, offset, size);
> +           if( data_entry.start_addr != NULL )
> +           {
> +               mmap_data_add( data_entry );
> +               return (void *)(data_entry.start_addr + arg);
> +           }
> +       }
> +
> +    }
> +
> +    return MAP_FAILED;
> +}
> +
> +
> +/* munmap for mingw32 */
> +long munmap( void *ptr, long size )
> +{
> +    mmap_data *data_entry = mmap_data_find_addr( ptr );
> +    if( data_entry != NULL  && UnmapViewOfFile( data_entry->start_addr ) != 0 )
> +    {
> +       CloseHandle( data_entry->hFileMappingObject );
> +       data_entry->start_addr = NULL;
> +       return 0;
> +    }
> +
> +    return -1;
> +}
> diff --git a/converter/babeltrace-log.c b/converter/babeltrace-log.c
> index 52a2fe1..b11eb99 100644
> --- a/converter/babeltrace-log.c
> +++ b/converter/babeltrace-log.c
> @@ -33,7 +33,7 @@
>  #include <sys/types.h>
>  #include <sys/stat.h>
>  #include <fcntl.h>
> -#include <sys/mman.h>
> +#include <babeltrace/compat/mman.h>
>  #include <dirent.h>
>  #include <stdio.h>
>  #include <stdlib.h>
> diff --git a/formats/bt-dummy/bt-dummy.c b/formats/bt-dummy/bt-dummy.c
> index 6192e88..4be9741 100644
> --- a/formats/bt-dummy/bt-dummy.c
> +++ b/formats/bt-dummy/bt-dummy.c
> @@ -28,7 +28,7 @@
>  #include <babeltrace/format.h>
>  #include <babeltrace/babeltrace-internal.h>
>  #include <inttypes.h>
> -#include <sys/mman.h>
> +#include <babeltrace/compat/mman.h>
>  #include <errno.h>
>  #include <sys/types.h>
>  #include <sys/stat.h>
> diff --git a/formats/ctf-metadata/ctf-metadata.c b/formats/ctf-metadata/ctf-metadata.c
> index a5a74c3..7ac36e1 100644
> --- a/formats/ctf-metadata/ctf-metadata.c
> +++ b/formats/ctf-metadata/ctf-metadata.c
> @@ -31,7 +31,7 @@
>  #include <babeltrace/babeltrace-internal.h>
>  #include <babeltrace/ctf/events-internal.h>
>  #include <inttypes.h>
> -#include <sys/mman.h>
> +#include <babeltrace/compat/mman.h>
>  #include <errno.h>
>  #include <sys/types.h>
>  #include <sys/stat.h>
> diff --git a/formats/ctf-text/ctf-text.c b/formats/ctf-text/ctf-text.c
> index 48ce31b..bc5c2a7 100644
> --- a/formats/ctf-text/ctf-text.c
> +++ b/formats/ctf-text/ctf-text.c
> @@ -32,7 +32,7 @@
>  #include <babeltrace/babeltrace-internal.h>
>  #include <babeltrace/ctf/events-internal.h>
>  #include <inttypes.h>
> -#include <sys/mman.h>
> +#include <babeltrace/compat/mman.h>
>  #include <errno.h>
>  #include <sys/types.h>
>  #include <sys/stat.h>
> diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c
> index d77c93a..0cfad44 100644
> --- a/formats/ctf/ctf.c
> +++ b/formats/ctf/ctf.c
> @@ -37,7 +37,7 @@
>  #include <babeltrace/endian.h>
>  #include <inttypes.h>
>  #include <stdio.h>
> -#include <sys/mman.h>
> +#include <babeltrace/compat/mman.h>
>  #include <errno.h>
>  #include <sys/types.h>
>  #include <sys/stat.h>
> diff --git a/include/babeltrace/align.h b/include/babeltrace/align.h
> index f6a1966..e7d715e 100644
> --- a/include/babeltrace/align.h
> +++ b/include/babeltrace/align.h
> @@ -30,8 +30,13 @@
>  #include <limits.h>
>
>  #ifndef PAGE_SIZE              /* Cygwin limits.h defines its own PAGE_SIZE */
> +#ifdef __MINGW32__
> +#define PAGE_SIZE              4096

You could get the real page size like this on Windows:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define PAGE_SIZE ({SYSTEM_INFO sys_info; GetSystemInfo (&sys_info);
sys_info.dwPageSize;})

> +#else
>  #define PAGE_SIZE              sysconf(_SC_PAGE_SIZE)
>  #endif
> +#endif
> +
>
>  #define ALIGN(x, a)            __ALIGN_MASK(x, (typeof(x))(a) - 1)
>  #define __ALIGN_MASK(x, mask)  (((x) + (mask)) & ~(mask))
> diff --git a/include/babeltrace/compat/mman.h b/include/babeltrace/compat/mman.h
> new file mode 100644
> index 0000000..a004b1e
> --- /dev/null
> +++ b/include/babeltrace/compat/mman.h
> @@ -0,0 +1,24 @@
> +#ifndef _BABELTRACE_INCLUDE_COMPAT_MMAN_H
> +#define _BABELTRACE_INCLUDE_COMPAT_MMAN_H
> +
> +#ifdef __MINGW32__
> +
> +#define PROT_READ      0x1
> +#define PROT_WRITE     0x2
> +#define PROT_EXEC      0x4
> +#define PROT_NONE      0x0
> +
> +#define MAP_SHARED     0x01
> +#define MAP_PRIVATE    0x02
> +#define MAP_FAILED     ((void *) -1)
> +
> +/* mmap for mingw32 */
> +void *mmap (void *ptr, long size, long prot, long type, long handle, long arg);
> +/* munmap for mingw32 */
> +long munmap (void *ptr, long size);
> +
> +#else
> +#include <sys/mman.h>
> +#endif
> +
> +#endif /* _BABELTRACE_INCLUDE_COMPAT_MMAN_H */
> diff --git a/include/babeltrace/ctf-text/types.h b/include/babeltrace/ctf-text/types.h
> index 7b4b717..c528355 100644
> --- a/include/babeltrace/ctf-text/types.h
> +++ b/include/babeltrace/ctf-text/types.h
> @@ -27,7 +27,7 @@
>   * SOFTWARE.
>   */
>
> -#include <sys/mman.h>
> +#include <babeltrace/compat/mman.h>
>  #include <errno.h>
>  #include <stdint.h>
>  #include <unistd.h>
> diff --git a/include/babeltrace/mmap-align.h b/include/babeltrace/mmap-align.h
> index f7c18fa..3d90c85 100644
> --- a/include/babeltrace/mmap-align.h
> +++ b/include/babeltrace/mmap-align.h
> @@ -27,7 +27,7 @@
>
>  #include <babeltrace/align.h>
>  #include <stdlib.h>
> -#include <sys/mman.h>
> +#include <babeltrace/compat/mman.h>
>
>  /*
>   * This header implements a wrapper over mmap (mmap_align) that memory
> --
> 1.8.1.msysgit.1
>
>
> _______________________________________________
> lttng-dev mailing list
> lttng-dev at lists.lttng.org
> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev



-- 
Jérémie Galarneau
EfficiOS Inc.
http://www.efficios.com



More information about the lttng-dev mailing list