1 /**
2 * @file IGateProvider.h
3 *
4 * @brief Interface implemented by all gate providers.
5 *
6 * Gates are used serialize access to data structures that are used by more
7 * than one thread.
8 *
9 * Gates are responsible for ensuring that only one out of multiple threads
10 * can access a data structure at a time. There
11 * are important scheduling latency and performance considerations that
12 * affect the "type" of gate used to protect each data structure. For
13 * example, the best way to protect a shared counter is to simply disable
14 * all interrupts before the update and restore the interrupt state after
15 * the update; disabling all interrupts prevents all thread switching, so
16 * the update is guaranteed to be "atomic". Although highly efficient, this
17 * method of creating atomic sections causes serious system latencies when
18 * the time required to update the data structure can't be bounded.
19 *
20 * For example, a memory manager's list of free blocks can grow indefinitely
21 * long during periods of high fragmentation. Searching such a list with
22 * interrupts disabled would cause system latencies to also become unbounded.
23 * In this case, the best solution is to provide a gate that suspends the
24 * execution of threads that try to enter a gate that has already been
25 * entered; i.e., the gate "blocks" the thread until the thread
26 * already in the gate leaves. The time required to enter and leave the
27 * gate is greater than simply enabling and restoring interrupts, but since
28 * the time spent within the gate is relatively large, the overhead caused by
29 * entering and leaving gates will not become a significant percentage of
30 * overall system time. More importantly, threads that do not need to
31 * access the shared data structure are completely unaffected by threads
32 * that do access it.
33 *
34 *
35 *
36 * @ver 02.00.00.46_alpha1
37 *
38 * ============================================================================
39 *
40 * Copyright (c) 2008-2009, Texas Instruments Incorporated
41 *
42 * Redistribution and use in source and binary forms, with or without
43 * modification, are permitted provided that the following conditions
44 * are met:
45 *
46 * * Redistributions of source code must retain the above copyright
47 * notice, this list of conditions and the following disclaimer.
48 *
49 * * Redistributions in binary form must reproduce the above copyright
50 * notice, this list of conditions and the following disclaimer in the
51 * documentation and/or other materials provided with the distribution.
52 *
53 * * Neither the name of Texas Instruments Incorporated nor the names of
54 * its contributors may be used to endorse or promote products derived
55 * from this software without specific prior written permission.
56 *
57 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
58 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
59 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
60 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
61 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
62 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
63 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
64 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
65 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
66 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
67 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
68 * Contact information for paper mail:
69 * Texas Instruments
70 * Post Office Box 655303
71 * Dallas, Texas 75265
72 * Contact information:
73 * http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
74 * DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
75 * ============================================================================
76 *
77 */
80 #ifndef __IGATEPROVIDER_H__
81 #define __IGATEPROVIDER_H__
84 #if defined (__cplusplus)
85 extern "C" {
86 #endif
89 /* -----------------------------------------------------------------------------
90 * Macros
91 * -----------------------------------------------------------------------------
92 */
93 /*! Invalid Igate */
94 #define IGateProvider_NULL (IGateProvider_Handle)0xFFFFFFFF
96 /*!
97 * ======== IGateProvider_Q_BLOCKING ========
98 * Blocking quality
99 *
100 * Gates with this "quality" may cause the calling thread to block;
101 * i.e., suspend execution until another thread leaves the gate.
102 */
103 #define IGateProvider_Q_BLOCKING 1
105 /*!
106 * ======== IGateProvider_Q_PREEMPTING ========
107 * Preempting quality
108 *
109 * Gates with this "quality" allow other threads to preempt the thread
110 * that has already entered the gate.
111 */
112 #define IGateProvider_Q_PREEMPTING 2
114 /*!
115 * ======== IGateProvider_SuperObject ========
116 * Object embedded in other Gate modules. (Inheritance)
117 */
118 #define IGateProvider_SuperObject \
119 IGateProvider_ENTER enter; \
120 IGateProvider_LEAVE leave
123 /*!
124 *
125 */
126 #define IGateProvider_ObjectInitializer(x,y) \
127 ((IGateProvider_Handle)(x))->enter = (IGateProvider_ENTER)y##_enter; \
128 ((IGateProvider_Handle)(x))->leave = (IGateProvider_LEAVE)y##_leave;
130 /* -----------------------------------------------------------------------------
131 * Defines
132 * -----------------------------------------------------------------------------
133 */
134 /*! Prototype of enter function */
135 typedef IArg (*IGateProvider_ENTER) (Void *);
137 /*! Prototype of leave function */
138 typedef Void (*IGateProvider_LEAVE) (Void *, IArg);
141 /* -----------------------------------------------------------------------------
142 * Structs & Enums
143 * -----------------------------------------------------------------------------
144 */
145 /*!
146 * Structure for generic gate instance
147 */
148 typedef struct IGateProvider_Object {
149 IGateProvider_SuperObject;
150 } IGateProvider_Object, *IGateProvider_Handle;
153 /* -----------------------------------------------------------------------------
154 * APIs
155 * -----------------------------------------------------------------------------
156 */
157 /*!
158 * Enter this gate
159 *
160 * Each gate provider can implement mutual exclusion using different
161 * algorithms; e.g., disabling all scheduling, disabling the scheduling
162 * of all threads below a specified "priority level", suspending the
163 * caller when the gate has been entered by another thread and
164 * re-enabling it when the the other thread leaves the gate. However,
165 * in all cases, after this method returns that caller has exclusive
166 * access to the data protected by this gate.
167 *
168 * A thread may reenter a gate without blocking or failing.
169 *
170 * @param handle Handle to the Gate.
171 *
172 * @retval IArg Returns the instance specific return values.
173 *
174 * @sa IGateProvider_leave
175 *
176 */
177 static inline IArg IGateProvider_enter (IGateProvider_Handle handle)
178 {
179 IArg key = 0;
181 if (handle != 0x0 && handle != IGateProvider_NULL) {
182 key = (handle->enter) ((void *)handle);
183 }
184 return key;
185 }
188 /*!
189 * Leave this gate
190 *
191 * This method is only called by threads that have previously entered
192 * this gate via `{@link #enter}`. After this method returns, the
193 * caller must not access the data structure protected by this gate
194 * (unless the caller has entered the gate more than once and other
195 * calls to `leave` remain to balance the number of previous
196 * calls to `enter`).
197 *
198 * @param handle Handle to the Gate.
199 * @param key Instance specific argument.
200 *
201 * @sa IGateProvider_enter
202 *
203 */
204 static inline Void IGateProvider_leave (IGateProvider_Handle handle, IArg key)
205 {
206 if (handle != 0x0 && handle != IGateProvider_NULL)
207 (handle->leave) ((void *)handle, key);
208 }
211 #if defined (__cplusplus)
212 }
213 #endif /* defined (__cplusplus) */
216 #endif /* ifndef __IGATEPROVIDER_H__ */