loader: make thirdparty code use allocation callbacks
Use TLS to keep instance pointer and use this for cJSON alloc/free
callback.
diff --git a/loader/dirent_on_windows.c b/loader/dirent_on_windows.c
index 3564a26..5efec82 100644
--- a/loader/dirent_on_windows.c
+++ b/loader/dirent_on_windows.c
@@ -13,7 +13,7 @@
#include <io.h> /* _findfirst and _findnext set errno iff they return -1 */
#include <stdlib.h>
#include <string.h>
-
+#include "loader.h"
#ifdef __cplusplus
extern "C"
{
@@ -39,8 +39,8 @@
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 @@
}
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 f509f31..13e3d02 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -58,6 +58,8 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
{
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 60b38c8..d719640 100644
--- a/loader/loader.h
+++ b/loader/loader.h
@@ -242,6 +242,7 @@
/* 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_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 5d14104..f2926b7 100644
--- a/loader/trampoline.c
+++ b/loader/trampoline.c
@@ -63,6 +63,7 @@
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_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 9207154..5001fe9 100644
--- a/loader/vk_loader_platform.h
+++ b/loader/vk_loader_platform.h
@@ -149,6 +149,7 @@
// 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 @@
// 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) \