Changes between Version 2 and Version 3 of Guidelines/VxWorks


Ignore:
Timestamp:
Apr 29, 2013, 11:06:38 AM (9 years ago)
Author:
Peter Brockamp
Comment:

Completed the documentation

Legend:

Unmodified
Added
Removed
Modified
  • Guidelines/VxWorks

    v2 v3  
    11== Introduction ==
     2
     3If you're not interested in the following technical details you may well skip forward to section "Patching the operating system".
    24
    35'''Differences to other operating systems'''
     
    2628* 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}}} - Yuk!
    2729* 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.
    28 * 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 and timing accuracy where a mission cirtical point for your application you would prabably not be using the heap and Boost, right?[[BR]]
     30* 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?
     31So, solution three - patching the OS - seems to be the best solution. How do we do it?[[BR]][[BR]]
     32
     33== Patching the operating system ==
     34
     35Here'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:
     36* Edit the file {{{/vxworks-6.9/target/usr/src/posix/pthreadLib.c}}} in the root of your Workbench-installation.
     37* Around line 917 there should be the definition of the default mutex attributes:
     38{{{
     39LOCAL pthread_mutexattr_t defaultMutexAttr =
     40  {
     41  PTHREAD_INITIALIZED_OBJ, PTHREAD_PRIO_NONE, 0,
     42  PTHREAD_MUTEX_DEFAULT
     43  };
     44}}}
     45  In the initializer list replace {{{PTHREAD_PRIO_NONE}}} by {{{PTHREAD_PRIO_INHERIT}}}.
     46* 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:
     47{{{
     48pAttr->mutexAttrStatus      = PTHREAD_INITIALIZED_OBJ;
     49pAttr->mutexAttrProtocol    = PTHREAD_PRIO_NONE;
     50pAttr->mutexAttrPrioceiling = 0;
     51pAttr->mutexAttrType        = PTHREAD_MUTEX_DEFAULT;
     52}}}
     53  Here again, replace {{{PTHREAD_PRIO_NONE}}} by {{{PTHREAD_PRIO_INHERIT}}}.
     54* Finally, rebuild your VSB. This will create a new VxWorks kernel with the changed properties.
     55That's it! Now, using Boost with this modified kernel should no longer cause any problems with task deadlocks! [[BR]][[BR]]
     56
     57
     58== Conclusions ==
     59
     60* The default values for POSIX mutexes under VxWorks make RTP's susceptible to the priority inversion problem.
     61* The best way around this is to patch the operating system accordingly, a step-by-step instruction is provided.
     62* 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.
     63* Here's another useful piece of information concerning VxWorks' POSIX-functionality in general:[[BR]] 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 to {{{malloc()}}} to allocate the memory required for the housekeeping of POSIX-threads. In a high priority RTP this {{{malloc()}}} 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 function {{{thread_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 a {{{malloc()}}} call is tolerable. So, if this could pose a problem for your code, remember to call {{{thread_self()}}} from the affected task at an early stage. Calling {{{thread_self()}}} to initiate the transformation is BTW an official recommendation by Wind River.