porting.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. /*
  2. Minetest
  3. Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. */
  16. /*
  17. Random portability stuff
  18. */
  19. #ifndef PORTING_HEADER
  20. #define PORTING_HEADER
  21. #ifdef _WIN32
  22. #ifdef _WIN32_WINNT
  23. #undef _WIN32_WINNT
  24. #endif
  25. #define _WIN32_WINNT 0x0501 // We need to do this before any other headers
  26. // because those might include sdkddkver.h which defines _WIN32_WINNT if not already set
  27. #endif
  28. #include <string>
  29. #include "irrlicht.h"
  30. #include "irrlichttypes.h" // u32
  31. #include "irrlichttypes_extrabloated.h"
  32. #include "debug.h"
  33. #include "constants.h"
  34. #include "gettime.h"
  35. #include "threads.h"
  36. #ifdef _MSC_VER
  37. #define SWPRINTF_CHARSTRING L"%S"
  38. #else
  39. #define SWPRINTF_CHARSTRING L"%s"
  40. #endif
  41. //currently not needed
  42. //template<typename T> struct alignment_trick { char c; T member; };
  43. //#define ALIGNOF(type) offsetof (alignment_trick<type>, member)
  44. #ifdef _WIN32
  45. #include <windows.h>
  46. #define sleep_ms(x) Sleep(x)
  47. #else
  48. #include <unistd.h>
  49. #include <stdint.h> //for uintptr_t
  50. #if (defined(linux) || defined(__linux)) && !defined(_GNU_SOURCE)
  51. #define _GNU_SOURCE
  52. #endif
  53. #include <sched.h>
  54. #ifdef __FreeBSD__
  55. #include <pthread_np.h>
  56. typedef cpuset_t cpu_set_t;
  57. #elif defined(__sun) || defined(sun)
  58. #include <sys/types.h>
  59. #include <sys/processor.h>
  60. #elif defined(_AIX)
  61. #include <sys/processor.h>
  62. #elif __APPLE__
  63. #include <mach/mach_init.h>
  64. #include <mach/thread_policy.h>
  65. #endif
  66. #define sleep_ms(x) usleep(x*1000)
  67. #define THREAD_PRIORITY_LOWEST 0
  68. #define THREAD_PRIORITY_BELOW_NORMAL 1
  69. #define THREAD_PRIORITY_NORMAL 2
  70. #define THREAD_PRIORITY_ABOVE_NORMAL 3
  71. #define THREAD_PRIORITY_HIGHEST 4
  72. #endif
  73. #ifdef _MSC_VER
  74. #define ALIGNOF(x) __alignof(x)
  75. #define strtok_r(x, y, z) strtok_s(x, y, z)
  76. #define strtof(x, y) (float)strtod(x, y)
  77. #define strtoll(x, y, z) _strtoi64(x, y, z)
  78. #define strtoull(x, y, z) _strtoui64(x, y, z)
  79. #define strcasecmp(x, y) stricmp(x, y)
  80. #define strncasecmp(x, y, n) strnicmp(x, y, n)
  81. #else
  82. #define ALIGNOF(x) __alignof__(x)
  83. #endif
  84. #ifdef __MINGW32__
  85. #define strtok_r(x, y, z) mystrtok_r(x, y, z)
  86. #endif
  87. // strlcpy is missing from glibc. thanks a lot, drepper.
  88. // strlcpy is also missing from AIX and HP-UX because they aim to be weird.
  89. // We can't simply alias strlcpy to MSVC's strcpy_s, since strcpy_s by
  90. // default raises an assertion error and aborts the program if the buffer is
  91. // too small.
  92. #if defined(__FreeBSD__) || defined(__NetBSD__) || \
  93. defined(__OpenBSD__) || defined(__DragonFly__) || \
  94. defined(__APPLE__) || \
  95. defined(__sun) || defined(sun) || \
  96. defined(__QNX__) || defined(__QNXNTO__)
  97. #define HAVE_STRLCPY
  98. #endif
  99. // So we need to define our own.
  100. #ifndef HAVE_STRLCPY
  101. #define strlcpy(d, s, n) mystrlcpy(d, s, n)
  102. #endif
  103. #define PADDING(x, y) ((ALIGNOF(y) - ((uintptr_t)(x) & (ALIGNOF(y) - 1))) & (ALIGNOF(y) - 1))
  104. #if defined(__APPLE__)
  105. #include <mach-o/dyld.h>
  106. #include <CoreFoundation/CoreFoundation.h>
  107. #endif
  108. namespace porting
  109. {
  110. /*
  111. Signal handler (grabs Ctrl-C on POSIX systems)
  112. */
  113. void signal_handler_init(void);
  114. // Returns a pointer to a bool.
  115. // When the bool is true, program should quit.
  116. bool * signal_handler_killstatus(void);
  117. /*
  118. Path of static data directory.
  119. */
  120. extern std::string path_share;
  121. /*
  122. Directory for storing user data. Examples:
  123. Windows: "C:\Documents and Settings\user\Application Data\<PROJECT_NAME>"
  124. Linux: "~/.<PROJECT_NAME>"
  125. Mac: "~/Library/Application Support/<PROJECT_NAME>"
  126. */
  127. extern std::string path_user;
  128. /*
  129. Get full path of stuff in data directory.
  130. Example: "stone.png" -> "../data/stone.png"
  131. */
  132. std::string getDataPath(const char *subpath);
  133. /*
  134. Initialize path_share and path_user.
  135. */
  136. void initializePaths();
  137. /*
  138. Get number of online processors in the system.
  139. */
  140. int getNumberOfProcessors();
  141. /*
  142. Set a thread's affinity to a particular processor.
  143. */
  144. bool threadBindToProcessor(threadid_t tid, int pnumber);
  145. /*
  146. Set a thread's priority.
  147. */
  148. bool threadSetPriority(threadid_t tid, int prio);
  149. /*
  150. Return system information
  151. e.g. "Linux/3.12.7 x86_64"
  152. */
  153. std::string get_sysinfo();
  154. void initIrrlicht(irr::IrrlichtDevice * );
  155. /*
  156. Resolution is 10-20ms.
  157. Remember to check for overflows.
  158. Overflow can occur at any value higher than 10000000.
  159. */
  160. #ifdef _WIN32 // Windows
  161. #ifndef _WIN32_WINNT
  162. #define _WIN32_WINNT 0x0501
  163. #endif
  164. #include <windows.h>
  165. inline u32 getTimeS()
  166. {
  167. return GetTickCount() / 1000;
  168. }
  169. inline u32 getTimeMs()
  170. {
  171. return GetTickCount();
  172. }
  173. inline u32 getTimeUs()
  174. {
  175. LARGE_INTEGER freq, t;
  176. QueryPerformanceFrequency(&freq);
  177. QueryPerformanceCounter(&t);
  178. return (double)(t.QuadPart) / ((double)(freq.QuadPart) / 1000000.0);
  179. }
  180. inline u32 getTimeNs()
  181. {
  182. LARGE_INTEGER freq, t;
  183. QueryPerformanceFrequency(&freq);
  184. QueryPerformanceCounter(&t);
  185. return (double)(t.QuadPart) / ((double)(freq.QuadPart) / 1000000000.0);
  186. }
  187. #else // Posix
  188. #include <sys/time.h>
  189. #include <time.h>
  190. #ifdef __MACH__
  191. #include <mach/clock.h>
  192. #include <mach/mach.h>
  193. #endif
  194. inline u32 getTimeS()
  195. {
  196. struct timeval tv;
  197. gettimeofday(&tv, NULL);
  198. return tv.tv_sec;
  199. }
  200. inline u32 getTimeMs()
  201. {
  202. struct timeval tv;
  203. gettimeofday(&tv, NULL);
  204. return tv.tv_sec * 1000 + tv.tv_usec / 1000;
  205. }
  206. inline u32 getTimeUs()
  207. {
  208. struct timeval tv;
  209. gettimeofday(&tv, NULL);
  210. return tv.tv_sec * 1000000 + tv.tv_usec;
  211. }
  212. inline u32 getTimeNs()
  213. {
  214. struct timespec ts;
  215. // from http://stackoverflow.com/questions/5167269/clock-gettime-alternative-in-mac-os-x
  216. #ifdef __MACH__ // OS X does not have clock_gettime, use clock_get_time
  217. clock_serv_t cclock;
  218. mach_timespec_t mts;
  219. host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
  220. clock_get_time(cclock, &mts);
  221. mach_port_deallocate(mach_task_self(), cclock);
  222. ts.tv_sec = mts.tv_sec;
  223. ts.tv_nsec = mts.tv_nsec;
  224. #else
  225. clock_gettime(CLOCK_REALTIME, &ts);
  226. #endif
  227. return ts.tv_sec * 1000000000 + ts.tv_nsec;
  228. }
  229. /*#include <sys/timeb.h>
  230. inline u32 getTimeMs()
  231. {
  232. struct timeb tb;
  233. ftime(&tb);
  234. return tb.time * 1000 + tb.millitm;
  235. }*/
  236. #endif
  237. inline u32 getTime(TimePrecision prec)
  238. {
  239. switch (prec) {
  240. case PRECISION_SECONDS:
  241. return getTimeS();
  242. case PRECISION_MILLI:
  243. return getTimeMs();
  244. case PRECISION_MICRO:
  245. return getTimeUs();
  246. case PRECISION_NANO:
  247. return getTimeNs();
  248. }
  249. return 0;
  250. }
  251. /**
  252. * Delta calculation function taking two 32bit arguments.
  253. * @param old_time_ms old time for delta calculation (order is relevant!)
  254. * @param new_time_ms new time for delta calculation (order is relevant!)
  255. * @return positive 32bit delta value
  256. */
  257. inline u32 getDeltaMs(u32 old_time_ms, u32 new_time_ms)
  258. {
  259. if (new_time_ms >= old_time_ms) {
  260. return (new_time_ms - old_time_ms);
  261. } else {
  262. return (old_time_ms - new_time_ms);
  263. }
  264. }
  265. #if defined(linux) || defined(__linux)
  266. #include <sys/prctl.h>
  267. inline void setThreadName(const char *name) {
  268. /* It would be cleaner to do this with pthread_setname_np,
  269. * which was added to glibc in version 2.12, but some major
  270. * distributions are still runing 2.11 and previous versions.
  271. */
  272. prctl(PR_SET_NAME, name);
  273. }
  274. #elif defined(__FreeBSD__) || defined(__OpenBSD__)
  275. #include <pthread.h>
  276. #include <pthread_np.h>
  277. inline void setThreadName(const char *name) {
  278. pthread_set_name_np(pthread_self(), name);
  279. }
  280. #elif defined(__NetBSD__)
  281. #include <pthread.h>
  282. inline void setThreadName(const char *name) {
  283. pthread_setname_np(pthread_self(), name);
  284. }
  285. #elif defined(_MSC_VER)
  286. typedef struct tagTHREADNAME_INFO {
  287. DWORD dwType; // must be 0x1000
  288. LPCSTR szName; // pointer to name (in user addr space)
  289. DWORD dwThreadID; // thread ID (-1=caller thread)
  290. DWORD dwFlags; // reserved for future use, must be zero
  291. } THREADNAME_INFO;
  292. inline void setThreadName(const char *name) {
  293. THREADNAME_INFO info;
  294. info.dwType = 0x1000;
  295. info.szName = name;
  296. info.dwThreadID = -1;
  297. info.dwFlags = 0;
  298. __try {
  299. RaiseException(0x406D1388, 0, sizeof(info) / sizeof(DWORD), (ULONG_PTR *) &info);
  300. } __except (EXCEPTION_CONTINUE_EXECUTION) {}
  301. }
  302. #elif defined(__APPLE__)
  303. #include <pthread.h>
  304. inline void setThreadName(const char *name) {
  305. pthread_setname_np(name);
  306. }
  307. #elif defined(_WIN32)
  308. inline void setThreadName(const char* name) {}
  309. #else
  310. #warning "Unrecognized platform, thread names will not be available."
  311. inline void setThreadName(const char* name) {}
  312. #endif
  313. #ifndef SERVER
  314. float getDisplayDensity();
  315. v2u32 getDisplaySize();
  316. v2u32 getWindowSize();
  317. #endif
  318. } // namespace porting
  319. #ifdef __ANDROID__
  320. #include "porting_android.h"
  321. #endif
  322. #endif // PORTING_HEADER