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