OLD | NEW |
1 /* Copyright (c) 2007, Google Inc. | 1 /* Copyright (c) 2007, Google Inc. |
2 * All rights reserved. | 2 * All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 22 matching lines...) Expand all Loading... |
33 * These are some portability typedefs and defines to make it a bit | 33 * These are some portability typedefs and defines to make it a bit |
34 * easier to compile this code under VC++. | 34 * easier to compile this code under VC++. |
35 * | 35 * |
36 * Several of these are taken from glib: | 36 * Several of these are taken from glib: |
37 * http://developer.gnome.org/doc/API/glib/glib-windows-compatability-functio
ns.html | 37 * http://developer.gnome.org/doc/API/glib/glib-windows-compatability-functio
ns.html |
38 */ | 38 */ |
39 | 39 |
40 #ifndef GOOGLE_BASE_WINDOWS_H_ | 40 #ifndef GOOGLE_BASE_WINDOWS_H_ |
41 #define GOOGLE_BASE_WINDOWS_H_ | 41 #define GOOGLE_BASE_WINDOWS_H_ |
42 | 42 |
43 // You should never include this file directly, but always include it | 43 /* You should never include this file directly, but always include it |
44 // from either config.h (MSVC) or mingw.h (MinGW/msys). | 44 from either config.h (MSVC) or mingw.h (MinGW/msys). */ |
45 #if !defined(GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_) && \ | 45 #if !defined(GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_) && \ |
46 !defined(GOOGLE_PERFTOOLS_WINDOWS_MINGW_H_) | 46 !defined(GOOGLE_PERFTOOLS_WINDOWS_MINGW_H_) |
47 # error "port.h should only be included from config.h or mingw.h" | 47 # error "port.h should only be included from config.h or mingw.h" |
48 #endif | 48 #endif |
49 | 49 |
50 #ifdef _WIN32 | 50 #ifdef _WIN32 |
51 | 51 |
52 #ifndef WIN32_LEAN_AND_MEAN | 52 #ifndef WIN32_LEAN_AND_MEAN |
53 #define WIN32_LEAN_AND_MEAN /* We always want minimal includes */ | 53 #define WIN32_LEAN_AND_MEAN /* We always want minimal includes */ |
54 #endif | 54 #endif |
55 #include <windows.h> | 55 #include <windows.h> |
56 #include <io.h> /* because we so often use open/close/etc */ | 56 #include <io.h> /* because we so often use open/close/etc */ |
| 57 #include <direct.h> /* for _getcwd */ |
57 #include <process.h> /* for _getpid */ | 58 #include <process.h> /* for _getpid */ |
| 59 #include <limits.h> /* for PATH_MAX */ |
58 #include <stdarg.h> /* for va_list */ | 60 #include <stdarg.h> /* for va_list */ |
59 #include <stdio.h> /* need this to override stdio's (v)snprintf */ | 61 #include <stdio.h> /* need this to override stdio's (v)snprintf */ |
| 62 #include <sys/types.h> /* for _off_t */ |
| 63 #include <assert.h> |
| 64 #include <stdlib.h> /* for rand, srand, _strtoxxx */ |
60 | 65 |
61 // 4018: signed/unsigned mismatch is common (and ok for signed_i < unsigned_i) | 66 /* |
62 // 4244: otherwise we get problems when substracting two size_t's to an int | 67 * 4018: signed/unsigned mismatch is common (and ok for signed_i < unsigned_i) |
63 // 4288: VC++7 gets confused when a var is defined in a loop and then after it | 68 * 4244: otherwise we get problems when substracting two size_t's to an int |
64 // 4267: too many false positives for "conversion gives possible data loss" | 69 * 4288: VC++7 gets confused when a var is defined in a loop and then after it |
65 // 4290: it's ok windows ignores the "throw" directive | 70 * 4267: too many false positives for "conversion gives possible data loss" |
66 // 4996: Yes, we're ok using "unsafe" functions like vsnprintf and getenv() | 71 * 4290: it's ok windows ignores the "throw" directive |
| 72 * 4996: Yes, we're ok using "unsafe" functions like vsnprintf and getenv() |
| 73 */ |
67 #ifdef _MSC_VER | 74 #ifdef _MSC_VER |
68 #pragma warning(disable:4018 4244 4288 4267 4290 4996) | 75 #pragma warning(disable:4018 4244 4288 4267 4290 4996) |
69 #endif | 76 #endif |
70 | 77 |
71 // ----------------------------------- BASIC TYPES | 78 #ifndef __cplusplus |
| 79 /* MSVC does not support C99 */ |
| 80 # if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L |
| 81 # ifdef _MSC_VER |
| 82 # define inline __inline |
| 83 # else |
| 84 # define inline static |
| 85 # endif |
| 86 # endif |
| 87 #endif |
| 88 |
| 89 #ifdef __cplusplus |
| 90 # define EXTERN_C extern "C" |
| 91 #else |
| 92 # define EXTERN_C extern |
| 93 #endif |
| 94 |
| 95 /* ----------------------------------- BASIC TYPES */ |
72 | 96 |
73 #ifndef HAVE_STDINT_H | 97 #ifndef HAVE_STDINT_H |
74 #ifndef HAVE___INT64 /* we need to have all the __intX names */ | 98 #ifndef HAVE___INT64 /* we need to have all the __intX names */ |
75 # error Do not know how to set up type aliases. Edit port.h for your system. | 99 # error Do not know how to set up type aliases. Edit port.h for your system. |
76 #endif | 100 #endif |
77 | 101 |
78 typedef __int8 int8_t; | 102 typedef __int8 int8_t; |
79 typedef __int16 int16_t; | 103 typedef __int16 int16_t; |
80 typedef __int32 int32_t; | 104 typedef __int32 int32_t; |
81 typedef __int64 int64_t; | 105 typedef __int64 int64_t; |
82 typedef unsigned __int8 uint8_t; | 106 typedef unsigned __int8 uint8_t; |
83 typedef unsigned __int16 uint16_t; | 107 typedef unsigned __int16 uint16_t; |
84 typedef unsigned __int32 uint32_t; | 108 typedef unsigned __int32 uint32_t; |
85 typedef unsigned __int64 uint64_t; | 109 typedef unsigned __int64 uint64_t; |
86 #endif // #ifndef HAVE_STDINT_H | 110 #endif /* #ifndef HAVE_STDINT_H */ |
87 | 111 |
88 // I guess MSVC's <types.h> doesn't include ssize_t by default? | 112 /* I guess MSVC's <types.h> doesn't include ssize_t by default? */ |
89 #ifdef _MSC_VER | 113 #ifdef _MSC_VER |
90 typedef intptr_t ssize_t; | 114 typedef intptr_t ssize_t; |
91 #endif | 115 #endif |
92 | 116 |
93 // ----------------------------------- THREADS | 117 /* ----------------------------------- THREADS */ |
94 | 118 |
95 #ifndef HAVE_PTHREAD // not true for MSVC, but may be true for MSYS | 119 #ifndef HAVE_PTHREAD /* not true for MSVC, but may be true for MSYS */ |
96 typedef DWORD pthread_t; | 120 typedef DWORD pthread_t; |
97 typedef DWORD pthread_key_t; | 121 typedef DWORD pthread_key_t; |
98 typedef LONG pthread_once_t; | 122 typedef LONG pthread_once_t; |
99 enum { PTHREAD_ONCE_INIT = 0 }; // important that this be 0! for SpinLock | 123 enum { PTHREAD_ONCE_INIT = 0 }; /* important that this be 0! for SpinLock */ |
100 #define pthread_self GetCurrentThreadId | 124 |
101 #define pthread_equal(pthread_t_1, pthread_t_2) ((pthread_t_1)==(pthread_t_2)) | 125 inline pthread_t pthread_self(void) { |
| 126 return GetCurrentThreadId(); |
| 127 } |
102 | 128 |
103 #ifdef __cplusplus | 129 #ifdef __cplusplus |
104 // This replaces maybe_threads.{h,cc} | 130 inline bool pthread_equal(pthread_t left, pthread_t right) { |
105 extern pthread_key_t PthreadKeyCreate(void (*destr_fn)(void*)); // in port.cc | 131 return left == right; |
106 #define perftools_pthread_key_create(pkey, destr_fn) \ | 132 } |
107 *(pkey) = PthreadKeyCreate(destr_fn) | 133 |
| 134 /* This replaces maybe_threads.{h,cc} */ |
| 135 EXTERN_C pthread_key_t PthreadKeyCreate(void (*destr_fn)(void*)); /* port.cc */ |
| 136 |
| 137 inline int perftools_pthread_key_create(pthread_key_t *pkey, |
| 138 void (*destructor)(void*)) { |
| 139 pthread_key_t key = PthreadKeyCreate(destructor); |
| 140 if (key != TLS_OUT_OF_INDEXES) { |
| 141 *(pkey) = key; |
| 142 return 0; |
| 143 } else { |
| 144 return GetLastError(); |
| 145 } |
| 146 } |
| 147 |
108 inline void* perftools_pthread_getspecific(DWORD key) { | 148 inline void* perftools_pthread_getspecific(DWORD key) { |
109 DWORD err = GetLastError(); | 149 DWORD err = GetLastError(); |
110 void* rv = TlsGetValue(key); | 150 void* rv = TlsGetValue(key); |
111 if (err) SetLastError(err); | 151 if (err) SetLastError(err); |
112 return rv; | 152 return rv; |
113 } | 153 } |
114 #define perftools_pthread_setspecific(key, val) \ | |
115 TlsSetValue((key), (val)) | |
116 // NOTE: this is Win2K and later. For Win98 we could use a CRITICAL_SECTION... | |
117 #define perftools_pthread_once(once, init) do { \ | |
118 if (InterlockedCompareExchange(once, 1, 0) == 0) (init)(); \ | |
119 } while (0) | |
120 #endif // __cplusplus | |
121 #endif // HAVE_PTHREAD | |
122 | 154 |
123 // __declspec(thread) isn't usable in a dll opened via LoadLibrary(). | 155 inline int perftools_pthread_setspecific(pthread_key_t key, const void *value) { |
124 // But it doesn't work to LoadLibrary() us anyway, because of all the | 156 if (TlsSetValue(key, (LPVOID)value)) |
125 // things we need to do before main()! So this kind of TLS is safe for us. | 157 return 0; |
| 158 else |
| 159 return GetLastError(); |
| 160 } |
| 161 |
| 162 EXTERN_C int perftools_pthread_once(pthread_once_t *once_control, |
| 163 void (*init_routine)(void)); |
| 164 |
| 165 #endif /* __cplusplus */ |
| 166 #endif /* HAVE_PTHREAD */ |
| 167 |
| 168 /* |
| 169 * __declspec(thread) isn't usable in a dll opened via LoadLibrary(). |
| 170 * But it doesn't work to LoadLibrary() us anyway, because of all the |
| 171 * things we need to do before main()! So this kind of TLS is safe for us. |
| 172 */ |
126 #define __thread __declspec(thread) | 173 #define __thread __declspec(thread) |
127 | 174 |
128 // This code is obsolete, but I keep it around in case we are ever in | 175 /* |
129 // an environment where we can't or don't want to use google spinlocks | 176 * This code is obsolete, but I keep it around in case we are ever in |
130 // (from base/spinlock.{h,cc}). In that case, uncommenting this out, | 177 * an environment where we can't or don't want to use google spinlocks |
131 // and removing spinlock.cc from the build, should be enough to revert | 178 * (from base/spinlock.{h,cc}). In that case, uncommenting this out, |
132 // back to using native spinlocks. | 179 * and removing spinlock.cc from the build, should be enough to revert |
| 180 * back to using native spinlocks. |
| 181 */ |
133 #if 0 | 182 #if 0 |
134 // Windows uses a spinlock internally for its mutexes, making our life easy! | 183 // Windows uses a spinlock internally for its mutexes, making our life easy! |
135 // However, the Windows spinlock must always be initialized, making life hard, | 184 // However, the Windows spinlock must always be initialized, making life hard, |
136 // since we want LINKER_INITIALIZED. We work around this by having the | 185 // since we want LINKER_INITIALIZED. We work around this by having the |
137 // linker initialize a bool to 0, and check that before accessing the mutex. | 186 // linker initialize a bool to 0, and check that before accessing the mutex. |
138 // This replaces spinlock.{h,cc}, and all the stuff it depends on (atomicops) | 187 // This replaces spinlock.{h,cc}, and all the stuff it depends on (atomicops) |
139 #ifdef __cplusplus | 188 #ifdef __cplusplus |
140 class SpinLock { | 189 class SpinLock { |
141 public: | 190 public: |
142 SpinLock() : initialize_token_(PTHREAD_ONCE_INIT) {} | 191 SpinLock() : initialize_token_(PTHREAD_ONCE_INIT) {} |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 SpinLock* lock_; | 239 SpinLock* lock_; |
191 public: | 240 public: |
192 inline explicit SpinLockHolder(SpinLock* l) : lock_(l) { l->Lock(); } | 241 inline explicit SpinLockHolder(SpinLock* l) : lock_(l) { l->Lock(); } |
193 inline ~SpinLockHolder() { lock_->Unlock(); } | 242 inline ~SpinLockHolder() { lock_->Unlock(); } |
194 }; | 243 }; |
195 #endif // #ifdef __cplusplus | 244 #endif // #ifdef __cplusplus |
196 | 245 |
197 // This keeps us from using base/spinlock.h's implementation of SpinLock. | 246 // This keeps us from using base/spinlock.h's implementation of SpinLock. |
198 #define BASE_SPINLOCK_H_ 1 | 247 #define BASE_SPINLOCK_H_ 1 |
199 | 248 |
200 #endif // #if 0 | 249 #endif /* #if 0 */ |
201 | 250 |
202 // This replaces testutil.{h,cc} | 251 /* ----------------------------------- MMAP and other memory allocation */ |
203 extern PERFTOOLS_DLL_DECL void RunInThread(void (*fn)()); | |
204 extern PERFTOOLS_DLL_DECL void RunManyInThread(void (*fn)(), int count); | |
205 extern PERFTOOLS_DLL_DECL void RunManyInThreadWithId(void (*fn)(int), int count, | |
206 int stacksize); | |
207 | 252 |
208 | 253 #ifndef HAVE_MMAP /* not true for MSVC, but may be true for msys */ |
209 // ----------------------------------- MMAP and other memory allocation | |
210 | |
211 #ifndef HAVE_MMAP // not true for MSVC, but may be true for msys | |
212 #define MAP_FAILED 0 | 254 #define MAP_FAILED 0 |
213 #define MREMAP_FIXED 2 // the value in linux, though it doesn't really matter | 255 #define MREMAP_FIXED 2 /* the value in linux, though it doesn't really matter
*/ |
214 // These, when combined with the mmap invariants below, yield the proper action | 256 /* These, when combined with the mmap invariants below, yield the proper action
*/ |
215 #define PROT_READ PAGE_READWRITE | 257 #define PROT_READ PAGE_READWRITE |
216 #define PROT_WRITE PAGE_READWRITE | 258 #define PROT_WRITE PAGE_READWRITE |
217 #define MAP_ANONYMOUS MEM_RESERVE | 259 #define MAP_ANONYMOUS MEM_RESERVE |
218 #define MAP_PRIVATE MEM_COMMIT | 260 #define MAP_PRIVATE MEM_COMMIT |
219 #define MAP_SHARED MEM_RESERVE // value of this #define is 100% arbitrary | 261 #define MAP_SHARED MEM_RESERVE /* value of this #define is 100% arbitrary
*/ |
220 | 262 |
221 // VirtualAlloc is only a replacement for mmap when certain invariants are kept | 263 #if __STDC__ |
222 #define mmap(start, length, prot, flags, fd, offset) \ | 264 typedef _off_t off_t; |
223 ( (start) == NULL && (fd) == -1 && (offset) == 0 && \ | 265 #endif |
224 (prot) == (PROT_READ|PROT_WRITE) && (flags) == (MAP_PRIVATE|MAP_ANONYMOUS)\ | |
225 ? VirtualAlloc(0, length, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE) \ | |
226 : NULL ) | |
227 | 266 |
228 #define munmap(start, length) (VirtualFree(start, 0, MEM_RELEASE) ? 0 : -1) | 267 /* VirtualAlloc only replaces for mmap when certain invariants are kept. */ |
229 #endif // HAVE_MMAP | 268 inline void *mmap(void *addr, size_t length, int prot, int flags, |
| 269 int fd, off_t offset) { |
| 270 if (addr == NULL && fd == -1 && offset == 0 && |
| 271 prot == (PROT_READ|PROT_WRITE) && flags == (MAP_PRIVATE|MAP_ANONYMOUS)) { |
| 272 return VirtualAlloc(0, length, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); |
| 273 } else { |
| 274 return NULL; |
| 275 } |
| 276 } |
230 | 277 |
231 // We could maybe use VirtualAlloc for sbrk as well, but no need | 278 inline int munmap(void *addr, size_t length) { |
232 #define sbrk(increment) ( (void*)-1 ) // sbrk returns -1 on failure | 279 return VirtualFree(addr, 0, MEM_RELEASE) ? 0 : -1; |
| 280 } |
| 281 #endif /* HAVE_MMAP */ |
| 282 |
| 283 /* We could maybe use VirtualAlloc for sbrk as well, but no need */ |
| 284 inline void *sbrk(intptr_t increment) { |
| 285 // sbrk returns -1 on failure |
| 286 return (void*)-1; |
| 287 } |
233 | 288 |
234 | 289 |
235 // ----------------------------------- STRING ROUTINES | 290 /* ----------------------------------- STRING ROUTINES */ |
236 | 291 |
237 // We can't just use _vsnprintf and _snprintf as drop-in-replacements, | 292 /* |
238 // because they don't always NUL-terminate. :-( We also can't use the | 293 * We can't just use _vsnprintf and _snprintf as drop-in-replacements, |
239 // name vsnprintf, since windows defines that (but not snprintf (!)). | 294 * because they don't always NUL-terminate. :-( We also can't use the |
240 extern PERFTOOLS_DLL_DECL int snprintf(char *str, size_t size, | 295 * name vsnprintf, since windows defines that (but not snprintf (!)). |
241 const char *format, ...); | 296 */ |
242 extern PERFTOOLS_DLL_DECL int safe_vsnprintf(char *str, size_t size, | 297 #if defined(_MSC_VER) && _MSC_VER >= 1400 |
243 const char *format, va_list ap); | 298 /* We can use safe CRT functions, which the required functionality */ |
244 #define vsnprintf(str, size, format, ap) safe_vsnprintf(str, size, format, ap) | 299 inline int perftools_vsnprintf(char *str, size_t size, const char *format, |
| 300 va_list ap) { |
| 301 return vsnprintf_s(str, size, _TRUNCATE, format, ap); |
| 302 } |
| 303 #else |
| 304 inline int perftools_vsnprintf(char *str, size_t size, const char *format, |
| 305 va_list ap) { |
| 306 if (size == 0) /* not even room for a \0? */ |
| 307 return -1; /* not what C99 says to do, but what windows does */ |
| 308 str[size-1] = '\0'; |
| 309 return _vsnprintf(str, size-1, format, ap); |
| 310 } |
| 311 #endif |
| 312 |
| 313 #ifndef HAVE_SNPRINTF |
| 314 inline int snprintf(char *str, size_t size, const char *format, ...) { |
| 315 va_list ap; |
| 316 int r; |
| 317 va_start(ap, format); |
| 318 r = perftools_vsnprintf(str, size, format, ap); |
| 319 va_end(ap); |
| 320 return r; |
| 321 } |
| 322 #endif |
245 | 323 |
246 #define PRIx64 "I64x" | 324 #define PRIx64 "I64x" |
247 #define SCNx64 "I64x" | 325 #define SCNx64 "I64x" |
248 #define PRId64 "I64d" | 326 #define PRId64 "I64d" |
249 #define SCNd64 "I64d" | 327 #define SCNd64 "I64d" |
250 #define PRIu64 "I64u" | 328 #define PRIu64 "I64u" |
251 #ifdef _WIN64 | 329 #ifdef _WIN64 |
252 # define PRIuPTR "llu" | 330 # define PRIuPTR "llu" |
253 # define PRIxPTR "llx" | 331 # define PRIxPTR "llx" |
254 #else | 332 #else |
255 # define PRIuPTR "lu" | 333 # define PRIuPTR "lu" |
256 # define PRIxPTR "lx" | 334 # define PRIxPTR "lx" |
257 #endif | 335 #endif |
258 | 336 |
259 // ----------------------------------- FILE IO | 337 /* ----------------------------------- FILE IO */ |
| 338 |
260 #ifndef PATH_MAX | 339 #ifndef PATH_MAX |
261 #define PATH_MAX 1024 | 340 #define PATH_MAX 1024 |
262 #endif | 341 #endif |
263 #ifndef __MINGW32__ | 342 #ifndef __MINGW32__ |
264 enum { STDIN_FILENO = 0, STDOUT_FILENO = 1, STDERR_FILENO = 2 }; | 343 enum { STDIN_FILENO = 0, STDOUT_FILENO = 1, STDERR_FILENO = 2 }; |
265 #endif | 344 #endif |
266 #define getcwd _getcwd | |
267 #define access _access | |
268 #define open _open | |
269 #define read _read | |
270 #define write _write | |
271 #define lseek _lseek | |
272 #define close _close | |
273 #define popen _popen | |
274 #define pclose _pclose | |
275 #define mkdir(dirname, mode) _mkdir(dirname) | |
276 #ifndef O_RDONLY | 345 #ifndef O_RDONLY |
277 #define O_RDONLY _O_RDONLY | 346 #define O_RDONLY _O_RDONLY |
278 #endif | 347 #endif |
279 | 348 |
280 // ----------------------------------- SYSTEM/PROCESS | 349 #if __STDC__ && !defined(__MINGW32__) |
| 350 /* These functions are considered non-standard */ |
| 351 inline int access(const char *pathname, int mode) { |
| 352 return _access(pathname, mode); |
| 353 } |
| 354 inline int open(const char *pathname, int flags, int mode = 0) { |
| 355 return _open(pathname, flags, mode); |
| 356 } |
| 357 inline int close(int fd) { |
| 358 return _close(fd); |
| 359 } |
| 360 inline ssize_t read(int fd, void *buf, size_t count) { |
| 361 return _read(fd, buf, count); |
| 362 } |
| 363 inline ssize_t write(int fd, const void *buf, size_t count) { |
| 364 return _write(fd, buf, count); |
| 365 } |
| 366 inline off_t lseek(int fd, off_t offset, int whence) { |
| 367 return _lseek(fd, offset, whence); |
| 368 } |
| 369 inline char *getcwd(char *buf, size_t size) { |
| 370 return _getcwd(buf, size); |
| 371 } |
| 372 inline int mkdir(const char *pathname, int) { |
| 373 return _mkdir(pathname); |
| 374 } |
| 375 #endif |
| 376 |
| 377 inline FILE *popen(const char *command, const char *type) { |
| 378 return _popen(command, type); |
| 379 } |
| 380 inline int pclose(FILE *stream) { |
| 381 return _pclose(stream); |
| 382 } |
| 383 |
| 384 EXTERN_C PERFTOOLS_DLL_DECL void WriteToStderr(const char* buf, int len); |
| 385 |
| 386 /* ----------------------------------- SYSTEM/PROCESS */ |
| 387 |
281 typedef int pid_t; | 388 typedef int pid_t; |
282 #define getpid _getpid | 389 #if __STDC__ |
283 #define getppid() (0) | 390 inline pid_t getpid(void) { return _getpid(); } |
| 391 #endif |
| 392 inline pid_t getppid(void) { return 0; } |
284 | 393 |
285 // Handle case when poll is used to simulate sleep. | 394 /* Handle case when poll is used to simulate sleep. */ |
286 #define poll(r, w, t) \ | 395 inline int poll(struct pollfd* fds, int nfds, int timeout) { |
287 do { \ | 396 assert(fds == NULL); |
288 assert(r == 0); \ | 397 assert(nfds == 0); |
289 assert(w == 0); \ | 398 Sleep(timeout); |
290 Sleep(t); \ | 399 return 0; |
291 } while(0) | 400 } |
292 | 401 |
293 extern PERFTOOLS_DLL_DECL int getpagesize(); // in port.cc | 402 EXTERN_C int getpagesize(); /* in port.cc */ |
294 | 403 |
295 // ----------------------------------- OTHER | 404 /* ----------------------------------- OTHER */ |
296 | 405 |
297 #define srandom srand | 406 inline void srandom(unsigned int seed) { srand(seed); } |
298 #define random rand | 407 inline long random(void) { return rand(); } |
299 #define sleep(t) Sleep(t * 1000) | 408 inline unsigned int sleep(unsigned int seconds) { |
| 409 Sleep(seconds * 1000); |
| 410 return 0; |
| 411 } |
300 | 412 |
301 struct timespec { | 413 struct timespec { |
302 int tv_sec; | 414 int tv_sec; |
303 int tv_nsec; | 415 int tv_nsec; |
304 }; | 416 }; |
305 | 417 |
306 #define nanosleep(tm_ptr, ignored) \ | 418 inline int nanosleep(const struct timespec *req, struct timespec *rem) { |
307 Sleep((tm_ptr)->tv_sec * 1000 + (tm_ptr)->tv_nsec / 1000000) | 419 Sleep(req->tv_sec * 1000 + req->tv_nsec / 1000000); |
| 420 return 0; |
| 421 } |
308 | 422 |
309 #ifndef __MINGW32__ | 423 #ifndef __MINGW32__ |
310 #define strtoq _strtoi64 | 424 inline long long int strtoll(const char *nptr, char **endptr, int base) { |
311 #define strtouq _strtoui64 | 425 return _strtoi64(nptr, endptr, base); |
312 #define strtoll _strtoi64 | 426 } |
313 #define strtoull _strtoui64 | 427 inline unsigned long long int strtoull(const char *nptr, char **endptr, |
314 #define atoll _atoi64 | 428 int base) { |
| 429 return _strtoui64(nptr, endptr, base); |
| 430 } |
| 431 inline long long int strtoq(const char *nptr, char **endptr, int base) { |
| 432 return _strtoi64(nptr, endptr, base); |
| 433 } |
| 434 inline unsigned long long int strtouq(const char *nptr, char **endptr, |
| 435 int base) { |
| 436 return _strtoui64(nptr, endptr, base); |
| 437 } |
| 438 inline long long atoll(const char *nptr) { |
| 439 return _atoi64(nptr); |
| 440 } |
315 #endif | 441 #endif |
316 | 442 |
317 #define __THROW throw() | 443 #define __THROW throw() |
318 | 444 |
319 // ----------------------------------- TCMALLOC-SPECIFIC | 445 /* ----------------------------------- TCMALLOC-SPECIFIC */ |
320 | 446 |
321 // tcmalloc.cc calls this so we can patch VirtualAlloc() et al. | 447 /* tcmalloc.cc calls this so we can patch VirtualAlloc() et al. */ |
322 extern PERFTOOLS_DLL_DECL void PatchWindowsFunctions(); | 448 extern void PatchWindowsFunctions(); |
323 | 449 |
324 // ----------------------------------- BUILD-SPECIFIC | 450 // ----------------------------------- BUILD-SPECIFIC |
325 | 451 |
326 // windows/port.h defines compatibility APIs for several .h files, which | 452 /* |
327 // we therefore shouldn't be #including directly. This hack keeps us from | 453 * windows/port.h defines compatibility APIs for several .h files, which |
328 // doing so. TODO(csilvers): do something more principled. | 454 * we therefore shouldn't be #including directly. This hack keeps us from |
| 455 * doing so. TODO(csilvers): do something more principled. |
| 456 */ |
329 #define GOOGLE_MAYBE_THREADS_H_ 1 | 457 #define GOOGLE_MAYBE_THREADS_H_ 1 |
330 | 458 |
331 | 459 |
332 #endif /* _WIN32 */ | 460 #endif /* _WIN32 */ |
333 | 461 |
| 462 #undef inline |
| 463 #undef EXTERN_C |
| 464 |
334 #endif /* GOOGLE_BASE_WINDOWS_H_ */ | 465 #endif /* GOOGLE_BASE_WINDOWS_H_ */ |
OLD | NEW |