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