blob: 614abb9b4f7f6554b3ee86098bca4eccb895d80b [file] [log] [blame]
Ian Elliott2d4ab1e2015-01-13 17:52:38 -07001/*
Ian Elliott2d4ab1e2015-01-13 17:52:38 -07002 *
Jon Ashburn23d36b12016-02-02 17:47:28 -07003 * Copyright (c) 2015-2016 The Khronos Group Inc.
4 * Copyright (c) 2015-2016 Valve Corporation
5 * Copyright (c) 2015-2016 LunarG, Inc.
Ian Elliott2d4ab1e2015-01-13 17:52:38 -07006 *
Jon Ashburn23d36b12016-02-02 17:47:28 -07007 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and/or associated documentation files (the "Materials"), to
9 * deal in the Materials without restriction, including without limitation the
10 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 * sell copies of the Materials, and to permit persons to whom the Materials are
12 * furnished to do so, subject to the following conditions:
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070013 *
Jon Ashburn23d36b12016-02-02 17:47:28 -070014 * The above copyright notice(s) and this permission notice shall be included in
15 * all copies or substantial portions of the Materials.
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070016 *
Jon Ashburn23d36b12016-02-02 17:47:28 -070017 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070018 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Jon Ashburn23d36b12016-02-02 17:47:28 -070019 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070020 *
Jon Ashburn23d36b12016-02-02 17:47:28 -070021 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
24 * USE OR OTHER DEALINGS IN THE MATERIALS.
25 *
26 * Author: Ian Elliot <ian@lunarg.com>
27 * Author: Jon Ashburn <jon@lunarg.com>
Courtney Goeltzenleuchter05559522015-10-30 11:14:30 -060028 *
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070029 */
Jon Ashburn3f8c3002015-10-15 13:47:58 -060030#pragma once
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070031
Mark Lobodzinski450e4632015-11-24 12:04:15 -070032#if defined(_WIN32)
33// WinSock2.h must be included *BEFORE* windows.h
Mark Lobodzinski450e4632015-11-24 12:04:15 -070034#include <WinSock2.h>
35#endif // _WIN32
36
David Pinedo9316d3b2015-11-06 12:54:48 -070037#include "vulkan/vk_platform.h"
38#include "vulkan/vk_sdk_platform.h"
Cody Northrop33fa0412015-07-08 16:48:37 -060039
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070040#if defined(__linux__)
41/* Linux-specific common code: */
42
43// Headers:
44//#define _GNU_SOURCE 1
45// TBD: Are the contents of the following file used?
46#include <unistd.h>
47// Note: The following file is for dynamic loading:
48#include <dlfcn.h>
49#include <pthread.h>
50#include <assert.h>
Jon Ashburnfc1031e2015-11-17 15:31:02 -070051#include <string.h>
Jon Ashburn2077e382015-06-29 11:25:34 -060052#include <stdbool.h>
Michael Lentine695f2c22015-09-09 12:39:13 -070053#include <stdlib.h>
Jon Ashburn15315172015-07-07 15:06:25 -060054#include <libgen.h>
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070055
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060056// VK Library Filenames, Paths, etc.:
Ian Elliott457810e2015-02-04 11:22:39 -070057#define PATH_SEPERATOR ':'
Jon Ashburn2077e382015-06-29 11:25:34 -060058#define DIRECTORY_SYMBOL '/'
59
Jon Ashburn23d36b12016-02-02 17:47:28 -070060#define VULKAN_ICDCONF_DIR \
61 "/" \
62 "vulkan" \
63 "/" \
64 "icd.d"
65#define VULKAN_ICD_DIR \
66 "/" \
67 "vulkan" \
68 "/" \
69 "icd"
70#define VULKAN_ELAYERCONF_DIR \
71 "/" \
72 "vulkan" \
73 "/" \
74 "explicit_layer.d"
75#define VULKAN_ILAYERCONF_DIR \
76 "/" \
77 "vulkan" \
78 "/" \
79 "implicit_layer.d"
80#define VULKAN_LAYER_DIR \
81 "/" \
82 "vulkan" \
83 "/" \
84 "layer"
James Jonesc28b0a12015-07-23 17:39:37 -070085
86#if defined(LOCALPREFIX)
Jon Ashburn23d36b12016-02-02 17:47:28 -070087#define LOCAL_DRIVERS_INFO \
88 LOCALPREFIX "/" SYSCONFDIR VULKAN_ICDCONF_DIR ":" LOCALPREFIX \
89 "/" DATADIR VULKAN_ICDCONF_DIR ":"
90#define LOCAL_ELAYERS_INFO \
91 LOCALPREFIX "/" SYSCONFDIR VULKAN_ELAYERCONF_DIR ":" LOCALPREFIX \
92 "/" DATADIR VULKAN_ELAYERCONF_DIR ":"
93#define LOCAL_ILAYERS_INFO \
94 LOCALPREFIX "/" SYSCONFDIR VULKAN_ILAYERCONF_DIR ":" LOCALPREFIX \
95 "/" DATADIR VULKAN_ILAYERCONF_DIR ":"
James Jonesc28b0a12015-07-23 17:39:37 -070096#else
97#define LOCAL_DRIVERS_INFO
Jon Ashburn075ce432015-12-17 17:38:24 -070098#define LOCAL_ELAYERS_INFO
99#define LOCAL_ILAYERS_INFO
James Jonesc28b0a12015-07-23 17:39:37 -0700100#endif
101
Jon Ashburn23d36b12016-02-02 17:47:28 -0700102#define DEFAULT_VK_DRIVERS_INFO \
103 LOCAL_DRIVERS_INFO \
104 "/" SYSCONFDIR VULKAN_ICDCONF_DIR ":" \
James Jonesc28b0a12015-07-23 17:39:37 -0700105 "/usr/" DATADIR VULKAN_ICDCONF_DIR
Daniel Dadap6e626842015-09-30 12:09:49 -0500106#define DEFAULT_VK_DRIVERS_PATH ""
Jon Ashburn23d36b12016-02-02 17:47:28 -0700107#define DEFAULT_VK_ELAYERS_INFO \
108 LOCAL_ELAYERS_INFO \
109 "/" SYSCONFDIR VULKAN_ELAYERCONF_DIR ":" \
Jon Ashburnb6822212016-02-16 15:34:16 -0700110 "/usr/" DATADIR VULKAN_ELAYERCONF_DIR
Jon Ashburn23d36b12016-02-02 17:47:28 -0700111#define DEFAULT_VK_ILAYERS_INFO \
112 LOCAL_ILAYERS_INFO \
113 "/" SYSCONFDIR VULKAN_ILAYERCONF_DIR ":" \
James Jonesc28b0a12015-07-23 17:39:37 -0700114 "/usr/" DATADIR VULKAN_ILAYERCONF_DIR
Daniel Dadap6e626842015-09-30 12:09:49 -0500115#define DEFAULT_VK_LAYERS_PATH ""
Jon Ashburn1b958222015-08-06 11:22:33 -0600116#define LAYERS_PATH_ENV "VK_LAYER_PATH"
Jon Ashburnb6822212016-02-16 15:34:16 -0700117#define HOME_VK_DRIVERS_INFO "/.local/share" VULKAN_ICDCONF_DIR
118#define HOME_VK_ELAYERS_INFO "/.local/share" VULKAN_ELAYERCONF_DIR
119#define HOME_VK_ILAYERS_INFO "/.local/share" VULKAN_ILAYERCONF_DIR
Ian Elliott457810e2015-02-04 11:22:39 -0700120
Ian Elliotte5369462015-02-12 16:44:56 -0700121// C99:
Jon Ashburn23d36b12016-02-02 17:47:28 -0700122#define PRINTF_SIZE_T_SPECIFIER "%zu"
Tobin Ehlisb0497852015-02-11 14:24:02 -0700123
Jon Ashburn2077e382015-06-29 11:25:34 -0600124// File IO
Jon Ashburn23d36b12016-02-02 17:47:28 -0700125static inline bool loader_platform_file_exists(const char *path) {
Jon Ashburn2077e382015-06-29 11:25:34 -0600126 if (access(path, F_OK))
127 return false;
128 else
129 return true;
130}
131
Jon Ashburn23d36b12016-02-02 17:47:28 -0700132static inline bool loader_platform_is_path_absolute(const char *path) {
Jon Ashburn15315172015-07-07 15:06:25 -0600133 if (path[0] == '/')
134 return true;
135 else
136 return false;
137}
138
Jon Ashburn23d36b12016-02-02 17:47:28 -0700139static inline char *loader_platform_dirname(char *path) {
Jon Ashburn15315172015-07-07 15:06:25 -0600140 return dirname(path);
141}
142
Jon Ashburn38a497f2016-01-04 14:01:38 -0700143// Environment variables
144
Jon Ashburn23d36b12016-02-02 17:47:28 -0700145static inline char *loader_getenv(const char *name) { return getenv(name); }
Jon Ashburn38a497f2016-01-04 14:01:38 -0700146
Jon Ashburn23d36b12016-02-02 17:47:28 -0700147static inline void loader_free_getenv(const char *val) {}
Jon Ashburn38a497f2016-01-04 14:01:38 -0700148
Jon Ashburn2077e382015-06-29 11:25:34 -0600149// Dynamic Loading of libraries:
Jon Ashburn23d36b12016-02-02 17:47:28 -0700150typedef void *loader_platform_dl_handle;
151static inline loader_platform_dl_handle
152loader_platform_open_library(const char *libPath) {
Chia-I Wu6a218342015-02-18 14:39:54 -0700153 return dlopen(libPath, RTLD_LAZY | RTLD_LOCAL);
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700154}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700155static inline const char *
156loader_platform_open_library_error(const char *libPath) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700157 return dlerror();
158}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700159static inline void
160loader_platform_close_library(loader_platform_dl_handle library) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700161 dlclose(library);
162}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700163static inline void *
164loader_platform_get_proc_address(loader_platform_dl_handle library,
165 const char *name) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700166 assert(library);
167 assert(name);
168 return dlsym(library, name);
169}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700170static inline const char *
171loader_platform_get_proc_address_error(const char *name) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700172 return dlerror();
173}
174
175// Threads:
176typedef pthread_t loader_platform_thread;
Jon Ashburn87d6aa92015-08-28 15:19:27 -0600177#define THREAD_LOCAL_DECL __thread
Jon Ashburn23d36b12016-02-02 17:47:28 -0700178#define LOADER_PLATFORM_THREAD_ONCE_DECLARATION(var) \
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700179 pthread_once_t var = PTHREAD_ONCE_INIT;
Jon Ashburn23d36b12016-02-02 17:47:28 -0700180#define LOADER_PLATFORM_THREAD_ONCE_DEFINITION(var) pthread_once_t var;
181static inline void loader_platform_thread_once(pthread_once_t *ctl,
182 void (*func)(void)) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700183 assert(func != NULL);
184 assert(ctl != NULL);
Michael Lentine695f2c22015-09-09 12:39:13 -0700185 pthread_once(ctl, func);
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700186}
187
188// Thread IDs:
189typedef pthread_t loader_platform_thread_id;
Jon Ashburn23d36b12016-02-02 17:47:28 -0700190static inline loader_platform_thread_id loader_platform_get_thread_id() {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700191 return pthread_self();
192}
193
194// Thread mutex:
195typedef pthread_mutex_t loader_platform_thread_mutex;
Jon Ashburn23d36b12016-02-02 17:47:28 -0700196static inline void
197loader_platform_thread_create_mutex(loader_platform_thread_mutex *pMutex) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700198 pthread_mutex_init(pMutex, NULL);
199}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700200static inline void
201loader_platform_thread_lock_mutex(loader_platform_thread_mutex *pMutex) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700202 pthread_mutex_lock(pMutex);
203}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700204static inline void
205loader_platform_thread_unlock_mutex(loader_platform_thread_mutex *pMutex) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700206 pthread_mutex_unlock(pMutex);
207}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700208static inline void
209loader_platform_thread_delete_mutex(loader_platform_thread_mutex *pMutex) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700210 pthread_mutex_destroy(pMutex);
211}
Mike Stroyaned238bb2015-05-15 08:50:57 -0600212typedef pthread_cond_t loader_platform_thread_cond;
Jon Ashburn23d36b12016-02-02 17:47:28 -0700213static inline void
214loader_platform_thread_init_cond(loader_platform_thread_cond *pCond) {
Mike Stroyaned238bb2015-05-15 08:50:57 -0600215 pthread_cond_init(pCond, NULL);
216}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700217static inline void
218loader_platform_thread_cond_wait(loader_platform_thread_cond *pCond,
219 loader_platform_thread_mutex *pMutex) {
Mike Stroyaned238bb2015-05-15 08:50:57 -0600220 pthread_cond_wait(pCond, pMutex);
221}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700222static inline void
223loader_platform_thread_cond_broadcast(loader_platform_thread_cond *pCond) {
Mike Stroyaned238bb2015-05-15 08:50:57 -0600224 pthread_cond_broadcast(pCond);
225}
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700226
Courtney Goeltzenleuchter7f5aafc2015-07-05 11:28:29 -0600227#define loader_stack_alloc(size) alloca(size)
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700228
229#elif defined(_WIN32) // defined(__linux__)
230/* Windows-specific common code: */
Tobin Ehlis890adf12015-11-02 15:45:19 -0700231// WinBase.h defines CreateSemaphore and synchapi.h defines CreateEvent
232// undefine them to avoid conflicts with VkLayerDispatchTable struct members.
233#ifdef CreateSemaphore
234#undef CreateSemaphore
235#endif
236#ifdef CreateEvent
237#undef CreateEvent
238#endif
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700239#include <assert.h>
Tony Barbour1d825c72015-06-18 16:29:32 -0600240#include <stdio.h>
Jon Ashburnfc1031e2015-11-17 15:31:02 -0700241#include <string.h>
Jon Ashburnffad94d2015-06-30 14:46:22 -0700242#include <io.h>
243#include <stdbool.h>
Cody Northrop33fa0412015-07-08 16:48:37 -0600244#include <shlwapi.h>
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700245#ifdef __cplusplus
246#include <iostream>
247#include <string>
248using namespace std;
249#endif // __cplusplus
250
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600251// VK Library Filenames, Paths, etc.:
Ian Elliott457810e2015-02-04 11:22:39 -0700252#define PATH_SEPERATOR ';'
Jon Ashburn2077e382015-06-29 11:25:34 -0600253#define DIRECTORY_SYMBOL '\\'
Jon Ashburnffad94d2015-06-30 14:46:22 -0700254#define DEFAULT_VK_REGISTRY_HIVE HKEY_LOCAL_MACHINE
255#define DEFAULT_VK_DRIVERS_INFO "SOFTWARE\\Khronos\\Vulkan\\Drivers"
Jon Ashburn2077e382015-06-29 11:25:34 -0600256// TODO: Are these the correct paths
scygan713b1b02015-06-01 19:47:08 +0200257#define DEFAULT_VK_DRIVERS_PATH "C:\\Windows\\System32;C:\\Windows\\SysWow64"
Jon Ashburn075ce432015-12-17 17:38:24 -0700258#define DEFAULT_VK_ELAYERS_INFO "SOFTWARE\\Khronos\\Vulkan\\ExplicitLayers"
259#define DEFAULT_VK_ILAYERS_INFO "SOFTWARE\\Khronos\\Vulkan\\ImplicitLayers"
Jon Ashburn15315172015-07-07 15:06:25 -0600260#define DEFAULT_VK_LAYERS_PATH "C:\\Windows\\System32;C:\\Windows\\SysWow64"
Jon Ashburn1b958222015-08-06 11:22:33 -0600261#define LAYERS_PATH_ENV "VK_LAYER_PATH"
Jon Ashburn83657862016-02-17 13:18:08 -0700262#define HOME_VK_DRIVERS_INFO ""
263#define HOME_VK_ELAYERS_INFO ""
264#define HOME_VK_ILAYERS_INFO ""
Jon Ashburn23d36b12016-02-02 17:47:28 -0700265#define PRINTF_SIZE_T_SPECIFIER "%Iu"
Courtney Goeltzenleuchter22d8d792015-10-07 17:03:42 -0600266
Jon Ashburn2077e382015-06-29 11:25:34 -0600267// File IO
Jon Ashburn23d36b12016-02-02 17:47:28 -0700268static bool loader_platform_file_exists(const char *path) {
Jon Ashburnffad94d2015-06-30 14:46:22 -0700269 if ((_access(path, 0)) == -1)
Jon Ashburn2077e382015-06-29 11:25:34 -0600270 return false;
271 else
272 return true;
273}
274
Jon Ashburn23d36b12016-02-02 17:47:28 -0700275static bool loader_platform_is_path_absolute(const char *path) {
Jon Ashburn15315172015-07-07 15:06:25 -0600276 return !PathIsRelative(path);
277}
278
279// WIN32 runtime doesn't have dirname().
Jon Ashburn23d36b12016-02-02 17:47:28 -0700280static inline char *loader_platform_dirname(char *path) {
Jon Ashburn15315172015-07-07 15:06:25 -0600281 char *current, *next;
282
283 // TODO/TBD: Do we need to deal with the Windows's ":" character?
284
285 for (current = path; *current != '\0'; current = next) {
286 next = strchr(current, DIRECTORY_SYMBOL);
287 if (next == NULL) {
288 if (current != path)
289 *(current - 1) = '\0';
290 return path;
291 } else {
292 // Point one character past the DIRECTORY_SYMBOL:
293 next++;
294 }
295 }
296 return path;
297}
298
299// WIN32 runtime doesn't have basename().
300// Microsoft also doesn't have basename(). Paths are different on Windows, and
301// so this is just a temporary solution in order to get us compiling, so that we
302// can test some scenarios, and develop the correct solution for Windows.
Jon Ashburn23d36b12016-02-02 17:47:28 -0700303// TODO: Develop a better, permanent solution for Windows, to replace this
304// temporary code:
305static char *loader_platform_basename(char *pathname) {
Jon Ashburn15315172015-07-07 15:06:25 -0600306 char *current, *next;
307
Jon Ashburn23d36b12016-02-02 17:47:28 -0700308 // TODO/TBD: Do we need to deal with the Windows's ":" character?
Jon Ashburn15315172015-07-07 15:06:25 -0600309
310 for (current = pathname; *current != '\0'; current = next) {
311 next = strchr(current, DIRECTORY_SYMBOL);
312 if (next == NULL) {
313 // No more DIRECTORY_SYMBOL's so return p:
314 return current;
315 } else {
316 // Point one character past the DIRECTORY_SYMBOL:
317 next++;
318 }
319 }
320 // We shouldn't get to here, but this makes the compiler happy:
321 return current;
322}
323
Jon Ashburn38a497f2016-01-04 14:01:38 -0700324// Environment variables
325
Jon Ashburn23d36b12016-02-02 17:47:28 -0700326static inline char *loader_getenv(const char *name) {
Jon Ashburn38a497f2016-01-04 14:01:38 -0700327 char *retVal;
328 DWORD valSize;
329
330 valSize = GetEnvironmentVariableA(name, NULL, 0);
331
332 // valSize DOES include the null terminator, so for any set variable
333 // will always be at least 1. If it's 0, the variable wasn't set.
334 if (valSize == 0)
335 return NULL;
336
Jon Ashburn23d36b12016-02-02 17:47:28 -0700337 // TODO; FIXME This should be using any app defined memory allocation
Jon Ashburn38a497f2016-01-04 14:01:38 -0700338 retVal = (char *)malloc(valSize);
339
340 GetEnvironmentVariableA(name, retVal, valSize);
341
342 return retVal;
343}
344
Jon Ashburn23d36b12016-02-02 17:47:28 -0700345static inline void loader_free_getenv(const char *val) { free((void *)val); }
Jon Ashburn38a497f2016-01-04 14:01:38 -0700346
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700347// Dynamic Loading:
348typedef HMODULE loader_platform_dl_handle;
Jon Ashburn23d36b12016-02-02 17:47:28 -0700349static loader_platform_dl_handle
350loader_platform_open_library(const char *libPath) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700351 return LoadLibrary(libPath);
352}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700353static char *loader_platform_open_library_error(const char *libPath) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700354 static char errorMsg[120];
355 snprintf(errorMsg, 119, "Failed to open dynamic library \"%s\"", libPath);
356 return errorMsg;
357}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700358static void loader_platform_close_library(loader_platform_dl_handle library) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700359 FreeLibrary(library);
360}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700361static void *loader_platform_get_proc_address(loader_platform_dl_handle library,
362 const char *name) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700363 assert(library);
364 assert(name);
365 return GetProcAddress(library, name);
366}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700367static char *loader_platform_get_proc_address_error(const char *name) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700368 static char errorMsg[120];
Jon Ashburn23d36b12016-02-02 17:47:28 -0700369 snprintf(errorMsg, 119, "Failed to find function \"%s\" in dynamic library",
370 name);
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700371 return errorMsg;
372}
373
374// Threads:
375typedef HANDLE loader_platform_thread;
Jon Ashburn87d6aa92015-08-28 15:19:27 -0600376#define THREAD_LOCAL_DECL __declspec(thread)
Jon Ashburn23d36b12016-02-02 17:47:28 -0700377#define LOADER_PLATFORM_THREAD_ONCE_DECLARATION(var) \
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700378 INIT_ONCE var = INIT_ONCE_STATIC_INIT;
Jon Ashburn23d36b12016-02-02 17:47:28 -0700379#define LOADER_PLATFORM_THREAD_ONCE_DEFINITION(var) INIT_ONCE var;
380static BOOL CALLBACK
381InitFuncWrapper(PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context) {
Piers Daniell4da523a2015-02-23 16:23:13 -0700382 void (*func)(void) = (void (*)(void))Parameter;
383 func();
384 return TRUE;
385}
386
Jon Ashburn23d36b12016-02-02 17:47:28 -0700387static void loader_platform_thread_once(void *ctl, void (*func)(void)) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700388 assert(func != NULL);
389 assert(ctl != NULL);
Jon Ashburn23d36b12016-02-02 17:47:28 -0700390 InitOnceExecuteOnce((PINIT_ONCE)ctl, InitFuncWrapper, func, NULL);
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700391}
392
393// Thread IDs:
394typedef DWORD loader_platform_thread_id;
Jon Ashburn23d36b12016-02-02 17:47:28 -0700395static loader_platform_thread_id loader_platform_get_thread_id() {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700396 return GetCurrentThreadId();
397}
398
399// Thread mutex:
400typedef CRITICAL_SECTION loader_platform_thread_mutex;
Jon Ashburn23d36b12016-02-02 17:47:28 -0700401static void
402loader_platform_thread_create_mutex(loader_platform_thread_mutex *pMutex) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700403 InitializeCriticalSection(pMutex);
404}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700405static void
406loader_platform_thread_lock_mutex(loader_platform_thread_mutex *pMutex) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700407 EnterCriticalSection(pMutex);
408}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700409static void
410loader_platform_thread_unlock_mutex(loader_platform_thread_mutex *pMutex) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700411 LeaveCriticalSection(pMutex);
412}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700413static void
414loader_platform_thread_delete_mutex(loader_platform_thread_mutex *pMutex) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700415 DeleteCriticalSection(pMutex);
416}
Mike Stroyanc3d98332015-05-15 17:34:51 -0600417typedef CONDITION_VARIABLE loader_platform_thread_cond;
Jon Ashburn23d36b12016-02-02 17:47:28 -0700418static void
419loader_platform_thread_init_cond(loader_platform_thread_cond *pCond) {
Mike Stroyanc3d98332015-05-15 17:34:51 -0600420 InitializeConditionVariable(pCond);
421}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700422static void
423loader_platform_thread_cond_wait(loader_platform_thread_cond *pCond,
424 loader_platform_thread_mutex *pMutex) {
Mike Stroyanc3d98332015-05-15 17:34:51 -0600425 SleepConditionVariableCS(pCond, pMutex, INFINITE);
426}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700427static void
428loader_platform_thread_cond_broadcast(loader_platform_thread_cond *pCond) {
Mike Stroyanc3d98332015-05-15 17:34:51 -0600429 WakeAllConditionVariable(pCond);
430}
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700431
Ian Elliott5aa4ea22015-03-31 15:32:41 -0600432// Windows Registry:
Jon Ashburn23d36b12016-02-02 17:47:28 -0700433char *loader_get_registry_string(const HKEY hive, const LPCTSTR sub_key,
Ian Elliott5aa4ea22015-03-31 15:32:41 -0600434 const char *value);
435
Jon Ashburn3f8c3002015-10-15 13:47:58 -0600436#define loader_stack_alloc(size) _alloca(size)
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700437#else // defined(_WIN32)
438
439#error The "loader_platform.h" file must be modified for this OS.
440
441// NOTE: In order to support another OS, an #elif needs to be added (above the
442// "#else // defined(_WIN32)") for that OS, and OS-specific versions of the
443// contents of this file must be created.
444
445// NOTE: Other OS-specific changes are also needed for this OS. Search for
446// files with "WIN32" in it, as a quick way to find files that must be changed.
447
448#endif // defined(_WIN32)
449
jon547bbee2015-10-29 14:57:03 -0600450// returns true if the given string appears to be a relative or absolute
451// path, as opposed to a bare filename.
Jon Ashburn23d36b12016-02-02 17:47:28 -0700452static inline bool loader_platform_is_path(const char *path) {
jon547bbee2015-10-29 14:57:03 -0600453 return strchr(path, DIRECTORY_SYMBOL) != NULL;
454}