summaryrefslogtreecommitdiff
path: root/boost/config/platform/vxworks.hpp
blob: a91e4ab439d82d2f2319898b0f3af7d218c73b20 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
//  (C) Copyright Dustin Spicuzza 2009.
//      Adapted to vxWorks 6.9 by Peter Brockamp 2012.
//      Updated for VxWorks 7 by Brian Kuhl 2016
//  Use, modification and distribution are subject to the
//  Boost Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org for most recent version.

//  Old versions of vxWorks (namely everything below 6.x) are
//  absolutely unable to use boost. Old STLs and compilers 
//  like (GCC 2.96) . Do not even think of getting this to work, 
//  a miserable failure will  be guaranteed!
//
//  Equally, this file has been tested for RTPs (Real Time Processes)
//  only, not for DKMs (Downloadable Kernel Modules). These two types
//  of executables differ largely in the available functionality of
//  the C-library, STL, and so on. A DKM uses a C89 library with no
//  wide character support and no guarantee of ANSI C. The same Dinkum 
//  STL library is used in both contexts. 
//
//  Similarly the Dinkum abridged STL that supports the loosely specified 
//  embedded C++ standard has not been tested and is unlikely to work 
//  on anything but the simplest library.
// ====================================================================
// 
//  Additional Configuration
//  -------------------------------------------------------------------
//
//  Because of the ordering of include files and other issues the following 
//  additional definitions worked better outside this file.
//
//  When building the log library add the following to the b2 invocation
//     define=BOOST_LOG_WITHOUT_IPC
//  and 
//     -DBOOST_LOG_WITHOUT_DEFAULT_FACTORIES
//  to your compile options.
//
//  When building the test library add 
//     -DBOOST_TEST_LIMITED_SIGNAL_DETAILS
//  to your compile options
//
//  When building containers library add
//     -DHAVE_MORECORE=0
//  to your c compile options so dlmalloc heap library is compiled 
//  without brk() calls
//
// ====================================================================
//
// Some important information regarding the usage of POSIX semaphores:
// -------------------------------------------------------------------
//
// VxWorks as a real time operating system handles threads somewhat
// different from what "normal" OSes do, regarding their scheduling!
// This could lead to a scenario called "priority inversion" when using
// semaphores, see http://en.wikipedia.org/wiki/Priority_inversion.
//
// Now, VxWorks POSIX-semaphores for DKM's default to the usage of
// priority inverting semaphores, which is fine. On the other hand,
// for RTP's it defaults to using non priority inverting semaphores,
// which could easily pose a serious problem for a real time process.
//
// To change the default properties for POSIX-semaphores in VxWorks 7
// enable core > CORE_USER Menu > DEFAULT_PTHREAD_PRIO_INHERIT 
//  
// In VxWorks 6.x so as to integrate with boost. 
// - Edit the file 
//   installDir/vxworks-6.x/target/usr/src/posix/pthreadLib.c
// - Around line 917 there should be the definition of the default
//   mutex attributes:
//
//   LOCAL pthread_mutexattr_t defaultMutexAttr =
//       {
//       PTHREAD_INITIALIZED_OBJ, PTHREAD_PRIO_NONE, 0,
//       PTHREAD_MUTEX_DEFAULT
//       };
//
//   Here, replace PTHREAD_PRIO_NONE by PTHREAD_PRIO_INHERIT.
// - Around line 1236 there should be a definition for the function
//   pthread_mutexattr_init(). A couple of lines below you should
//   find a block of code like this:
//
//   pAttr->mutexAttrStatus      = PTHREAD_INITIALIZED_OBJ;
//   pAttr->mutexAttrProtocol    = PTHREAD_PRIO_NONE;
//   pAttr->mutexAttrPrioceiling = 0;
//   pAttr->mutexAttrType        = PTHREAD_MUTEX_DEFAULT;
//
//   Here again, replace PTHREAD_PRIO_NONE by PTHREAD_PRIO_INHERIT.
// - Finally, rebuild your VSB. This will rebuild the libraries
//   with the changed properties. That's it! Now, using boost should
//   no longer cause any problems with task deadlocks!
//
//  ====================================================================

// Block out all versions before vxWorks 6.x, as these don't work:
// Include header with the vxWorks version information and query them
#include <version.h>
#if !defined(_WRS_VXWORKS_MAJOR) || (_WRS_VXWORKS_MAJOR < 6)
#  error "The vxWorks version you're using is so badly outdated,\
          it doesn't work at all with boost, sorry, no chance!"
