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
1.4.4