1 /*
2 * Copyright (c) 2015, 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 * ======== HeapTrack.xdc ========
34 *
35 */
36 package ti.sysbios.heaps;
37
38 import xdc.runtime.Memory;
39 import xdc.runtime.IHeap;
40 import ti.sysbios.knl.Task;
41 import ti.sysbios.knl.Queue;
42 import xdc.rov.ViewInfo;
43
44 /*!
45 * ======== HeapTrack ========
46 * Heap manager that enables tracking of all allocated blocks.
47 *
48 * HeapTrack manager provides functions to allocate and free storage from a
49 * configured heap which inherits from IHeap. The calling context is going to
50 * match the heap being used.
51 *
52 * HeapTrack is useful for detecting memory leaks, double frees and buffer
53 * overflows. There is a performance overhead cost when using heap track as
54 * well as a size impact. Every alloc will include a {@link #Tracker}
55 * structure (plus memory to get proper alignment of the stucture) at
56 * the end of the buffer that should not be modified by the user. It is
57 * important to remember this when deciding on heap sizes and you may have to
58 * adjust the total size or buffer sizes (for HeapBuf/HeapMultiBuf).
59 *
60 * ROV displays peaks and current in-use for both allocated memory (requested
61 * size + Tracker structure) and requested memory (without Tracker).
62 *
63 * The information stored in the tracker packet is used to display information
64 * in RTOS Object Viewer (ROV) as well as with the printTask and printHeap
65 * functions.
66 *
67 * The asserts used in this module are listed below and include error checking
68 * for double frees, calling printHeap with a null handle, buffer overflows
69 * and deleting a non empty heap.
70 */
71
72 @InstanceFinalize /* Destroys the trackQueue Q */
73
74 module HeapTrack inherits xdc.runtime.IHeap {
75
76 /*!
77 * ======== BasicView ========
78 * @_nodoc 79 */
80 metaonlystruct BasicView {
81 IHeap.Handle heapHandle;
82 String inUse;
83 String inUsePeak;
84 String inUseWithoutTracker;
85 String inUsePeakWithoutTracker;
86 }
87
88 /*!
89 * ======== TaskView ========
90 * @_nodoc 91 */
92 metaonlystruct TaskView {
93 String block;
94 String heapHandle;
95 String blockAddr;
96 String requestedSize;
97 String clockTick;
98 String overflow;
99 }
100
101 /*!
102 * ======== HeapListView ========
103 * @_nodoc 104 */
105 metaonlystruct HeapListView {
106 String block;
107 String taskHandle;
108 String heapHandle;
109 String blockAddr;
110 String requestedSize;
111 String clockTick;
112 String overflow;
113 }
114
115 /*! @_nodoc */
116 @Facet
117 metaonlyconfig ViewInfo.Instance rovViewInfo =
118 ViewInfo.create({
119 viewMap: [
120 ['Basic', {type: ViewInfo.INSTANCE, viewInitFxn:
121 'viewInitBasic', structName: 'BasicView'}],
122 ['HeapAllocList', {type: ViewInfo.INSTANCE_DATA, viewInitFxn:
123 'viewInitHeapList', structName: 'HeapListView'}],
124 ['TaskAllocList', {type: ViewInfo.TREE_TABLE, viewInitFxn:
125 'viewInitTask', structName: 'TaskView'}],
126 ]
127 });
128
129 /*!
130 * ======== Tracker ========
131 * Structure added to the end of each allocated block
132 *
133 * When a block is allocated from a HeapTrack heap with a size,
134 * internally HeapTrack calls Memory_alloc on the configured
135 * {@link #heap}. The value of sizeof(HeapTrack_Tracker)
136 * is added to the requested size.
137 *
138 * For example, if the caller makes the following call (where heapHandle
139 * is an HeapTrack handle that has been converted to an IHeap_Handle).
140 * @p(code) 141 * buf = Memory_alloc(heapHandle, MYSIZE, MYALIGN, &eb);
142 * @p 143 *
144 * Internally, HeapTrack will make the following call
145 * (where size is MYSIZE, align is MYALIGN and obj is the HeapTrack handle).
146 * @p(code) 147 * block = Memory_alloc(obj->heap, size + sizeof(HeapTrack_Tracker), align, &eb);
148 * @p 149 *
150 * When using HeapTrack, depending on the actual heap
151 * (i.e. {@link #heap}), you might need to make adjustments to the heap
152 * (e.g. increase the blockSize if using a HeapBuf instance).
153 *
154 * The HeapTrack module manages the contents of this structure and should
155 * not be directly accessing them.
156 */
157 struct Tracker {
158 UInt32 scribble;
159 Queue.Elem queElem;
160 SizeT size;
161 UInt32 tick;
162 Task.Handle taskHandle;
163 }
164
165 /*!
166 * ======== STARTSCRIBBLE ========
167 * @_nodoc 168 * Constant used to help detect over-writing of a buffer
169 */
170 const UInt32 STARTSCRIBBLE = 0xa5a5a5a5;
171
172 /*!
173 * ======== printTask ========
174 * Print out the blocks that are currently allocated by a task
175 *
176 * Iterates through all instances of HeapTrack and prints out information
177 * about all allocated blocks of memory for a given task handle. This
178 * function is not thread safe.
179 *
180 * @params(taskHandle) Task to print stats for
181 */
182 Void printTask(Task.Handle taskHandle);
183
184 /*!
185 * ======== A_doubleFree ========
186 * Assert raised when freeing a buffer that was already freed
187 */
188 config xdc.runtime.Assert.Id A_doubleFree =
189 {msg: "A_doubleFree: Buffer already free"};
190
191 /*!
192 * ======== A_bufOverflow ========
193 * Assert raised when freeing memory with corrupted data or using the
194 * wrong size
195 */
196 config xdc.runtime.Assert.Id A_bufOverflow =
197 {msg: "A_bufOverflow: Buffer overflow"};
198
199 /*!
200 * ======== A_notEmpty ========
201 * Assert raised when deleting a non-empty heap
202 */
203 config xdc.runtime.Assert.Id A_notEmpty =
204 {msg: "A_notEmpty: Heap not empty"};
205
206
207 /*!
208 * ======== A_nullObject ========
209 * Assert raised when calling printTask with a null HeapTrack object
210 */
211 config xdc.runtime.Assert.Id A_nullObject =
212 {msg: "A_nullObject: HeapTrack_printHeap called with null obj"};
213
214 instance:
215
216 /*!
217 * ======== internalHeap ========
218 * Heap to use with HeapTrack
219 */
220 config IHeap.Handle heap = null;
221
222 /*!
223 * ======== printHeap ========
224 * Print details for a HeapTrack instance
225 *
226 * Print the details of all allocated blocks of memory for a HeapTrack
227 * instance. This function is not thread safe.
228 */
229 Void printHeap();
230
231 internal:
232
233 /*
234 * ======== NOSCRIBBLE ========
235 * Using a non-zero constant in the free to aid in the development
236 * of this module.
237 */
238 const UInt32 NOSCRIBBLE = 0x05101920;
239
240 /*
241 * ======== printTrack ========
242 */
243 Void printTrack(Tracker *tracker, Handle handle);
244
245 /* instance object */
246 struct Instance_State {
247 IHeap.Handle internalHeap;
248 ti.sysbios.knl.Queue.Object trackQueue;
249 SizeT size;
250 SizeT peak;
251 SizeT sizeWithoutTracker;
252 SizeT peakWithoutTracker;
253 };
254 }