#endif

// Handle versions above 5.X but below 6.9
#if (_WRS_VXWORKS_MAJOR == 6) && (_WRS_VXWORKS_MINOR < 9)
// TODO: Starting from what version does vxWorks work with boost?
// We can't reasonably insert a #warning "" as a user hint here,
// as this will show up with every file including some boost header,
// badly bugging the user... So for the time being we just leave it.
#endif

// vxWorks specific config options:
// --------------------------------
#define BOOST_PLATFORM "vxWorks"

// Special behaviour for DKMs:
#ifdef _WRS_KERNEL
  // DKMs do not have the <cwchar>-header,
  // but apparently they do have an intrinsic wchar_t meanwhile!
#  define BOOST_NO_CWCHAR

  // Lots of wide-functions and -headers are unavailable for DKMs as well:
#  define BOOST_NO_CWCTYPE
#  define BOOST_NO_SWPRINTF
#  define BOOST_NO_STD_WSTRING
#  define BOOST_NO_STD_WSTREAMBUF
#endif

// Generally available headers:
#define BOOST_HAS_UNISTD_H
#define BOOST_HAS_STDINT_H
#define BOOST_HAS_DIRENT_H
#define BOOST_HAS_SLIST

// vxWorks does not have installed an iconv-library by default,
// so unfortunately no Unicode support from scratch is available!
// Thus, instead it is suggested to switch to ICU, as this seems
// to be the most complete and portable option...
#define BOOST_LOCALE_WITH_ICU

// Generally available functionality:
#define BOOST_HAS_THREADS
#define BOOST_HAS_NANOSLEEP
#define BOOST_HAS_GETTIMEOFDAY
#define BOOST_HAS_CLOCK_GETTIME
#define BOOST_HAS_MACRO_USE_FACET

// Generally available threading API's:
#define BOOST_HAS_PTHREADS
#define BOOST_HAS_SCHED_YIELD
#define BOOST_HAS_SIGACTION

// Functionality available for RTPs only:
#ifdef __RTP__
#  define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE
#  define BOOST_HAS_LOG1P
#  define BOOST_HAS_EXPM1
#endif

// Functionality available for DKMs only:
#ifdef _WRS_KERNEL
  // Luckily, at the moment there seems to be none!
#endif

// These #defines allow detail/posix_features to work, since vxWorks doesn't
// #define them itself for DKMs (for RTPs on the contrary it does):
#ifdef _WRS_KERNEL
#  ifndef _POSIX_TIMERS
#    define _POSIX_TIMERS  1
#  endif
#  ifndef _POSIX_THREADS
#    define _POSIX_THREADS 1
#  endif
#endif

#if (_WRS_VXWORKS_MAJOR < 7) 
// vxWorks-around: <time.h> #defines CLOCKS_PER_SEC as sysClkRateGet() but
//                 miserably fails to #include the required <sysLib.h> to make
//                 sysClkRateGet() available! So we manually include it here.
#ifdef __RTP__
#  include <time.h>
#  include <sysLib.h>
#endif

// vxWorks-around: In <stdint.h> the macros INT32_C(), UINT32_C(), INT64_C() and
//                 UINT64_C() are defined erroneously, yielding not a signed/
//                 unsigned long/long long type, but a signed/unsigned int/long
//                 type. Eventually this leads to compile errors in ratio_fwd.hpp,
//                 when trying to define several constants which do not fit into a
//                 long type! We correct them here by redefining.

#include <cstdint>

// Some macro-magic to do the job
#define VX_JOIN(X, Y)     VX_DO_JOIN(X, Y)
#define VX_DO_JOIN(X, Y)  VX_DO_JOIN2(X, Y)
#define VX_DO_JOIN2(X, Y) X##Y

// Correctly setup the macros
#undef  INT32_C
#undef  UINT32_C
#undef  INT64_C
#undef  UINT64_C
#define INT32_C(x)  VX_JOIN(x, L)
#define UINT32_C(x) VX_JOIN(x, UL)
#define INT64_C(x)  VX_JOIN(x, LL)
#define UINT64_C(x) VX_JOIN(x, ULL)

// #include Libraries required for the following function adaption
#include <sys/time.h>
#endif  // _WRS_VXWORKS_MAJOR < 7

