blob: 920715492f7f8bb4c31b1925c1599fca85274479 [file] [log] [blame]
Ian Elliott81ac44c2015-01-13 17:52:38 -07001/*
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002 * Vulkan
Ian Elliott81ac44c2015-01-13 17:52:38 -07003 *
4 * Copyright (C) 2015 LunarG, Inc.
5 * Copyright 2014 Valve Software
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 *
26 * Authors:
Jon Ashburnffd5d672015-06-29 11:25:34 -060027 * Jon Ashburn <jon@luanrg.com>
Ian Elliott81ac44c2015-01-13 17:52:38 -070028 * Ian Elliott <ian@lunarg.com>
29 */
30
31#ifndef LOADER_PLATFORM_H
32#define LOADER_PLATFORM_H
33
Cody Northrop62ac1c52015-07-08 16:48:37 -060034#include "vk_platform.h"
Mark Lobodzinskieccbb372015-09-01 09:00:16 -060035#include "vk_sdk_platform.h"
Cody Northrop62ac1c52015-07-08 16:48:37 -060036
Ian Elliott81ac44c2015-01-13 17:52:38 -070037#if defined(__linux__)
38/* Linux-specific common code: */
39
40// Headers:
41//#define _GNU_SOURCE 1
42// TBD: Are the contents of the following file used?
43#include <unistd.h>
44// Note: The following file is for dynamic loading:
45#include <dlfcn.h>
46#include <pthread.h>
47#include <assert.h>
Jon Ashburnffd5d672015-06-29 11:25:34 -060048#include <stdbool.h>
Jon Ashburn38144502015-07-07 15:06:25 -060049#include <libgen.h>
Ian Elliott81ac44c2015-01-13 17:52:38 -070050
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060051// VK Library Filenames, Paths, etc.:
Ian Elliott665c5632015-02-04 11:22:39 -070052#define PATH_SEPERATOR ':'
Jon Ashburnffd5d672015-06-29 11:25:34 -060053#define DIRECTORY_SYMBOL '/'
54
James Jonesac945bc2015-07-23 17:39:37 -070055#define VULKAN_ICDCONF_DIR "/" "vulkan" "/" "icd.d"
56#define VULKAN_ICD_DIR "/" "vulkan" "/" "icd"
James Jones3f731442015-07-24 11:35:16 -070057#define VULKAN_ELAYERCONF_DIR "/" "vulkan" "/" "explicit_layer.d"
James Jonesac945bc2015-07-23 17:39:37 -070058#define VULKAN_ILAYERCONF_DIR "/" "vulkan" "/" "implicit_layer.d"
59#define VULKAN_LAYER_DIR "/" "vulkan" "/" "layer"
60
61#if defined(LOCALPREFIX)
62#define LOCAL_DRIVERS_INFO \
63 LOCALPREFIX "/" SYSCONFDIR VULKAN_ICDCONF_DIR ":" \
64 LOCALPREFIX "/" DATADIR VULKAN_ICDCONF_DIR ":"
65#define LOCAL_DRIVERS_PATH \
66 LOCALPREFIX "/" LIBDIR VULKAN_ICD_DIR ":"
67#define LOCAL_LAYERS_INFO \
68 LOCALPREFIX "/" SYSCONFDIR VULKAN_ELAYERCONF_DIR ":" \
69 LOCALPREFIX "/" SYSCONFDIR VULKAN_ILAYERCONF_DIR ":" \
70 LOCALPREFIX "/" DATADIR VULKAN_ELAYERCONF_DIR ":" \
71 LOCALPREFIX "/" DATADIR VULKAN_ILAYERCONF_DIR ":"
72#define LOCAL_LAYERS_PATH \
73 LOCALPREFIX "/" LIBDIR VULKAN_LAYER_DIR ":"
74#else
75#define LOCAL_DRIVERS_INFO
76#define LOCAL_DRIVERS_PATH
77#define LOCAL_LAYERS_INFO
78#define LOCAL_LAYERS_PATH
79#endif
80
Adam Jackson05487a22015-07-23 16:29:26 -040081#define DEFAULT_VK_DRIVERS_INFO \
James Jonesac945bc2015-07-23 17:39:37 -070082 LOCAL_DRIVERS_INFO \
James Jonesfb6b3b32015-07-24 09:47:37 -070083 "/" SYSCONFDIR VULKAN_ICDCONF_DIR ":" \
James Jonesac945bc2015-07-23 17:39:37 -070084 "/usr/" DATADIR VULKAN_ICDCONF_DIR
Adam Jackson05487a22015-07-23 16:29:26 -040085#define DEFAULT_VK_DRIVERS_PATH \
James Jonesac945bc2015-07-23 17:39:37 -070086 LOCAL_DRIVERS_PATH \
87 "/usr/" LIBDIR VULKAN_ICD_DIR
Adam Jackson05487a22015-07-23 16:29:26 -040088#define DEFAULT_VK_LAYERS_INFO \
James Jonesac945bc2015-07-23 17:39:37 -070089 LOCAL_LAYERS_INFO \
James Jonesfb6b3b32015-07-24 09:47:37 -070090 "/" SYSCONFDIR VULKAN_ELAYERCONF_DIR ":" \
91 "/" SYSCONFDIR VULKAN_ILAYERCONF_DIR ":" \
James Jonesac945bc2015-07-23 17:39:37 -070092 "/usr/" DATADIR VULKAN_ELAYERCONF_DIR ":" \
93 "/usr/" DATADIR VULKAN_ILAYERCONF_DIR
Adam Jackson05487a22015-07-23 16:29:26 -040094#define DEFAULT_VK_LAYERS_PATH \
James Jonesac945bc2015-07-23 17:39:37 -070095 LOCAL_LAYERS_PATH \
96 "/usr/" LIBDIR VULKAN_LAYER_DIR
Jon Ashburn68e2bef2015-08-06 11:22:33 -060097#define LAYERS_PATH_ENV "VK_LAYER_PATH"
Ian Elliott665c5632015-02-04 11:22:39 -070098
Ian Elliottecb60ec2015-02-12 16:44:56 -070099// C99:
Tobin Ehlisbf0146e2015-02-11 14:24:02 -0700100#define PRINTF_SIZE_T_SPECIFIER "%zu"
101
Jon Ashburnffd5d672015-06-29 11:25:34 -0600102// File IO
103static inline bool loader_platform_file_exists(const char *path)
104{
105 if (access(path, F_OK))
106 return false;
107 else
108 return true;
109}
110
Jon Ashburn38144502015-07-07 15:06:25 -0600111static inline bool loader_platform_is_path_absolute(const char *path)
112{
113 if (path[0] == '/')
114 return true;
115 else
116 return false;
117}
118
119static inline char *loader_platform_dirname(char *path)
120{
121 return dirname(path);
122}
123
Jon Ashburnffd5d672015-06-29 11:25:34 -0600124// Dynamic Loading of libraries:
Ian Elliott81ac44c2015-01-13 17:52:38 -0700125typedef void * loader_platform_dl_handle;
126static inline loader_platform_dl_handle loader_platform_open_library(const char* libPath)
127{
Chia-I Wu7397c432015-02-18 14:39:54 -0700128 return dlopen(libPath, RTLD_LAZY | RTLD_LOCAL);
Ian Elliott81ac44c2015-01-13 17:52:38 -0700129}
130static inline char * loader_platform_open_library_error(const char* libPath)
131{
132 return dlerror();
133}
134static inline void loader_platform_close_library(loader_platform_dl_handle library)
135{
136 dlclose(library);
137}
138static inline void * loader_platform_get_proc_address(loader_platform_dl_handle library,
139 const char *name)
140{
141 assert(library);
142 assert(name);
143 return dlsym(library, name);
144}
145static inline char * loader_platform_get_proc_address_error(const char *name)
146{
147 return dlerror();
148}
149
150// Threads:
151typedef pthread_t loader_platform_thread;
152#define LOADER_PLATFORM_THREAD_ONCE_DECLARATION(var) \
153 pthread_once_t var = PTHREAD_ONCE_INIT;
Jon Ashburnfce93d92015-05-12 17:26:48 -0600154#define LOADER_PLATFORM_THREAD_ONCE_DEFINITION(var) \
155 pthread_once_t var;
Ian Elliott81ac44c2015-01-13 17:52:38 -0700156static inline void loader_platform_thread_once(void *ctl, void (* func) (void))
157{
158 assert(func != NULL);
159 assert(ctl != NULL);
160 pthread_once((pthread_once_t *) ctl, func);
161}
162
163// Thread IDs:
164typedef pthread_t loader_platform_thread_id;
165static inline loader_platform_thread_id loader_platform_get_thread_id()
166{
167 return pthread_self();
168}
169
170// Thread mutex:
171typedef pthread_mutex_t loader_platform_thread_mutex;
172static inline void loader_platform_thread_create_mutex(loader_platform_thread_mutex* pMutex)
173{
174 pthread_mutex_init(pMutex, NULL);
175}
176static inline void loader_platform_thread_lock_mutex(loader_platform_thread_mutex* pMutex)
177{
178 pthread_mutex_lock(pMutex);
179}
180static inline void loader_platform_thread_unlock_mutex(loader_platform_thread_mutex* pMutex)
181{
182 pthread_mutex_unlock(pMutex);
183}
184static inline void loader_platform_thread_delete_mutex(loader_platform_thread_mutex* pMutex)
185{
186 pthread_mutex_destroy(pMutex);
187}
Mike Stroyan354ed672015-05-15 08:50:57 -0600188typedef pthread_cond_t loader_platform_thread_cond;
189static inline void loader_platform_thread_init_cond(loader_platform_thread_cond* pCond)
190{
191 pthread_cond_init(pCond, NULL);
192}
193static inline void loader_platform_thread_cond_wait(loader_platform_thread_cond* pCond, loader_platform_thread_mutex* pMutex)
194{
195 pthread_cond_wait(pCond, pMutex);
196}
197static inline void loader_platform_thread_cond_broadcast(loader_platform_thread_cond* pCond)
198{
199 pthread_cond_broadcast(pCond);
200}
Ian Elliott81ac44c2015-01-13 17:52:38 -0700201
Courtney Goeltzenleuchterb620ace2015-07-05 11:28:29 -0600202#define loader_stack_alloc(size) alloca(size)
203static inline void *loader_aligned_alloc(size_t alignment, size_t size) { return aligned_alloc(alignment, size); }
Ian Elliott81ac44c2015-01-13 17:52:38 -0700204
205#elif defined(_WIN32) // defined(__linux__)
206/* Windows-specific common code: */
207
208// Headers:
Piers Danielle2bca482015-02-24 13:58:47 -0700209#include <WinSock2.h>
Ian Elliott81ac44c2015-01-13 17:52:38 -0700210#include <windows.h>
211#include <assert.h>
Tony Barbour69698512015-06-18 16:29:32 -0600212#include <stdio.h>
Jon Ashburnee33ae72015-06-30 14:46:22 -0700213#include <io.h>
214#include <stdbool.h>
Cody Northrop62ac1c52015-07-08 16:48:37 -0600215#include <shlwapi.h>
Ian Elliott81ac44c2015-01-13 17:52:38 -0700216#ifdef __cplusplus
217#include <iostream>
218#include <string>
219using namespace std;
220#endif // __cplusplus
221
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600222// VK Library Filenames, Paths, etc.:
Ian Elliott665c5632015-02-04 11:22:39 -0700223#define PATH_SEPERATOR ';'
Jon Ashburnffd5d672015-06-29 11:25:34 -0600224#define DIRECTORY_SYMBOL '\\'
Jon Ashburnee33ae72015-06-30 14:46:22 -0700225#define DEFAULT_VK_REGISTRY_HIVE HKEY_LOCAL_MACHINE
226#define DEFAULT_VK_DRIVERS_INFO "SOFTWARE\\Khronos\\Vulkan\\Drivers"
Jon Ashburnffd5d672015-06-29 11:25:34 -0600227// TODO: Are these the correct paths
scygan8420b4c2015-06-01 19:47:08 +0200228#define DEFAULT_VK_DRIVERS_PATH "C:\\Windows\\System32;C:\\Windows\\SysWow64"
Jon Ashburn1b111de2015-07-06 15:40:35 -0600229#define DEFAULT_VK_LAYERS_INFO "SOFTWARE\\Khronos\\Vulkan\\ExplicitLayers;SOFTWARE\\Khronos\\Vulkan\\ImplicitLayers"
Jon Ashburn38144502015-07-07 15:06:25 -0600230#define DEFAULT_VK_LAYERS_PATH "C:\\Windows\\System32;C:\\Windows\\SysWow64"
Jon Ashburn68e2bef2015-08-06 11:22:33 -0600231#define LAYERS_PATH_ENV "VK_LAYER_PATH"
Ian Elliott665c5632015-02-04 11:22:39 -0700232
Ian Elliott81ac44c2015-01-13 17:52:38 -0700233// C99:
234// Microsoft didn't implement C99 in Visual Studio; but started adding it with
235// VS2013. However, VS2013 still didn't have snprintf(). The following is a
Ian Elliott64f74a82015-02-04 12:06:46 -0700236// work-around (Note: The _CRT_SECURE_NO_WARNINGS macro must be set in the
237// "CMakeLists.txt" file).
Ian Elliott81ac44c2015-01-13 17:52:38 -0700238#define snprintf _snprintf
Jon Ashburn38144502015-07-07 15:06:25 -0600239#define strdup _strdup
Tobin Ehlisbf0146e2015-02-11 14:24:02 -0700240#define PRINTF_SIZE_T_SPECIFIER "%Iu"
David Pinedo3053c672015-07-02 09:04:37 -0600241
David Pinedo3053c672015-07-02 09:04:37 -0600242
Jon Ashburnffd5d672015-06-29 11:25:34 -0600243// File IO
Jon Ashburnee33ae72015-06-30 14:46:22 -0700244static bool loader_platform_file_exists(const char *path)
Jon Ashburnffd5d672015-06-29 11:25:34 -0600245{
Jon Ashburnee33ae72015-06-30 14:46:22 -0700246 if ((_access(path, 0)) == -1)
Jon Ashburnffd5d672015-06-29 11:25:34 -0600247 return false;
248 else
249 return true;
250}
251
Cody Northrop62ac1c52015-07-08 16:48:37 -0600252static bool loader_platform_is_path_absolute(const char *path)
Jon Ashburn38144502015-07-07 15:06:25 -0600253{
254 return !PathIsRelative(path);
255}
256
257// WIN32 runtime doesn't have dirname().
258static inline char *loader_platform_dirname(char *path)
259{
260 char *current, *next;
261
262 // TODO/TBD: Do we need to deal with the Windows's ":" character?
263
264 for (current = path; *current != '\0'; current = next) {
265 next = strchr(current, DIRECTORY_SYMBOL);
266 if (next == NULL) {
267 if (current != path)
268 *(current - 1) = '\0';
269 return path;
270 } else {
271 // Point one character past the DIRECTORY_SYMBOL:
272 next++;
273 }
274 }
275 return path;
276}
277
278// WIN32 runtime doesn't have basename().
279// Microsoft also doesn't have basename(). Paths are different on Windows, and
280// so this is just a temporary solution in order to get us compiling, so that we
281// can test some scenarios, and develop the correct solution for Windows.
282 // TODO: Develop a better, permanent solution for Windows, to replace this
283 // temporary code:
284static char *loader_platform_basename(char *pathname)
285{
286 char *current, *next;
287
288// TODO/TBD: Do we need to deal with the Windows's ":" character?
289
290 for (current = pathname; *current != '\0'; current = next) {
291 next = strchr(current, DIRECTORY_SYMBOL);
292 if (next == NULL) {
293 // No more DIRECTORY_SYMBOL's so return p:
294 return current;
295 } else {
296 // Point one character past the DIRECTORY_SYMBOL:
297 next++;
298 }
299 }
300 // We shouldn't get to here, but this makes the compiler happy:
301 return current;
302}
303
Ian Elliott81ac44c2015-01-13 17:52:38 -0700304// Dynamic Loading:
305typedef HMODULE loader_platform_dl_handle;
306static loader_platform_dl_handle loader_platform_open_library(const char* libPath)
307{
308 return LoadLibrary(libPath);
309}
310static char * loader_platform_open_library_error(const char* libPath)
311{
312 static char errorMsg[120];
313 snprintf(errorMsg, 119, "Failed to open dynamic library \"%s\"", libPath);
314 return errorMsg;
315}
316static void loader_platform_close_library(loader_platform_dl_handle library)
317{
318 FreeLibrary(library);
319}
320static void * loader_platform_get_proc_address(loader_platform_dl_handle library,
321 const char *name)
322{
323 assert(library);
324 assert(name);
325 return GetProcAddress(library, name);
326}
327static char * loader_platform_get_proc_address_error(const char *name)
328{
329 static char errorMsg[120];
330 snprintf(errorMsg, 119, "Failed to find function \"%s\" in dynamic library", name);
331 return errorMsg;
332}
333
334// Threads:
335typedef HANDLE loader_platform_thread;
336#define LOADER_PLATFORM_THREAD_ONCE_DECLARATION(var) \
337 INIT_ONCE var = INIT_ONCE_STATIC_INIT;
Jon Ashburnfce93d92015-05-12 17:26:48 -0600338#define LOADER_PLATFORM_THREAD_ONCE_DEFINITION(var) \
339 INIT_ONCE var;
Piers Daniell886be472015-02-23 16:23:13 -0700340static BOOL CALLBACK InitFuncWrapper(PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
341{
342 void (*func)(void) = (void (*)(void))Parameter;
343 func();
344 return TRUE;
345}
346
Ian Elliott81ac44c2015-01-13 17:52:38 -0700347static void loader_platform_thread_once(void *ctl, void (* func) (void))
348{
349 assert(func != NULL);
350 assert(ctl != NULL);
Piers Daniell886be472015-02-23 16:23:13 -0700351 InitOnceExecuteOnce((PINIT_ONCE) ctl, InitFuncWrapper, func, NULL);
Ian Elliott81ac44c2015-01-13 17:52:38 -0700352}
353
354// Thread IDs:
355typedef DWORD loader_platform_thread_id;
356static loader_platform_thread_id loader_platform_get_thread_id()
357{
358 return GetCurrentThreadId();
359}
360
361// Thread mutex:
362typedef CRITICAL_SECTION loader_platform_thread_mutex;
363static void loader_platform_thread_create_mutex(loader_platform_thread_mutex* pMutex)
364{
365 InitializeCriticalSection(pMutex);
366}
367static void loader_platform_thread_lock_mutex(loader_platform_thread_mutex* pMutex)
368{
369 EnterCriticalSection(pMutex);
370}
371static void loader_platform_thread_unlock_mutex(loader_platform_thread_mutex* pMutex)
372{
373 LeaveCriticalSection(pMutex);
374}
375static void loader_platform_thread_delete_mutex(loader_platform_thread_mutex* pMutex)
376{
377 DeleteCriticalSection(pMutex);
378}
Mike Stroyan33053d02015-05-15 17:34:51 -0600379typedef CONDITION_VARIABLE loader_platform_thread_cond;
380static void loader_platform_thread_init_cond(loader_platform_thread_cond* pCond)
381{
382 InitializeConditionVariable(pCond);
383}
384static void loader_platform_thread_cond_wait(loader_platform_thread_cond* pCond, loader_platform_thread_mutex* pMutex)
385{
386 SleepConditionVariableCS(pCond, pMutex, INFINITE);
387}
388static void loader_platform_thread_cond_broadcast(loader_platform_thread_cond* pCond)
389{
390 WakeAllConditionVariable(pCond);
391}
Ian Elliott81ac44c2015-01-13 17:52:38 -0700392
Ian Elliott76005132015-03-31 15:32:41 -0600393// Windows Registry:
394char *loader_get_registry_string(const HKEY hive,
395 const LPCTSTR sub_key,
396 const char *value);
397
Ian Elliott81ac44c2015-01-13 17:52:38 -0700398#else // defined(_WIN32)
399
400#error The "loader_platform.h" file must be modified for this OS.
401
402// NOTE: In order to support another OS, an #elif needs to be added (above the
403// "#else // defined(_WIN32)") for that OS, and OS-specific versions of the
404// contents of this file must be created.
405
406// NOTE: Other OS-specific changes are also needed for this OS. Search for
407// files with "WIN32" in it, as a quick way to find files that must be changed.
408
409#endif // defined(_WIN32)
410
Ian Elliott20f06872015-02-12 17:08:34 -0700411#else /* LOADER_PLATFORM_H */
412#ifndef LOADER_PLATFORM_H_TEMP
413#define LOADER_PLATFORM_H_TEMP
414
415// NOTE: The following are hopefully-temporary macros to ensure that people
416// don't forget to use the loader_platform_*() functions above:
417
418#if defined(__linux__)
419/* Linux-specific common code: */
420
421// Dynamic Loading:
422#define dlopen PLEASE USE THE loader_platform_open_library() FUNCTION
423#define dlerror PLEASE DO NOT USE THE dlerror() FUNCTION DIRECTLY
424#define dlclose PLEASE USE THE loader_platform_close_library() FUNCTION
425#define dlsym PLEASE USE THE loader_platform_get_proc_address() FUNCTION
426
427// Threads:
428#define pthread_once PLEASE USE THE loader_platform_thread_once() FUNCTION
429#define pthread_self PLEASE USE THE loader_platform_get_thread_id() FUNCTION
430
431// Thread mutex:
432#define pthread_mutex_init PLEASE USE THE loader_platform_thread_create_mutex() FUNCTION
433#define pthread_mutex_lock PLEASE USE THE loader_platform_thread_lock_mutex() FUNCTION
434#define pthread_mutex_unlock PLEASE USE THE loader_platform_thread_unlock_mutex() FUNCTION
435#define pthread_mutex_destroy PLEASE USE THE loader_platform_thread_delete_mutex() FUNCTION
436
437
438#elif defined(_WIN32) // defined(__linux__)
439/* Windows-specific common code: */
440
441// Dynamic Loading:
442//#define LoadLibrary PLEASE USE THE loader_platform_open_library() FUNCTION
443#define FreeLibrary PLEASE USE THE loader_platform_close_library() FUNCTION
444#define GetProcAddress PLEASE USE THE loader_platform_get_proc_address() FUNCTION
445
446// Threads:
447#define InitOnceExecuteOnce PLEASE USE THE loader_platform_thread_once() FUNCTION
448#define GetCurrentThreadId PLEASE USE THE loader_platform_get_thread_id() FUNCTION
449
450// Thread mutex:
451#define InitializeCriticalSection PLEASE USE THE loader_platform_thread_create_mutex() FUNCTION
452#define EnterCriticalSection PLEASE USE THE loader_platform_thread_lock_mutex() FUNCTION
453#define LeaveCriticalSection PLEASE USE THE loader_platform_thread_unlock_mutex() FUNCTION
454#define DeleteCriticalSection PLEASE USE THE loader_platform_thread_delete_mutex() FUNCTION
455
Courtney Goeltzenleuchterb620ace2015-07-05 11:28:29 -0600456#define loader_stack_alloc(size) _alloca(size)
Cody Northrop62ac1c52015-07-08 16:48:37 -0600457static inline void *loader_aligned_alloc(size_t alignment, size_t size) { return _aligned_malloc(alignment, size); }
Ian Elliott20f06872015-02-12 17:08:34 -0700458
459#endif // defined(_WIN32)
460#endif /* LOADER_PLATFORM_H_TEMP */
Ian Elliott81ac44c2015-01-13 17:52:38 -0700461#endif /* LOADER_PLATFORM_H */