1    /* 
     2     *  Copyright (c) 2008 Texas Instruments. All rights reserved.
     3     *  This program and the accompanying materials are made available under the
     4     *  terms of the Eclipse Public License v1.0 and Eclipse Distribution License
     5     *  v. 1.0 which accompanies this distribution. The Eclipse Public License is
     6     *  available at http://www.eclipse.org/legal/epl-v10.html and the Eclipse
     7     *  Distribution License is available at
     8     *  http://www.eclipse.org/org/documents/edl-v10.php.
     9     *
    10     *  Contributors:
    11     *      Texas Instruments - initial implementation
    12     * */
    13    /*
    14     *  ======== Thread.xdc ========
    15     */
    16    
    17    import xdc.runtime.Error;
    18    import xdc.runtime.Assert;
    19    import xdc.runtime.knl.IThreadSupport;
    20    
    21    /*!
    22     *  ======== Thread ========
    23     *  Thread services.
    24     *
    25     *  This module manages threads through a proxy which inherits from
    26     *  IThreadSupport interface. It has a module wide config parameter
    27     *  {@link #Proxy} which needs to be bound to an OS specific delegate before
    28     *  this module can be used.
    29     *
    30     *  Here is an example showing how the proxy is bound to a BIOS 6.x specific
    31     *  delegate.
    32     *
    33     *  @p(code)
    34     *  var Thread = xdc.useModule('xdc.runtime.knl.Thread');
    35     *  Thread.Proxy = xdc.useModule('ti.sysbios.xdcruntime.ThreadSupport');
    36     *  @p
    37     *
    38     *  Typically a package containing the delegates has a Settings module that 
    39     *  will bind all {@link xdc.runtime.knl} proxies. The following
    40     *  example sets up all the xdc.runtime.knl proxies.
    41     *
    42     *  @p(code)
    43     *  xdc.useModule('ti.sysbios.xdcruntime.Settings');
    44     *  @p
    45     */
    46    @InstanceInitError      /* because initialization can fail */
    47    @InstanceFinalize       /* have to Thread_Proxy_delete(sem) on delete */
    48    @DirectCall
    49    
    50    module Thread
    51    {
    52        /*! Thread priorities which are mapped to OS specific value by Proxy */
    53        enum Priority {
    54            Priority_INVALID,
    55            Priority_LOWEST,
    56            Priority_BELOW_NORMAL,
    57            Priority_NORMAL,
    58            Priority_ABOVE_NORMAL,
    59            Priority_HIGHEST
    60        };
    61    
    62        /*! Invalid OS priority value */
    63        const Int INVALID_OS_PRIORITY = 0;
    64    
    65        /*! Status returned by {@link #getPri} when an error occurs */
    66        const Int GETPRI_FAILED = -2;
    67    
    68        /*! Status returned by {@link #compareOsPriorities} when an error occurs */
    69        enum CompStatus {
    70            CompStatus_ERROR = -2,
    71            CompStatus_LOWER = -1,
    72            CompStatus_EQUAL = 0,
    73            CompStatus_HIGHER = 1
    74        };
    75    
    76        /*! Proxy that needs to be bound to an OS specific delegate. */
    77        proxy Proxy inherits IThreadSupport;
    78    
    79        /*! Typedef for thread function */
    80        typedef Void (*RunFxn)(IArg);
    81    
    82        /*! Struct to hold thread statistics from {@link #stat} */
    83        struct Stat {
    84            SizeT stackSize;
    85            SizeT stackUsed;
    86        }
    87    
    88        /*! Assert when  timeout passed to {@link #sleep} is zero */
    89        config Assert.Id A_zeroTimeout= {
    90            msg: "A_zeroTimeout: Timeout value annot be zero"
    91        };
    92    
    93        /*! Default thread stack size. */
    94        config SizeT defaultStackSize = 0;
    95    
    96        /*!
    97         *  ======== self ========
    98         *  Return the currently executing thread's handle
    99         *
   100         *  @param(eb)      Pointer to Error.Block
   101         *  @a(returns)     Returns a handle to the currently executing thread.
   102         *                  If the current thread is the main thread, this function
   103         *                  returns `NULL`. NULL is also returned in case of error.
   104         */
   105        Handle self(Error.Block *eb);
   106    
   107        /*!
   108         *  ======== start ========
   109         *  Start threads running
   110         *
   111         *  This function can be used to start all statically created threads,
   112         *  and all threads created dynamically before this function is called.
   113         *  Any thread created after this function is called, starts automatically
   114         *  (i.e., there is no need to call Thread_start() more than once).
   115         *
   116         *  @param(eb)      Pointer to Error.Block
   117         *  @a(returns)     true for success; false for error
   118         */
   119        Bool start(Error.Block *eb);
   120    
   121        /*!
   122         *  ======== yield ========
   123         *  Yield the currently scheduled thread
   124         *
   125         *  @param(eb)      Pointer to Error.Block
   126         *  @a(returns)     true for success; false for error
   127         */
   128        Bool yield(Error.Block *eb);
   129    
   130        /*!
   131         *  ======== compareOsPriorities ========
   132         *  Compare two os specific priority values and find out which one
   133         *  represents a higher priority.
   134         *
   135         *  @p(blist)
   136         *  -{@link #CompStatus_ERROR} if an error occured
   137         *  -{@link #CompStatus_LOWER} if p1 is lower than p2
   138         *  -{@link #CompStatus_EQUAL} if p1=p2
   139         *  -{@link #CompStatus_HIGHER} if p1 is higher than p2
   140         *    details.
   141         *  @p
   142         *
   143         *  @param(p1)      priority one
   144         *  @param(p2)      priority two
   145         *  @param(eb)      Pointer to Error.Block
   146         *  @a(returns)     refer to description above
   147         */
   148        Int compareOsPriorities(Int p1, Int p2, Error.Block *eb);
   149    
   150        /*!
   151         *  ======== sleep ========
   152         *  Sleep for given number of microseconds
   153         *
   154         *  This function is gauranteed to sleep for at least as long as the 
   155         *  timeout value but the actual sleep time may be longer. NOTE:
   156         *  The timeout value cannot be zero.
   157         *
   158         *  @param(timeout)     timeout in microseconds
   159         *  @param(eb)          Pointer to Error.Block
   160         *  @a(returns)         true for success; false for error
   161         */
   162        Bool sleep(UInt timeout, Error.Block *eb);
   163    
   164    instance:
   165    
   166        /*! Thread function argument. Default is 0. */
   167        config IArg arg = 0;
   168    
   169        /*!
   170         *  ======== priority ========
   171         *  Specify the new thread's priority
   172         *
   173         *  Thread defines several constants which allows applications to select
   174         *  a priority in an OS independent way: Priority_LOWEST, 
   175         *  Priority_BELOW_NORMAL, Priority_NORMAL, Priority_ABOVE_NORMAL and 
   176         *  Priority_HIGHEST. These values get mapped to OS specific priorities 
   177         *  by the OS specific delegate.
   178         */
   179        config Priority priority = Priority_NORMAL;
   180    
   181        /*!
   182         *  ======== osPriority ========
   183         *  OS specific thread priority
   184         *
   185         *  Used to specify an OS specific value for priority. If set this value
   186         *  takes precedence over {@link #priority}.
   187         */
   188        config Int osPriority = INVALID_OS_PRIORITY;
   189    
   190        /*!
   191         *  ======== stackSize ========
   192         *  Thread stack size
   193         *
   194         *  The default value of 0 means that `{@link #defaultStackSize}` is used.
   195         */
   196        config SizeT stackSize = 0;
   197        
   198        /*! 
   199         *  ======== tls ========
   200         *  Thread local storage.
   201         *
   202         *  User data associated with a thread. Must persist for the life of
   203         *  the thread.
   204         */
   205        config Ptr tls = null;
   206    
   207        /*!
   208         *  ======== create ========
   209         *  Create a Thread object
   210         *
   211         *  This function spawns a new thread calling the function fxn.
   212         *
   213         *  @param(fxn)     function for new thread to begin execution
   214         */
   215        create(RunFxn fxn);
   216    
   217        /*!
   218         *  ======== join ========
   219         *  Block calling thread until given thread terminates.
   220         *
   221         *  Use this functions to ensure that a thread has terminated. It is OK to
   222         *  call this function on a thread that has already terminated.
   223         *
   224         *  @param(eb)      Pointer to Error.Block
   225         *  @a(returns)     true for success; false for error
   226         */
   227        Bool join(Error.Block *eb);
   228    
   229        /*!
   230         *  ======== getPriority ========
   231         *  Obtain a thread's priority.
   232         *
   233         *  For OSes that support dynamic priority boosting, this function
   234         *  retrieves the base priority of the thread.
   235         *
   236         *  @param(eb)      Pointer to Error.Block
   237         *  @a(returns)     thread priority in case of success; PRIORITY_INVALID in
   238         *                  case of error;
   239         */
   240        Priority getPriority(Error.Block *eb);
   241    
   242        /*!
   243         *  ======== setPriority ========
   244         *  Set a thread's priority.
   245         *
   246         *  For OSes that support dynamic priority boosting, this function
   247         *  changes the base priority of the thread.
   248         *
   249         *  @param(newPri)  new thread priority
   250         *  @param(eb)      Pointer to Error.Block
   251         *  @a(returns)     true for success; false for error
   252         */
   253        Bool setPriority(Priority newPri, Error.Block *eb);
   254    
   255        /*!
   256         *  ======== getOsPriority ========
   257         *  Obtain a thread's OS specific priority.
   258         *
   259         *  For OSes that support dynamic priority boosting, the value returned 
   260         *  is the base priority of the thread.
   261         *
   262         *  @param(eb)      Pointer to Error.Block
   263         *  @a(returns)     thread priority in case of success; GETPRI_FAILED in
   264         *                  case of error;
   265         */
   266        Int getOsPriority(Error.Block *eb);
   267    
   268        /*!
   269         *  ======== setOsPriority ========
   270         *  Set a thread's priority.
   271         *
   272         *  This API sets the base priority of the thread on OSes that
   273         *  support dynamic priority boosting
   274         *
   275         *  @param(newPri)  new thread priority
   276         *  @param(eb)      Pointer to Error.Block
   277         *  @a(returns)     true for success; false for error
   278         */
   279        Bool setOsPriority(Int newPri, Error.Block *eb);
   280    
   281        /*!
   282         *  ======== getOsHandle ========
   283         *  Get the OS thread handle
   284         *
   285         *   @a(returns)     OS thread handle
   286         */
   287        Ptr getOsHandle();
   288    
   289        /*!
   290         *  ======== getTls ========
   291         *  Obtain a thread's local storage.
   292         *
   293         *   @a(returns)     null when tls has not been set.
   294         */
   295        Ptr getTls();
   296    
   297        /*!
   298         *  ======== setTls ========
   299         *  Change a thread's local storage.
   300         *
   301         *  @param(tls)     tls
   302         */
   303        Void setTls(Ptr tls);
   304    
   305        /*!
   306         *  ======== stat ========
   307         *  Get thread statistics
   308         *
   309         *  @param(buf)     Pointer to Stat
   310         *  @param(eb)      Pointer to Error.Block
   311         *  @a(returns)     true for success; false for failure
   312         */
   313        Bool stat(Stat* buf, Error.Block *eb);
   314    
   315    internal:
   316    
   317        struct Instance_State {
   318            Thread.Proxy.Handle proxyHandle; /*! handle for real implementation */
   319            Ptr                 tls;         /*! store tls parameter */
   320        }
   321    }
   322    /*
   323     *  @(#) xdc.runtime.knl; 1, 0, 0,0; 2-20-2019 10:22:55; /db/ztree/library/trees/xdc/xdc-F09/src/packages/
   324     */
   325