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