1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19 20 21 22
23
24 package ti.sdo.ipc.heaps;
25
26 import ti.sdo.ipc.SharedRegion;
27 import ti.sdo.ipc.Ipc;
28 import ti.sdo.ipc.GateMP;
29 import ti.sdo.utils.NameServer;
30
31 import xdc.rov.ViewInfo;
32
33 import xdc.runtime.Error;
34 import xdc.runtime.Assert;
35 import xdc.runtime.Memory;
36 import xdc.runtime.Startup;
37
38 /*!
39 * ======== HeapMultiBufMP ========
40 * Multi-processor fixed-size buffer heap implementation
41 *
42 * This module has a common header that can be found in the {@link ti.ipc}
43 * package. Application code should include the common header file (not the
44 * RTSC-generated one):
45 *
46 * <PRE>#include <ti/ipc/HeapMultiBufMP.h></PRE>
47 *
48 * The RTSC module must be used in the application's RTSC configuration file
49 * (.cfg) if runtime APIs will be used in the application:
50 *
51 * <PRE>HeapMultiBufMP = xdc.useModule('ti.sdo.ipc.heaps.HeapMultiBufMP');
52 * </PRE>
53 *
54 * Documentation for all runtime APIs, instance configuration parameters,
55 * error codes macros and type definitions available to the application
56 * integrator can be found in the
57 * <A HREF="../../../../doxygen/html/files.html">Doxygen documenation</A>
58 * for the IPC product. However, the documentation presented on this page
59 * should be referred to for information specific to the RTSC module, such as
60 * module configuration, Errors, and Asserts.
61 * @p
62 *
63 * It is important to note that max allocation tracking is disabled by default
64 * in {@link #trackMaxAllocs}. Disabling allocation tracking improves alloc/
65 * free performance especially when cache calls are required in shared memory.
66 */
67 @InstanceInitError
68 @InstanceFinalize
69
70 module HeapMultiBufMP inherits xdc.runtime.IHeap
71 {
72 /*! @_nodoc */
73 metaonly struct BasicView {
74 String name;
75 Ptr buf;
76 Memory.Size totalSize;
77 String objType;
78 Ptr gate;
79 Bool exact;
80 }
81
82 /*! @_nodoc */
83 metaonly struct BucketsView {
84 Ptr baseAddr;
85 UInt blockSize;
86 UInt align;
87 UInt numBlocks;
88 UInt numFreeBlocks;
89 UInt minFreeBlocks;
90 }
91
92 /*! @_nodoc */
93 @Facet
94 metaonly config ViewInfo.Instance rovViewInfo =
95 ViewInfo.create({
96 viewMap: [
97 [
98 'Basic',
99 {
100 type: ViewInfo.INSTANCE,
101 viewInitFxn: 'viewInitBasic',
102 structName: 'BasicView'
103 }
104 ],
105 [
106 'Buffer Information',
107 {
108 type: ViewInfo.INSTANCE_DATA,
109 viewInitFxn: 'viewInitData',
110 structName: 'BucketsView'
111 }
112 ],
113 ]
114 });
115
116 /*!
117 * Structure for bucket configuration
118 *
119 * An array of buckets is a required parameter to create any
120 * HeapMultiBufMP instance. The fields of each bucket correspond
121 * to the attributes of each buffer in the HeapMultiBufMP. The actual
122 * block sizes and alignments may be adjusted per the process described
123 * at {@link #bucketEntries}.
124 *
125 * @field(blockSize) Size of each block (in MADUs)
126 * @field(numBlocks) Number of blocks
127 * @field(align) Alignment of each block (in MADUs)
128 */
129 struct Bucket {
130 SizeT blockSize;
131 UInt numBlocks;
132 SizeT align;
133 }
134
135 /*!
136 * ======== ExtendedStats ========
137 * Stats structure for the getExtendedStats API.
138 *
139 * @field(numBuckets) Number of buckets
140 * @field(numBlocks) Number of blocks in each buffer
141 * @field(blockSize) Block size of each buffer
142 * @field(align) Alignment of each buffer
143 * @field(maxAllocatedBlocks) The maximum number of blocks allocated from
144 * this heap at any single point in time during
145 * the lifetime of this HeapMultiBufMP instance
146 *
147 * @field(numAllocatedBlocks) The total number of blocks currently
148 * allocated in this HeapMultiBufMP instance
149 */
150 struct ExtendedStats {
151 UInt numBuckets;
152 UInt numBlocks [8];
153 UInt blockSize [8];
154 UInt align [8];
155 UInt maxAllocatedBlocks [8];
156 UInt numAllocatedBlocks [8];
157 }
158
159 /*!
160 * Assert raised when the align parameter is not a power of 2.
161 */
162 config Assert.Id A_invalidAlign =
163 {msg: "align parameter must be a power of 2"};
164
165 /*!
166 * Assert raised when an invalid buffer size was passed to free()
167 */
168 config Assert.Id A_sizeNotFound =
169 {msg: "an invalid buffer size was passed to free"};
170
171 /*!
172 * Assert raised when an invalid block address was passed to free()
173 */
174 config Assert.Id A_addrNotFound =
175 {msg: "an invalid buffer address was passed to free"};
176
177 /*!
178 * Error raised when exact matching failed
179 */
180 config Error.Id E_exactFail =
181 {msg: "E_exactFail: Exact allocation failed (requested size = 0x%x and buffer size = 0x%x)"};
182
183 /*!
184 * Maximum runtime entries
185 *
186 * Maximum number of HeapMultiBufMP's that can be dynamically created and
187 * added to the NameServer.
188 *
189 * To minimize the amount of runtime allocation, this parameter allows
190 * the pre-allocation of memory for the HeapMultiBufMP's NameServer table.
191 * The default is to allow growth (i.e. memory allocation when
192 * creating a new instance).
193 */
194 metaonly config UInt maxRuntimeEntries = NameServer.ALLOWGROWTH;
195
196 /*!
197 * Maximum length for heap names
198 */
199 config UInt maxNameLen = 32;
200
201 /*!
202 * Section name is used to place the names table
203 *
204 * The default value of NULL implies that no explicit placement is
205 * performed.
206 */
207 metaonly config String tableSection = null;
208
209 /*!
210 * Track the maximum number of allocated blocks
211 *
212 * This will enable/disable the tracking of the maximum number of
213 * allocations for a HeapMultiBufMP instance. This maximum refers to the
214 * "all time" maximum number of allocations for the history of a
215 * HeapMultiBufMP instance, not the current number of allocations.
216 *
217 * Tracking the maximum might adversely affect performance when allocating
218 * and/or freeing. If this feature is not needed, setting this to false
219 * avoids the performance penalty.
220 */
221 config Bool trackMaxAllocs = false;
222
223 instance:
224
225 /*!
226 * GateMP used for critical region management of the shared memory
227 *
228 * Using the default value of NULL will result in use of the GateMP
229 * system gate for context protection.
230 */
231 config GateMP.Handle gate = null;
232
233 /*! @_nodoc
234 * by the open() call. No one else should touch this!
235 */
236 config Bool openFlag = false;
237
238 /*!
239 * Use exact matching
240 *
241 * Setting this flag will allow allocation only if the requested size
242 * is equal to (rather than less than or equal to) a buffer's block size.
243 */
244 config Bool exact = false;
245
246 /*!
247 * Name of this instance.
248 *
249 * The name (if not NULL) must be unique among all HeapMultiBufMP
250 * instances in the entire system. When creating a new
251 * heap, it is necessary to supply an instance name.
252 */
253 config String name = null;
254
255 /*!
256 * Number of buckets in {@link #bucketEntries}
257 *
258 * This parameter is required to create any instance.
259 */
260 config Int numBuckets = 0;
261
262 /*!
263 * Bucket Entries
264 *
265 * The bucket entries are an array of {@link #Bucket}s whose values
266 * correspond to the desired alignment, block size and length for each
267 * buffer. It is important to note that the alignments and sizes for each
268 * buffer may be adjusted due to cache and alignment related constraints.
269 * Buffer sizes are rounded up by their corresponding alignments. Buffer
270 * alignments themselves will assume the value of region cache alignment
271 * size when the cache size is greater than the requested buffer alignment.
272 *
273 * For example, specifying a bucket with {blockSize: 192, align: 256} will
274 * result in a buffer of blockSize = 256 and alignment = 256. If cache
275 * alignment is required, then a bucket of {blockSize: 96, align: 64} will
276 * result in a buffer of blockSize = 128 and alignment = 128 (assuming
277 * cacheSize = 128).
278 */
279 config Bucket bucketEntries[];
280
281 /*!
282 * Shared region ID
283 *
284 * The index corresponding to the shared region from which shared memory
285 * will be allocated.
286 */
287 config UInt16 regionId = 0;
288
289 /*! @_nodoc
290 * Physical address of the shared memory
291 *
292 * This value can be left as 'null' unless it is required to place the
293 * heap at a specific location in shared memory. If sharedAddr is null,
294 * then shared memory for a new instance will be allocated from the
295 * heap belonging to the region identified by {@link #regionId}.
296 */
297 config Ptr sharedAddr = null;
298
299 internal:
300
301 /*! Used in the attrs->status field */
302 const UInt32 CREATED = 0x05101920;
303
304 /*!
305 * This Params object is used for temporary storage of the
306 * module wide parameters that are for setting the NameServer instance.
307 */
308 metaonly config NameServer.Params nameSrvPrms;
309
310 /*! slice and dice the buffer */
311 Void postInit(Object *obj, Error.Block *eb);
312
313 /*!
314 * Takes in modifiable array of bucket entries, performs an in-place sort
315 * of the bucket entries, combines the entries as necessary, and returns
316 * the new number of buckets in the combined entries
317 */
318 UInt processBuckets(Bucket *bucketEntries, Params *params,
319 UInt16 regionId);
320
321 /*! Comparison function for Buckets used in processBuckets */
322 Int sizeAlignCompare(const Void *a, const Void *b);
323
324 /*!
325 * Add the block to the tail; index specifies the buffer number
326 *
327 * Precondition: inv obj->attrs->bucket[index]
328 * Postcondition: wb obj->attrs->bucket[index] and wb the block
329 */
330 Void putTail(Object *obj, Int index, Elem *block);
331
332 /*!
333 * Removes a block from the head and returns it; index specifies
334 * the buffer number. The block is invalidated before returned
335 *
336 * Precondition: inv obj->attrs->bucket[index]
337 * Postcondition: wb obj->attrs->bucket[index]
338 */
339 Elem *getHead(Object *obj, Int index);
340
341 /*! Needed for freelist */
342 @Opaque struct Elem {
343
344 volatile SharedRegion.SRPtr next;
345 };
346
347 /*! Shared memory state for a single buffer. */
348 struct BucketAttrs {
349 SharedRegion.SRPtr head;
350 SharedRegion.SRPtr tail;
351 SharedRegion.SRPtr baseAddr;
352 Bits32 numFreeBlocks;
353 Bits32 minFreeBlocks;
354 Bits32 blockSize;
355 Bits32 align;
356 Bits32 numBlocks;
357 }
358
359 /*! Shared memory state for a HeapMultiBufMP instance */
360 struct Attrs {
361 Bits32 status;
362 SharedRegion.SRPtr gateMPAddr;
363 Bits32 numBuckets;
364 BucketAttrs buckets[8];
365 Bits16 exact;
366 }
367
368 struct Instance_State {
369 Attrs *attrs;
370 GateMP.Handle gate;
371 Ipc.ObjType objType;
372 Ptr nsKey;
373 Bool cacheEnabled;
374 UInt16 regionId;
375 SizeT allocSize;
376 Char *buf;
377 Bucket bucketEntries[];
378
379 UInt numBuckets;
380 Bool exact;
381 };
382
383 struct Module_State {
384 NameServer.Handle nameServer;
385 };
386 }