1    /*
     2     * Copyright (c) 2015-2020 Texas Instruments Incorporated - http://www.ti.com
     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 Newlib
    51     *  libraries and provides an overloaded implementation of the library's
    52     *  __getreent() function to make the C runtime library calls re-entrant and
    53     *  thread safe.
    54     *
    55     *  The C runtime library (newlib libc/libm) functions internally call
    56     *  __getreent() to get the address of the currently executing thread's
    57     *  reentrancy structure.
    58     *
    59     *  The __getreent() function allocates storage for the reentrancy structure
    60     *  when it is called for the very first time within a thread context. Any
    61     *  subsequent calls to __getreent() within the same thread context read the
    62     *  current thread's stored context to determine the previously allocated
    63     *  reentrancy structure's address and return it.
    64     *
    65     *  When a thread is deleted, the DeleteHook is called and will free any memory
    66     *  that was allocated to store the reentrancy structure associated with the
    67     *  thread.
    68     *
    69     *  The C runtime library calls locking APIs to ensure thread safety. The
    70     *  locking APIs are defined in the sys/lock.h header in the version of Newlib
    71     *  distributed with SYS/BIOS. This module provides an implementation for these
    72     *  locking APIs.
    73     *
    74     *  Reentrancy support is enabled by default if tasking is enabled
    75     *  and can be disabled by adding the following code to the application's
    76     *  config script.
    77     *
    78     *  @p(code)
    79     *  var ReentSupport = xdc.useModule('ti.sysbios.rts.gnu.ReentSupport');
    80     *
    81     *  // 'true' to enable Task level reentrancy support (default)
    82     *  // 'false' to disable Task level reentrancy support
    83     *  ReentSupport.enableReentSupport = false;
    84     *  @p
    85     *
    86     *  Note: Calling C runtime functions from SWI and HWI threads
    87     *        is not supported and will generate an exception if
    88     *        reentrancy support is enabled.
    89     *
    90     */
    91    
    92    @Template ("./ReentSupport.xdt") /* generate __getreent() function */
    93    @ModuleStartup
    94    
    95    module ReentSupport 
    96    {
    97        /*!
    98         *  ======== ModuleView ========
    99         *  @_nodoc
   100         */
   101        metaonly struct ModuleView {
   102            Bool enableReentSupport;
   103        }
   104    
   105        /*!
   106         *  ======== rovViewInfo ========
   107         *  @_nodoc
   108         */
   109        @Facet
   110        metaonly config ViewInfo.Instance rovViewInfo = 
   111            ViewInfo.create({
   112                viewMap: [
   113                [
   114                    'Module',
   115                    {
   116                        type: ViewInfo.MODULE,
   117                        viewInitFxn: 'viewInitModule',
   118                        structName: 'ModuleView'
   119                    }
   120                ],
   121                ]
   122            });
   123    
   124        /*! 
   125         *  ======== enableReentSupport ========
   126         *  Enable re-entrancy support
   127         */
   128        config Bool enableReentSupport = true;
   129    
   130        // Asserts
   131    
   132        /*! Asserted in ReentSupport_getReent() */
   133        config Assert.Id A_badThreadType = {
   134            msg: "A_badThreadType: Cannot call a C runtime library API from a Hwi or Swi thread."
   135        };
   136    
   137    internal:   /* not for client use */ 
   138    
   139        /* -------- Hook Functions -------- */
   140    
   141        /*
   142         *  ======== getReent ========
   143         *  Return a pointer to the current thread's Reentrancy structure
   144         *
   145         *  @b(returns) Pointer to current thread's Reentrancy structure
   146         *
   147         */
   148        Ptr getReent();
   149    
   150        /*
   151         *  ======== initGlobalReent ========
   152         *  Initialize global re-entrancy structure
   153         */
   154        Void initGlobalReent();
   155    
   156        /*
   157         *  ======== taskCreateHook ========
   158         *  Create hook function used to create and initialize all task's
   159         *  hook context.
   160         *                
   161         *  @param(task) Handle of the Task to initialize.
   162         *  @param(eb) Error block.
   163         *
   164         */
   165        Void taskCreateHook(Task.Handle task, Error.Block *eb);
   166    
   167        /*
   168         *  ======== taskDeleteHook ========
   169         *  Delete hook function used to remove the task's hook context.
   170         *           
   171         *  @param(task) Handle of the Task to delete.
   172         *
   173         */
   174        Void taskDeleteHook(Task.Handle task);
   175    
   176        /*
   177         *  ======== taskRegHook ========
   178         *  Registration function for the module's hook 
   179         *  
   180         *  @param(id) The id of the hook for use in load.
   181         *       
   182         */
   183        Void taskRegHook(Int id);
   184    
   185        /* -------- Internal Module Types -------- */
   186    
   187        struct Module_State {     
   188            Int               taskHId;   /* Task Hook Context Id for this module */
   189            Semaphore.Handle  lock;      /* Static binary semaphore handle */
   190        };
   191    }