From d42181fd35f4964c14c9fb87506aa07c7f263765 Mon Sep 17 00:00:00 2001 From: Jon Ashburn Date: Fri, 28 Aug 2015 15:19:27 -0600 Subject: loader: make thirdparty code use allocation callbacks Use TLS to keep instance pointer and use this for cJSON alloc/free callback. --- loader/dirent_on_windows.c | 12 ++++++------ loader/loader.c | 33 +++++++++++++++++++++++++++------ loader/loader.h | 5 +++++ loader/trampoline.c | 2 +- loader/vk_loader_platform.h | 2 ++ 5 files changed, 41 insertions(+), 13 deletions(-) diff --git a/loader/dirent_on_windows.c b/loader/dirent_on_windows.c index 3564a26f..5efec829 100644 --- a/loader/dirent_on_windows.c +++ b/loader/dirent_on_windows.c @@ -13,7 +13,7 @@ #include /* _findfirst and _findnext set errno iff they return -1 */ #include #include - +#include "loader.h" #ifdef __cplusplus extern "C" { @@ -39,8 +39,8 @@ DIR *opendir(const char *name) const char *all = /* search pattern must end with suitable wildcard */ strchr("/\\", name[base_length - 1]) ? "*" : "/*"; - if((dir = (DIR *) malloc(sizeof *dir)) != 0 && - (dir->name = (char *) malloc(base_length + strlen(all) + 1)) != 0) + if((dir = (DIR *) loader_tls_heap_alloc(sizeof *dir)) != 0 && + (dir->name = (char *) loader_tls_heap_alloc(base_length + strlen(all) + 1)) != 0) { strcat(strcpy(dir->name, name), all); @@ -51,14 +51,14 @@ DIR *opendir(const char *name) } else /* rollback */ { - free(dir->name); - free(dir); + loader_tls_heap_free(dir->name); + loader_tls_heap_free(dir); dir = 0; } } else /* rollback */ { - free(dir); + loader_tls_heap_free(dir); dir = 0; errno = ENOMEM; } diff --git a/loader/loader.c b/loader/loader.c index f509f31d..13e3d022 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -58,6 +58,8 @@ static void loader_remove_layer_lib( struct loader_layer_properties *layer_prop); struct loader_struct loader = {0}; +// TLS for instance for alloc/free callbacks +THREAD_LOCAL_DECL struct loader_instance *tls_instance; static PFN_vkVoidFunction VKAPI loader_GetInstanceProcAddr( VkInstance instance, @@ -173,6 +175,16 @@ void* loader_heap_realloc( return realloc(pMem, size); } +void *loader_tls_heap_alloc(size_t size) +{ + return loader_heap_alloc(tls_instance, size, VK_SYSTEM_ALLOC_TYPE_INTERNAL); +} + +void loader_tls_heap_free(void *pMem) +{ + return loader_heap_free(tls_instance, pMem); +} + static void loader_log(VkFlags msg_type, int32_t msg_code, const char *format, ...) { @@ -1172,6 +1184,13 @@ void loader_initialize(void) // initialize logging loader_debug_init(); + + // initial cJSON to use alloc callbacks + cJSON_Hooks alloc_fns = { + .malloc_fn = loader_tls_heap_alloc, + .free_fn = loader_tls_heap_free, + }; + cJSON_InitHooks(&alloc_fns); } struct loader_manifest_files { @@ -1384,7 +1403,7 @@ static void loader_add_layer_properties(const struct loader_instance *inst, filename, file_vers); if (strcmp(file_vers, "\"0.9.0\"") != 0) loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Unexpected manifest file version (expected 0.9.0), may cause errors"); - free(file_vers); + loader_tls_heap_free(file_vers); layer_node = cJSON_GetObjectItem(json, "layer"); if (layer_node == NULL) { @@ -1411,7 +1430,7 @@ static void loader_add_layer_properties(const struct loader_instance *inst, temp[strlen(temp) - 1] = '\0'; \ var = loader_stack_alloc(strlen(temp) + 1); \ strcpy(var, &temp[1]); \ - free(temp); \ + loader_tls_heap_free(temp); \ } GET_JSON_ITEM(layer_node, name) GET_JSON_ITEM(layer_node, type) @@ -1504,7 +1523,7 @@ static void loader_add_layer_properties(const struct loader_instance *inst, temp[strlen(temp) - 1] = '\0'; \ var = loader_stack_alloc(strlen(temp) + 1); \ strcpy(var, &temp[1]); \ - free(temp); \ + loader_tls_heap_free(temp); \ } cJSON *instance_extensions, *device_extensions, *functions, *enable_environment; @@ -1798,7 +1817,7 @@ void loader_icd_scan( file_str, file_vers); if (strcmp(file_vers, "\"1.0.0\"") != 0) loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Unexpected manifest file version (expected 1.0.0), may cause errors"); - free(file_vers); + loader_tls_heap_free(file_vers); item = cJSON_GetObjectItem(json, "ICD"); if (item != NULL) { item = cJSON_GetObjectItem(item, "library_path"); @@ -1806,7 +1825,7 @@ void loader_icd_scan( char *temp= cJSON_Print(item); if (!temp || strlen(temp) == 0) { loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Can't find \"library_path\" in ICD JSON file %s, skipping", file_str); - free(temp); + loader_tls_heap_free(temp); loader_heap_free(inst, file_str); cJSON_Delete(json); continue; @@ -1815,7 +1834,7 @@ void loader_icd_scan( temp[strlen(temp) - 1] = '\0'; char *library_path = loader_stack_alloc(strlen(temp) + 1); strcpy(library_path, &temp[1]); - free(temp); + loader_tls_heap_free(temp); if (!library_path || strlen(library_path) == 0) { loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Can't find \"library_path\" in ICD JSON file %s, skipping", file_str); loader_heap_free(inst, file_str); @@ -3075,6 +3094,7 @@ LOADER_EXPORT VkResult VKAPI vkGetGlobalExtensionProperties( struct loader_icd_libs icd_libs; uint32_t copy_size; + tls_instance = NULL; if (pCount == NULL) { return VK_ERROR_INVALID_POINTER; } @@ -3141,6 +3161,7 @@ LOADER_EXPORT VkResult VKAPI vkGetGlobalLayerProperties( { struct loader_layer_list instance_layer_list; + tls_instance = NULL; loader_platform_thread_once(&once_init, loader_initialize); diff --git a/loader/loader.h b/loader/loader.h index 60b38c83..d7196405 100644 --- a/loader/loader.h +++ b/loader/loader.h @@ -242,6 +242,7 @@ static inline void loader_init_dispatch(void* obj, const void *data) /* global variables used across files */ extern struct loader_struct loader; +extern THREAD_LOCAL_DECL struct loader_instance *tls_instance; extern LOADER_PLATFORM_THREAD_ONCE_DEFINITION(once_init); extern loader_platform_thread_mutex loader_lock; extern const VkLayerInstanceDispatchTable instance_disp; @@ -406,4 +407,8 @@ void* loader_aligned_heap_alloc( void loader_heap_free( const struct loader_instance *instance, void *pMem); + +void *loader_tls_heap_alloc(size_t size); + +void loader_tls_heap_free(void *pMem); #endif /* LOADER_H */ diff --git a/loader/trampoline.c b/loader/trampoline.c index 5d14104d..f2926b7c 100644 --- a/loader/trampoline.c +++ b/loader/trampoline.c @@ -63,6 +63,7 @@ LOADER_EXPORT VkResult VKAPI vkCreateInstance( return VK_ERROR_OUT_OF_HOST_MEMORY; } + tls_instance = ptr_instance; loader_platform_thread_lock_mutex(&loader_lock); memset(ptr_instance, 0, sizeof(struct loader_instance)); @@ -195,7 +196,6 @@ LOADER_EXPORT VkResult VKAPI vkDestroyInstance( loader_deactivate_instance_layers(ptr_instance); loader_heap_free(ptr_instance, ptr_instance->disp); loader_heap_free(ptr_instance, ptr_instance); - loader_platform_thread_unlock_mutex(&loader_lock); return res; diff --git a/loader/vk_loader_platform.h b/loader/vk_loader_platform.h index 92071549..5001fe91 100644 --- a/loader/vk_loader_platform.h +++ b/loader/vk_loader_platform.h @@ -149,6 +149,7 @@ static inline char * loader_platform_get_proc_address_error(const char *name) // Threads: typedef pthread_t loader_platform_thread; +#define THREAD_LOCAL_DECL __thread #define LOADER_PLATFORM_THREAD_ONCE_DECLARATION(var) \ pthread_once_t var = PTHREAD_ONCE_INIT; #define LOADER_PLATFORM_THREAD_ONCE_DEFINITION(var) \ @@ -333,6 +334,7 @@ static char * loader_platform_get_proc_address_error(const char *name) // Threads: typedef HANDLE loader_platform_thread; +#define THREAD_LOCAL_DECL __declspec(thread) #define LOADER_PLATFORM_THREAD_ONCE_DECLARATION(var) \ INIT_ONCE var = INIT_ONCE_STATIC_INIT; #define LOADER_PLATFORM_THREAD_ONCE_DEFINITION(var) \ -- cgit v1.2.3