summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
5cbf534)
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
#include <errno.h>
#include <io.h>
#include <pthread.h>
#include <errno.h>
#include <io.h>
#include <pthread.h>
#include <windows.h>
#include <babeltrace/compat/mman-internal.h>
#include <windows.h>
#include <babeltrace/compat/mman-internal.h>
-struct mmap_info {
- HANDLE file_handle; /* the duplicated handle */
- HANDLE map_handle; /* handle returned by CreateFileMapping */
- void *start; /* ptr returned by MapViewOfFile */
+struct mmap_mapping {
+ /* The duplicated handle. */
+ HANDLE file_handle;
+ /* Handle returned by CreateFileMapping. */
+ HANDLE map_handle;
+static
+GHashTable *mmap_mappings = NULL;
+
- * This mutex protects the array of memory mappings and its associated
- * counters. (mmap_infos, mmap_infos_cur mmap_infos_max)
+ * This mutex protects the hashtable of memory mappings.
*/
static pthread_mutex_t mmap_mutex = PTHREAD_MUTEX_INITIALIZER;
*/
static pthread_mutex_t mmap_mutex = PTHREAD_MUTEX_INITIALIZER;
-static int mmap_infos_cur = 0;
-static int mmap_infos_max = 0;
-static struct mmap_info *mmap_infos = NULL;
+static
+struct mmap_mapping *mapping_create(void)
+{
+ struct mmap_mapping *mapping;
+
+ mapping = malloc(sizeof(struct mmap_mapping));
+ if (mapping != NULL) {
+ mapping->file_handle = NULL;
+ mapping->map_handle = NULL;
+ }
-#define NEW_MMAP_STRUCT_CNT 10
+ return mapping;
+}
+
+static
+void mapping_clean(struct mmap_mapping *mapping)
+{
+ if (mapping) {
+ if (!CloseHandle(mapping->map_handle)) {
+ BT_LOGF_STR("Failed to close mmap map_handle.");
+ abort();
+ }
+ if (!CloseHandle(mapping->file_handle)) {
+ BT_LOGF_STR("Failed to close mmap file_handle.");
+ abort();
+ }
+ free(mapping);
+ mapping = NULL;
+ }
+}
+
+static
+void addr_clean(void *addr)
+{
+ /* Cleanup of handles should never fail. */
+ if (!UnmapViewOfFile(addr)) {
+ BT_LOGF_STR("Failed to unmap mmap mapping.");
+ abort();
+ }
+}
static
void mmap_lock(void)
{
if (pthread_mutex_lock(&mmap_mutex)) {
static
void mmap_lock(void)
{
if (pthread_mutex_lock(&mmap_mutex)) {
+ BT_LOGF_STR("Failed to acquire mmap_mutex.");
void mmap_unlock(void)
{
if (pthread_mutex_unlock(&mmap_mutex)) {
void mmap_unlock(void)
{
if (pthread_mutex_unlock(&mmap_mutex)) {
+ BT_LOGF_STR("Failed to release mmap_mutex.");
return PAGE_EXECUTE_READ;
}
return PAGE_EXECUTE_READ;
}
*dwDesiredAccess = 0;
return 0;
}
*dwDesiredAccess = 0;
return 0;
}
-void *mmap(void *start, size_t length, int prot, int flags, int fd,
+BT_HIDDEN
+void *bt_mmap(void *addr, size_t length, int prot, int flags, int fd,
- struct mmap_info mapping;
+ struct mmap_mapping *mapping = NULL;
+ void *mapping_addr;
DWORD dwDesiredAccess;
DWORD flProtect;
HANDLE handle;
DWORD dwDesiredAccess;
DWORD flProtect;
HANDLE handle;
- /* Check for a valid fd */
+ /* Check for a valid fd. */
if (fd == -1) {
_set_errno(EBADF);
if (fd == -1) {
_set_errno(EBADF);
- /* we don't support this atm */
+ /* We don't support this at the moment. */
if (flags == MAP_FIXED) {
_set_errno(ENOTSUP);
if (flags == MAP_FIXED) {
_set_errno(ENOTSUP);
- /* Map mmap flags to windows API */
+ /* Map mmap flags to those of the Windows API. */
flProtect = map_prot_flags(prot, &dwDesiredAccess);
if (flProtect == 0) {
_set_errno(EINVAL);
flProtect = map_prot_flags(prot, &dwDesiredAccess);
if (flProtect == 0) {
_set_errno(EINVAL);
- /* Get a handle from the fd */
+ /* Allocate the mapping struct. */
+ mapping = mapping_create();
+ if (!mapping) {
+ BT_LOGE_STR("Failed to allocate mmap mapping.");
+ _set_errno(ENOMEM);
+ goto error;
+ }
+
+ /* Get a handle from the fd. */
handle = (HANDLE) _get_osfhandle(fd);
handle = (HANDLE) _get_osfhandle(fd);
- /* Duplicate the handle and store it in 'mapping.file_handle' */
+ /* Duplicate the handle and store it in 'mapping.file_handle'. */
if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(),
if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(),
- &mapping.file_handle, 0, FALSE,
+ &mapping->file_handle, 0, FALSE,
DUPLICATE_SAME_ACCESS)) {
DUPLICATE_SAME_ACCESS)) {
+ _set_errno(ENOMEM);
+ goto error;
}
/*
* Create a file mapping object with a maximum size
}
/*
* Create a file mapping object with a maximum size
- * of 'offset' + 'length'
+ * of 'offset' + 'length'.
- mapping.map_handle = CreateFileMapping(mapping.file_handle, NULL,
+ mapping->map_handle = CreateFileMapping(mapping->file_handle, NULL,
flProtect, 0, offset + length, NULL);
flProtect, 0, offset + length, NULL);
- if (mapping.map_handle == 0) {
- if (!CloseHandle(mapping.file_handle)) {
- abort();
- }
+ if (mapping->map_handle == 0) {
- /* Map the requested block starting at 'offset' for 'length' bytes */
- mapping.start = MapViewOfFile(mapping.map_handle, dwDesiredAccess, 0,
+ /* Map the requested block starting at 'offset' for 'length' bytes. */
+ mapping_addr = MapViewOfFile(mapping->map_handle, dwDesiredAccess, 0,
- if (mapping.start == 0) {
+ if (mapping_addr == 0) {
DWORD dwLastErr = GetLastError();
DWORD dwLastErr = GetLastError();
- if (!CloseHandle(mapping.map_handle)) {
- abort();
- }
- if (!CloseHandle(mapping.file_handle)) {
- abort();
- }
-
if (dwLastErr == ERROR_MAPPED_ALIGNMENT) {
_set_errno(EINVAL);
} else {
_set_errno(EACCES);
}
if (dwLastErr == ERROR_MAPPED_ALIGNMENT) {
_set_errno(EINVAL);
} else {
_set_errno(EACCES);
}
- /* If we have never done any mappings, allocate the array */
- if (mmap_infos == NULL) {
- mmap_infos_max = NEW_MMAP_STRUCT_CNT;
- mmap_infos = (struct mmap_info *) calloc(mmap_infos_max,
- sizeof(struct mmap_info));
- if (mmap_infos == NULL) {
- mmap_infos_max = 0;
+ /* If we have never done any mappings, allocate the hashtable. */
+ if (!mmap_mappings) {
+ mmap_mappings = g_hash_table_new_full(g_direct_hash,
+ g_direct_equal, (GDestroyNotify) addr_clean,
+ (GDestroyNotify) mapping_clean);
+ if (!mmap_mappings) {
+ BT_LOGE_STR("Failed to allocate mmap hashtable.");
+ _set_errno(ENOMEM);
goto error_mutex_unlock;
}
}
goto error_mutex_unlock;
}
}
- /* if we have reached our current mapping limit, expand it */
- if (mmap_infos_cur == mmap_infos_max) {
- struct mmap_info *realloc_mmap_infos = NULL;
-
- mmap_infos_max += NEW_MMAP_STRUCT_CNT;
- realloc_mmap_infos = (struct mmap_info *) realloc(mmap_infos,
- mmap_infos_max * sizeof(struct mmap_info));
- if (realloc_mmap_infos == NULL) {
- mmap_infos_max -= NEW_MMAP_STRUCT_CNT;
- goto error_mutex_unlock;
- }
- mmap_infos = realloc_mmap_infos;
+ /* Add the new mapping to the hashtable. */
+ if (!g_hash_table_insert(mmap_mappings, mapping_addr, mapping)) {
+ BT_LOGF_STR("Failed to insert mapping in the hashtable.");
+ abort();
- /* Add the new mapping to the array */
- memcpy(&mmap_infos[mmap_infos_cur], &mapping,
- sizeof(struct mmap_info));
- mmap_infos_cur++;
-
error_mutex_unlock:
mmap_unlock();
error_mutex_unlock:
mmap_unlock();
-
- if (!CloseHandle(mapping.map_handle)) {
- abort();
- }
- if (!CloseHandle(mapping.file_handle)) {
- abort();
- }
-
- _set_errno(ENOMEM);
+error:
+ mapping_clean(mapping);
-int munmap(void *start, size_t length)
+BT_HIDDEN
+int bt_munmap(void *addr, size_t length)
- /* Find the mapping to unmap */
- for (i = 0; i < mmap_infos_cur; i++) {
- if (mmap_infos[i].start == start)
- break;
- }
- /* Mapping was not found */
- if (i == mmap_infos_cur) {
+ /* Check if the mapping exists in the hashtable. */
+ if (g_hash_table_lookup(mmap_mappings, addr) == NULL) {
- /* Cleanup of handles should never fail */
- if (!UnmapViewOfFile(mmap_infos[i].start)) {
- abort();
- }
- if (!CloseHandle(mmap_infos[i].map_handle)) {
+ /* Remove it. */
+ if (!g_hash_table_remove(mmap_mappings, addr)) {
+ BT_LOGF_STR("Failed to remove mapping from hashtable.");
- if (!CloseHandle(mmap_infos[i].file_handle)) {
- abort();
- }
-
- mmap_lock();
-
- /* Clean the mapping list */
- for (j = i + 1; j < mmap_infos_cur; j++) {
- memcpy(&mmap_infos[j - 1], &mmap_infos[j],
- sizeof(struct mmap_info));
- }
- mmap_infos_cur--;
-
- /* If the mapping list is now empty, free it */
- if (mmap_infos_cur == 0) {
- free(mmap_infos);
- mmap_infos = NULL;
- mmap_infos_max = 0;
- }
-#ifndef __MINGW32__
-
-#include <sys/mman.h>
-
-#else /* __MINGW32__ */
#define MAP_ANON MAP_ANONYMOUS
#define MAP_FAILED ((void *) -1)
#define MAP_ANON MAP_ANONYMOUS
#define MAP_FAILED ((void *) -1)
-void *mmap(void *addr, size_t length, int prot, int flags, int fd,
+void *bt_mmap(void *addr, size_t length, int prot, int flags, int fd,
-int munmap(void *addr, size_t length);
+int bt_munmap(void *addr, size_t length);
+
+#else /* __MINGW32__ */
+
+#include <sys/mman.h>
+
+static inline
+void *bt_mmap(void *addr, size_t length, int prot, int flags, int fd,
+ off_t offset)
+{
+ return (void *) mmap(addr, length, prot, flags, fd, offset);
+}
+
+static inline
+int bt_munmap(void *addr, size_t length)
+{
+ return munmap(addr, length);
+}
#endif /* __MINGW32__ */
#ifndef MAP_ANONYMOUS
#endif /* __MINGW32__ */
#ifndef MAP_ANONYMOUS
* boundary.
*/
mma->page_aligned_length = ALIGN(length + offset - page_aligned_offset, page_size);
* boundary.
*/
mma->page_aligned_length = ALIGN(length + offset - page_aligned_offset, page_size);
- mma->page_aligned_addr = mmap(NULL, mma->page_aligned_length,
+ mma->page_aligned_addr = bt_mmap(NULL, mma->page_aligned_length,
prot, flags, fd, page_aligned_offset);
if (mma->page_aligned_addr == MAP_FAILED) {
free(mma);
prot, flags, fd, page_aligned_offset);
if (mma->page_aligned_addr == MAP_FAILED) {
free(mma);
page_aligned_addr = mma->page_aligned_addr;
page_aligned_length = mma->page_aligned_length;
free(mma);
page_aligned_addr = mma->page_aligned_addr;
page_aligned_length = mma->page_aligned_length;
free(mma);
- return munmap(page_aligned_addr, page_aligned_length);
+ return bt_munmap(page_aligned_addr, page_aligned_length);
- if (munmap(ds_file->mmap_addr, ds_file->mmap_len)) {
+ if (bt_munmap(ds_file->mmap_addr, ds_file->mmap_len)) {
BT_LOGE("Cannot memory-unmap address %p (size %zu) of file \"%s\" (%p): %s",
ds_file->mmap_addr, ds_file->mmap_len,
ds_file->file->path->str, ds_file->file->fp,
BT_LOGE("Cannot memory-unmap address %p (size %zu) of file \"%s\" (%p): %s",
ds_file->mmap_addr, ds_file->mmap_len,
ds_file->file->path->str, ds_file->file->fp,
& ~(page_size - 1);
/* Map new region */
assert(ds_file->mmap_len);
& ~(page_size - 1);
/* Map new region */
assert(ds_file->mmap_len);
- ds_file->mmap_addr = mmap((void *) 0, ds_file->mmap_len,
+ ds_file->mmap_addr = bt_mmap((void *) 0, ds_file->mmap_len,
PROT_READ, MAP_PRIVATE, fileno(ds_file->file->fp),
ds_file->mmap_offset);
if (ds_file->mmap_addr == MAP_FAILED) {
PROT_READ, MAP_PRIVATE, fileno(ds_file->file->fp),
ds_file->mmap_offset);
if (ds_file->mmap_addr == MAP_FAILED) {