vxworks.hpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. // (C) Copyright Dustin Spicuzza 2009.
  2. // Adapted to vxWorks 6.9 by Peter Brockamp 2012.
  3. // Updated for VxWorks 7 by Brian Kuhl 2016
  4. // Use, modification and distribution are subject to the
  5. // Boost Software License, Version 1.0. (See accompanying file
  6. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. // See http://www.boost.org for most recent version.
  8. // Old versions of vxWorks (namely everything below 6.x) are
  9. // absolutely unable to use boost. Old STLs and compilers
  10. // like (GCC 2.96) . Do not even think of getting this to work,
  11. // a miserable failure will be guaranteed!
  12. //
  13. // Equally, this file has been tested for RTPs (Real Time Processes)
  14. // only, not for DKMs (Downloadable Kernel Modules). These two types
  15. // of executables differ largely in the available functionality of
  16. // the C-library, STL, and so on. A DKM uses a C89 library with no
  17. // wide character support and no guarantee of ANSI C. The same Dinkum
  18. // STL library is used in both contexts.
  19. //
  20. // Similarly the Dinkum abridged STL that supports the loosely specified
  21. // embedded C++ standard has not been tested and is unlikely to work
  22. // on anything but the simplest library.
  23. // ====================================================================
  24. //
  25. // Additional Configuration
  26. // -------------------------------------------------------------------
  27. //
  28. // Because of the ordering of include files and other issues the following
  29. // additional definitions worked better outside this file.
  30. //
  31. // When building the log library add the following to the b2 invocation
  32. // define=BOOST_LOG_WITHOUT_IPC
  33. // and
  34. // -DBOOST_LOG_WITHOUT_DEFAULT_FACTORIES
  35. // to your compile options.
  36. //
  37. // When building the test library add
  38. // -DBOOST_TEST_LIMITED_SIGNAL_DETAILS
  39. // to your compile options
  40. //
  41. // When building containers library add
  42. // -DHAVE_MORECORE=0
  43. // to your c compile options so dlmalloc heap library is compiled
  44. // without brk() calls
  45. //
  46. // ====================================================================
  47. //
  48. // Some important information regarding the usage of POSIX semaphores:
  49. // -------------------------------------------------------------------
  50. //
  51. // VxWorks as a real time operating system handles threads somewhat
  52. // different from what "normal" OSes do, regarding their scheduling!
  53. // This could lead to a scenario called "priority inversion" when using
  54. // semaphores, see http://en.wikipedia.org/wiki/Priority_inversion.
  55. //
  56. // Now, VxWorks POSIX-semaphores for DKM's default to the usage of
  57. // priority inverting semaphores, which is fine. On the other hand,
  58. // for RTP's it defaults to using non priority inverting semaphores,
  59. // which could easily pose a serious problem for a real time process.
  60. //
  61. // To change the default properties for POSIX-semaphores in VxWorks 7
  62. // enable core > CORE_USER Menu > DEFAULT_PTHREAD_PRIO_INHERIT
  63. //
  64. // In VxWorks 6.x so as to integrate with boost.
  65. // - Edit the file
  66. // installDir/vxworks-6.x/target/usr/src/posix/pthreadLib.c
  67. // - Around line 917 there should be the definition of the default
  68. // mutex attributes:
  69. //
  70. // LOCAL pthread_mutexattr_t defaultMutexAttr =
  71. // {
  72. // PTHREAD_INITIALIZED_OBJ, PTHREAD_PRIO_NONE, 0,
  73. // PTHREAD_MUTEX_DEFAULT
  74. // };
  75. //
  76. // Here, replace PTHREAD_PRIO_NONE by PTHREAD_PRIO_INHERIT.
  77. // - Around line 1236 there should be a definition for the function
  78. // pthread_mutexattr_init(). A couple of lines below you should
  79. // find a block of code like this:
  80. //
  81. // pAttr->mutexAttrStatus = PTHREAD_INITIALIZED_OBJ;
  82. // pAttr->mutexAttrProtocol = PTHREAD_PRIO_NONE;
  83. // pAttr->mutexAttrPrioceiling = 0;
  84. // pAttr->mutexAttrType = PTHREAD_MUTEX_DEFAULT;
  85. //
  86. // Here again, replace PTHREAD_PRIO_NONE by PTHREAD_PRIO_INHERIT.
  87. // - Finally, rebuild your VSB. This will rebuild the libraries
  88. // with the changed properties. That's it! Now, using boost should
  89. // no longer cause any problems with task deadlocks!
  90. //
  91. // ====================================================================
  92. // Block out all versions before vxWorks 6.x, as these don't work:
  93. // Include header with the vxWorks version information and query them
  94. #include <version.h>
  95. #if !defined(_WRS_VXWORKS_MAJOR) || (_WRS_VXWORKS_MAJOR < 6)
  96. # error "The vxWorks version you're using is so badly outdated,\
  97. it doesn't work at all with boost, sorry, no chance!"
  98. #endif
  99. // Handle versions above 5.X but below 6.9
  100. #if (_WRS_VXWORKS_MAJOR == 6) && (_WRS_VXWORKS_MINOR < 9)
  101. // TODO: Starting from what version does vxWorks work with boost?
  102. // We can't reasonably insert a #warning "" as a user hint here,
  103. // as this will show up with every file including some boost header,
  104. // badly bugging the user... So for the time being we just leave it.
  105. #endif
  106. // vxWorks specific config options:
  107. // --------------------------------
  108. #define BOOST_PLATFORM "vxWorks"
  109. // Special behaviour for DKMs:
  110. #ifdef _WRS_KERNEL
  111. // DKMs do not have the <cwchar>-header,
  112. // but apparently they do have an intrinsic wchar_t meanwhile!
  113. # define BOOST_NO_CWCHAR
  114. // Lots of wide-functions and -headers are unavailable for DKMs as well:
  115. # define BOOST_NO_CWCTYPE
  116. # define BOOST_NO_SWPRINTF
  117. # define BOOST_NO_STD_WSTRING
  118. # define BOOST_NO_STD_WSTREAMBUF
  119. #endif
  120. // Generally available headers:
  121. #define BOOST_HAS_UNISTD_H
  122. #define BOOST_HAS_STDINT_H
  123. #define BOOST_HAS_DIRENT_H
  124. #define BOOST_HAS_SLIST
  125. // vxWorks does not have installed an iconv-library by default,
  126. // so unfortunately no Unicode support from scratch is available!
  127. // Thus, instead it is suggested to switch to ICU, as this seems
  128. // to be the most complete and portable option...
  129. #define BOOST_LOCALE_WITH_ICU
  130. // Generally available functionality:
  131. #define BOOST_HAS_THREADS
  132. #define BOOST_HAS_NANOSLEEP
  133. #define BOOST_HAS_GETTIMEOFDAY
  134. #define BOOST_HAS_CLOCK_GETTIME
  135. #define BOOST_HAS_MACRO_USE_FACET
  136. // Generally available threading API's:
  137. #define BOOST_HAS_PTHREADS
  138. #define BOOST_HAS_SCHED_YIELD
  139. #define BOOST_HAS_SIGACTION
  140. // Functionality available for RTPs only:
  141. #ifdef __RTP__
  142. # define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE
  143. # define BOOST_HAS_LOG1P
  144. # define BOOST_HAS_EXPM1
  145. #endif
  146. // Functionality available for DKMs only:
  147. #ifdef _WRS_KERNEL
  148. // Luckily, at the moment there seems to be none!
  149. #endif
  150. // These #defines allow detail/posix_features to work, since vxWorks doesn't
  151. // #define them itself for DKMs (for RTPs on the contrary it does):
  152. #ifdef _WRS_KERNEL
  153. # ifndef _POSIX_TIMERS
  154. # define _POSIX_TIMERS 1
  155. # endif
  156. # ifndef _POSIX_THREADS
  157. # define _POSIX_THREADS 1
  158. # endif
  159. #endif
  160. #if (_WRS_VXWORKS_MAJOR < 7)
  161. // vxWorks-around: <time.h> #defines CLOCKS_PER_SEC as sysClkRateGet() but
  162. // miserably fails to #include the required <sysLib.h> to make
  163. // sysClkRateGet() available! So we manually include it here.
  164. #ifdef __RTP__
  165. # include <time.h>
  166. # include <sysLib.h>
  167. #endif
  168. // vxWorks-around: In <stdint.h> the macros INT32_C(), UINT32_C(), INT64_C() and
  169. // UINT64_C() are defined erroneously, yielding not a signed/
  170. // unsigned long/long long type, but a signed/unsigned int/long
  171. // type. Eventually this leads to compile errors in ratio_fwd.hpp,
  172. // when trying to define several constants which do not fit into a
  173. // long type! We correct them here by redefining.
  174. #include <cstdint>
  175. // Some macro-magic to do the job
  176. #define VX_JOIN(X, Y) VX_DO_JOIN(X, Y)
  177. #define VX_DO_JOIN(X, Y) VX_DO_JOIN2(X, Y)
  178. #define VX_DO_JOIN2(X, Y) X##Y
  179. // Correctly setup the macros
  180. #undef INT32_C
  181. #undef UINT32_C
  182. #undef INT64_C
  183. #undef UINT64_C
  184. #define INT32_C(x) VX_JOIN(x, L)
  185. #define UINT32_C(x) VX_JOIN(x, UL)
  186. #define INT64_C(x) VX_JOIN(x, LL)
  187. #define UINT64_C(x) VX_JOIN(x, ULL)
  188. // #include Libraries required for the following function adaption
  189. #include <sys/time.h>
  190. #endif // _WRS_VXWORKS_MAJOR < 7
  191. #include <ioLib.h>
  192. #include <tickLib.h>
  193. // Use C-linkage for the following helper functions
  194. #ifdef __cplusplus
  195. extern "C" {
  196. #endif
  197. // vxWorks-around: The required functions getrlimit() and getrlimit() are missing.
  198. // But we have the similar functions getprlimit() and setprlimit(),
  199. // which may serve the purpose.
  200. // Problem: The vxWorks-documentation regarding these functions
  201. // doesn't deserve its name! It isn't documented what the first two
  202. // parameters idtype and id mean, so we must fall back to an educated
  203. // guess - null, argh... :-/
  204. // TODO: getprlimit() and setprlimit() do exist for RTPs only, for whatever reason.
  205. // Thus for DKMs there would have to be another implementation.
  206. #if defined ( __RTP__) && (_WRS_VXWORKS_MAJOR < 7)
  207. inline int getrlimit(int resource, struct rlimit *rlp){
  208. return getprlimit(0, 0, resource, rlp);
  209. }
  210. inline int setrlimit(int resource, const struct rlimit *rlp){
  211. return setprlimit(0, 0, resource, const_cast<struct rlimit*>(rlp));
  212. }
  213. #endif
  214. // vxWorks has ftruncate() only, so we do simulate truncate():
  215. inline int truncate(const char *p, off_t l){
  216. int fd = open(p, O_WRONLY);
  217. if (fd == -1){
  218. errno = EACCES;
  219. return -1;
  220. }
  221. if (ftruncate(fd, l) == -1){
  222. close(fd);
  223. errno = EACCES;
  224. return -1;
  225. }
  226. return close(fd);
  227. }
  228. #ifdef __GNUC__
  229. #define ___unused __attribute__((unused))
  230. #else
  231. #define ___unused
  232. #endif
  233. // Fake symlink handling by dummy functions:
  234. inline int symlink(const char* path1 ___unused, const char* path2 ___unused){
  235. // vxWorks has no symlinks -> always return an error!
  236. errno = EACCES;
  237. return -1;
  238. }
  239. inline ssize_t readlink(const char* path1 ___unused, char* path2 ___unused, size_t size ___unused){
  240. // vxWorks has no symlinks -> always return an error!
  241. errno = EACCES;
  242. return -1;
  243. }
  244. #if (_WRS_VXWORKS_MAJOR < 7)
  245. inline int gettimeofday(struct timeval *tv, void * /*tzv*/) {
  246. struct timespec ts;
  247. clock_gettime(CLOCK_MONOTONIC, &ts);
  248. tv->tv_sec = ts.tv_sec;
  249. tv->tv_usec = ts.tv_nsec / 1000;
  250. return 0;
  251. }
  252. #endif
  253. #ifdef __cplusplus
  254. } // extern "C"
  255. #endif
  256. /*
  257. * moved to os/utils/unix/freind_h/times.h in VxWorks 7
  258. * to avoid conflict with MPL operator times
  259. */
  260. #if (_WRS_VXWORKS_MAJOR < 7)
  261. #ifdef __cplusplus
  262. // vxWorks provides neither struct tms nor function times()!
  263. // We implement an empty dummy-function, simply setting the user
  264. // and system time to the half of thew actual system ticks-value
  265. // and the child user and system time to 0.
  266. // Rather ugly but at least it suppresses compiler errors...
  267. // Unfortunately, this of course *does* have an severe impact on
  268. // dependant libraries, actually this is chrono only! Here it will
  269. // not be possible to correctly use user and system times! But
  270. // as vxWorks is lacking the ability to calculate user and system
  271. // process times there seems to be no other possible solution.
  272. struct tms{
  273. clock_t tms_utime; // User CPU time
  274. clock_t tms_stime; // System CPU time
  275. clock_t tms_cutime; // User CPU time of terminated child processes
  276. clock_t tms_cstime; // System CPU time of terminated child processes
  277. };
  278. inline clock_t times(struct tms *t){
  279. struct timespec ts;
  280. clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
  281. clock_t ticks(static_cast<clock_t>(static_cast<double>(ts.tv_sec) * CLOCKS_PER_SEC +
  282. static_cast<double>(ts.tv_nsec) * CLOCKS_PER_SEC / 1000000.0));
  283. t->tms_utime = ticks/2U;
  284. t->tms_stime = ticks/2U;
  285. t->tms_cutime = 0; // vxWorks is lacking the concept of a child process!
  286. t->tms_cstime = 0; // -> Set the wait times for childs to 0
  287. return ticks;
  288. }
  289. namespace std {
  290. using ::times;
  291. }
  292. #endif // __cplusplus
  293. #endif // _WRS_VXWORKS_MAJOR < 7
  294. #ifdef __cplusplus
  295. extern "C" void bzero (void *, size_t); // FD_ZERO uses bzero() but doesn't include strings.h
  296. // Put the selfmade functions into the std-namespace, just in case
  297. namespace std {
  298. # ifdef __RTP__
  299. using ::getrlimit;
  300. using ::setrlimit;
  301. # endif
  302. using ::truncate;
  303. using ::symlink;
  304. using ::readlink;
  305. #if (_WRS_VXWORKS_MAJOR < 7)
  306. using ::gettimeofday;
  307. #endif
  308. }
  309. #endif // __cplusplus
  310. // Some more macro-magic:
  311. // vxWorks-around: Some functions are not present or broken in vxWorks
  312. // but may be patched to life via helper macros...
  313. // Include signal.h which might contain a typo to be corrected here
  314. #include <signal.h>
  315. #if (_WRS_VXWORKS_MAJOR < 7)
  316. #define getpagesize() sysconf(_SC_PAGESIZE) // getpagesize is deprecated anyway!
  317. inline int lstat(p, b) { return stat(p, b); } // lstat() == stat(), as vxWorks has no symlinks!
  318. #endif
  319. #ifndef S_ISSOCK
  320. # define S_ISSOCK(mode) ((mode & S_IFMT) == S_IFSOCK) // Is file a socket?
  321. #endif
  322. #ifndef FPE_FLTINV
  323. # define FPE_FLTINV (FPE_FLTSUB+1) // vxWorks has no FPE_FLTINV, so define one as a dummy
  324. #endif
  325. #if !defined(BUS_ADRALN) && defined(BUS_ADRALNR)
  326. # define BUS_ADRALN BUS_ADRALNR // Correct a supposed typo in vxWorks' <signal.h>
  327. #endif
  328. typedef int locale_t; // locale_t is a POSIX-extension, currently not present in vxWorks!
  329. // #include boilerplate code:
  330. #include <boost/config/detail/posix_features.hpp>
  331. // vxWorks lies about XSI conformance, there is no nl_types.h:
  332. #undef BOOST_HAS_NL_TYPES_H
  333. // vxWorks 7 adds C++11 support
  334. // however it is optional, and does not match exactly the support determined
  335. // by examining the Dinkum STL version and GCC version (or ICC and DCC)
  336. #ifndef _WRS_CONFIG_LANG_LIB_CPLUS_CPLUS_USER_2011
  337. # define BOOST_NO_CXX11_ADDRESSOF // C11 addressof operator on memory location
  338. # define BOOST_NO_CXX11_ALLOCATOR
  339. # define BOOST_NO_CXX11_ATOMIC_SMART_PTR
  340. # define BOOST_NO_CXX11_NUMERIC_LIMITS // max_digits10 in test/../print_helper.hpp
  341. # define BOOST_NO_CXX11_SMART_PTR
  342. # define BOOST_NO_CXX11_STD_ALIGN
  343. # define BOOST_NO_CXX11_HDR_ARRAY
  344. # define BOOST_NO_CXX11_HDR_ATOMIC
  345. # define BOOST_NO_CXX11_HDR_CHRONO
  346. # define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE
  347. # define BOOST_NO_CXX11_HDR_FORWARD_LIST //serialization/test/test_list.cpp
  348. # define BOOST_NO_CXX11_HDR_FUNCTIONAL
  349. # define BOOST_NO_CXX11_HDR_FUTURE
  350. # define BOOST_NO_CXX11_HDR_MUTEX
  351. # define BOOST_NO_CXX11_HDR_RANDOM //math/../test_data.hpp
  352. # define BOOST_NO_CXX11_HDR_RATIO
  353. # define BOOST_NO_CXX11_HDR_REGEX
  354. # define BOOST_NO_CXX14_HDR_SHARED_MUTEX
  355. # define BOOST_NO_CXX11_HDR_SYSTEM_ERROR
  356. # define BOOST_NO_CXX11_HDR_THREAD
  357. # define BOOST_NO_CXX11_HDR_TYPEINDEX
  358. # define BOOST_NO_CXX11_HDR_TYPE_TRAITS
  359. # define BOOST_NO_CXX11_HDR_TUPLE
  360. # define BOOST_NO_CXX11_HDR_UNORDERED_MAP
  361. # define BOOST_NO_CXX11_HDR_UNORDERED_SET
  362. #else
  363. #ifndef BOOST_SYSTEM_NO_DEPRECATED
  364. # define BOOST_SYSTEM_NO_DEPRECATED // workaround link error in spirit
  365. #endif
  366. #endif
  367. // NONE is used in enums in lamda and other libraries
  368. #undef NONE
  369. // restrict is an iostreams class
  370. #undef restrict
  371. // use fake poll() from Unix layer in ASIO to get full functionality
  372. // most libraries will use select() but this define allows 'iostream' functionality
  373. // which is based on poll() only
  374. #if (_WRS_VXWORKS_MAJOR > 6)
  375. # ifndef BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR
  376. # define BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR
  377. # endif
  378. #else
  379. # define BOOST_ASIO_DISABLE_SERIAL_PORT
  380. #endif