1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
50
51 package ti.sdo.ipc.gates;
52
53 import xdc.runtime.Error;
54 import xdc.runtime.Assert;
55 import xdc.runtime.IGateProvider;
56 import xdc.runtime.Diags;
57 import xdc.runtime.Log;
58 import xdc.rov.ViewInfo;
59
60 import ti.sdo.utils.MultiProc;
61 import ti.sdo.ipc.Ipc;
62
63 import ti.sdo.ipc.interfaces.IGateMPSupport;
64
65 /*!
66 * ======== GatePeterson ========
67 * IGateMPSupport gate based on the Peterson algorithm
68 *
69 * This module implements the {@link ti.sdo.ipc.interfaces.IGateMPSupport}
70 * interface using the Peterson Algorithm in shared memory. This
71 * implementation works for only 2 processors.
72 *
73 * Each GatePeterson instance requires a small piece of
74 * shared memory. The base address of this shared memory is specified as
75 * the 'sharedAddr' argument to the create. The amount of shared memory
76 * consumed by a single instance can be obtained using the
77 * {@link #sharedMemReq} call.
78 *
79 * Shared memory has to conform to the following specification. Padding is
80 * added between certain elements in shared memory if cache alignment is
81 * required for the region in which the instance is placed.
82 *
83 * @p(code)
84 *
85 * shmBaseAddr -> --------------------------- bytes
86 * | version | 4
87 * (Attrs struct) | creatorProcId | 2
88 * | openerProcId | 2
89 * | (PADDING if aligned) |
90 * |-------------------------|
91 * | flag[0] | 2
92 * | (PADDING if aligned) |
93 * |-------------------------|
94 * | flag[1] | 2
95 * | (PADDING if aligned) |
96 * |-------------------------|
97 * | turn | 2
98 * | (PADDING if aligned) |
99 * |-------------------------|
100 * @p
101 */
102 @InstanceInitError
103 @InstanceFinalize
104
105 module GatePeterson inherits IGateMPSupport
106 {
107 /*! @_nodoc */
108 metaonly struct BasicView {
109 String objType;
110 Ptr localGate;
111 UInt nested;
112 UInt creatorProcId;
113 UInt openerProcId;
114 String gateOwner;
115 }
116
117 /*! @_nodoc */
118 @Facet
119 metaonly config ViewInfo.Instance rovViewInfo =
120 ViewInfo.create({
121 viewMap: [
122 ['Basic',
123 {
124 type: ViewInfo.INSTANCE,
125 viewInitFxn: 'viewInitBasic',
126 structName: 'BasicView'
127 }
128 ],
129 ]
130 });
131
132 /*!
133 * ======== E_gateRemotelyOpened ========
134 * Error raised when gate cannot be opened because of the opener's ID
135 *
136 * Error raised in {@link #open} when trying to remotely open a
137 * GatePeterson instance whose configured opener processor Id does
138 * not match that of the opener's MultiProc id. but it has already been
139 * opened/created on two other processors. GatePeterson only works with
140 * two processors.
141 */
142 config Error.Id E_gateRemotelyOpened = {
143 msg: "E_gateRemotelyOpened: Gate already in use by two other processors: creator: %d, opener: %d"
144 };
145
146 /*!
147 * ======== numInstances ========
148 * Maximum number of instances supported by the GatePeterson module
149 */
150 config UInt numInstances = 512;
151
152 instance:
153
154 /*!
155 * @_nodoc
156 * ======== enter ========
157 * Enter this gate
158 */
159 @DirectCall
160 override IArg enter();
161
162 /*!
163 * @_nodoc
164 * ======== leave ========
165 * Leave this gate
166 */
167 @DirectCall
168 override Void leave(IArg key);
169
170 internal:
171
172
173 const UInt32 FREE = 0;
174 const UInt32 BUSY = 1;
175
176
177 struct Attrs {
178 Bits16 creatorProcId;
179 Bits16 openerProcId;
180 };
181
182
183 Void postInit(Object *obj);
184
185 struct Instance_State {
186 Attrs *attrs;
187 volatile Bits16 *flag[2];
188 volatile Bits16 *turn;
189 UInt16 selfId;
190 UInt16 otherId;
191 UInt nested;
192 IGateProvider.Handle localGate;
193 Ipc.ObjType objType;
194 SizeT cacheLineSize;
195 Bool cacheEnabled;
196 };
197 }