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