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    
    47    @InstanceInitError      /* because initialization can fail */
    48    @InstanceFinalize       /* have to Thread_Proxy_delete(sem) on delete */
    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        @DirectCall
   106        Handle self(Error.Block *eb);
   107    
   108        /*!
   109         *  ======== start ========
   110         *  Start threads running
   111         *
   112         *  This function can be used to start all statically created threads,
   113         *  and all threads created dynamically before this function is called.
   114         *  Any thread created after this function is called, starts automatically.
   115         *  (i.e., there is no need to call Thread_start() more than once).
   116         *
   117         *  @param(eb)      Pointer to Error.Block
   118         *  @a(returns)     true for success; false for error
   119         */
   120        Bool start(Error.Block *eb);
   121    
   122        /*!
   123         *  ======== yield ========
   124         *  Yield the currently scheduled thread
   125         *
   126         *  @param(eb)      Pointer to Error.Block
   127         *  @a(returns)     true for success; false for error
   128         */
   129        Bool yield(Error.Block *eb);
   130    
   131        /*!
   132         *  ======== compareOsPriorities ========
   133         *  Compare two os specific priority values and find out which one 
   134         *  represents a higher priority.
   135         *
   136         *  @p(blist)
   137         *  -{@link #CompStatus_ERROR} if an error occured
   138         *  -{@link #CompStatus_LOWER} if p1 is lower than p2
   139         *  -{@link #CompStatus_EQUAL} if p1=p2
   140         *  -{@link #CompStatus_HIGHER} if p1 is higher than p2
   141         *    details.
   142         *  @p
   143         *
   144         *  @param(p1)      priority one
   145         *  @param(p2)      priority two
   146         *  @param(eb)      Pointer to Error.Block
   147         *  @a(returns)     refer to description above
   148         */
   149        Int compareOsPriorities(Int p1, Int p2, Error.Block *eb);
   150        
   151        /*!
   152         *  ======== sleep ========
   153         *  Sleep for given number of microseconds
   154         *
   155         *  This function is gauranteed to sleep for at least as long as the 
   156         *  timeout value but the actual sleep time may be longer. NOTE:
   157         *  The timeout value cannot be zero.
   158         *
   159         *  @param(timeout)     timeout in microseconds
   160         *  @param(eb)          Pointer to Error.Block
   161         *  @a(returns)         true for success; false for error
   162         */
   163        Bool sleep(UInt timeout, Error.Block *eb);
   164    
   165    instance:
   166    
   167        /*! Thread function argument. Default is 0. */
   168        config IArg arg = 0;
   169    
   170        /*!
   171         *  ======== priority ========
   172         *  Specify the new thread's priority
   173         *
   174         *  Thread defines several constants which allows applications to select
   175         *  a priority in an OS independent way: Priority_LOWEST, 
   176         *  Priority_BELOW_NORMAL, Priority_NORMAL, Priority_ABOVE_NORMAL and 
   177         *  Priority_HIGHEST. These values get mapped to OS specific priorities 
   178         *  by the OS specific delegate.
   179         */
   180        config Priority priority = Priority_NORMAL;
   181    
   182        /*!
   183         *  ======== osPriority ========
   184         *  OS specific thread priority
   185         *
   186         *  Used to specify an OS specific value for priority. If set this value
   187         *  takes precedence over {@link #priority}.
   188         */
   189        config Int osPriority = INVALID_OS_PRIORITY;
   190    
   191        /*!
   192         *  ======== stackSize ========
   193         *  Thread stack size
   194         *
   195         *  The default value of 0 means that `{@link #defaultStackSize}` is used.
   196         */
   197        config SizeT stackSize = 0;
   198        
   199        /*! 
   200         *  ======== tls ========
   201         *  Thread local storage.
   202         *
   203         *  User data associated with a thread. Must persist for the life of
   204         *  the thread.
   205         */
   206        config Ptr tls = null;
   207    
   208        /*!
   209         *  ======== create ========
   210         *  Create a Thread object
   211         *
   212         *  This function spawns a new thread calling the function fxn.
   213         *
   214         *  @param(fxn)     function for new thread to begin execution
   215         */
   216        create(RunFxn fxn);
   217    
   218        /*!
   219         *  ======== join ========
   220         *  Block calling thread until given thread terminates.
   221         *
   222         *  Use this functions to ensure that a thread has terminated. It is OK to
   223         *  call this function on a thread that has already terminated.
   224         *
   225         *  @param(eb)      Pointer to Error.Block
   226         *  @a(returns)     true for success; false for error
   227         */
   228        Bool join(Error.Block *eb);
   229    
   230        /*!
   231         *  ======== getPriority ========
   232         *  Obtain a thread's priority.
   233         *
   234         *  For OSes that support dynamic priority boosting, this function
   235         *  retrieves the base priority of the thread.
   236         *
   237         *  @param(eb)      Pointer to Error.Block
   238         *  @a(returns)     thread priority in case of success; PRIORITY_INVALID in
   239         *                  case of error;
   240         */
   241        Priority getPriority(Error.Block *eb);
   242    
   243        /*!
   244         *  ======== setPriority ========
   245         *  Set a thread's priority.
   246         *
   247         *  For OSes that support dynamic priority boosting, this function
   248         *  changes the base priority of the thread.
   249         *
   250         *  @param(newPri)  new thread priority
   251         *  @param(eb)      Pointer to Error.Block
   252         *  @a(returns)     true for success; false for error
   253         */
   254        Bool setPriority(Priority newPri, Error.Block *eb);
   255    
   256        /*!
   257         *  ======== getOsPriority ========
   258         *  Obtain a thread's OS specific priority.
   259         *
   260         *  For OSes that support dynamic priority boosting, the value returned 
   261         *  is the base priority of the thread.
   262         *
   263         *  @param(eb)      Pointer to Error.Block
   264         *  @a(returns)     thread priority in case of success; GETPRI_FAILED in
   265         *                  case of error;
   266         */
   267        Int getOsPriority(Error.Block *eb);
   268    
   269        /*!
   270         *  ======== setOsPriority ========
   271         *  Set a thread's priority.
   272         *
   273         *  This API sets the base priority of the thread on OSes that
   274         *  support dynamic priority boosting
   275         *
   276         *  @param(newPri)  new thread priority
   277         *  @param(eb)      Pointer to Error.Block
   278         *  @a(returns)     true for success; false for error
   279         */
   280        Bool setOsPriority(Int newPri, Error.Block *eb);
   281    
   282        /*!
   283         *  ======== getOsHandle ========
   284         *  Get the OS thread handle
   285         *
   286         *   @a(returns)     OS thread handle
   287         */
   288        Ptr getOsHandle();
   289    
   290        /*!
   291         *  ======== getTls ========
   292         *  Obtain a thread's local storage.
   293         *
   294         *   @a(returns)     null when tls has not been set.
   295         */
   296        Ptr getTls();
   297    
   298        /*!
   299         *  ======== setTls ========
   300         *  Change a thread's local storage.
   301         *
   302         *  @param(tls)     tls
   303         */
   304        Void setTls(Ptr tls);
   305    
   306        /*!
   307         *  ======== stat ========
   308         *  Get thread statistics
   309         *
   310         *  @param(buf)     Pointer to Stat
   311         *  @param(eb)      Pointer to Error.Block
   312         *  @a(returns)     true for success; false for failure
   313         */
   314        Bool stat(Stat* buf, Error.Block *eb);
   315    
   316    internal:
   317    
   318        struct Instance_State {
   319            Thread.Proxy.Handle proxyHandle; /*! handle for real implementation */
   320            Ptr                 tls;         /*! store tls parameter */
   321        }
   322    }
   323    /*
   324     *  @(#) xdc.runtime.knl; 1, 0, 0,194; 9-3-2012 16:22:18; /db/ztree/library/trees/xdc/xdc-y35x/src/packages/
   325     */
   326