• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * tracebuf.c
3  *
4  * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  *  * Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  *  * Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  *  * Neither the name Texas Instruments nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 /*
35  * Benchmark tracing utility
36  */
37 
38 #include "osApi.h"
39 #include "tracebuf.h"
40 #include "tracebuf_api.h"
41 #include "report.h"
42 
43 typedef struct {
44       unsigned long loc;/* trace entry identification */
45       unsigned long ts;/* Timestamp */
46       unsigned long p1; /* Parameter 1 */
47       unsigned long p2; /* Parameter 2 */
48       char msg[MAX_TB_MSG];
49 } tb_entry_t;
50 
51 typedef struct {
52       int pos;
53       int count;
54       int print_pos;
55       int nusers;
56       unsigned long self_delay;
57       unsigned long options;
58       tb_entry_t entry[1]; /* Array of entries */
59 } tb_control_t;
60 
61 static tb_control_t *tb_control;
62 
tb_control_size(void)63 static  int tb_control_size(void)
64 {
65    return TI_FIELD_OFFSET(tb_control_t, entry) + sizeof(tb_entry_t)*TB_NUM_ENTRIES;
66 }
67 
68 
69 /* Initialization */
tb_init(unsigned long options)70 int tb_init(unsigned long options)
71 {
72    if (tb_control)
73    {
74       ++tb_control->nusers;
75       return 0;
76    }
77    tb_control = (tb_control_t *)TB_MALLOC(tb_control_size());
78    if (!tb_control)
79       return -1;
80    memset(tb_control, 0, tb_control_size());
81    tb_control->nusers = 1;
82 
83    /* Measure self-delay */
84    tb_trace(0, 0, 0);
85    tb_trace(0, 0, 0);
86    tb_control->self_delay = tb_control->entry[1].ts - tb_control->entry[0].ts;
87    tb_control->pos = tb_control->count = 0;
88    tb_control->options = options;
89    return 0;
90 }
91 
92 /* De-initialization */
tb_destroy(void)93 void tb_destroy(void)
94 {
95    if (--tb_control->nusers)
96       return;
97    TB_FREE(tb_control );
98 }
99 
tb_next(void)100 static int tb_next(void)
101 {
102     int pos;
103     if (!tb_control || tb_control->print_pos)
104        return -1;
105     pos = tb_control->pos;
106     tb_control->pos = (pos+1) % TB_NUM_ENTRIES;
107     ++tb_control->count;
108 
109     tb_control->entry[tb_control->pos].ts =
110     tb_control->entry[tb_control->pos].loc=
111     tb_control->entry[tb_control->pos].p1 =
112     tb_control->entry[tb_control->pos].p2 = 0xffffffff;
113 
114     return pos;
115 }
tb_autoprint(void)116 static void tb_autoprint(void)
117 {
118     if ((tb_control->pos == 0) && (tb_control->count))
119     {
120         if (tb_control->options & TB_OPTION_PRINTONCE)
121         {
122             tb_printf();
123             tb_reset_option(TB_OPTION_PRINTONCE);
124         }
125         else if (tb_control->options & TB_OPTION_AUTOPRINT)
126         {
127             tb_printf();
128         }
129     }
130 }
131 
132 /* Add trace entry. not safe, but will do */
tb_trace(int loc,unsigned long p1,unsigned long p2)133 int tb_trace(int loc, unsigned long p1, unsigned long p2)
134 {
135    int pos;
136 
137    if ((tb_control->options & TB_OPTION_STOP) || ((pos = tb_next()) < 0))
138    {
139        return -1;
140    }
141    tb_control->entry[pos].ts = os_timeStampUs(NULL);
142    tb_control->entry[pos].loc= loc;
143    tb_control->entry[pos].p1 = p1;
144    tb_control->entry[pos].p2 = p2;
145 
146    return pos;
147 }
tb_dump(void)148 void tb_dump(void)
149 {
150 	int j, pos;
151 
152 	WLAN_OS_REPORT(("Trace Dump:\n"));
153 	WLAN_OS_REPORT(("===========\n\n"));
154     if (tb_control->count < TB_NUM_ENTRIES)
155     {
156         pos = 0;
157     }
158     else
159     {
160         pos = (tb_control->pos + 1) % TB_NUM_ENTRIES;
161     }
162 	for (j=0; (unsigned int)j < tb_min((unsigned int)TB_NUM_ENTRIES,(unsigned int)tb_control->count); j++)
163 	{
164 		WLAN_OS_REPORT(("%4i %08x %08x %08x %08x\n", j,
165 			(int)tb_control->entry[pos].ts,
166 			(int)tb_control->entry[pos].loc,
167 			(int)tb_control->entry[pos].p1,
168 			(int)tb_control->entry[pos].p2));
169 		pos = (pos+1) % TB_NUM_ENTRIES;
170 	}
171 
172 }
173 
tb_sprintf(const char * format,...)174 int tb_sprintf(const char *format ,...)
175 {
176 
177 	va_list ap;
178     int pos;
179 
180     if ((tb_control->options & TB_OPTION_STOP) || ((pos = tb_next()) < 0))
181     {
182         return -1;
183     }
184     tb_control->entry[pos].loc = TB_ID;
185 	va_start(ap,format);
186 	vsprintf(&tb_control->entry[pos].msg[0], format, ap);
187     tb_autoprint();
188     return pos;
189 }
190 
tb_printf(void)191 void tb_printf(void)
192 {
193 	int j, pos;
194     unsigned long saved_options=tb_control->options;
195 
196     tb_set_option(TB_OPTION_STOP);
197 	WLAN_OS_REPORT(("Trace Dump:\n"));
198 	WLAN_OS_REPORT(("===========\n\n"));
199     if (tb_control->count < TB_NUM_ENTRIES)
200     {
201         pos = 0;
202     }
203     else
204     {
205         pos = (tb_control->pos + 1) % TB_NUM_ENTRIES;
206     }
207 	for (j=0; (unsigned int)j < tb_min((unsigned int)TB_NUM_ENTRIES,(unsigned int)tb_control->count); j++)
208 	{
209 		WLAN_OS_REPORT(("%4i id=0x%8x %s \n", j,
210 tb_control->entry[pos].loc, tb_control->entry[pos].msg));
211 		pos = (pos+1) % TB_NUM_ENTRIES;
212 	}
213     tb_control->options = saved_options;
214 }
tb_set_option(unsigned long option)215 void tb_set_option(unsigned long option)
216 {
217     tb_control->options |= option;
218 }
219 
tb_reset_option(unsigned long option)220 void tb_reset_option(unsigned long option)
221 {
222     tb_control->options &= ~option;
223 }
224 
tb_scan(void)225 void tb_scan(void)
226 {
227 
228   int j,k, Size, nAllocs=0, nFrees=0;
229   unsigned long address, Allocs=0, Frees=0;
230 
231   for (j=0; j < TB_NUM_ENTRIES; j++)
232   {
233     Size = (int)tb_control->entry[j].p2;
234     if (Size > 0) /* Alloc */
235     {
236       nAllocs += 1;
237       Allocs  += Size;
238       address = tb_control->entry[j].p1;
239       for (k=j+1; k < TB_NUM_ENTRIES; k++)
240       {
241 	if (address == tb_control->entry[k].p1)
242 	{
243 	  if (tb_control->entry[k].p2 != -Size)
244 	  {
245 	    TB_PRINTF("Bad free size at 0x%lx address = 0x%lx Size = %ld Allocated = %d\n",
246 		   tb_control->entry[k].loc, tb_control->entry[k].p1, (long)tb_control->entry[k].p2, Size);
247 	  }
248 	  Frees  += tb_control->entry[k].p2;
249 	  nFrees += 1;
250 	  break;
251 	}
252       }
253       if (k == TB_NUM_ENTRIES)
254       {
255 	TB_PRINTF("Memory leak at 0x%lx address = 0x%lx Size = %d\n",
256 	       tb_control->entry[j].loc, address, Size);
257       }
258     }
259   }
260   TB_PRINTF("tb_scan() Allocs = %ld nAllocs = %d Frees = %ld nFrees = %d\n", Allocs, nAllocs, Frees, nFrees);
261 }
262 
263