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