Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

IGateProvider.h

Go to the documentation of this file.
00001 /** 
00002  *  @file   IGateProvider.h
00003  *
00004  *  @brief      Interface implemented by all gate providers.
00005  *
00006  *  Gates are used serialize access to data structures that are used by more
00007  *  than one thread.
00008  *
00009  *  Gates are responsible for ensuring that only one out of multiple threads
00010  *  can access a data structure at a time.  There
00011  *  are important scheduling latency and performance considerations that
00012  *  affect the "type" of gate used to protect each data structure.  For
00013  *  example, the best way to protect a shared counter is to simply disable
00014  *  all interrupts before the update and restore the interrupt state after
00015  *  the update; disabling all interrupts prevents all thread switching, so
00016  *  the update is guaranteed to be "atomic".  Although highly efficient, this
00017  *  method of creating atomic sections causes serious system latencies when
00018  *  the time required to update the data structure can't be bounded.
00019  *
00020  *  For example, a memory manager's list of free blocks can grow indefinitely
00021  *  long during periods of high fragmentation.  Searching such a list with
00022  *  interrupts disabled would cause system latencies to also become unbounded.
00023  *  In this case, the best solution is to provide a gate that suspends the
00024  *  execution of  threads that try to enter a gate that has already been
00025  *  entered; i.e., the gate "blocks" the thread until the thread
00026  *  already in the gate leaves.  The time required to enter and leave the
00027  *  gate is greater than simply enabling and restoring interrupts, but since
00028  *  the time spent within the gate is relatively large, the overhead caused by
00029  *  entering and leaving gates will not become a significant percentage of
00030  *  overall system time.  More importantly, threads that do not need to
00031  *  access the shared data structure are completely unaffected by threads
00032  *  that do access it.
00033  *
00034  *
00035  *
00036  *  @ver        02.00.00.68_beta1
00037  *  
00038  *  ============================================================================
00039  *  
00040  *  Copyright (c) 2008-2009, Texas Instruments Incorporated
00041  *
00042  *  Redistribution and use in source and binary forms, with or without
00043  *  modification, are permitted provided that the following conditions
00044  *  are met:
00045  *  
00046  *  *  Redistributions of source code must retain the above copyright
00047  *     notice, this list of conditions and the following disclaimer.
00048  *  
00049  *  *  Redistributions in binary form must reproduce the above copyright
00050  *     notice, this list of conditions and the following disclaimer in the
00051  *     documentation and/or other materials provided with the distribution.
00052  *  
00053  *  *  Neither the name of Texas Instruments Incorporated nor the names of
00054  *     its contributors may be used to endorse or promote products derived
00055  *     from this software without specific prior written permission.
00056  *  
00057  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00058  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
00059  *  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00060  *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
00061  *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00062  *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00063  *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
00064  *  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00065  *  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00066  *  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
00067  *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00068  *  Contact information for paper mail:
00069  *  Texas Instruments
00070  *  Post Office Box 655303
00071  *  Dallas, Texas 75265
00072  *  Contact information: 
00073  *  http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
00074  *  DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
00075  *  ============================================================================
00076  *  
00077  */
00078 
00079 
00080 #ifndef __IGATEPROVIDER_H__
00081 #define __IGATEPROVIDER_H__
00082 
00083 #include <ti/syslink/utils/Trace.h>
00084 
00085 #if defined (__cplusplus)
00086 extern "C" {
00087 #endif
00088 
00089 
00090 /* -----------------------------------------------------------------------------
00091  *  Macros
00092  * -----------------------------------------------------------------------------
00093  */
00094 /*! Invalid Igate */
00095 #define IGateProvider_NULL      (IGateProvider_Handle)0xFFFFFFFF
00096 
00097 /*!
00098  *  ======== IGateProvider_Q_BLOCKING ========
00099  *  Blocking quality
00100  *
00101  *  Gates with this "quality" may cause the calling thread to block;
00102  *  i.e., suspend execution until another thread leaves the gate.
00103  */
00104 #define IGateProvider_Q_BLOCKING 1
00105 
00106 /*!
00107  *  ======== IGateProvider_Q_PREEMPTING ========
00108  *  Preempting quality
00109  *
00110  *  Gates with this "quality" allow other threads to preempt the thread
00111  *  that has already entered the gate.
00112  */
00113 #define IGateProvider_Q_PREEMPTING 2
00114 
00115 /*!
00116  *  ======== IGateProvider_SuperObject ========
00117  *  Object embedded in other Gate modules. (Inheritance)
00118  */
00119 #define IGateProvider_SuperObject                                              \
00120         IGateProvider_ENTER enter;                                                 \
00121         IGateProvider_LEAVE leave
00122         
00123 
00124 /*!
00125  *
00126  */
00127 #define IGateProvider_ObjectInitializer(x,y)                                   \
00128         ((IGateProvider_Handle)(x))->enter = (IGateProvider_ENTER)y##_enter;   \
00129         ((IGateProvider_Handle)(x))->leave = (IGateProvider_LEAVE)y##_leave;
00130 
00131 /* -----------------------------------------------------------------------------
00132  *  Defines
00133  * -----------------------------------------------------------------------------
00134  */
00135 /*! Prototype of enter function */
00136 typedef IArg (*IGateProvider_ENTER) (Void *);
00137 
00138 /*! Prototype of leave function */
00139 typedef Void (*IGateProvider_LEAVE) (Void *, IArg);
00140 
00141 
00142 /* -----------------------------------------------------------------------------
00143  *  Structs & Enums
00144  * -----------------------------------------------------------------------------
00145  */
00146 /*!
00147  * Structure for generic gate instance
00148  */
00149 typedef struct IGateProvider_Object {
00150         IGateProvider_SuperObject;
00151 } IGateProvider_Object, *IGateProvider_Handle;
00152 
00153 
00154 /* -----------------------------------------------------------------------------
00155  *  APIs
00156  * -----------------------------------------------------------------------------
00157  */
00158 /*!
00159  *  Enter this gate
00160  *
00161  *  Each gate provider can implement mutual exclusion using different
00162  *  algorithms; e.g., disabling all scheduling, disabling the scheduling
00163  *  of all threads below a specified "priority level", suspending the
00164  *  caller when the gate has been entered by another thread and
00165  *  re-enabling it when the the other thread leaves the gate.  However,
00166  *  in all cases, after this method returns that caller has exclusive
00167  *  access to the data protected by this gate.
00168  *
00169  *  A thread may reenter a gate without blocking or failing.
00170  *
00171  *  @param handle Handle to the Gate.
00172  *
00173  *  @retval IArg Returns the instance specific return values.
00174  *
00175  *  @sa IGateProvider_leave
00176  *
00177  */
00178 static inline IArg IGateProvider_enter (IGateProvider_Handle  handle)
00179 {
00180     IArg key = 0;
00181 
00182     GT_assert (curTrace, ((IGateProvider_Object *) handle != NULL));
00183     if (handle != IGateProvider_NULL) {
00184         key = (handle->enter) ((void *)handle);
00185     }
00186     return key;
00187 }
00188 
00189 
00190 /*!
00191  *  Leave this gate
00192  *
00193  *  This method is only called by threads that have previously entered
00194  *  this gate via `{@link #enter}`.  After this method returns, the
00195  *  caller must not access the data structure protected by this gate
00196  *  (unless the caller has entered the gate more than once and other
00197  *  calls to `leave` remain to balance the number of previous
00198  *  calls to `enter`).
00199  *
00200  *  @param handle Handle to the Gate.
00201  *  @param key    Instance specific argument.
00202  *
00203  *  @sa IGateProvider_enter
00204  *
00205  */
00206 static inline Void IGateProvider_leave (IGateProvider_Handle  handle, IArg key)
00207 {
00208     GT_assert (curTrace, ((IGateProvider_Object *) handle != NULL));
00209     if (handle != IGateProvider_NULL)
00210         (handle->leave) ((void *)handle, key);
00211 }
00212 
00213 
00214 #if defined (__cplusplus)
00215 }
00216 #endif /* defined (__cplusplus) */
00217 
00218 
00219 #endif /* ifndef __IGATEPROVIDER_H__ */
00220 

Generated on Mon Mar 14 11:59:45 2011 for Syslink by  doxygen 1.4.4