Version 9 (modified by 9 years ago) ( diff ) | ,
---|
Introduction
If you're not interested in the following technical details you may well skip forward to section (1).
Differences to other operating systems
VxWorks is a real time operating system intended for the execution of "mission critical" tasks. This has some impact on the way things are organized and do work internally. One aspect is that it uses a completely different approach for the scheduling of tasks with different priorities. A task in VxWorks more or less corresponds to what is known as a thread in other operating systems, but the operating system will not assign any CPU-cycles to a low priority task if another, higher priority task is ready to run. This could lead to a problematic scenario called "priority inversion problem". You may read more details about priority inversion on wikipedia:
http://en.wikipedia.org/wiki/Priority_inversion
The effect of a priority inversion situation is that tasks could deadlock, when competing for a resource: The classical example is a low priority task T1 owning a semaphore. Now T1 is prempted by a higher priority task T2, it doesn't get any cpu-cylces assigned anymore. Eventually an even higher priority Task T3 prempts T2 and tries to get the ownership of the semaphore. This results in a low priority task (T2) blocking a high priority task (T3), potentially deadlocking all three tasks. This obviously is a situation to be avoided and this can be done via a mechanism called "priority inversion protocol". Basically the OS temporarily boosts the priority of a low priority task owning a semaphore to the priority of the task with the highest priority trying to aquire this semaphore.
Operating modes
We are talking here about the actual Version of VxWorks, for the timing being this is V6.9. Much older versions like the V5.x branch are being left aside as they are very outdated and the libraries that come bundled with it are partially not standard conformant, making it impossible to use Boost. The current version of VxWorks can execute software in two modes. You can compile your project as a DKM (Downlodable Kernel Module, sort of a driver in Windows terms) or as a RTP (Real Time Process, sort of a normal program in Windows terms). For both modes different behaviour, available functionality and default values are present, keep that in mind for the next couple of minutes.
POSIX-conformance
Boost internally comes mainly in two flavors, a Windows implementation and a POSIX implementation. VxWorks in itself is not a POSIX-compliant operating system. Instead it implements the POSIX functionality via a compatibility layer (sort of a wrapper, converting POSIX function calls to native OS calls).
Now, let's take a look at what the standard says about the properties of POSIX-semaphores (see http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread.h.html):
When creating a mutex (i. e. a semaphore) via a call to pthread_mutex_init()
one is allowed to specify NULL
as the pointer value for the mutex attributes. For this case the standard specifies "If attr is NULL
, the default mutex attributes are used". And about the values of the default is only says they are "defined by the implementation". So, then what are the default values for VxWorks? Actually, they are different for DKM's and RTP's. When we take a closer look at the attributes, POSIX gives you the option to choose the priority protocol to use via a call to pthread_mutexattr_setprotocol()
. The possible options are PTHREAD_PRIO_NONE
, PTHREAD_PRIO_INHERIT
and PTHREAD_PRIO_PROTECT
. PTHREAD_PRIO_NONE
switches the priority inversion protocol off, whereas the others choose different flavors of priority inversion protocols. As a default, in VxWorks DKM's use PTHREAD_PRIO_INHERIT
(which should be fine) and RTP's use PTHREAD_PRIO_NONE
. The latter has the advantage to offer the best performance but potentially makes RTP's susceptible for the priority inversion problem.
Usage of Boost
When taking a look at the implementation of the Boost libraries you will quickly find out that a couple of them do use mutexes. And as universal libraries by definition you cannot predict the way a user will use them. A striking example is the shared_ptr
. Naturally, the implementation uses a mutex to control access to the reference counter and the makers of shared_ptr
can't (and won't) make any assumptions about the way a shared_ptr
will be used. A more than likely scenario is the access to heap objects from different tasks with different priorities. It's plain to see that this scenario is prone to the priority inheritance problem. What we can conclude from this is that to be on the safe side we must assume the worst case and all mutexes internally used by Boost should adhere to the priority inversion protocol.
Almost all mutex-instances used by Boost do use the default values, which at glance appears logical - it's the OS' resposibility to choose the proper default! But here's a little dilemma: What is a proper value depends on what you're trying to do, the ball is passed back to Boost from the OS. Now you could pass it over from Boost to the user: Boost can't know what is a proper value, it depends on what the user tries to do! I think you got the problem, right?
So, how will we get out of this dilemma (or is it even a tri-lemma)? Three possibilities:
- Implement and interface, allowing the user to choose the proper value for his/her application. This is not really an option! It will bleed out deeply burried implementation details to the user, resulting in unportable, error prone code and it force the user to study mutex details for a specific platform - whereas he just wanted to use e.g. a
shared_ptr
on Windows - Yuk! - Change the implementation of all Boost libraries to use mutexes with non-default attributes. This would be viable and would not interfere with the non-Boost part of a user application. But it has the disadvantage to be very fragile. If with a new version of Boost all in a sudden a library starts using mutexes the priority inversion problem will resurrect every once in a while.
- Change the operating system to use other defaults. This may at first sound odd for users of a closed source system, but VxWorks in its latest versions luckily comes with the source code included and the possibility to compile a new kernel adapted to your needs. So, this has a lot of advantages, but it may interfere with the user's code (e. g. when he's using POSIX-mutexes with default values). Anyway, this should not pose a major problem, obeying the priority inheritance protocol does not break anything, it just puts on some additional burden on the task-scheduler where it wouldn't be neccessary. But if utmost performance, predictability and timing accuracy were paramount for your application you would probably not be using C++, the heap and Boost, right?
So, solution three - patching the OS - seems to be the best solution. How do we do it?
Patching the operating system (1)
Here's a step by step instruction how to change the default attributes for POSIX-mutexes for RTP's. It's been taken mostly from a Wind River TSR:
- Edit the file
/vxworks-6.9/target/usr/src/posix/pthreadLib.c
in the root of your Workbench-installation. - 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 };
In the initializer list replacePTHREAD_PRIO_NONE
byPTHREAD_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, replacePTHREAD_PRIO_NONE
byPTHREAD_PRIO_INHERIT
. - Finally, rebuild your VSB (Consult your documentation on how to do this). This will create a new VxWorks kernel with the changed properties.
That's it! Now, using Boost with this modified kernel should no longer cause any problems with task deadlocks!
Conclusions
- The default values for POSIX mutexes under VxWorks make RTP's susceptible to the priority inversion problem.
- The best way around this is to patch the operating system accordingly, a step-by-step instruction is provided.
- Other real time OSes (e. g. QNX) may be prone to the problem as well, depending on the defaults used. Consult your OS' documentation to gain clarity about this.
- Here's another useful piece of information concerning VxWorks' POSIX-functionality in general:
At the time a task calls it's first POSIX-function during runtime it is being transformed by VxWorks into a POSIX-thread. This transformation does include a call tomalloc()
to allocate the memory required for the housekeeping of POSIX-threads. In a high priority RTP thismalloc()
call may be highly undesirable, as its timing is more or less unpredictable (depending on what your actual heap looks like). You can circumvent this problem by calling the functionthread_self()
at a well defined point in the code of the task, e.g. shortly after the task spawns up. Thereby you are able to define the time when the task-transformation will take place and you could shift it to an uncritical point where amalloc()
call is tolerable. So, if this could pose a problem for your code, remember to callthread_self()
from the affected task at an early stage. Callingthread_self()
to initiate the transformation is BTW an official recommendation by Wind River. - Building Boost for VxWorks is not quite an easy task! At least I couldn't find out how to use bjam to do it. I'll save you the technical details, but it would be neccessary to make bjam call VxWorks' compiler (a patched, renamed GCC or the diab-compiler) inside of the VxWorks Development Shell (a special shell with lot's of environmental variables set). You can circumvent this for the time being by having the workbench build Boost itself. Below you will find for your convenience the
.wrproject
-file I use for Boost V1.53.- Create a Workbench project for your Boost directory and copy this content to a text file called
.wrproject
, replacing the file automatically generated by the workbench. - Adapt to your personal needs.
- Static linking Boost to your project will be OK, though I haven't tested dynamic linking.
- I use environment variables to announce the local directories for Boost and other libraries I regularly use. These are called
BOOST_ROOT
,BZIP2_ROOT
,ZLIB_ROOT
etc. Create this system variables appropriately or use your own hardcoded paths (Change the include settings of your project). - The file below is for the GCC compiler, as I don't use the diab-compiler, and for x86 as a platform. For other settings you are on your own.
- Create a Workbench project for your Boost directory and copy this content to a text file called
No warranty whatsoever!
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <wrxml> <properties platform="VxWorks" platform_name="vxworks-6.9" root="1" type="RealTimeProcessProject"/> <attributes> <mapAttribute> <listAttribute key="BLD::Info|Definess|COREgnu_RTP"> <stringAttribute value="-D_VX_CPU=_VX_$(CPU)"/> <stringAttribute value="-D_VX_TOOL_FAMILY=$(TOOL_FAMILY)"/> <stringAttribute value="-D_VX_TOOL=$(TOOL)"/> <stringAttribute value="-DBOOST_TEST_NO_MAIN"/> <stringAttribute value="-DBOOST_THREAD_BUILD_LIB"/> <stringAttribute value=" "/> </listAttribute> <listAttribute key="BLD::Info|GlobalMacros"> <stringAttribute value="PROJECT_TYPE"/> <stringAttribute value="DEFINES"/> <stringAttribute value="DO_STRIP"/> <stringAttribute value="EXPAND_DBG"/> </listAttribute> <stringAttribute key="BLD::Info|GlobalMacro|DEFINES" value=""/> <stringAttribute key="BLD::Info|GlobalMacro|DO_STRIP" value="0"/> <stringAttribute key="BLD::Info|GlobalMacro|EXPAND_DBG" value="0"/> <stringAttribute key="BLD::Info|GlobalMacro|PROJECT_TYPE" value="RTP"/> <listAttribute key="BLD::Info|Incl|COREgnu_RTP"> <stringAttribute value="-I$(WIND_BASE)/target/usr/h"/> <stringAttribute value="-I$(WIND_BASE)/target/usr/h/wrn/coreip"/> <stringAttribute value="-isystem$(BOOST_ROOT)"/> <stringAttribute value="-isystem$(BOOST_ROOT)/libs/math/src/tr1"/> <stringAttribute value="-isystem$(BZIP2_ROOT)"/> <stringAttribute value="-isystem$(ZLIB_ROOT)"/> </listAttribute> <listAttribute key="BLD::Info|Macros"> <stringAttribute value="VX_CPU_FAMILY"/> <stringAttribute value="CPU"/> <stringAttribute value="TOOL_FAMILY"/> <stringAttribute value="TOOL"/> <stringAttribute value="TOOL_PATH"/> <stringAttribute value="CC_ARCH_SPEC"/> <stringAttribute value="LIBPATH"/> <stringAttribute value="LIBS"/> <stringAttribute value="VSB_DIR"/> </listAttribute> <stringAttribute key="BLD::Info|Macro|CC_ARCH_SPEC|value|COREgnu_RTP" value="-march=core2"/> <stringAttribute key="BLD::Info|Macro|CPU|value|COREgnu_RTP" value="CORE"/> <stringAttribute key="BLD::Info|Macro|LIBPATH|value|COREgnu_RTP" value=""/> <stringAttribute key="BLD::Info|Macro|LIBS|value|COREgnu_RTP" value="-lstdc++"/> <stringAttribute key="BLD::Info|Macro|TOOL_FAMILY|value|COREgnu_RTP" value="gnu"/> <stringAttribute key="BLD::Info|Macro|TOOL_PATH|value|COREgnu_RTP" value=""/> <stringAttribute key="BLD::Info|Macro|TOOL|value|COREgnu_RTP" value="gnu"/> <stringAttribute key="BLD::Info|Macro|VSB_DIR|value|COREgnu_RTP" value="$(WIND_BASE)/target/lib"/> <stringAttribute key="BLD::Info|Macro|VX_CPU_FAMILY|value|COREgnu_RTP" value="pentium"/> <listAttribute key="BLD::Info|Tools"> <stringAttribute value="C-Compiler"/> <stringAttribute value="C++-Compiler"/> <stringAttribute value="Linker"/> <stringAttribute value="Librarian"/> <stringAttribute value="Assembler"/> </listAttribute> <stringAttribute key="BLD::Info|Tool|Assembler|cmd|COREgnu_RTP" value="echo "building $@";%assemblerprefix% $(TOOL_PATH)ccpentium %DebugModeFlags% %ToolFlags% %Defines% $(DEFINES) $(ADDED_CFLAGS) %Includes% $(ADDED_INCLUDES) -o %OutFile% -c %InFile%"/> <stringAttribute key="BLD::Info|Tool|Assembler|dbgFlags|COREgnu_RTP" value="-g"/> <stringAttribute key="BLD::Info|Tool|Assembler|derivedSigs|COREgnu_RTP" value="*.o"/> <stringAttribute key="BLD::Info|Tool|Assembler|flags|COREgnu_RTP" value="$(CC_ARCH_SPEC) -mrtp -fno-strict-aliasing -D_C99 -D_HAS_C9X -std=c99 -fasm -P -xassembler-with-cpp -MD -MP"/> <stringAttribute key="BLD::Info|Tool|Assembler|nonDbgFlags|COREgnu_RTP" value=" -O2"/> <booleanAttribute key="BLD::Info|Tool|Assembler|object" value="true"/> <booleanAttribute key="BLD::Info|Tool|Assembler|passAble" value="false"/> <stringAttribute key="BLD::Info|Tool|Assembler|sigs" value="*.s"/> <stringAttribute key="BLD::Info|Tool|C++-Compiler|cmd|COREgnu_RTP" value="echo "building $@";%cppcompilerprefix% $(TOOL_PATH)c++pentium %DebugModeFlags% %ToolFlags% %Defines% $(DEFINES) $(ADDED_C++FLAGS) %Includes% $(ADDED_INCLUDES) -o %OutFile% -c %InFile%"/> <stringAttribute key="BLD::Info|Tool|C++-Compiler|dbgFlags|COREgnu_RTP" value="-g"/> <stringAttribute key="BLD::Info|Tool|C++-Compiler|derivedSigs|COREgnu_RTP" value="*.o"/> <stringAttribute key="BLD::Info|Tool|C++-Compiler|flags|COREgnu_RTP" value="$(CC_ARCH_SPEC) -ansi -mrtp -fno-strict-aliasing -D_C99 -D_HAS_C9X -Wall -Wsystem-headers -MD -MP"/> <stringAttribute key="BLD::Info|Tool|C++-Compiler|nonDbgFlags|COREgnu_RTP" value=" -O2"/> <booleanAttribute key="BLD::Info|Tool|C++-Compiler|object" value="true"/> <booleanAttribute key="BLD::Info|Tool|C++-Compiler|passAble" value="false"/> <stringAttribute key="BLD::Info|Tool|C++-Compiler|sigs" value="*.cpp;*.CPP;*.C;*.cxx;*.cc"/> <stringAttribute key="BLD::Info|Tool|C-Compiler|cmd|COREgnu_RTP" value="echo "building $@";%ccompilerprefix% $(TOOL_PATH)ccpentium %DebugModeFlags% %ToolFlags% %Defines% $(DEFINES) $(ADDED_CFLAGS) %Includes% $(ADDED_INCLUDES) -o %OutFile% -c %InFile%"/> <stringAttribute key="BLD::Info|Tool|C-Compiler|dbgFlags|COREgnu_RTP" value="-g"/> <stringAttribute key="BLD::Info|Tool|C-Compiler|derivedSigs|COREgnu_RTP" value="*.o"/> <stringAttribute key="BLD::Info|Tool|C-Compiler|flags|COREgnu_RTP" value="$(CC_ARCH_SPEC) -mrtp -fno-strict-aliasing -D_C99 -D_HAS_C9X -std=c99 -fasm -Wall -Wsystem-headers -MD -MP"/> <stringAttribute key="BLD::Info|Tool|C-Compiler|nonDbgFlags|COREgnu_RTP" value=" -O2"/> <booleanAttribute key="BLD::Info|Tool|C-Compiler|object" value="true"/> <booleanAttribute key="BLD::Info|Tool|C-Compiler|passAble" value="false"/> <stringAttribute key="BLD::Info|Tool|C-Compiler|sigs" value="*.c"/> <stringAttribute key="BLD::Info|Tool|Librarian|cmd|COREgnu_RTP" value="echo "building $@";%archiverprefix% $(TOOL_PATH)arpentium %ToolFlags% %OutFile% %Objects% $(ADDED_OBJECTS)"/> <stringAttribute key="BLD::Info|Tool|Librarian|dbgFlags|COREgnu_RTP" value=""/> <stringAttribute key="BLD::Info|Tool|Librarian|derivedSigs|COREgnu_RTP" value="*.a"/> <stringAttribute key="BLD::Info|Tool|Librarian|flags|COREgnu_RTP" value="crus"/> <stringAttribute key="BLD::Info|Tool|Librarian|nonDbgFlags|COREgnu_RTP" value=""/> <booleanAttribute key="BLD::Info|Tool|Librarian|object" value="false"/> <booleanAttribute key="BLD::Info|Tool|Librarian|passAble" value="true"/> <stringAttribute key="BLD::Info|Tool|Librarian|sigs" value=""/> <stringAttribute key="BLD::Info|Tool|Linker|cmd|COREgnu_RTP" value="echo "building $@";%cpplinkerprefix% $(TOOL_PATH)c++pentium %DebugModeFlags% %ToolFlags% -o %OutFile% %Objects% $(ADDED_OBJECTS) %Libraries% $(LIBPATH) $(LIBS) -L$(VSB_DIR)/usr/lib/pentium/CORE/common $(ADDED_LIBPATH) $(ADDED_LIBS) -Wl,--start-group -Wl,--end-group && if [ "$(DO_STRIP)" = "1" ]; then mv -f "$@" "$@.unstripped" && strippentium -g -o "$@" "$@.unstripped";fi && if [ "$(EXPAND_DBG)" = "1" ]; then plink "$@";fi"/> <stringAttribute key="BLD::Info|Tool|Linker|dbgFlags|COREgnu_RTP" value=""/> <stringAttribute key="BLD::Info|Tool|Linker|derivedSigs|COREgnu_RTP" value="*.vxe"/> <stringAttribute key="BLD::Info|Tool|Linker|flags|COREgnu_RTP" value="$(CC_ARCH_SPEC) -mrtp -fno-strict-aliasing -D_C99 -D_HAS_C9X -std=c99 -fasm -Wall -Wsystem-headers -MD -MP -mrtp"/> <stringAttribute key="BLD::Info|Tool|Linker|nonDbgFlags|COREgnu_RTP" value=""/> <booleanAttribute key="BLD::Info|Tool|Linker|object" value="false"/> <booleanAttribute key="BLD::Info|Tool|Linker|passAble" value="false"/> <stringAttribute key="BLD::Info|Tool|Linker|sigs" value=""/> <stringAttribute key="BLD::Info|cmd" value="%makeprefix% make --no-print-directory"/> <stringAttribute key="BLD::Info|defaultSpec" value="COREgnu_RTP"/> <stringAttribute key="BLD::Info|redirDir|COREgnu_RTP" value="COREgnu_RTP"/> <stringAttribute key="BLD::Info|redirRoot" value=""/> <listAttribute key="BLD::Info|specs"> <stringAttribute value="COREgnu_RTP"/> </listAttribute> <intAttribute key="BuildSupportEnabled" value="1"/> <booleanAttribute key="BuildTargetCentric" value="true"/> </mapAttribute> </attributes> <buildtargets> <buildtarget buildtool="Librarian" name="Boost" passed="false" targetname="Boost"> <contents> <folder name="/Boost" recursive="true"> <excludes> <folder name="doc"/> <folder name="more"/> <folder name="status"/> <folder name="tools"/> <folder name="lib"/> <folder name="libs/accumulators"/> <folder name="libs/algorithm"/> <folder name="libs/any"/> <folder name="libs/array"/> <folder name="libs/asio"/> <folder name="libs/assign"/> <folder name="libs/bimap"/> <folder name="libs/bind"/> <folder name="libs/chrono/build"/> <folder name="libs/chrono/doc"/> <folder name="libs/chrono/example"/> <folder name="libs/chrono/perf"/> <folder name="libs/chrono/test"/> <folder name="libs/circular_buffer"/> <folder name="libs/compatibility"/> <folder name="libs/compose"/> <folder name="libs/concept_check"/> <folder name="libs/container"/> <folder name="libs/context/build"/> <folder name="libs/context/config"/> <folder name="libs/context/doc"/> <folder name="libs/context/example"/> <folder name="libs/context/performance"/> <folder name="libs/context/test"/> <folder name="libs/conversion"/> <folder name="libs/crc"/> <folder name="libs/date_time/build"/> <folder name="libs/date_time/data"/> <folder name="libs/date_time/doc"/> <folder name="libs/date_time/example"/> <folder name="libs/date_time/test"/> <folder name="libs/date_time/xmldoc"/> <folder name="libs/detail"/> <folder name="libs/disjoint_sets"/> <folder name="libs/dynamic_bitset"/> <folder name="libs/exception/build"/> <folder name="libs/exception/doc"/> <folder name="libs/exception/example"/> <folder name="libs/exception/test"/> <folder name="libs/filesystem/build"/> <folder name="libs/filesystem/doc"/> <folder name="libs/filesystem/example"/> <folder name="libs/filesystem/test"/> <folder name="libs/filesystem/tools"/> <folder name="libs/flyweight"/> <folder name="libs/foreach"/> <folder name="libs/format"/> <folder name="libs/function"/> <folder name="libs/function_types"/> <folder name="libs/functional"/> <folder name="libs/fusion"/> <folder name="libs/geometry"/> <folder name="libs/gil"/> <folder name="libs/graph/build"/> <folder name="libs/graph/doc"/> <folder name="libs/graph/example"/> <folder name="libs/graph/test"/> <folder name="libs/graph_parallel/build"/> <folder name="libs/graph_parallel/doc"/> <folder name="libs/graph_parallel/example"/> <folder name="libs/graph_parallel/test"/> <folder name="libs/heap"/> <folder name="libs/icl"/> <folder name="libs/integer"/> <folder name="libs/interprocess"/> <folder name="libs/intrusive"/> <folder name="libs/io"/> <folder name="libs/iostreams/build"/> <folder name="libs/iostreams/doc"/> <folder name="libs/iostreams/example"/> <folder name="libs/iostreams/test"/> <folder name="libs/iterator"/> <folder name="libs/lambda"/> <folder name="libs/local_function"/> <folder name="libs/locale/build"/> <folder name="libs/locale/doc"/> <folder name="libs/locale/examples"/> <folder name="libs/locale/performance"/> <folder name="libs/locale/test"/> <folder name="libs/locale/tools"/> <folder name="libs/logic"/> <folder name="libs/math/build"/> <folder name="libs/math/config"/> <folder name="libs/math/doc"/> <folder name="libs/math/dot_net_example"/> <folder name="libs/math/example"/> <folder name="libs/math/minimax"/> <folder name="libs/math/octonion"/> <folder name="libs/math/performance"/> <folder name="libs/math/quaternion"/> <folder name="libs/math/special_functions"/> <folder name="libs/math/test"/> <folder name="libs/math/tools"/> <folder name="libs/math/vc71_fix"/> <folder name="libs/mem_fn"/> <folder name="libs/move"/> <folder name="libs/mpi/build"/> <folder name="libs/mpi/doc"/> <folder name="libs/mpi/example"/> <folder name="libs/mpi/test"/> <folder name="libs/mpl"/> <folder name="libs/msm"/> <folder name="libs/multi_array"/> <folder name="libs/multi_index"/> <folder name="libs/numeric"/> <folder name="libs/optional"/> <folder name="libs/parameter"/> <folder name="libs/phoenix"/> <folder name="libs/polygon"/> <folder name="libs/pool"/> <folder name="libs/preprocessor"/> <folder name="libs/program_options/build"/> <folder name="libs/program_options/doc"/> <folder name="libs/program_options/example"/> <folder name="libs/program_options/test"/> <folder name="libs/property_map"/> <folder name="libs/property_tree"/> <folder name="libs/proto"/> <folder name="libs/ptr_container"/> <folder name="libs/python/build"/> <file name="libs/python/class.cpp"/> <folder name="libs/python/doc"/> <folder name="libs/python/example"/> <folder name="libs/python/pyste"/> <folder name="libs/python/test"/> <folder name="libs/random/build"/> <folder name="libs/random/doc"/> <folder name="libs/random/example"/> <folder name="libs/random/extra"/> <folder name="libs/random/performance"/> <folder name="libs/random/test"/> <folder name="libs/range"/> <folder name="libs/ratio"/> <folder name="libs/rational"/> <folder name="libs/regex/build"/> <folder name="libs/regex/doc"/> <folder name="libs/regex/example"/> <folder name="libs/regex/performance"/> <folder name="libs/regex/test"/> <folder name="libs/regex/tools"/> <folder name="libs/scope_exit"/> <folder name="libs/serialization/build"/> <folder name="libs/serialization/doc"/> <folder name="libs/serialization/example"/> <folder name="libs/serialization/performance"/> <folder name="libs/serialization/test"/> <folder name="libs/serialization/util"/> <folder name="libs/serialization/vc7ide"/> <folder name="libs/signals/build"/> <folder name="libs/signals/doc"/> <folder name="libs/signals/example"/> <folder name="libs/signals/test"/> <folder name="libs/signals2"/> <folder name="libs/smart_ptr/example"/> <folder name="libs/smart_ptr/test"/> <folder name="libs/spirit"/> <folder name="libs/statechart"/> <folder name="libs/static_assert"/> <folder name="libs/system/build"/> <folder name="libs/system/doc"/> <folder name="libs/system/test"/> <folder name="libs/test/build"/> <folder name="libs/test/doc"/> <folder name="libs/test/docbook"/> <folder name="libs/test/example"/> <folder name="libs/test/test"/> <folder name="libs/test/tools"/> <folder name="libs/thread/build"/> <folder name="libs/thread/doc"/> <folder name="libs/thread/example"/> <folder name="libs/thread/test"/> <folder name="libs/thread/tutorial"/> <folder name="libs/timer/build"/> <folder name="libs/timer/doc"/> <folder name="libs/timer/example"/> <folder name="libs/timer/test"/> <folder name="libs/tokenizer"/> <folder name="libs/tr1"/> <folder name="libs/tuple"/> <folder name="libs/type_traits"/> <folder name="libs/typeof"/> <folder name="libs/units"/> <folder name="libs/utility"/> <folder name="libs/unordered"/> <folder name="libs/uuid"/> <folder name="libs/variant"/> <folder name="libs/wave/build"/> <folder name="libs/wave/doc"/> <folder name="libs/wave/samples"/> <folder name="libs/wave/test"/> <folder name="libs/xpressive"/> <file name="libs/context/src/seh.cpp"/> <folder name="libs/thread/src/win32"/> <folder name=".settings"/> <folder name=".coveragescope"/> <folder name="libs/config"/> <file name="boost/asio/impl/src.cpp"/> <folder name="libs/locale/src/win32"/> <folder name="libs/locale/src/posix"/> <folder name="libs/python"/> <folder name="libs/graph_parallel"/> <file name="boost/spirit/home/support/char_encoding/unicode/create_tables.cpp"/> <folder name="libs/locale"/> <folder name="libs/mpi"/> <folder name=".svn"/> <folder name=".settings"/> <folder name=".coveragescope"/> <file name="libs/context/src/guarded_stack_allocator_windows.cpp"/> <file name="libs/context/src/utils_windows.cpp"/> <folder name="bin.v2"/> <folder name="VisualStudio"/> <folder name="stage"/> <file name="libs/context/src/unsupported.cpp"/> <folder name="libs/coroutine"/> <folder name="libs/lockfree"/> <folder name="libs/multiprecision"/> </excludes> </folder> </contents> </buildtarget> </buildtargets> </wrxml>