1 /****************************************************************************
3 * Copyright 2008-2009 VMware, Inc.
5 * This program is free software: you can redistribute it and/or modify it
6 * under the terms of the GNU Lesser General Public License as published
7 * by the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 ****************************************************************************/
35 #define PATH_MAX _MAX_PATH
38 #define snprintf _snprintf
41 #define vsnprintf _vsnprintf
49 static gzFile g_gzFile = NULL;
50 static char g_szFileName[PATH_MAX];
51 static CRITICAL_SECTION CriticalSection;
53 static void _Close(void) {
54 if(g_gzFile != NULL) {
57 DeleteCriticalSection(&CriticalSection);
61 static void _Open(const char *szName, const char *szExtension) {
64 static unsigned dwCounter = 0;
70 snprintf(g_szFileName, PATH_MAX, "%s.%u.%s.gz", szName, dwCounter, szExtension);
72 snprintf(g_szFileName, PATH_MAX, "%s.%s.gz", szName, szExtension);
74 file = fopen(g_szFileName, "rb");
83 g_gzFile = gzopen(g_szFileName, "wb");
84 InitializeCriticalSection(&CriticalSection);
87 static inline void _ReOpen(void) {
91 static inline void Write(const char *sBuffer, size_t dwBytesToWrite) {
95 gzwrite(g_gzFile, sBuffer, dwBytesToWrite);
98 static inline void Write(const char *szText) {
99 Write(szText, strlen(szText));
103 Escape(const char *s) {
109 Indent(unsigned level) {
110 for(unsigned i = 0; i < level; ++i)
120 Tag(const char *name) {
127 BeginTag(const char *name) {
134 BeginTag(const char *name,
135 const char *attr1, const char *value1) {
146 BeginTag(const char *name,
147 const char *attr1, const char *value1,
148 const char *attr2, const char *value2) {
163 BeginTag(const char *name,
164 const char *attr1, const char *value1,
165 const char *attr2, const char *value2,
166 const char *attr3, const char *value3) {
185 EndTag(const char *name) {
191 void Open(const char *name) {
193 Write("<?xml version='1.0' encoding='UTF-8'?>");
195 Write("<?xml-stylesheet type='text/xsl' href='apitrace.xsl'?>");
211 void Text(const char *text) {
215 static void TextChar(char c) {
222 void TextF(const char *format, ...) {
225 va_start(ap, format);
226 vsnprintf(szBuffer, sizeof(szBuffer), format, ap);
231 static LARGE_INTEGER frequency = {0};
232 static LARGE_INTEGER startcounter;
234 void BeginCall(const char *function) {
235 EnterCriticalSection(&CriticalSection);
237 BeginTag("call", "name", function);
240 if(!frequency.QuadPart)
241 QueryPerformanceFrequency(&frequency);
243 QueryPerformanceCounter(&startcounter);
247 LARGE_INTEGER endcounter;
250 QueryPerformanceCounter(&endcounter);
251 usecs = (endcounter.QuadPart - startcounter.QuadPart)*1000000/frequency.QuadPart;
254 BeginTag("duration");
255 TextF("%llu", usecs);
262 gzflush(g_gzFile, Z_SYNC_FLUSH);
263 LeaveCriticalSection(&CriticalSection);
266 void BeginArg(const char *type, const char *name) {
268 BeginTag("arg", "type", type, "name", name);
276 void BeginReturn(const char *type) {
278 BeginTag("ret", "type", type);
281 void EndReturn(void) {
286 void BeginElement(const char *type, const char *name) {
287 BeginTag("elem", "type", type, "name", name);
290 void BeginElement(const char *type) {
291 BeginTag("elem", "type", type);
294 void EndElement(void) {
298 void BeginReference(const char *type, const void *addr) {
300 snprintf(saddr, sizeof(saddr), "%p", addr);
301 BeginTag("ref", "type", type, "addr", saddr);
304 void EndReference(void) {
308 void DumpString(const char *str) {
309 const unsigned char *p = (const unsigned char *)str;
312 while((c = *p++) != 0) {
317 else if(c >= 0x20 && c <= 0x7e)
326 unsigned char octal0 = c & 0x7;
327 unsigned char octal1 = (c >> 3) & 0x7;
328 unsigned char octal2 = (c >> 3) & 0x7;
330 TextF("\\%u%u%u", octal2, octal1, octal0);
332 TextF("\\%u%u", octal1, octal0);
334 TextF("\\%u", octal0);
340 void DumpWString(const wchar_t *str) {
341 const wchar_t *p = str;
344 while((c = *p++) != 0) {
349 else if(c >= 0x20 && c <= 0x7e)
358 unsigned octal0 = c & 0x7;
359 unsigned octal1 = (c >> 3) & 0x7;
360 unsigned octal2 = (c >> 3) & 0x7;
362 TextF("\\%u%u%u", octal2, octal1, octal0);
364 TextF("\\%u%u", octal1, octal0);
366 TextF("\\%u", octal0);
372 } /* namespace Log */