1 /*
2 * Copyright (c) 2012-2013, 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 */
32 /*
33 * ======== GatePeterson.xdc ========
34 *
35 */
37 package ti.sdo.ipc.gates;
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;
46 import ti.sdo.utils.MultiProc;
47 import ti.sdo.ipc.Ipc;
49 import ti.sdo.ipc.interfaces.IGateMPSupport;
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
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 }
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 });
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 };
132 /*!
133 * ======== numInstances ========
134 * Maximum number of instances supported by the GatePeterson module
135 */
136 config UInt numInstances = 512;
138 instance:
140 /*!
141 * @_nodoc
142 * ======== enter ========
143 * Enter this gate
144 */
145 @DirectCall
146 override IArg enter();
148 /*!
149 * @_nodoc
150 * ======== leave ========
151 * Leave this gate
152 */
153 @DirectCall
154 override Void leave(IArg key);
156 internal:
158 /* Used for the 'flag' in shared memory */
159 const UInt32 FREE = 0;
160 const UInt32 BUSY = 1;
162 /* Stored in shared memory */
163 struct Attrs {
164 Bits16 creatorProcId;
165 Bits16 openerProcId;
166 };
168 /* initializes shared memory */
169 Void postInit(Object *obj);
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; /* For nesting */
178 IGateProvider.Handle localGate;
179 Ipc.ObjType objType;
180 SizeT cacheLineSize;
181 Bool cacheEnabled;
182 };
183 }