Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:30:07

0001 //  (C) Copyright Dustin Spicuzza 2009.
0002 //      Adapted to vxWorks 6.9 by Peter Brockamp 2012.
0003 //      Updated for VxWorks 7 by Brian Kuhl 2016
0004 //  Use, modification and distribution are subject to the
0005 //  Boost Software License, Version 1.0. (See accompanying file
0006 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 
0008 //  See http://www.boost.org for most recent version.
0009 
0010 //  Old versions of vxWorks (namely everything below 6.x) are
0011 //  absolutely unable to use boost. Old STLs and compilers 
0012 //  like (GCC 2.96) . Do not even think of getting this to work, 
0013 //  a miserable failure will  be guaranteed!
0014 //
0015 //  VxWorks supports C++ linkage in the kernel with
0016 //  DKMs (Downloadable Kernel Modules). But, until recently 
0017 //  the kernel used a C89 library with no
0018 //  wide character support and no guarantee of ANSI C. 
0019 //  Regardless of the C library the same Dinkum 
0020 //  STL library is used in both contexts. 
0021 //
0022 //  Similarly the Dinkum abridged STL that supports the loosely specified 
0023 //  embedded C++ standard has not been tested and is unlikely to work 
0024 //  on anything but the simplest library.
0025 // ====================================================================
0026 //
0027 // Some important information regarding the usage of POSIX semaphores:
0028 // -------------------------------------------------------------------
0029 //
0030 // VxWorks as a real time operating system handles threads somewhat
0031 // different from what "normal" OSes do, regarding their scheduling!
0032 // This could lead to a scenario called "priority inversion" when using
0033 // semaphores, see http://en.wikipedia.org/wiki/Priority_inversion.
0034 //
0035 // Now, VxWorks POSIX-semaphores for DKM's default to the usage of
0036 // priority inverting semaphores, which is fine. On the other hand,
0037 // for RTP's it defaults to using non priority inverting semaphores,
0038 // which could easily pose a serious problem for a real time process.
0039 //
0040 // To change the default properties for POSIX-semaphores in VxWorks 7
0041 // enable core > CORE_USER Menu > DEFAULT_PTHREAD_PRIO_INHERIT 
0042 //  
0043 // In VxWorks 6.x so as to integrate with boost. 
0044 // - Edit the file 
0045 //   installDir/vxworks-6.x/target/usr/src/posix/pthreadLib.c
0046 // - Around line 917 there should be the definition of the default
0047 //   mutex attributes:
0048 //
0049 //   LOCAL pthread_mutexattr_t defaultMutexAttr =
0050 //       {
0051 //       PTHREAD_INITIALIZED_OBJ, PTHREAD_PRIO_NONE, 0,
0052 //       PTHREAD_MUTEX_DEFAULT
0053 //       };
0054 //
0055 //   Here, replace PTHREAD_PRIO_NONE by PTHREAD_PRIO_INHERIT.
0056 // - Around line 1236 there should be a definition for the function
0057 //   pthread_mutexattr_init(). A couple of lines below you should
0058 //   find a block of code like this:
0059 //
0060 //   pAttr->mutexAttrStatus      = PTHREAD_INITIALIZED_OBJ;
0061 //   pAttr->mutexAttrProtocol    = PTHREAD_PRIO_NONE;
0062 //   pAttr->mutexAttrPrioceiling = 0;
0063 //   pAttr->mutexAttrType        = PTHREAD_MUTEX_DEFAULT;
0064 //
0065 //   Here again, replace PTHREAD_PRIO_NONE by PTHREAD_PRIO_INHERIT.
0066 // - Finally, rebuild your VSB. This will rebuild the libraries
0067 //   with the changed properties. That's it! Now, using boost should
0068 //   no longer cause any problems with task deadlocks!
0069 //
0070 //  ====================================================================
0071 
0072 // Block out all versions before vxWorks 6.x, as these don't work:
0073 // Include header with the vxWorks version information and query them
0074 #include <version.h>
0075 #if !defined(_WRS_VXWORKS_MAJOR) || (_WRS_VXWORKS_MAJOR < 6)
0076 #  error "The vxWorks version you're using is so badly outdated,\
0077           it doesn't work at all with boost, sorry, no chance!"
0078 #endif
0079 
0080 // Handle versions above 5.X but below 6.9
0081 #if (_WRS_VXWORKS_MAJOR == 6) && (_WRS_VXWORKS_MINOR < 9)
0082 // TODO: Starting from what version does vxWorks work with boost?
0083 // We can't reasonably insert a #warning "" as a user hint here,
0084 // as this will show up with every file including some boost header,
0085 // badly bugging the user... So for the time being we just leave it.
0086 #endif
0087 
0088 // vxWorks specific config options:
0089 // --------------------------------
0090 #define BOOST_PLATFORM "vxWorks"
0091 
0092 
0093 // Generally available headers:
0094 #define BOOST_HAS_UNISTD_H
0095 #define BOOST_HAS_STDINT_H
0096 #define BOOST_HAS_DIRENT_H
0097 //#define BOOST_HAS_SLIST
0098 
0099 // vxWorks does not have installed an iconv-library by default,
0100 // so unfortunately no Unicode support from scratch is available!
0101 // Thus, instead it is suggested to switch to ICU, as this seems
0102 // to be the most complete and portable option...
0103 #ifndef BOOST_LOCALE_WITH_ICU
0104    #define BOOST_LOCALE_WITH_ICU
0105 #endif
0106 
0107 // Generally available functionality:
0108 #define BOOST_HAS_THREADS
0109 #define BOOST_HAS_NANOSLEEP
0110 #define BOOST_HAS_GETTIMEOFDAY
0111 #define BOOST_HAS_CLOCK_GETTIME
0112 #define BOOST_HAS_MACRO_USE_FACET
0113 
0114 // Generally available threading API's:
0115 #define BOOST_HAS_PTHREADS
0116 #define BOOST_HAS_SCHED_YIELD
0117 #define BOOST_HAS_SIGACTION
0118 
0119 // Functionality available for RTPs only:
0120 #ifdef __RTP__
0121 #  define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE
0122 #  define BOOST_HAS_LOG1P
0123 #  define BOOST_HAS_EXPM1
0124 #endif
0125 
0126 // Functionality available for DKMs only:
0127 #ifdef _WRS_KERNEL
0128   // Luckily, at the moment there seems to be none!
0129 #endif
0130 
0131 // These #defines allow detail/posix_features to work, since vxWorks doesn't
0132 // #define them itself for DKMs (for RTPs on the contrary it does):
0133 #ifdef _WRS_KERNEL
0134 #  ifndef _POSIX_TIMERS
0135 #    define _POSIX_TIMERS  1
0136 #  endif
0137 #  ifndef _POSIX_THREADS
0138 #    define _POSIX_THREADS 1
0139 #  endif
0140 // no sysconf( _SC_PAGESIZE) in kernel
0141 #  define BOOST_THREAD_USES_GETPAGESIZE
0142 #endif
0143 
0144 #if (_WRS_VXWORKS_MAJOR < 7) 
0145 // vxWorks-around: <time.h> #defines CLOCKS_PER_SEC as sysClkRateGet() but
0146 //                 miserably fails to #include the required <sysLib.h> to make
0147 //                 sysClkRateGet() available! So we manually include it here.
0148 #  ifdef __RTP__
0149 #    include <time.h>
0150 #    include <sysLib.h>
0151 #  endif
0152 
0153 // vxWorks-around: In <stdint.h> the macros INT32_C(), UINT32_C(), INT64_C() and
0154 //                 UINT64_C() are defined erroneously, yielding not a signed/
0155 //                 unsigned long/long long type, but a signed/unsigned int/long
0156 //                 type. Eventually this leads to compile errors in ratio_fwd.hpp,
0157 //                 when trying to define several constants which do not fit into a
0158 //                 long type! We correct them here by redefining.
0159 
0160 #  include <cstdint>
0161 
0162 // Special behaviour for DKMs:
0163 
0164 // Some macro-magic to do the job
0165 #  define VX_JOIN(X, Y)     VX_DO_JOIN(X, Y)
0166 #  define VX_DO_JOIN(X, Y)  VX_DO_JOIN2(X, Y)
0167 #  define VX_DO_JOIN2(X, Y) X##Y
0168 
0169 // Correctly setup the macros
0170 #  undef  INT32_C
0171 #  undef  UINT32_C
0172 #  undef  INT64_C
0173 #  undef  UINT64_C
0174 #  define INT32_C(x)  VX_JOIN(x, L)
0175 #  define UINT32_C(x) VX_JOIN(x, UL)
0176 #  define INT64_C(x)  VX_JOIN(x, LL)
0177 #  define UINT64_C(x) VX_JOIN(x, ULL)
0178 
0179 // #include Libraries required for the following function adaption
0180 #  include <sys/time.h>
0181 #endif  // _WRS_VXWORKS_MAJOR < 7
0182 
0183 #include <ioLib.h>
0184 #include <tickLib.h>
0185 
0186 #if defined(_WRS_KERNEL) && (_CPPLIB_VER < 700)
0187   // recent kernels use Dinkum clib v7.00+
0188   // with widechar but older kernels
0189   // do not have the <cwchar>-header,
0190   // but apparently they do have an intrinsic wchar_t meanwhile!
0191 #  define BOOST_NO_CWCHAR
0192 
0193   // Lots of wide-functions and -headers are unavailable for DKMs as well:
0194 #  define BOOST_NO_CWCTYPE
0195 #  define BOOST_NO_SWPRINTF
0196 #  define BOOST_NO_STD_WSTRING
0197 #  define BOOST_NO_STD_WSTREAMBUF
0198 #endif
0199 
0200 
0201 // Use C-linkage for the following helper functions
0202 #ifdef __cplusplus
0203 extern "C" {
0204 #endif
0205 
0206 // vxWorks-around: The required functions getrlimit() and getrlimit() are missing.
0207 //                 But we have the similar functions getprlimit() and setprlimit(),
0208 //                 which may serve the purpose.
0209 //                 Problem: The vxWorks-documentation regarding these functions
0210 //                 doesn't deserve its name! It isn't documented what the first two
0211 //                 parameters idtype and id mean, so we must fall back to an educated
0212 //                 guess - null, argh... :-/
0213 
0214 // TODO: getprlimit() and setprlimit() do exist for RTPs only, for whatever reason.
0215 //       Thus for DKMs there would have to be another implementation.
0216 #if defined ( __RTP__) &&  (_WRS_VXWORKS_MAJOR < 7)
0217   inline int getrlimit(int resource, struct rlimit *rlp){
0218     return getprlimit(0, 0, resource, rlp);
0219   }
0220 
0221   inline int setrlimit(int resource, const struct rlimit *rlp){
0222     return setprlimit(0, 0, resource, const_cast<struct rlimit*>(rlp));
0223   }
0224 #endif
0225 
0226 // vxWorks has ftruncate() only, so we do simulate truncate():
0227 inline int truncate(const char *p, off_t l){
0228   int fd = open(p, O_WRONLY);
0229   if (fd == -1){
0230     errno = EACCES;
0231     return -1;
0232   }
0233   if (ftruncate(fd, l) == -1){
0234     close(fd);
0235     errno = EACCES;
0236     return -1;
0237   }
0238   return close(fd);
0239 }
0240 
0241 #ifdef __GNUC__
0242 #  define ___unused __attribute__((unused))
0243 #else
0244 #  define ___unused
0245 #endif
0246 
0247 // Fake symlink handling by dummy functions:
0248 inline int symlink(const char* path1 ___unused, const char* path2 ___unused){
0249   // vxWorks has no symlinks -> always return an error!
0250   errno = EACCES;
0251   return -1;
0252 }
0253 
0254 inline ssize_t readlink(const char* path1 ___unused, char* path2 ___unused, size_t size ___unused){
0255   // vxWorks has no symlinks -> always return an error!
0256   errno = EACCES;
0257   return -1;
0258 }
0259 
0260 #if (_WRS_VXWORKS_MAJOR < 7)
0261 
0262 inline int gettimeofday(struct timeval *tv, void * /*tzv*/) {
0263   struct timespec ts;
0264   clock_gettime(CLOCK_MONOTONIC, &ts);
0265   tv->tv_sec  = ts.tv_sec;
0266   tv->tv_usec = ts.tv_nsec / 1000;
0267   return 0;
0268 }
0269 #endif
0270 
0271 #ifdef __cplusplus
0272 } // extern "C"
0273 #endif
0274 
0275 /* 
0276  * moved to os/utils/unix/freind_h/times.h in VxWorks 7
0277  * to avoid conflict with MPL operator times
0278  */
0279 #if (_WRS_VXWORKS_MAJOR < 7) 
0280 #  ifdef __cplusplus
0281 
0282 // vxWorks provides neither struct tms nor function times()!
0283 // We implement an empty dummy-function, simply setting the user
0284 // and system time to the half of thew actual system ticks-value
0285 // and the child user and system time to 0.
0286 // Rather ugly but at least it suppresses compiler errors...
0287 // Unfortunately, this of course *does* have an severe impact on
0288 // dependant libraries, actually this is chrono only! Here it will
0289 // not be possible to correctly use user and system times! But
0290 // as vxWorks is lacking the ability to calculate user and system
0291 // process times there seems to be no other possible solution.
0292 struct tms{
0293   clock_t tms_utime;  // User CPU time
0294   clock_t tms_stime;  // System CPU time
0295   clock_t tms_cutime; // User CPU time of terminated child processes
0296   clock_t tms_cstime; // System CPU time of terminated child processes
0297 };
0298 
0299 
0300  inline clock_t times(struct tms *t){
0301   struct timespec ts;
0302   clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
0303   clock_t ticks(static_cast<clock_t>(static_cast<double>(ts.tv_sec)  * CLOCKS_PER_SEC +
0304                                      static_cast<double>(ts.tv_nsec) * CLOCKS_PER_SEC / 1000000.0));
0305   t->tms_utime  = ticks/2U;
0306   t->tms_stime  = ticks/2U;
0307   t->tms_cutime = 0; // vxWorks is lacking the concept of a child process!
0308   t->tms_cstime = 0; // -> Set the wait times for childs to 0
0309   return ticks;
0310 }
0311 
0312 
0313 namespace std {
0314     using ::times;
0315 }
0316 #  endif // __cplusplus
0317 #endif // _WRS_VXWORKS_MAJOR < 7
0318 
0319 
0320 #ifdef __cplusplus
0321 extern "C" void   bzero     (void *, size_t);    // FD_ZERO uses bzero() but doesn't include strings.h
0322 
0323 // Put the selfmade functions into the std-namespace, just in case
0324 namespace std {
0325 #  ifdef __RTP__
0326     using ::getrlimit;
0327     using ::setrlimit;
0328 #  endif
0329   using ::truncate;
0330   using ::symlink;
0331   using ::readlink;
0332 #  if (_WRS_VXWORKS_MAJOR < 7)  
0333     using ::gettimeofday;
0334 #  endif  
0335 }
0336 #endif // __cplusplus
0337 
0338 // Some more macro-magic:
0339 // vxWorks-around: Some functions are not present or broken in vxWorks
0340 //                 but may be patched to life via helper macros...
0341 
0342 // Include signal.h which might contain a typo to be corrected here
0343 #include <signal.h>
0344 
0345 #if (_WRS_VXWORKS_MAJOR < 7)
0346 #  define getpagesize()    sysconf(_SC_PAGESIZE)         // getpagesize is deprecated anyway!
0347 inline int lstat(p, b) { return stat(p, b); }  // lstat() == stat(), as vxWorks has no symlinks!
0348 #endif
0349 
0350 #ifndef S_ISSOCK
0351 #  define S_ISSOCK(mode) ((mode & S_IFMT) == S_IFSOCK) // Is file a socket?
0352 #endif
0353 #ifndef FPE_FLTINV
0354 #  define FPE_FLTINV     (FPE_FLTSUB+1)                // vxWorks has no FPE_FLTINV, so define one as a dummy
0355 #endif
0356 #if !defined(BUS_ADRALN) && defined(BUS_ADRALNR)
0357 #  define BUS_ADRALN     BUS_ADRALNR                   // Correct a supposed typo in vxWorks' <signal.h>
0358 #endif
0359 typedef int              locale_t;                     // locale_t is a POSIX-extension, currently not present in vxWorks!
0360 
0361 // #include boilerplate code:
0362 #include <boost/config/detail/posix_features.hpp>
0363 
0364 // vxWorks lies about XSI conformance, there is no nl_types.h:
0365 #undef BOOST_HAS_NL_TYPES_H
0366 
0367 // vxWorks 7 adds C++11 support 
0368 // however it is optional, and does not match exactly the support determined
0369 // by examining the Dinkum STL version and GCC version (or ICC and DCC) 
0370 #if !( defined( _WRS_CONFIG_LANG_LIB_CPLUS_CPLUS_USER_2011) || defined(_WRS_CONFIG_LIBCPLUS_STD))
0371 #  define BOOST_NO_CXX11_ADDRESSOF      // C11 addressof operator on memory location
0372 #  define BOOST_NO_CXX11_ALLOCATOR
0373 #  define BOOST_NO_CXX11_ATOMIC_SMART_PTR
0374 #  define BOOST_NO_CXX11_NUMERIC_LIMITS  // max_digits10 in test/../print_helper.hpp
0375 #  define BOOST_NO_CXX11_SMART_PTR 
0376 #  define BOOST_NO_CXX11_STD_ALIGN
0377 
0378 
0379 #  define BOOST_NO_CXX11_HDR_ARRAY
0380 #  define BOOST_NO_CXX11_HDR_ATOMIC
0381 #  define BOOST_NO_CXX11_HDR_CHRONO
0382 #  define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE
0383 #  define BOOST_NO_CXX11_HDR_FORWARD_LIST  //serialization/test/test_list.cpp
0384 #  define BOOST_NO_CXX11_HDR_FUNCTIONAL 
0385 #  define BOOST_NO_CXX11_HDR_FUTURE
0386 #  define BOOST_NO_CXX11_HDR_MUTEX
0387 #  define BOOST_NO_CXX11_HDR_RANDOM      //math/../test_data.hpp
0388 #  define BOOST_NO_CXX11_HDR_RATIO
0389 #  define BOOST_NO_CXX11_HDR_REGEX
0390 #  define BOOST_NO_CXX14_HDR_SHARED_MUTEX
0391 #  define BOOST_NO_CXX11_HDR_SYSTEM_ERROR
0392 #  define BOOST_NO_CXX11_HDR_THREAD
0393 #  define BOOST_NO_CXX11_HDR_TYPEINDEX 
0394 #  define BOOST_NO_CXX11_HDR_TYPE_TRAITS
0395 #  define BOOST_NO_CXX11_HDR_TUPLE 
0396 #  define BOOST_NO_CXX11_HDR_UNORDERED_MAP
0397 #  define BOOST_NO_CXX11_HDR_UNORDERED_SET 
0398 #else
0399 #  ifndef  BOOST_SYSTEM_NO_DEPRECATED
0400 #    define BOOST_SYSTEM_NO_DEPRECATED  // workaround link error in spirit
0401 #  endif
0402 #endif
0403 
0404 
0405 // NONE is used in enums in lamda and other libraries
0406 #undef NONE
0407 // restrict is an iostreams class
0408 #undef restrict
0409 // affects some typeof tests
0410 #undef V7
0411 
0412 // use fake poll() from Unix layer in ASIO to get full functionality 
0413 // most libraries will use select() but this define allows 'iostream' functionality
0414 // which is based on poll() only
0415 #if (_WRS_VXWORKS_MAJOR > 6)
0416 #  ifndef BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR
0417 #    define BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR
0418 #  endif
0419 #else 
0420 #  define BOOST_ASIO_DISABLE_SERIAL_PORT
0421 #endif
0422