blob: d13185394ce0017fa6dc9283a4eccf2353ebc494 [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 Ashburn3ebf1252016-04-19 11:30:31 -06007 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070010 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -060011 * http://www.apache.org/licenses/LICENSE-2.0
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070012 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -060013 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Jon Ashburn23d36b12016-02-02 17:47:28 -070018 *
19 * Author: Ian Elliot <ian@lunarg.com>
20 * Author: Jon Ashburn <jon@lunarg.com>
Courtney Goeltzenleuchter05559522015-10-30 11:14:30 -060021 *
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070022 */
Jon Ashburn3f8c3002015-10-15 13:47:58 -060023#pragma once
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070024
Mark Lobodzinski450e4632015-11-24 12:04:15 -070025#if defined(_WIN32)
26// WinSock2.h must be included *BEFORE* windows.h
Mark Lobodzinski450e4632015-11-24 12:04:15 -070027#include <WinSock2.h>
28#endif // _WIN32
29
David Pinedo9316d3b2015-11-06 12:54:48 -070030#include "vulkan/vk_platform.h"
31#include "vulkan/vk_sdk_platform.h"
Cody Northrop33fa0412015-07-08 16:48:37 -060032
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070033#if defined(__linux__)
34/* Linux-specific common code: */
35
36// Headers:
37//#define _GNU_SOURCE 1
38// TBD: Are the contents of the following file used?
39#include <unistd.h>
40// Note: The following file is for dynamic loading:
41#include <dlfcn.h>
42#include <pthread.h>
43#include <assert.h>
Jon Ashburnfc1031e2015-11-17 15:31:02 -070044#include <string.h>
Jon Ashburn2077e382015-06-29 11:25:34 -060045#include <stdbool.h>
Michael Lentine695f2c22015-09-09 12:39:13 -070046#include <stdlib.h>
Jon Ashburn15315172015-07-07 15:06:25 -060047#include <libgen.h>
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070048
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060049// VK Library Filenames, Paths, etc.:
Ian Elliott457810e2015-02-04 11:22:39 -070050#define PATH_SEPERATOR ':'
Jon Ashburn2077e382015-06-29 11:25:34 -060051#define DIRECTORY_SYMBOL '/'
52
Jon Ashburn23d36b12016-02-02 17:47:28 -070053#define VULKAN_ICDCONF_DIR \
54 "/" \
55 "vulkan" \
56 "/" \
57 "icd.d"
58#define VULKAN_ICD_DIR \
59 "/" \
60 "vulkan" \
61 "/" \
62 "icd"
63#define VULKAN_ELAYERCONF_DIR \
64 "/" \
65 "vulkan" \
66 "/" \
67 "explicit_layer.d"
68#define VULKAN_ILAYERCONF_DIR \
69 "/" \
70 "vulkan" \
71 "/" \
72 "implicit_layer.d"
73#define VULKAN_LAYER_DIR \
74 "/" \
75 "vulkan" \
76 "/" \
77 "layer"
James Jonesc28b0a12015-07-23 17:39:37 -070078
79#if defined(LOCALPREFIX)
Jon Ashburn23d36b12016-02-02 17:47:28 -070080#define LOCAL_DRIVERS_INFO \
81 LOCALPREFIX "/" SYSCONFDIR VULKAN_ICDCONF_DIR ":" LOCALPREFIX \
82 "/" DATADIR VULKAN_ICDCONF_DIR ":"
83#define LOCAL_ELAYERS_INFO \
84 LOCALPREFIX "/" SYSCONFDIR VULKAN_ELAYERCONF_DIR ":" LOCALPREFIX \
85 "/" DATADIR VULKAN_ELAYERCONF_DIR ":"
86#define LOCAL_ILAYERS_INFO \
87 LOCALPREFIX "/" SYSCONFDIR VULKAN_ILAYERCONF_DIR ":" LOCALPREFIX \
88 "/" DATADIR VULKAN_ILAYERCONF_DIR ":"
James Jonesc28b0a12015-07-23 17:39:37 -070089#else
90#define LOCAL_DRIVERS_INFO
Jon Ashburn075ce432015-12-17 17:38:24 -070091#define LOCAL_ELAYERS_INFO
92#define LOCAL_ILAYERS_INFO
James Jonesc28b0a12015-07-23 17:39:37 -070093#endif
94
Jon Ashburn23d36b12016-02-02 17:47:28 -070095#define DEFAULT_VK_DRIVERS_INFO \
96 LOCAL_DRIVERS_INFO \
97 "/" SYSCONFDIR VULKAN_ICDCONF_DIR ":" \
James Jonesc28b0a12015-07-23 17:39:37 -070098 "/usr/" DATADIR VULKAN_ICDCONF_DIR
Jamie Madill2fcbd152016-04-27 16:33:23 -040099#define DEFAULT_VK_DRIVERS_PATH ""
Jon Ashburn23d36b12016-02-02 17:47:28 -0700100#define DEFAULT_VK_ELAYERS_INFO \
101 LOCAL_ELAYERS_INFO \
102 "/" SYSCONFDIR VULKAN_ELAYERCONF_DIR ":" \
Jon Ashburnb6822212016-02-16 15:34:16 -0700103 "/usr/" DATADIR VULKAN_ELAYERCONF_DIR
Jon Ashburn23d36b12016-02-02 17:47:28 -0700104#define DEFAULT_VK_ILAYERS_INFO \
105 LOCAL_ILAYERS_INFO \
106 "/" SYSCONFDIR VULKAN_ILAYERCONF_DIR ":" \
James Jonesc28b0a12015-07-23 17:39:37 -0700107 "/usr/" DATADIR VULKAN_ILAYERCONF_DIR
Jamie Madill2fcbd152016-04-27 16:33:23 -0400108#define DEFAULT_VK_LAYERS_PATH ""
Jamie Madill00c3c912016-04-06 18:26:46 -0400109#if !defined(LAYERS_SOURCE_PATH)
110#define LAYERS_SOURCE_PATH NULL
111#endif
Jon Ashburn1b958222015-08-06 11:22:33 -0600112#define LAYERS_PATH_ENV "VK_LAYER_PATH"
Jon Ashburnb6822212016-02-16 15:34:16 -0700113#define HOME_VK_DRIVERS_INFO "/.local/share" VULKAN_ICDCONF_DIR
114#define HOME_VK_ELAYERS_INFO "/.local/share" VULKAN_ELAYERCONF_DIR
115#define HOME_VK_ILAYERS_INFO "/.local/share" VULKAN_ILAYERCONF_DIR
Ian Elliott457810e2015-02-04 11:22:39 -0700116
Ian Elliotte5369462015-02-12 16:44:56 -0700117// C99:
Jon Ashburn23d36b12016-02-02 17:47:28 -0700118#define PRINTF_SIZE_T_SPECIFIER "%zu"
Tobin Ehlisb0497852015-02-11 14:24:02 -0700119
Jon Ashburn2077e382015-06-29 11:25:34 -0600120// File IO
Jon Ashburn23d36b12016-02-02 17:47:28 -0700121static inline bool loader_platform_file_exists(const char *path) {
Jon Ashburn2077e382015-06-29 11:25:34 -0600122 if (access(path, F_OK))
123 return false;
124 else
125 return true;
126}
127
Jon Ashburn23d36b12016-02-02 17:47:28 -0700128static inline bool loader_platform_is_path_absolute(const char *path) {
Jon Ashburn15315172015-07-07 15:06:25 -0600129 if (path[0] == '/')
130 return true;
131 else
132 return false;
133}
134
Jon Ashburn23d36b12016-02-02 17:47:28 -0700135static inline char *loader_platform_dirname(char *path) {
Jon Ashburn15315172015-07-07 15:06:25 -0600136 return dirname(path);
137}
138
Jon Ashburn2077e382015-06-29 11:25:34 -0600139// Dynamic Loading of libraries:
Jon Ashburn23d36b12016-02-02 17:47:28 -0700140typedef void *loader_platform_dl_handle;
141static inline loader_platform_dl_handle
142loader_platform_open_library(const char *libPath) {
Chia-I Wu6a218342015-02-18 14:39:54 -0700143 return dlopen(libPath, RTLD_LAZY | RTLD_LOCAL);
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700144}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700145static inline const char *
146loader_platform_open_library_error(const char *libPath) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700147 return dlerror();
148}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700149static inline void
150loader_platform_close_library(loader_platform_dl_handle library) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700151 dlclose(library);
152}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700153static inline void *
154loader_platform_get_proc_address(loader_platform_dl_handle library,
155 const char *name) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700156 assert(library);
157 assert(name);
158 return dlsym(library, name);
159}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700160static inline const char *
161loader_platform_get_proc_address_error(const char *name) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700162 return dlerror();
163}
164
165// Threads:
166typedef pthread_t loader_platform_thread;
Jon Ashburn87d6aa92015-08-28 15:19:27 -0600167#define THREAD_LOCAL_DECL __thread
Jon Ashburn23d36b12016-02-02 17:47:28 -0700168#define LOADER_PLATFORM_THREAD_ONCE_DECLARATION(var) \
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700169 pthread_once_t var = PTHREAD_ONCE_INIT;
Jon Ashburn23d36b12016-02-02 17:47:28 -0700170#define LOADER_PLATFORM_THREAD_ONCE_DEFINITION(var) pthread_once_t var;
171static inline void loader_platform_thread_once(pthread_once_t *ctl,
172 void (*func)(void)) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700173 assert(func != NULL);
174 assert(ctl != NULL);
Michael Lentine695f2c22015-09-09 12:39:13 -0700175 pthread_once(ctl, func);
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700176}
177
178// Thread IDs:
179typedef pthread_t loader_platform_thread_id;
Jon Ashburn23d36b12016-02-02 17:47:28 -0700180static inline loader_platform_thread_id loader_platform_get_thread_id() {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700181 return pthread_self();
182}
183
184// Thread mutex:
185typedef pthread_mutex_t loader_platform_thread_mutex;
Jon Ashburn23d36b12016-02-02 17:47:28 -0700186static inline void
187loader_platform_thread_create_mutex(loader_platform_thread_mutex *pMutex) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700188 pthread_mutex_init(pMutex, NULL);
189}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700190static inline void
191loader_platform_thread_lock_mutex(loader_platform_thread_mutex *pMutex) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700192 pthread_mutex_lock(pMutex);
193}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700194static inline void
195loader_platform_thread_unlock_mutex(loader_platform_thread_mutex *pMutex) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700196 pthread_mutex_unlock(pMutex);
197}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700198static inline void
199loader_platform_thread_delete_mutex(loader_platform_thread_mutex *pMutex) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700200 pthread_mutex_destroy(pMutex);
201}
Mike Stroyaned238bb2015-05-15 08:50:57 -0600202typedef pthread_cond_t loader_platform_thread_cond;
Jon Ashburn23d36b12016-02-02 17:47:28 -0700203static inline void
204loader_platform_thread_init_cond(loader_platform_thread_cond *pCond) {
Mike Stroyaned238bb2015-05-15 08:50:57 -0600205 pthread_cond_init(pCond, NULL);
206}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700207static inline void
208loader_platform_thread_cond_wait(loader_platform_thread_cond *pCond,
209 loader_platform_thread_mutex *pMutex) {
Mike Stroyaned238bb2015-05-15 08:50:57 -0600210 pthread_cond_wait(pCond, pMutex);
211}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700212static inline void
213loader_platform_thread_cond_broadcast(loader_platform_thread_cond *pCond) {
Mike Stroyaned238bb2015-05-15 08:50:57 -0600214 pthread_cond_broadcast(pCond);
215}
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700216
Courtney Goeltzenleuchter7f5aafc2015-07-05 11:28:29 -0600217#define loader_stack_alloc(size) alloca(size)
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700218
219#elif defined(_WIN32) // defined(__linux__)
220/* Windows-specific common code: */
Tobin Ehlis890adf12015-11-02 15:45:19 -0700221// WinBase.h defines CreateSemaphore and synchapi.h defines CreateEvent
222// undefine them to avoid conflicts with VkLayerDispatchTable struct members.
223#ifdef CreateSemaphore
224#undef CreateSemaphore
225#endif
226#ifdef CreateEvent
227#undef CreateEvent
228#endif
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700229#include <assert.h>
Tony Barbour1d825c72015-06-18 16:29:32 -0600230#include <stdio.h>
Jon Ashburnfc1031e2015-11-17 15:31:02 -0700231#include <string.h>
Jon Ashburnffad94d2015-06-30 14:46:22 -0700232#include <io.h>
233#include <stdbool.h>
Cody Northrop33fa0412015-07-08 16:48:37 -0600234#include <shlwapi.h>
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700235#ifdef __cplusplus
236#include <iostream>
237#include <string>
238using namespace std;
239#endif // __cplusplus
240
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600241// VK Library Filenames, Paths, etc.:
Ian Elliott457810e2015-02-04 11:22:39 -0700242#define PATH_SEPERATOR ';'
Jon Ashburn2077e382015-06-29 11:25:34 -0600243#define DIRECTORY_SYMBOL '\\'
Jon Ashburnffad94d2015-06-30 14:46:22 -0700244#define DEFAULT_VK_REGISTRY_HIVE HKEY_LOCAL_MACHINE
245#define DEFAULT_VK_DRIVERS_INFO "SOFTWARE\\Khronos\\Vulkan\\Drivers"
Jamie Madill2fcbd152016-04-27 16:33:23 -0400246// TODO: Are these the correct paths
247#define DEFAULT_VK_DRIVERS_PATH ""
Jon Ashburn075ce432015-12-17 17:38:24 -0700248#define DEFAULT_VK_ELAYERS_INFO "SOFTWARE\\Khronos\\Vulkan\\ExplicitLayers"
249#define DEFAULT_VK_ILAYERS_INFO "SOFTWARE\\Khronos\\Vulkan\\ImplicitLayers"
Jamie Madill00c3c912016-04-06 18:26:46 -0400250#if !defined(DEFAULT_VK_LAYERS_PATH)
Jamie Madill2fcbd152016-04-27 16:33:23 -0400251#define DEFAULT_VK_LAYERS_PATH ""
Jamie Madill00c3c912016-04-06 18:26:46 -0400252#endif
253#if !defined(LAYERS_SOURCE_PATH)
254#define LAYERS_SOURCE_PATH NULL
255#endif
Jon Ashburn1b958222015-08-06 11:22:33 -0600256#define LAYERS_PATH_ENV "VK_LAYER_PATH"
Jon Ashburn83657862016-02-17 13:18:08 -0700257#define HOME_VK_DRIVERS_INFO ""
258#define HOME_VK_ELAYERS_INFO ""
259#define HOME_VK_ILAYERS_INFO ""
Jon Ashburn23d36b12016-02-02 17:47:28 -0700260#define PRINTF_SIZE_T_SPECIFIER "%Iu"
Courtney Goeltzenleuchter22d8d792015-10-07 17:03:42 -0600261
Jon Ashburn2077e382015-06-29 11:25:34 -0600262// File IO
Jon Ashburn23d36b12016-02-02 17:47:28 -0700263static bool loader_platform_file_exists(const char *path) {
Jon Ashburnffad94d2015-06-30 14:46:22 -0700264 if ((_access(path, 0)) == -1)
Jon Ashburn2077e382015-06-29 11:25:34 -0600265 return false;
266 else
267 return true;
268}
269
Jon Ashburn23d36b12016-02-02 17:47:28 -0700270static bool loader_platform_is_path_absolute(const char *path) {
Jon Ashburn15315172015-07-07 15:06:25 -0600271 return !PathIsRelative(path);
272}
273
274// WIN32 runtime doesn't have dirname().
Jon Ashburn23d36b12016-02-02 17:47:28 -0700275static inline char *loader_platform_dirname(char *path) {
Jon Ashburn15315172015-07-07 15:06:25 -0600276 char *current, *next;
277
278 // TODO/TBD: Do we need to deal with the Windows's ":" character?
279
280 for (current = path; *current != '\0'; current = next) {
281 next = strchr(current, DIRECTORY_SYMBOL);
282 if (next == NULL) {
283 if (current != path)
284 *(current - 1) = '\0';
285 return path;
286 } else {
287 // Point one character past the DIRECTORY_SYMBOL:
288 next++;
289 }
290 }
291 return path;
292}
293
294// WIN32 runtime doesn't have basename().
295// Microsoft also doesn't have basename(). Paths are different on Windows, and
296// so this is just a temporary solution in order to get us compiling, so that we
297// can test some scenarios, and develop the correct solution for Windows.
Jon Ashburn23d36b12016-02-02 17:47:28 -0700298// TODO: Develop a better, permanent solution for Windows, to replace this
299// temporary code:
300static char *loader_platform_basename(char *pathname) {
Jon Ashburn15315172015-07-07 15:06:25 -0600301 char *current, *next;
302
Jon Ashburn23d36b12016-02-02 17:47:28 -0700303 // TODO/TBD: Do we need to deal with the Windows's ":" character?
Jon Ashburn15315172015-07-07 15:06:25 -0600304
305 for (current = pathname; *current != '\0'; current = next) {
306 next = strchr(current, DIRECTORY_SYMBOL);
307 if (next == NULL) {
308 // No more DIRECTORY_SYMBOL's so return p:
309 return current;
310 } else {
311 // Point one character past the DIRECTORY_SYMBOL:
312 next++;
313 }
314 }
315 // We shouldn't get to here, but this makes the compiler happy:
316 return current;
317}
318
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700319// Dynamic Loading:
320typedef HMODULE loader_platform_dl_handle;
Jon Ashburn23d36b12016-02-02 17:47:28 -0700321static loader_platform_dl_handle
322loader_platform_open_library(const char *libPath) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700323 return LoadLibrary(libPath);
324}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700325static char *loader_platform_open_library_error(const char *libPath) {
Tobin Ehlisb2dfb552016-06-07 06:07:13 -0600326 static char errorMsg[164];
327 snprintf(errorMsg, 163, "Failed to open dynamic library \"%s\"", libPath);
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700328 return errorMsg;
329}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700330static void loader_platform_close_library(loader_platform_dl_handle library) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700331 FreeLibrary(library);
332}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700333static void *loader_platform_get_proc_address(loader_platform_dl_handle library,
334 const char *name) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700335 assert(library);
336 assert(name);
337 return GetProcAddress(library, name);
338}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700339static char *loader_platform_get_proc_address_error(const char *name) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700340 static char errorMsg[120];
Jon Ashburn23d36b12016-02-02 17:47:28 -0700341 snprintf(errorMsg, 119, "Failed to find function \"%s\" in dynamic library",
342 name);
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700343 return errorMsg;
344}
345
346// Threads:
347typedef HANDLE loader_platform_thread;
Jon Ashburn87d6aa92015-08-28 15:19:27 -0600348#define THREAD_LOCAL_DECL __declspec(thread)
Jon Ashburn23d36b12016-02-02 17:47:28 -0700349#define LOADER_PLATFORM_THREAD_ONCE_DECLARATION(var) \
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700350 INIT_ONCE var = INIT_ONCE_STATIC_INIT;
Jon Ashburn23d36b12016-02-02 17:47:28 -0700351#define LOADER_PLATFORM_THREAD_ONCE_DEFINITION(var) INIT_ONCE var;
352static BOOL CALLBACK
353InitFuncWrapper(PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context) {
Piers Daniell4da523a2015-02-23 16:23:13 -0700354 void (*func)(void) = (void (*)(void))Parameter;
355 func();
356 return TRUE;
357}
358
Jon Ashburn23d36b12016-02-02 17:47:28 -0700359static void loader_platform_thread_once(void *ctl, void (*func)(void)) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700360 assert(func != NULL);
361 assert(ctl != NULL);
Jon Ashburn23d36b12016-02-02 17:47:28 -0700362 InitOnceExecuteOnce((PINIT_ONCE)ctl, InitFuncWrapper, func, NULL);
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700363}
364
365// Thread IDs:
366typedef DWORD loader_platform_thread_id;
Jon Ashburn23d36b12016-02-02 17:47:28 -0700367static loader_platform_thread_id loader_platform_get_thread_id() {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700368 return GetCurrentThreadId();
369}
370
371// Thread mutex:
372typedef CRITICAL_SECTION loader_platform_thread_mutex;
Jon Ashburn23d36b12016-02-02 17:47:28 -0700373static void
374loader_platform_thread_create_mutex(loader_platform_thread_mutex *pMutex) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700375 InitializeCriticalSection(pMutex);
376}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700377static void
378loader_platform_thread_lock_mutex(loader_platform_thread_mutex *pMutex) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700379 EnterCriticalSection(pMutex);
380}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700381static void
382loader_platform_thread_unlock_mutex(loader_platform_thread_mutex *pMutex) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700383 LeaveCriticalSection(pMutex);
384}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700385static void
386loader_platform_thread_delete_mutex(loader_platform_thread_mutex *pMutex) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700387 DeleteCriticalSection(pMutex);
388}
Mike Stroyanc3d98332015-05-15 17:34:51 -0600389typedef CONDITION_VARIABLE loader_platform_thread_cond;
Jon Ashburn23d36b12016-02-02 17:47:28 -0700390static void
391loader_platform_thread_init_cond(loader_platform_thread_cond *pCond) {
Mike Stroyanc3d98332015-05-15 17:34:51 -0600392 InitializeConditionVariable(pCond);
393}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700394static void
395loader_platform_thread_cond_wait(loader_platform_thread_cond *pCond,
396 loader_platform_thread_mutex *pMutex) {
Mike Stroyanc3d98332015-05-15 17:34:51 -0600397 SleepConditionVariableCS(pCond, pMutex, INFINITE);
398}
Jon Ashburn23d36b12016-02-02 17:47:28 -0700399static void
400loader_platform_thread_cond_broadcast(loader_platform_thread_cond *pCond) {
Mike Stroyanc3d98332015-05-15 17:34:51 -0600401 WakeAllConditionVariable(pCond);
402}
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700403
Ian Elliott5aa4ea22015-03-31 15:32:41 -0600404// Windows Registry:
Jon Ashburn23d36b12016-02-02 17:47:28 -0700405char *loader_get_registry_string(const HKEY hive, const LPCTSTR sub_key,
Ian Elliott5aa4ea22015-03-31 15:32:41 -0600406 const char *value);
407
Jon Ashburn3f8c3002015-10-15 13:47:58 -0600408#define loader_stack_alloc(size) _alloca(size)
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700409#else // defined(_WIN32)
410
411#error The "loader_platform.h" file must be modified for this OS.
412
413// NOTE: In order to support another OS, an #elif needs to be added (above the
414// "#else // defined(_WIN32)") for that OS, and OS-specific versions of the
415// contents of this file must be created.
416
417// NOTE: Other OS-specific changes are also needed for this OS. Search for
418// files with "WIN32" in it, as a quick way to find files that must be changed.
419
420#endif // defined(_WIN32)
421
jon547bbee2015-10-29 14:57:03 -0600422// returns true if the given string appears to be a relative or absolute
423// path, as opposed to a bare filename.
Jon Ashburn23d36b12016-02-02 17:47:28 -0700424static inline bool loader_platform_is_path(const char *path) {
jon547bbee2015-10-29 14:57:03 -0600425 return strchr(path, DIRECTORY_SYMBOL) != NULL;
426}