]> git.cworth.org Git - apitrace/blob - os_win32.cpp
Merge branch 'compression'
[apitrace] / os_win32.cpp
1 /**************************************************************************
2  *
3  * Copyright 2010 VMware, Inc.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  *
24  **************************************************************************/
25
26 #include <windows.h>
27 #include <assert.h>
28 #include <signal.h>
29 #include <string.h>
30 #include <stdio.h>
31
32 #include "os.hpp"
33
34
35 namespace OS {
36
37
38 /* 
39  * Trick from http://locklessinc.com/articles/pthreads_on_windows/
40  */
41 static CRITICAL_SECTION
42 CriticalSection = {
43     (PCRITICAL_SECTION_DEBUG)-1, -1, 0, 0, 0, 0
44 };
45
46
47 void
48 AcquireMutex(void)
49 {
50     EnterCriticalSection(&CriticalSection); 
51 }
52
53
54 void
55 ReleaseMutex(void)
56 {
57     LeaveCriticalSection(&CriticalSection); 
58 }
59
60
61 bool
62 GetProcessName(char *str, size_t size)
63 {
64     char szProcessPath[PATH_MAX];
65     char *lpProcessName;
66     char *lpProcessExt;
67
68     GetModuleFileNameA(NULL, szProcessPath, sizeof(szProcessPath)/sizeof(szProcessPath[0]));
69
70     lpProcessName = strrchr(szProcessPath, '\\');
71     lpProcessName = lpProcessName ? lpProcessName + 1 : szProcessPath;
72
73     lpProcessExt = strrchr(lpProcessName, '.');
74     if (lpProcessExt) {
75         *lpProcessExt = '\0';
76     }
77
78     strncpy(str, lpProcessName, size);
79
80     return true;
81 }
82
83 bool
84 GetCurrentDir(char *str, size_t size)
85 {
86     DWORD ret;
87     ret = GetCurrentDirectoryA(size, str);
88     str[size - 1] = 0;
89     return ret == 0 ? false : true;
90 }
91
92 void
93 DebugMessage(const char *format, ...)
94 {
95     char buf[4096];
96
97     va_list ap;
98     va_start(ap, format);
99     fflush(stdout);
100     vsnprintf(buf, sizeof buf, format, ap);
101     va_end(ap);
102
103     OutputDebugStringA(buf);
104
105     /*
106      * Also write the message to stderr, when a debugger is not present (to
107      * avoid duplicate messages in command line debuggers).
108      */
109 #if _WIN32_WINNT > 0x0400
110     if (!IsDebuggerPresent()) {
111         fflush(stdout);
112         fputs(buf, stderr);
113         fflush(stderr);
114     }
115 #endif
116 }
117
118 long long GetTime(void)
119 {
120     static LARGE_INTEGER frequency;
121     LARGE_INTEGER counter;
122     if (!frequency.QuadPart)
123         QueryPerformanceFrequency(&frequency);
124     QueryPerformanceCounter(&counter);
125     return counter.QuadPart*1000000LL/frequency.QuadPart;
126 }
127
128 void
129 Abort(void)
130 {
131 #ifndef NDEBUG
132     DebugBreak();
133 #else
134     ExitProcess(0);
135 #endif
136 }
137
138
139 static LPTOP_LEVEL_EXCEPTION_FILTER prevExceptionFilter = NULL;
140 static void (*gCallback)(void) = NULL;
141
142 static LONG WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo)
143 {
144     if (gCallback) {
145         gCallback();
146     }
147
148         if (prevExceptionFilter) {
149                 return prevExceptionFilter(pExceptionInfo);
150     } else {
151                 return EXCEPTION_CONTINUE_SEARCH;
152     }
153 }
154
155 void
156 SetExceptionCallback(void (*callback)(void))
157 {
158     assert(!gCallback);
159
160     if (!gCallback) {
161         gCallback = callback;
162
163         assert(!prevExceptionFilter);
164         prevExceptionFilter = SetUnhandledExceptionFilter(UnhandledExceptionFilter);
165     }
166 }
167
168 void
169 ResetExceptionCallback(void)
170 {
171     gCallback = NULL;
172 }
173
174
175 } /* namespace OS */