os.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. /*
  2. * Copyright 2010-2016 Branimir Karadzic. All rights reserved.
  3. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
  4. */
  5. #ifndef BX_OS_H_HEADER_GUARD
  6. #define BX_OS_H_HEADER_GUARD
  7. #include "bx.h"
  8. #include "debug.h"
  9. #include <sys/stat.h>
  10. #if BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
  11. # include <windows.h>
  12. # include <psapi.h>
  13. #elif BX_PLATFORM_ANDROID \
  14. || BX_PLATFORM_EMSCRIPTEN \
  15. || BX_PLATFORM_BSD \
  16. || BX_PLATFORM_HURD \
  17. || BX_PLATFORM_IOS \
  18. || BX_PLATFORM_LINUX \
  19. || BX_PLATFORM_NACL \
  20. || BX_PLATFORM_OSX \
  21. || BX_PLATFORM_PS4 \
  22. || BX_PLATFORM_RPI \
  23. || BX_PLATFORM_STEAMLINK
  24. # include <sched.h> // sched_yield
  25. # if BX_PLATFORM_BSD \
  26. || BX_PLATFORM_IOS \
  27. || BX_PLATFORM_NACL \
  28. || BX_PLATFORM_OSX \
  29. || BX_PLATFORM_PS4 \
  30. || BX_PLATFORM_STEAMLINK
  31. # include <pthread.h> // mach_port_t
  32. # endif // BX_PLATFORM_*
  33. # include <time.h> // nanosleep
  34. # if !BX_PLATFORM_PS4 && !BX_PLATFORM_NACL
  35. # include <dlfcn.h> // dlopen, dlclose, dlsym
  36. # endif // !BX_PLATFORM_PS4 && !BX_PLATFORM_NACL
  37. # if BX_PLATFORM_ANDROID
  38. # include <malloc.h> // mallinfo
  39. # elif BX_PLATFORM_LINUX \
  40. || BX_PLATFORM_RPI \
  41. || BX_PLATFORM_STEAMLINK
  42. # include <unistd.h> // syscall
  43. # include <sys/syscall.h>
  44. # elif BX_PLATFORM_OSX
  45. # include <mach/mach.h> // mach_task_basic_info
  46. # elif BX_PLATFORM_HURD
  47. # include <pthread/pthread.h> // pthread_self
  48. # elif BX_PLATFORM_ANDROID
  49. # include "debug.h" // getTid is not implemented...
  50. # endif // BX_PLATFORM_ANDROID
  51. #endif // BX_PLATFORM_
  52. #if BX_CRT_MSVC
  53. # include <direct.h> // _getcwd
  54. #else
  55. # include <unistd.h> // getcwd
  56. #endif // BX_CRT_MSVC
  57. #if BX_PLATFORM_OSX
  58. # define BX_DL_EXT "dylib"
  59. #elif BX_PLATFORM_WINDOWS
  60. # define BX_DL_EXT "dll"
  61. #else
  62. # define BX_DL_EXT "so"
  63. #endif //
  64. namespace bx
  65. {
  66. inline void sleep(uint32_t _ms)
  67. {
  68. #if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360
  69. ::Sleep(_ms);
  70. #elif BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
  71. BX_UNUSED(_ms);
  72. debugOutput("sleep is not implemented"); debugBreak();
  73. #else
  74. timespec req = {(time_t)_ms/1000, (long)((_ms%1000)*1000000)};
  75. timespec rem = {0, 0};
  76. ::nanosleep(&req, &rem);
  77. #endif // BX_PLATFORM_
  78. }
  79. inline void yield()
  80. {
  81. #if BX_PLATFORM_WINDOWS
  82. ::SwitchToThread();
  83. #elif BX_PLATFORM_XBOX360
  84. ::Sleep(0);
  85. #elif BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
  86. debugOutput("yield is not implemented"); debugBreak();
  87. #else
  88. ::sched_yield();
  89. #endif // BX_PLATFORM_
  90. }
  91. inline uint32_t getTid()
  92. {
  93. #if BX_PLATFORM_WINDOWS
  94. return ::GetCurrentThreadId();
  95. #elif BX_PLATFORM_LINUX || BX_PLATFORM_RPI || BX_PLATFORM_STEAMLINK
  96. return (pid_t)::syscall(SYS_gettid);
  97. #elif BX_PLATFORM_IOS || BX_PLATFORM_OSX
  98. return (mach_port_t)::pthread_mach_thread_np(pthread_self() );
  99. #elif BX_PLATFORM_BSD || BX_PLATFORM_NACL
  100. // Casting __nc_basic_thread_data*... need better way to do this.
  101. return *(uint32_t*)::pthread_self();
  102. #elif BX_PLATFORM_HURD
  103. return (pthread_t)::pthread_self();
  104. #else
  105. //# pragma message "not implemented."
  106. debugOutput("getTid is not implemented"); debugBreak();
  107. return 0;
  108. #endif //
  109. }
  110. inline size_t getProcessMemoryUsed()
  111. {
  112. #if BX_PLATFORM_ANDROID
  113. struct mallinfo mi = mallinfo();
  114. return mi.uordblks;
  115. #elif BX_PLATFORM_LINUX || BX_PLATFORM_HURD
  116. FILE* file = fopen("/proc/self/statm", "r");
  117. if (NULL == file)
  118. {
  119. return 0;
  120. }
  121. long pages = 0;
  122. int items = fscanf(file, "%*s%ld", &pages);
  123. fclose(file);
  124. return 1 == items
  125. ? pages * sysconf(_SC_PAGESIZE)
  126. : 0
  127. ;
  128. #elif BX_PLATFORM_OSX
  129. # if defined(MACH_TASK_BASIC_INFO)
  130. mach_task_basic_info info;
  131. mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
  132. int const result = task_info(mach_task_self()
  133. , MACH_TASK_BASIC_INFO
  134. , (task_info_t)&info
  135. , &infoCount
  136. );
  137. # else // MACH_TASK_BASIC_INFO
  138. task_basic_info info;
  139. mach_msg_type_number_t infoCount = TASK_BASIC_INFO_COUNT;
  140. int const result = task_info(mach_task_self()
  141. , TASK_BASIC_INFO
  142. , (task_info_t)&info
  143. , &infoCount
  144. );
  145. # endif // MACH_TASK_BASIC_INFO
  146. if (KERN_SUCCESS != result)
  147. {
  148. return 0;
  149. }
  150. return info.resident_size;
  151. #elif BX_PLATFORM_WINDOWS
  152. PROCESS_MEMORY_COUNTERS pmc;
  153. GetProcessMemoryInfo(GetCurrentProcess()
  154. , &pmc
  155. , sizeof(pmc)
  156. );
  157. return pmc.WorkingSetSize;
  158. #else
  159. return 0;
  160. #endif // BX_PLATFORM_*
  161. }
  162. inline void* dlopen(const char* _filePath)
  163. {
  164. #if BX_PLATFORM_WINDOWS
  165. return (void*)::LoadLibraryA(_filePath);
  166. #elif BX_PLATFORM_EMSCRIPTEN \
  167. || BX_PLATFORM_NACL \
  168. || BX_PLATFORM_PS4 \
  169. || BX_PLATFORM_XBOXONE \
  170. || BX_PLATFORM_WINRT
  171. BX_UNUSED(_filePath);
  172. return NULL;
  173. #else
  174. return ::dlopen(_filePath, RTLD_LOCAL|RTLD_LAZY);
  175. #endif // BX_PLATFORM_
  176. }
  177. inline void dlclose(void* _handle)
  178. {
  179. #if BX_PLATFORM_WINDOWS
  180. ::FreeLibrary( (HMODULE)_handle);
  181. #elif BX_PLATFORM_EMSCRIPTEN \
  182. || BX_PLATFORM_NACL \
  183. || BX_PLATFORM_PS4 \
  184. || BX_PLATFORM_XBOXONE \
  185. || BX_PLATFORM_WINRT
  186. BX_UNUSED(_handle);
  187. #else
  188. ::dlclose(_handle);
  189. #endif // BX_PLATFORM_
  190. }
  191. inline void* dlsym(void* _handle, const char* _symbol)
  192. {
  193. #if BX_PLATFORM_WINDOWS
  194. return (void*)::GetProcAddress( (HMODULE)_handle, _symbol);
  195. #elif BX_PLATFORM_EMSCRIPTEN \
  196. || BX_PLATFORM_NACL \
  197. || BX_PLATFORM_PS4 \
  198. || BX_PLATFORM_XBOXONE \
  199. || BX_PLATFORM_WINRT
  200. BX_UNUSED(_handle, _symbol);
  201. return NULL;
  202. #else
  203. return ::dlsym(_handle, _symbol);
  204. #endif // BX_PLATFORM_
  205. }
  206. inline bool getenv(const char* _name, char* _out, uint32_t* _inOutSize)
  207. {
  208. #if BX_PLATFORM_WINDOWS
  209. DWORD len = ::GetEnvironmentVariableA(_name, _out, *_inOutSize);
  210. bool result = len != 0 && len < *_inOutSize;
  211. *_inOutSize = len;
  212. return result;
  213. #elif BX_PLATFORM_PS4 \
  214. || BX_PLATFORM_XBOXONE \
  215. || BX_PLATFORM_WINRT
  216. BX_UNUSED(_name, _out, _inOutSize);
  217. return false;
  218. #else
  219. const char* ptr = ::getenv(_name);
  220. uint32_t len = 0;
  221. if (NULL != ptr)
  222. {
  223. len = (uint32_t)strlen(ptr);
  224. }
  225. bool result = len != 0 && len < *_inOutSize;
  226. if (len < *_inOutSize)
  227. {
  228. strcpy(_out, ptr);
  229. }
  230. *_inOutSize = len;
  231. return result;
  232. #endif // BX_PLATFORM_
  233. }
  234. inline void setenv(const char* _name, const char* _value)
  235. {
  236. #if BX_PLATFORM_WINDOWS
  237. ::SetEnvironmentVariableA(_name, _value);
  238. #elif BX_PLATFORM_PS4 \
  239. || BX_PLATFORM_XBOXONE \
  240. || BX_PLATFORM_WINRT
  241. BX_UNUSED(_name, _value);
  242. #else
  243. ::setenv(_name, _value, 1);
  244. #endif // BX_PLATFORM_
  245. }
  246. inline void unsetenv(const char* _name)
  247. {
  248. #if BX_PLATFORM_WINDOWS
  249. ::SetEnvironmentVariableA(_name, NULL);
  250. #elif BX_PLATFORM_PS4 \
  251. || BX_PLATFORM_XBOXONE \
  252. || BX_PLATFORM_WINRT
  253. BX_UNUSED(_name);
  254. #else
  255. ::unsetenv(_name);
  256. #endif // BX_PLATFORM_
  257. }
  258. inline int chdir(const char* _path)
  259. {
  260. #if BX_PLATFORM_PS4 \
  261. || BX_PLATFORM_XBOXONE \
  262. || BX_PLATFORM_WINRT
  263. BX_UNUSED(_path);
  264. return -1;
  265. #elif BX_CRT_MSVC
  266. return ::_chdir(_path);
  267. #else
  268. return ::chdir(_path);
  269. #endif // BX_COMPILER_
  270. }
  271. inline char* pwd(char* _buffer, uint32_t _size)
  272. {
  273. #if BX_PLATFORM_PS4 \
  274. || BX_PLATFORM_XBOXONE \
  275. || BX_PLATFORM_WINRT
  276. BX_UNUSED(_buffer, _size);
  277. return NULL;
  278. #elif BX_CRT_MSVC
  279. return ::_getcwd(_buffer, (int)_size);
  280. #else
  281. return ::getcwd(_buffer, _size);
  282. #endif // BX_COMPILER_
  283. }
  284. struct FileInfo
  285. {
  286. enum Enum
  287. {
  288. Regular,
  289. Directory,
  290. Count
  291. };
  292. uint64_t m_size;
  293. Enum m_type;
  294. };
  295. inline bool stat(const char* _filePath, FileInfo& _fileInfo)
  296. {
  297. _fileInfo.m_size = 0;
  298. _fileInfo.m_type = FileInfo::Count;
  299. #if BX_COMPILER_MSVC
  300. struct ::_stat64 st;
  301. int32_t result = ::_stat64(_filePath, &st);
  302. if (0 != result)
  303. {
  304. return false;
  305. }
  306. if (0 != (st.st_mode & _S_IFREG) )
  307. {
  308. _fileInfo.m_type = FileInfo::Regular;
  309. }
  310. else if (0 != (st.st_mode & _S_IFDIR) )
  311. {
  312. _fileInfo.m_type = FileInfo::Directory;
  313. }
  314. #else
  315. struct ::stat st;
  316. int32_t result = ::stat(_filePath, &st);
  317. if (0 != result)
  318. {
  319. return false;
  320. }
  321. if (0 != (st.st_mode & S_IFREG) )
  322. {
  323. _fileInfo.m_type = FileInfo::Regular;
  324. }
  325. else if (0 != (st.st_mode & S_IFDIR) )
  326. {
  327. _fileInfo.m_type = FileInfo::Directory;
  328. }
  329. #endif // BX_COMPILER_MSVC
  330. _fileInfo.m_size = st.st_size;
  331. return true;
  332. }
  333. } // namespace bx
  334. #endif // BX_OS_H_HEADER_GUARD