#include <ioLib.h>
#include <tickLib.h>

// Use C-linkage for the following helper functions
#ifdef __cplusplus
extern "C" {
#endif

// vxWorks-around: The required functions getrlimit() and getrlimit() are missing.
//                 But we have the similar functions getprlimit() and setprlimit(),
//                 which may serve the purpose.
//                 Problem: The vxWorks-documentation regarding these functions
//                 doesn't deserve its name! It isn't documented what the first two
//                 parameters idtype and id mean, so we must fall back to an educated
//                 guess - null, argh... :-/

// TODO: getprlimit() and setprlimit() do exist for RTPs only, for whatever reason.
//       Thus for DKMs there would have to be another implementation.
#if defined ( __RTP__) &&  (_WRS_VXWORKS_MAJOR < 7)
  inline int getrlimit(int resource, struct rlimit *rlp){
    return getprlimit(0, 0, resource, rlp);
  }

  inline int setrlimit(int resource, const struct rlimit *rlp){
    return setprlimit(0, 0, resource, const_cast<struct rlimit*>(rlp));
  }
#endif

// vxWorks has ftruncate() only, so we do simulate truncate():
inline int truncate(const char *p, off_t l){
  int fd = open(p, O_WRONLY);
  if (fd == -1){
    errno = EACCES;
    return -1;
  }
  if (ftruncate(fd, l) == -1){
    close(fd);
    errno = EACCES;
    return -1;
  }
  return close(fd);
}

#ifdef __GNUC__
#define ___unused __attribute__((unused))
#else
#define ___unused
#endif

// Fake symlink handling by dummy functions:
inline int symlink(const char* path1 ___unused, const char* path2 ___unused){
  // vxWorks has no symlinks -> always return an error!
  errno = EACCES;
  return -1;
}

inline ssize_t readlink(const char* path1 ___unused, char* path2 ___unused, size_t size ___unused){
  // vxWorks has no symlinks -> always return an error!
  errno = EACCES;
  return -1;
}

#if (_WRS_VXWORKS_MAJOR < 7)

inline int gettimeofday(struct timeval *tv, void * /*tzv*/) {
  struct timespec ts;
  clock_gettime(CLOCK_MONOTONIC, &ts);
  tv->tv_sec  = ts.tv_sec;
  tv->tv_usec = ts.tv_nsec / 1000;
  return 0;
}
#endif

#ifdef __cplusplus
} // extern "C"
#endif

/* 
 * moved to os/utils/unix/freind_h/times.h in VxWorks 7
 * to avoid conflict with MPL operator times
 */
#if (_WRS_VXWORKS_MAJOR < 7) 
#ifdef __cplusplus

// vxWorks provides neither struct tms nor function times()!
// We implement an empty dummy-function, simply setting the user
// and system time to the half of thew actual system ticks-value
// and the child user and system time to 0.
// Rather ugly but at least it suppresses compiler errors...
// Unfortunately, this of course *does* have an severe impact on
// dependant libraries, actually this is chrono only! Here it will
// not be possible to correctly use user and system times! But
// as vxWorks is lacking the ability to calculate user and system
// process times there seems to be no other possible solution.
struct tms{
  clock_t tms_utime;  // User CPU time
  clock_t tms_stime;  // System CPU time
  clock_t tms_cutime; // User CPU time of terminated child processes
  clock_t tms_cstime; // System CPU time of terminated child processes
};


 inline clock_t times(struct tms *t){
  struct timespec ts;
  clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
  clock_t ticks(static_cast<clock_t>(static_cast<double>(ts.tv_sec)  * CLOCKS_PER_SEC +
                                     static_cast<double>(ts.tv_nsec) * CLOCKS_PER_SEC / 1000000.0));
  t->tms_utime  = ticks/2U;
  t->tms_stime  = ticks/2U;
  t->tms_cutime = 0; // vxWorks is lacking the concept of a child process!
  t->tms_cstime = 0; // -> Set the wait times for childs to 0
  return ticks;
}


namespace std {
    using ::times;
}
#endif // __cplusplus
#endif // _WRS_VXWORKS_MAJOR < 7


#ifdef __cplusplus
extern "C" void 	bzero	    (void *, size_t);    // FD_ZERO uses bzero() but doesn't include strings.h

