annotate DEPENDENCIES/generic/include/boost/config/platform/vxworks.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // (C) Copyright Dustin Spicuzza 2009.
Chris@16 2 // Adapted to vxWorks 6.9 by Peter Brockamp 2012.
Chris@16 3 // Use, modification and distribution are subject to the
Chris@16 4 // Boost Software License, Version 1.0. (See accompanying file
Chris@16 5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 6
Chris@16 7 // See http://www.boost.org for most recent version.
Chris@16 8
Chris@16 9 // Since WRS does not yet properly support boost under vxWorks
Chris@16 10 // and this file was badly outdated, but I was keen on using it,
Chris@16 11 // I patched boost myself to make things work. This has been tested
Chris@16 12 // and adapted by me for vxWorks 6.9 *only*, as I'm lacking access
Chris@16 13 // to earlier 6.X versions! The only thing I know for sure is that
Chris@16 14 // very old versions of vxWorks (namely everything below 6.x) are
Chris@16 15 // absolutely unable to use boost. This is mainly due to the completely
Chris@16 16 // outdated libraries and ancient compiler (GCC 2.96 or worse). Do
Chris@16 17 // not even think of getting this to work, a miserable failure will
Chris@16 18 // be guaranteed!
Chris@16 19 // Equally, this file has been tested for RTPs (Real Time Processes)
Chris@16 20 // only, not for DKMs (Downloadable Kernel Modules). These two types
Chris@16 21 // of executables differ largely in the available functionality of
Chris@16 22 // the C-library, STL, and so on. A DKM uses a library similar to those
Chris@16 23 // of vxWorks 5.X - with all its limitations and incompatibilities
Chris@16 24 // with respect to ANSI C++ and STL. So probably there might be problems
Chris@16 25 // with the usage of boost from DKMs. WRS or any voluteers are free to
Chris@16 26 // prove the opposite!
Chris@16 27
Chris@16 28 // ====================================================================
Chris@16 29 //
Chris@16 30 // Some important information regarding the usage of POSIX semaphores:
Chris@16 31 // -------------------------------------------------------------------
Chris@16 32 //
Chris@16 33 // VxWorks as a real time operating system handles threads somewhat
Chris@16 34 // different from what "normal" OSes do, regarding their scheduling!
Chris@16 35 // This could lead to a scenario called "priority inversion" when using
Chris@16 36 // semaphores, see http://en.wikipedia.org/wiki/Priority_inversion.
Chris@16 37 //
Chris@16 38 // Now, VxWorks POSIX-semaphores for DKM's default to the usage of
Chris@16 39 // priority inverting semaphores, which is fine. On the other hand,
Chris@16 40 // for RTP's it defaults to using non priority inverting semaphores,
Chris@16 41 // which could easily pose a serious problem for a real time process,
Chris@16 42 // i.e. deadlocks! To overcome this two possibilities do exist:
Chris@16 43 //
Chris@16 44 // a) Patch every piece of boost that uses semaphores to instanciate
Chris@16 45 // the proper type of semaphores. This is non-intrusive with respect
Chris@16 46 // to the OS and could relatively easy been done by giving all
Chris@16 47 // semaphores attributes deviating from the default (for in-depth
Chris@16 48 // information see the POSIX functions pthread_mutexattr_init()
Chris@16 49 // and pthread_mutexattr_setprotocol()). However this breaks all
Chris@16 50 // too easily, as with every new version some boost library could
Chris@16 51 // all in a sudden start using semaphores, resurrecting the very
Chris@16 52 // same, hard to locate problem over and over again!
Chris@16 53 //
Chris@16 54 // b) We could change the default properties for POSIX-semaphores
Chris@16 55 // that VxWorks uses for RTP's and this is being suggested here,
Chris@16 56 // as it will more or less seamlessly integrate with boost. I got
Chris@16 57 // the following information from WRS how to do this, compare
Chris@16 58 // Wind River TSR# 1209768:
Chris@16 59 //
Chris@16 60 // Instructions for changing the default properties of POSIX-
Chris@16 61 // semaphores for RTP's in VxWorks 6.9:
Chris@16 62 // - Edit the file /vxworks-6.9/target/usr/src/posix/pthreadLib.c
Chris@16 63 // in the root of your Workbench-installation.
Chris@16 64 // - Around line 917 there should be the definition of the default
Chris@16 65 // mutex attributes:
Chris@16 66 //
Chris@16 67 // LOCAL pthread_mutexattr_t defaultMutexAttr =
Chris@16 68 // {
Chris@16 69 // PTHREAD_INITIALIZED_OBJ, PTHREAD_PRIO_NONE, 0,
Chris@16 70 // PTHREAD_MUTEX_DEFAULT
Chris@16 71 // };
Chris@16 72 //
Chris@16 73 // Here, replace PTHREAD_PRIO_NONE by PTHREAD_PRIO_INHERIT.
Chris@16 74 // - Around line 1236 there should be a definition for the function
Chris@16 75 // pthread_mutexattr_init(). A couple of lines below you should
Chris@16 76 // find a block of code like this:
Chris@16 77 //
Chris@16 78 // pAttr->mutexAttrStatus = PTHREAD_INITIALIZED_OBJ;
Chris@16 79 // pAttr->mutexAttrProtocol = PTHREAD_PRIO_NONE;
Chris@16 80 // pAttr->mutexAttrPrioceiling = 0;
Chris@16 81 // pAttr->mutexAttrType = PTHREAD_MUTEX_DEFAULT;
Chris@16 82 //
Chris@16 83 // Here again, replace PTHREAD_PRIO_NONE by PTHREAD_PRIO_INHERIT.
Chris@16 84 // - Finally, rebuild your VSB. This will create a new VxWorks kernel
Chris@16 85 // with the changed properties. That's it! Now, using boost should
Chris@16 86 // no longer cause any problems with task deadlocks!
Chris@16 87 //
Chris@16 88 // And here's another useful piece of information concerning VxWorks'
Chris@16 89 // POSIX-functionality in general:
Chris@16 90 // VxWorks is not a genuine POSIX-OS in itself, rather it is using a
Chris@16 91 // kind of compatibility layer (sort of a wrapper) to emulate the
Chris@16 92 // POSIX-functionality by using its own resources and functions.
Chris@16 93 // At the time a task (thread) calls it's first POSIX-function during
Chris@16 94 // runtime it is being transformed by the OS into a POSIX-thread.
Chris@16 95 // This transformation does include a call to malloc() to allocate the
Chris@16 96 // memory required for the housekeeping of POSIX-threads. In a high
Chris@16 97 // priority RTP this malloc() call may be highly undesirable, as its
Chris@16 98 // timing is more or less unpredictable (depending on what your actual
Chris@16 99 // heap looks like). You can circumvent this problem by calling the
Chris@16 100 // function thread_self() at a well defined point in the code of the
Chris@16 101 // task, e.g. shortly after the task spawns up. Thereby you are able
Chris@16 102 // to define the time when the task-transformation will take place and
Chris@16 103 // you could shift it to an uncritical point where a malloc() call is
Chris@16 104 // tolerable. So, if this could pose a problem for your code, remember
Chris@16 105 // to call thread_self() from the affected task at an early stage.
Chris@16 106 //
Chris@16 107 // ====================================================================
Chris@16 108
Chris@16 109 // Block out all versions before vxWorks 6.x, as these don't work:
Chris@16 110 // Include header with the vxWorks version information and query them
Chris@16 111 #include <version.h>
Chris@16 112 #if !defined(_WRS_VXWORKS_MAJOR) || (_WRS_VXWORKS_MAJOR < 6)
Chris@16 113 # error "The vxWorks version you're using is so badly outdated,\
Chris@16 114 it doesn't work at all with boost, sorry, no chance!"
Chris@16 115 #endif
Chris@16 116
Chris@16 117 // Handle versions above 5.X but below 6.9
Chris@16 118 #if (_WRS_VXWORKS_MAJOR == 6) && (_WRS_VXWORKS_MINOR < 9)
Chris@16 119 // TODO: Starting from what version does vxWorks work with boost?
Chris@16 120 // We can't reasonably insert a #warning "" as a user hint here,
Chris@16 121 // as this will show up with every file including some boost header,
Chris@16 122 // badly bugging the user... So for the time being we just leave it.
Chris@16 123 #endif
Chris@16 124
Chris@16 125 // vxWorks specific config options:
Chris@16 126 // --------------------------------
Chris@16 127 #define BOOST_PLATFORM "vxWorks"
Chris@16 128
Chris@16 129 // Special behaviour for DKMs:
Chris@16 130 #ifdef _WRS_KERNEL
Chris@16 131 // DKMs do not have the <cwchar>-header,
Chris@16 132 // but apparently they do have an intrinsic wchar_t meanwhile!
Chris@16 133 # define BOOST_NO_CWCHAR
Chris@16 134
Chris@16 135 // Lots of wide-functions and -headers are unavailable for DKMs as well:
Chris@16 136 # define BOOST_NO_CWCTYPE
Chris@16 137 # define BOOST_NO_SWPRINTF
Chris@16 138 # define BOOST_NO_STD_WSTRING
Chris@16 139 # define BOOST_NO_STD_WSTREAMBUF
Chris@16 140 #endif
Chris@16 141
Chris@16 142 // Generally available headers:
Chris@16 143 #define BOOST_HAS_UNISTD_H
Chris@16 144 #define BOOST_HAS_STDINT_H
Chris@16 145 #define BOOST_HAS_DIRENT_H
Chris@16 146 #define BOOST_HAS_SLIST
Chris@16 147
Chris@16 148 // vxWorks does not have installed an iconv-library by default,
Chris@16 149 // so unfortunately no Unicode support from scratch is available!
Chris@16 150 // Thus, instead it is suggested to switch to ICU, as this seems
Chris@16 151 // to be the most complete and portable option...
Chris@16 152 #define BOOST_LOCALE_WITH_ICU
Chris@16 153
Chris@16 154 // Generally available functionality:
Chris@16 155 #define BOOST_HAS_THREADS
Chris@16 156 #define BOOST_HAS_NANOSLEEP
Chris@16 157 #define BOOST_HAS_GETTIMEOFDAY
Chris@16 158 #define BOOST_HAS_CLOCK_GETTIME
Chris@16 159 #define BOOST_HAS_MACRO_USE_FACET
Chris@16 160
Chris@16 161 // Generally unavailable functionality, delivered by boost's test function:
Chris@16 162 //#define BOOST_NO_DEDUCED_TYPENAME // Commented this out, boost's test gives an errorneous result!
Chris@16 163 #define BOOST_NO_CXX11_EXTERN_TEMPLATE
Chris@16 164 #define BOOST_NO_CXX11_VARIADIC_MACROS
Chris@16 165
Chris@16 166 // Generally available threading API's:
Chris@16 167 #define BOOST_HAS_PTHREADS
Chris@16 168 #define BOOST_HAS_SCHED_YIELD
Chris@16 169 #define BOOST_HAS_SIGACTION
Chris@16 170
Chris@16 171 // Functionality available for RTPs only:
Chris@16 172 #ifdef __RTP__
Chris@16 173 # define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE
Chris@16 174 # define BOOST_HAS_LOG1P
Chris@16 175 # define BOOST_HAS_EXPM1
Chris@16 176 #endif
Chris@16 177
Chris@16 178 // Functionality available for DKMs only:
Chris@16 179 #ifdef _WRS_KERNEL
Chris@16 180 // Luckily, at the moment there seems to be none!
Chris@16 181 #endif
Chris@16 182
Chris@16 183 // These #defines allow posix_features to work, since vxWorks doesn't
Chris@16 184 // #define them itself for DKMs (for RTPs on the contrary it does):
Chris@16 185 #ifdef _WRS_KERNEL
Chris@16 186 # ifndef _POSIX_TIMERS
Chris@16 187 # define _POSIX_TIMERS 1
Chris@16 188 # endif
Chris@16 189 # ifndef _POSIX_THREADS
Chris@16 190 # define _POSIX_THREADS 1
Chris@16 191 # endif
Chris@16 192 #endif
Chris@16 193
Chris@16 194 // vxWorks doesn't work with asio serial ports:
Chris@16 195 #define BOOST_ASIO_DISABLE_SERIAL_PORT
Chris@16 196 // TODO: The problem here seems to bee that vxWorks uses its own, very specific
Chris@16 197 // ways to handle serial ports, incompatible with POSIX or anything...
Chris@16 198 // Maybe a specific implementation would be possible, but until the
Chris@16 199 // straight need arises... This implementation would presumably consist
Chris@16 200 // of some vxWorks specific ioctl-calls, etc. Any voluteers?
Chris@16 201
Chris@16 202 // vxWorks-around: <time.h> #defines CLOCKS_PER_SEC as sysClkRateGet() but
Chris@16 203 // miserably fails to #include the required <sysLib.h> to make
Chris@16 204 // sysClkRateGet() available! So we manually include it here.
Chris@16 205 #ifdef __RTP__
Chris@16 206 # include <time.h>
Chris@16 207 # include <sysLib.h>
Chris@16 208 #endif
Chris@16 209
Chris@16 210 // vxWorks-around: In <stdint.h> the macros INT32_C(), UINT32_C(), INT64_C() and
Chris@16 211 // UINT64_C() are defined errorneously, yielding not a signed/
Chris@16 212 // unsigned long/long long type, but a signed/unsigned int/long
Chris@16 213 // type. Eventually this leads to compile errors in ratio_fwd.hpp,
Chris@16 214 // when trying to define several constants which do not fit into a
Chris@16 215 // long type! We correct them here by redefining.
Chris@16 216 #include <cstdint>
Chris@16 217
Chris@16 218 // Some macro-magic to do the job
Chris@16 219 #define VX_JOIN(X, Y) VX_DO_JOIN(X, Y)
Chris@16 220 #define VX_DO_JOIN(X, Y) VX_DO_JOIN2(X, Y)
Chris@16 221 #define VX_DO_JOIN2(X, Y) X##Y
Chris@16 222
Chris@16 223 // Correctly setup the macros
Chris@16 224 #undef INT32_C
Chris@16 225 #undef UINT32_C
Chris@16 226 #undef INT64_C
Chris@16 227 #undef UINT64_C
Chris@16 228 #define INT32_C(x) VX_JOIN(x, L)
Chris@16 229 #define UINT32_C(x) VX_JOIN(x, UL)
Chris@16 230 #define INT64_C(x) VX_JOIN(x, LL)
Chris@16 231 #define UINT64_C(x) VX_JOIN(x, ULL)
Chris@16 232
Chris@16 233 // #include Libraries required for the following function adaption
Chris@16 234 #include <ioLib.h>
Chris@16 235 #include <tickLib.h>
Chris@16 236 #include <sys/time.h>
Chris@16 237
Chris@16 238 // Use C-linkage for the following helper functions
Chris@16 239 extern "C" {
Chris@16 240
Chris@16 241 // vxWorks-around: The required functions getrlimit() and getrlimit() are missing.
Chris@16 242 // But we have the similar functions getprlimit() and setprlimit(),
Chris@16 243 // which may serve the purpose.
Chris@16 244 // Problem: The vxWorks-documentation regarding these functions
Chris@16 245 // doesn't deserve its name! It isn't documented what the first two
Chris@16 246 // parameters idtype and id mean, so we must fall back to an educated
Chris@16 247 // guess - null, argh... :-/
Chris@16 248
Chris@16 249 // TODO: getprlimit() and setprlimit() do exist for RTPs only, for whatever reason.
Chris@16 250 // Thus for DKMs there would have to be another implementation.
Chris@16 251 #ifdef __RTP__
Chris@16 252 inline int getrlimit(int resource, struct rlimit *rlp){
Chris@16 253 return getprlimit(0, 0, resource, rlp);
Chris@16 254 }
Chris@16 255
Chris@16 256 inline int setrlimit(int resource, const struct rlimit *rlp){
Chris@16 257 return setprlimit(0, 0, resource, const_cast<struct rlimit*>(rlp));
Chris@16 258 }
Chris@16 259 #endif
Chris@16 260
Chris@16 261 // vxWorks has ftruncate() only, so we do simulate truncate():
Chris@16 262 inline int truncate(const char *p, off_t l){
Chris@16 263 int fd = open(p, O_WRONLY);
Chris@16 264 if (fd == -1){
Chris@16 265 errno = EACCES;
Chris@16 266 return -1;
Chris@16 267 }
Chris@16 268 if (ftruncate(fd, l) == -1){
Chris@16 269 close(fd);
Chris@16 270 errno = EACCES;
Chris@16 271 return -1;
Chris@16 272 }
Chris@16 273 return close(fd);
Chris@16 274 }
Chris@16 275
Chris@16 276 // Fake symlink handling by dummy functions:
Chris@16 277 inline int symlink(const char*, const char*){
Chris@16 278 // vxWorks has no symlinks -> always return an error!
Chris@16 279 errno = EACCES;
Chris@16 280 return -1;
Chris@16 281 }
Chris@16 282
Chris@16 283 inline ssize_t readlink(const char*, char*, size_t){
Chris@16 284 // vxWorks has no symlinks -> always return an error!
Chris@16 285 errno = EACCES;
Chris@16 286 return -1;
Chris@16 287 }
Chris@16 288
Chris@16 289 // vxWorks claims to implement gettimeofday in sys/time.h
Chris@16 290 // but nevertheless does not provide it! See
Chris@16 291 // https://support.windriver.com/olsPortal/faces/maintenance/techtipDetail_noHeader.jspx?docId=16442&contentId=WR_TECHTIP_006256
Chris@16 292 // We implement a surrogate version here via clock_gettime:
Chris@16 293 inline int gettimeofday(struct timeval *tv, void * /*tzv*/) {
Chris@16 294 struct timespec ts;
Chris@16 295 clock_gettime(CLOCK_MONOTONIC, &ts);
Chris@16 296 tv->tv_sec = ts.tv_sec;
Chris@16 297 tv->tv_usec = ts.tv_nsec / 1000;
Chris@16 298 return 0;
Chris@16 299 }
Chris@16 300
Chris@16 301 // vxWorks does provide neither struct tms nor function times()!
Chris@16 302 // We implement an empty dummy-function, simply setting the user
Chris@16 303 // and system time to the half of thew actual system ticks-value
Chris@16 304 // and the child user and system time to 0.
Chris@16 305 // Rather ugly but at least it suppresses compiler errors...
Chris@16 306 // Unfortunately, this of course *does* have an severe impact on
Chris@16 307 // dependant libraries, actually this is chrono only! Here it will
Chris@16 308 // not be possible to correctly use user and system times! But
Chris@16 309 // as vxWorks is lacking the ability to calculate user and system
Chris@16 310 // process times there seems to be no other possible solution.
Chris@16 311 struct tms{
Chris@16 312 clock_t tms_utime; // User CPU time
Chris@16 313 clock_t tms_stime; // System CPU time
Chris@16 314 clock_t tms_cutime; // User CPU time of terminated child processes
Chris@16 315 clock_t tms_cstime; // System CPU time of terminated child processes
Chris@16 316 };
Chris@16 317
Chris@16 318 inline clock_t times(struct tms *t){
Chris@16 319 struct timespec ts;
Chris@16 320 clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
Chris@16 321 clock_t ticks(static_cast<clock_t>(static_cast<double>(ts.tv_sec) * CLOCKS_PER_SEC +
Chris@16 322 static_cast<double>(ts.tv_nsec) * CLOCKS_PER_SEC / 1000000.0));
Chris@16 323 t->tms_utime = ticks/2U;
Chris@16 324 t->tms_stime = ticks/2U;
Chris@16 325 t->tms_cutime = 0; // vxWorks is lacking the concept of a child process!
Chris@16 326 t->tms_cstime = 0; // -> Set the wait times for childs to 0
Chris@16 327 return ticks;
Chris@16 328 }
Chris@16 329
Chris@16 330 } // extern "C"
Chris@16 331
Chris@16 332 // Put the selfmade functions into the std-namespace, just in case
Chris@16 333 namespace std {
Chris@16 334 # ifdef __RTP__
Chris@16 335 using ::getrlimit;
Chris@16 336 using ::setrlimit;
Chris@16 337 # endif
Chris@16 338 using ::truncate;
Chris@16 339 using ::symlink;
Chris@16 340 using ::readlink;
Chris@16 341 using ::times;
Chris@16 342 using ::gettimeofday;
Chris@16 343 }
Chris@16 344
Chris@16 345 // Some more macro-magic:
Chris@16 346 // vxWorks-around: Some functions are not present or broken in vxWorks
Chris@16 347 // but may be patched to life via helper macros...
Chris@16 348
Chris@16 349 // Include signal.h which might contain a typo to be corrected here
Chris@16 350 #include <signal.h>
Chris@16 351
Chris@16 352 #define getpagesize() sysconf(_SC_PAGESIZE) // getpagesize is deprecated anyway!
Chris@16 353 #ifndef S_ISSOCK
Chris@16 354 # define S_ISSOCK(mode) ((mode & S_IFMT) == S_IFSOCK) // Is file a socket?
Chris@16 355 #endif
Chris@16 356 #define lstat(p, b) stat(p, b) // lstat() == stat(), as vxWorks has no symlinks!
Chris@16 357 #ifndef FPE_FLTINV
Chris@16 358 # define FPE_FLTINV (FPE_FLTSUB+1) // vxWorks has no FPE_FLTINV, so define one as a dummy
Chris@16 359 #endif
Chris@16 360 #if !defined(BUS_ADRALN) && defined(BUS_ADRALNR)
Chris@16 361 # define BUS_ADRALN BUS_ADRALNR // Correct a supposed typo in vxWorks' <signal.h>
Chris@16 362 #endif
Chris@16 363 //typedef int locale_t; // locale_t is a POSIX-extension, currently unpresent in vxWorks!
Chris@16 364
Chris@16 365 // #include boilerplate code:
Chris@16 366 #include <boost/config/posix_features.hpp>
Chris@16 367
Chris@16 368 // vxWorks lies about XSI conformance, there is no nl_types.h:
Chris@16 369 #undef BOOST_HAS_NL_TYPES_H