OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/sync/util/pthread_helpers.h" | 5 #include "chrome/browser/sync/util/pthread_helpers.h" |
6 | 6 |
7 #if (defined(OS_LINUX) || defined(OS_MACOSX)) | 7 #if (defined(OS_LINUX) || defined(OS_MACOSX)) |
8 #include <sys/time.h> | 8 #include <sys/time.h> |
9 #endif // (defined(OS_LINUX) || defined(OS_MACOSX)) | 9 #endif // (defined(OS_LINUX) || defined(OS_MACOSX)) |
10 | 10 |
11 #include "base/atomicops.h" | 11 #include "base/atomicops.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/port.h" | 13 #include "base/port.h" |
14 #include "base/scoped_ptr.h" | 14 #include "base/scoped_ptr.h" |
15 #include "chrome/browser/sync/protocol/service_constants.h" | 15 #include "chrome/browser/sync/protocol/service_constants.h" |
16 | 16 |
17 #ifdef OS_WINDOWS | 17 #ifdef OS_WIN |
18 | 18 |
19 namespace { | 19 namespace { |
20 | 20 |
21 // Ensure that we don't bug the user more than once about the process being | 21 // Ensure that we don't bug the user more than once about the process being |
22 // terminated. | 22 // terminated. |
23 base::subtle::AtomicWord g_process_terminating = 0; | 23 base::subtle::AtomicWord g_process_terminating = 0; |
24 | 24 |
25 struct ThreadStartParams { | 25 struct ThreadStartParams { |
26 void *(*start) (void* payload); | 26 void *(*start) (void* payload); |
27 void* param; | 27 void* param; |
(...skipping 25 matching lines...) Expand all Loading... |
53 | 53 |
54 ::ExitProcess(GetExceptionCode()); | 54 ::ExitProcess(GetExceptionCode()); |
55 } | 55 } |
56 } | 56 } |
57 | 57 |
58 return result; | 58 return result; |
59 } | 59 } |
60 | 60 |
61 } // namespace | 61 } // namespace |
62 | 62 |
63 #endif // OS_WINDOWS | 63 #endif // OS_WIN |
64 | 64 |
65 thread_handle CreatePThread(void *(*start) (void *), void* parameter) { | 65 thread_handle CreatePThread(void *(*start) (void *), void* parameter) { |
66 #ifdef OS_WINDOWS | 66 #ifdef OS_WIN |
67 scoped_ptr<ThreadStartParams> param(new ThreadStartParams); | 67 scoped_ptr<ThreadStartParams> param(new ThreadStartParams); |
68 if (NULL == param.get()) | 68 if (NULL == param.get()) |
69 return NULL; | 69 return NULL; |
70 | 70 |
71 param->start = start; | 71 param->start = start; |
72 param->param = parameter; | 72 param->param = parameter; |
73 | 73 |
74 pthread_t pthread; | 74 pthread_t pthread; |
75 if (0 != pthread_create(&pthread, NULL, ThreadMainProc, param.get())) | 75 if (0 != pthread_create(&pthread, NULL, ThreadMainProc, param.get())) |
76 return NULL; | 76 return NULL; |
(...skipping 14 matching lines...) Expand all Loading... |
91 return thread_copy; | 91 return thread_copy; |
92 #else | 92 #else |
93 pthread_t handle; | 93 pthread_t handle; |
94 | 94 |
95 int result = pthread_create(&handle, NULL, start, parameter); | 95 int result = pthread_create(&handle, NULL, start, parameter); |
96 if (result == 0) { | 96 if (result == 0) { |
97 return handle; | 97 return handle; |
98 } else { | 98 } else { |
99 return 0; | 99 return 0; |
100 } | 100 } |
101 #endif // OS_WINDOWS | 101 #endif // OS_WIN |
102 } | 102 } |
103 | 103 |
104 struct timespec GetPThreadAbsoluteTime(uint32 ms) { | 104 struct timespec GetPThreadAbsoluteTime(uint32 ms) { |
105 #ifdef OS_WINDOWS | 105 #ifdef OS_WIN |
106 FILETIME filenow; | 106 FILETIME filenow; |
107 GetSystemTimeAsFileTime(&filenow); | 107 GetSystemTimeAsFileTime(&filenow); |
108 ULARGE_INTEGER n; | 108 ULARGE_INTEGER n; |
109 n.LowPart = filenow.dwLowDateTime; | 109 n.LowPart = filenow.dwLowDateTime; |
110 n.HighPart = filenow.dwHighDateTime; | 110 n.HighPart = filenow.dwHighDateTime; |
111 // Filetime unit is 100-nanosecond intervals | 111 // Filetime unit is 100-nanosecond intervals |
112 const int64 ms_ftime = 10000; | 112 const int64 ms_ftime = 10000; |
113 n.QuadPart += ms_ftime * ms; | 113 n.QuadPart += ms_ftime * ms; |
114 | 114 |
115 // The number of 100 nanosecond intervals from Jan 1, 1601 'til Jan 1, 1970. | 115 // The number of 100 nanosecond intervals from Jan 1, 1601 'til Jan 1, 1970. |
116 const int64 kOffset = GG_LONGLONG(116444736000000000); | 116 const int64 kOffset = GG_LONGLONG(116444736000000000); |
117 timespec result; | 117 timespec result; |
118 result.tv_sec = static_cast<long>((n.QuadPart - kOffset) / 10000000); | 118 result.tv_sec = static_cast<long>((n.QuadPart - kOffset) / 10000000); |
119 result.tv_nsec = static_cast<long>((n.QuadPart - kOffset - | 119 result.tv_nsec = static_cast<long>((n.QuadPart - kOffset - |
120 (result.tv_sec * GG_LONGLONG(10000000))) * 100); | 120 (result.tv_sec * GG_LONGLONG(10000000))) * 100); |
121 return result; | 121 return result; |
122 #else | 122 #else |
123 struct timeval now; | 123 struct timeval now; |
124 struct timezone zone; | 124 struct timezone zone; |
125 gettimeofday(&now, &zone); | 125 gettimeofday(&now, &zone); |
126 struct timespec deadline = { now.tv_sec }; | 126 struct timespec deadline = { now.tv_sec }; |
127 // microseconds to nanoseconds. | 127 // microseconds to nanoseconds. |
128 // and add the ms delay. | 128 // and add the ms delay. |
129 ms += now.tv_usec / 1000; | 129 ms += now.tv_usec / 1000; |
130 deadline.tv_sec += ms / 1000; | 130 deadline.tv_sec += ms / 1000; |
131 deadline.tv_nsec = (ms % 1000) * 1000000; | 131 deadline.tv_nsec = (ms % 1000) * 1000000; |
132 return deadline; | 132 return deadline; |
133 #endif // OS_WINDOWS | 133 #endif // OS_WIN |
134 } | 134 } |
135 | 135 |
136 void NameCurrentThreadForDebugging(char* name) { | 136 void NameCurrentThreadForDebugging(char* name) { |
137 #if defined(OS_WINDOWS) | 137 #if defined(OS_WIN) |
138 // This implementation is taken from Chromium's platform_thread framework. | 138 // This implementation is taken from Chromium's platform_thread framework. |
139 // The information on how to set the thread name comes from a MSDN article: | 139 // The information on how to set the thread name comes from a MSDN article: |
140 // http://msdn2.microsoft.com/en-us/library/xcb2z8hs.aspx | 140 // http://msdn2.microsoft.com/en-us/library/xcb2z8hs.aspx |
141 const DWORD kVCThreadNameException = 0x406D1388; | 141 const DWORD kVCThreadNameException = 0x406D1388; |
142 typedef struct tagTHREADNAME_INFO { | 142 typedef struct tagTHREADNAME_INFO { |
143 DWORD dwType; // Must be 0x1000. | 143 DWORD dwType; // Must be 0x1000. |
144 LPCSTR szName; // Pointer to name (in user addr space). | 144 LPCSTR szName; // Pointer to name (in user addr space). |
145 DWORD dwThreadID; // Thread ID (-1=caller thread). | 145 DWORD dwThreadID; // Thread ID (-1=caller thread). |
146 DWORD dwFlags; // Reserved for future use, must be zero. | 146 DWORD dwFlags; // Reserved for future use, must be zero. |
147 } THREADNAME_INFO; | 147 } THREADNAME_INFO; |
148 | 148 |
149 // The debugger needs to be around to catch the name in the exception. If | 149 // The debugger needs to be around to catch the name in the exception. If |
150 // there isn't a debugger, we are just needlessly throwing an exception. | 150 // there isn't a debugger, we are just needlessly throwing an exception. |
151 if (!::IsDebuggerPresent()) | 151 if (!::IsDebuggerPresent()) |
152 return; | 152 return; |
153 | 153 |
154 THREADNAME_INFO info = { 0x1000, name, GetCurrentThreadId(), 0 }; | 154 THREADNAME_INFO info = { 0x1000, name, GetCurrentThreadId(), 0 }; |
155 | 155 |
156 __try { | 156 __try { |
157 RaiseException(kVCThreadNameException, 0, sizeof(info)/sizeof(DWORD), | 157 RaiseException(kVCThreadNameException, 0, sizeof(info)/sizeof(DWORD), |
158 reinterpret_cast<DWORD_PTR*>(&info)); | 158 reinterpret_cast<DWORD_PTR*>(&info)); |
159 } __except(EXCEPTION_CONTINUE_EXECUTION) { | 159 } __except(EXCEPTION_CONTINUE_EXECUTION) { |
160 } | 160 } |
161 #endif // defined(OS_WINDOWS) | 161 #endif // defined(OS_WIN) |
162 } | 162 } |
OLD | NEW |