// Put the selfmade functions into the std-namespace, just in case
namespace std {
# ifdef __RTP__
    using ::getrlimit;
    using ::setrlimit;
# endif
  using ::truncate;
  using ::symlink;
  using ::readlink;
#if (_WRS_VXWORKS_MAJOR < 7)  
    using ::gettimeofday;
#endif  
}
#endif // __cplusplus

// Some more macro-magic:
// vxWorks-around: Some functions are not present or broken in vxWorks
//                 but may be patched to life via helper macros...

// Include signal.h which might contain a typo to be corrected here
#include <signal.h>
#if (_WRS_VXWORKS_MAJOR < 7)
#define getpagesize()    sysconf(_SC_PAGESIZE)         // getpagesize is deprecated anyway!
inline int lstat(p, b) { return stat(p, b); }  // lstat() == stat(), as vxWorks has no symlinks!
#endif
#ifndef S_ISSOCK
#  define S_ISSOCK(mode) ((mode & S_IFMT) == S_IFSOCK) // Is file a socket?
#endif
#ifndef FPE_FLTINV
#  define FPE_FLTINV     (FPE_FLTSUB+1)                // vxWorks has no FPE_FLTINV, so define one as a dummy
#endif
#if !defined(BUS_ADRALN) && defined(BUS_ADRALNR)
#  define BUS_ADRALN     BUS_ADRALNR                   // Correct a supposed typo in vxWorks' <signal.h>
#endif
typedef int              locale_t;                     // locale_t is a POSIX-extension, currently not present in vxWorks!

// #include boilerplate code:
#include <boost/config/detail/posix_features.hpp>

// vxWorks lies about XSI conformance, there is no nl_types.h:
#undef BOOST_HAS_NL_TYPES_H

// vxWorks 7 adds C++11 support 
// however it is optional, and does not match exactly the support determined
// by examining the Dinkum STL version and GCC version (or ICC and DCC) 
#ifndef _WRS_CONFIG_LANG_LIB_CPLUS_CPLUS_USER_2011
#  define BOOST_NO_CXX11_ADDRESSOF      // C11 addressof operator on memory location
#  define BOOST_NO_CXX11_ALLOCATOR
#  define BOOST_NO_CXX11_ATOMIC_SMART_PTR
#  define BOOST_NO_CXX11_NUMERIC_LIMITS  // max_digits10 in test/../print_helper.hpp
#  define BOOST_NO_CXX11_SMART_PTR 
#  define BOOST_NO_CXX11_STD_ALIGN


#  define BOOST_NO_CXX11_HDR_ARRAY
#  define BOOST_NO_CXX11_HDR_ATOMIC
#  define BOOST_NO_CXX11_HDR_CHRONO
#  define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE
#  define BOOST_NO_CXX11_HDR_FORWARD_LIST  //serialization/test/test_list.cpp
#  define BOOST_NO_CXX11_HDR_FUNCTIONAL 
#  define BOOST_NO_CXX11_HDR_FUTURE
#  define BOOST_NO_CXX11_HDR_MUTEX
#  define BOOST_NO_CXX11_HDR_RANDOM      //math/../test_data.hpp
#  define BOOST_NO_CXX11_HDR_RATIO
#  define BOOST_NO_CXX11_HDR_REGEX
#  define BOOST_NO_CXX14_HDR_SHARED_MUTEX
#  define BOOST_NO_CXX11_HDR_SYSTEM_ERROR
#  define BOOST_NO_CXX11_HDR_THREAD
#  define BOOST_NO_CXX11_HDR_TYPEINDEX 
#  define BOOST_NO_CXX11_HDR_TYPE_TRAITS
#  define BOOST_NO_CXX11_HDR_TUPLE 
#  define BOOST_NO_CXX11_HDR_UNORDERED_MAP
#  define BOOST_NO_CXX11_HDR_UNORDERED_SET 
#else
#ifndef  BOOST_SYSTEM_NO_DEPRECATED
#  define BOOST_SYSTEM_NO_DEPRECATED  // workaround link error in spirit
#endif
#endif


// NONE is used in enums in lamda and other libraries
#undef NONE
// restrict is an iostreams class
#undef restrict

// use fake poll() from Unix layer in ASIO to get full functionality 
// most libraries will use select() but this define allows 'iostream' functionality
// which is based on poll() only
#if (_WRS_VXWORKS_MAJOR > 6)
#  ifndef BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR
#    define BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR
#  endif
#else 
#  define BOOST_ASIO_DISABLE_SERIAL_PORT
#endif