1    /*
     2     * Copyright (c) 2015, Texas Instruments Incorporated
     3     * All rights reserved.
     4     *
     5     * Redistribution and use in source and binary forms, with or without
     6     * modification, are permitted provided that the following conditions
     7     * are met:
     8     *
     9     * *  Redistributions of source code must retain the above copyright
    10     *    notice, this list of conditions and the following disclaimer.
    11     *
    12     * *  Redistributions in binary form must reproduce the above copyright
    13     *    notice, this list of conditions and the following disclaimer in the
    14     *    documentation and/or other materials provided with the distribution.
    15     *
    16     * *  Neither the name of Texas Instruments Incorporated nor the names of
    17     *    its contributors may be used to endorse or promote products derived
    18     *    from this software without specific prior written permission.
    19     *
    20     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    21     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
    22     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    23     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    24     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    25     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    26     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
    27     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    28     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    29     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
    30     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    31     */
    32    /*
    33     *  ======== ReentSupport.xdc ========
    34     */
    35    
    36    package ti.sysbios.rts.gnu;
    37    
    38    import xdc.rov.ViewInfo;
    39    
    40    import xdc.runtime.Error;
    41    import xdc.runtime.Assert;
    42    
    43    import ti.sysbios.knl.Task;
    44    import ti.sysbios.knl.Semaphore;
    45    
    46    /*!
    47     *  ======== ReentSupport ========
    48     *  Newlib RTS library re-entrancy support module
    49     *
    50     *  The Reentrancy Support module implements locking APIs for the
    51     *  Newlib libraries and provides an overloaded implementation of
    52     *  the library's __getreent() function to make the C runtime library
    53     *  calls re-entrant and thread safe.
    54     *
    55     *  The C runtime library (newlib libc/libm) functions internally
    56     *  call __getreent() to get the address of the currently executing
    57     *  thread's reentrancy structure.
    58     *
    59     *  The __getreent() function allocates storage for the reentrancy
    60     *  structure when it is called for the very first time within a
    61     *  thread context. Any subsequent calls to __getreent() within the
    62     *  same thread context read the current thread's stored context to
    63     *  determine the previously allocated reentrancy structure's address
    64     *  and return it.
    65     *
    66     *  When a thread is deleted, the DeleteHook is called and will free
    67     *  any memory that was allocated to store the reentrancy structure
    68     *  associated with the thread.
    69     *
    70     *  The C runtime library calls locking APIs to ensure thread
    71     *  safety. The locking APIs are defined in the sys/lock.h header
    72     *  that is distributed with XDC tools. This module provides an
    73     *  implementation for these locking APIs.
    74     *
    75     *  Reentrancy support is enabled by default if tasking is enabled
    76     *  and can be disabled by adding the following code to the application's
    77     *  config script.
    78     *
    79     *  @p(code)
    80     *  var ReentSupport = xdc.useModule('ti.sysbios.rts.gnu.ReentSupport');
    81     *
    82     *  // 'true' to enable Task level reentrancy support (default)
    83     *  // 'false' to disable Task level reentrancy support
    84     *  ReentSupport.enableReentSupport = false;
    85     *  @p
    86     *
    87     *  Note: Calling C runtime functions from SWI and HWI threads
    88     *        is not supported and will generate an exception if
    89     *        reentrancy support is enabled.
    90     *
    91     */
    92    
    93    @Template ("./ReentSupport.xdt") /* generate __getreent() function */
    94    @ModuleStartup
    95    
    96    module ReentSupport 
    97    {
    98        /*!
    99         *  ======== ModuleView ========
   100         *  @_nodoc
   101         */
   102        metaonly struct ModuleView {
   103            Bool enableReentSupport;
   104        }
   105    
   106        /*!
   107         *  ======== rovViewInfo ========
   108         *  @_nodoc
   109         */
   110        @Facet
   111        metaonly config ViewInfo.Instance rovViewInfo = 
   112            ViewInfo.create({
   113                viewMap: [
   114                [
   115                    'Module',
   116                    {
   117                        type: ViewInfo.MODULE,
   118                        viewInitFxn: 'viewInitModule',
   119                        structName: 'ModuleView'
   120                    }
   121                ],
   122                ]
   123            });
   124    
   125        /*! 
   126         *  ======== enableReentSupport ========
   127         *  Enable re-entrancy support
   128         */
   129        config Bool enableReentSupport = true;
   130    
   131        // Asserts
   132    
   133        /*! Asserted in ReentSupport_getReent() */
   134        config Assert.Id A_badThreadType = {
   135            msg: "A_badThreadType: Cannot call a C runtime library API from a Hwi or Swi thread."
   136        };
   137    
   138    internal:   /* not for client use */ 
   139    
   140        /* -------- Hook Functions -------- */
   141    
   142        /*!
   143         *  ======== getReent ========
   144         *  Return a pointer to the current thread's Reentrancy structure
   145         *
   146         *  @b(returns) Pointer to current thread's Reentrancy structure
   147         *
   148         */
   149        Ptr getReent();
   150    
   151        /*!
   152         *  ======== taskCreateHook ========
   153         *  Create hook function used to create and initialize all task's
   154         *  hook context.
   155         *                
   156         *  @param(task) Handle of the Task to initialize.
   157         *  @param(eb) Error block.
   158         *
   159         */
   160        Void taskCreateHook(Task.Handle task, Error.Block *eb);
   161    
   162        /*!
   163         *  ======== taskDeleteHook ========
   164         *  Delete hook function used to remove the task's hook context.
   165         *           
   166         *  @param(task) Handle of the Task to delete.
   167         *
   168         */
   169        Void taskDeleteHook(Task.Handle task);
   170    
   171        /*!
   172         *  ======== taskRegHook ========
   173         *  Registration function for the module's hook 
   174         *  
   175         *  @param(id) The id of the hook for use in load.
   176         *       
   177         */
   178        Void taskRegHook(Int id);
   179    
   180        /* -------- Internal Module Types -------- */
   181    
   182        struct Module_State {     
   183            Int               taskHId;   /* Task Hook Context Id for this module */
   184            Semaphore.Handle  lock;      /* Static binary semaphore handle */
   185        };
   186    }