| Index: third_party/tcmalloc/chromium/src/windows/port.h
|
| ===================================================================
|
| --- third_party/tcmalloc/chromium/src/windows/port.h (revision 87277)
|
| +++ third_party/tcmalloc/chromium/src/windows/port.h (working copy)
|
| @@ -40,8 +40,8 @@
|
| #ifndef GOOGLE_BASE_WINDOWS_H_
|
| #define GOOGLE_BASE_WINDOWS_H_
|
|
|
| -// You should never include this file directly, but always include it
|
| -// from either config.h (MSVC) or mingw.h (MinGW/msys).
|
| +/* You should never include this file directly, but always include it
|
| + from either config.h (MSVC) or mingw.h (MinGW/msys). */
|
| #if !defined(GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_) && \
|
| !defined(GOOGLE_PERFTOOLS_WINDOWS_MINGW_H_)
|
| # error "port.h should only be included from config.h or mingw.h"
|
| @@ -54,22 +54,46 @@
|
| #endif
|
| #include <windows.h>
|
| #include <io.h> /* because we so often use open/close/etc */
|
| +#include <direct.h> /* for _getcwd */
|
| #include <process.h> /* for _getpid */
|
| +#include <limits.h> /* for PATH_MAX */
|
| #include <stdarg.h> /* for va_list */
|
| #include <stdio.h> /* need this to override stdio's (v)snprintf */
|
| +#include <sys/types.h> /* for _off_t */
|
| +#include <assert.h>
|
| +#include <stdlib.h> /* for rand, srand, _strtoxxx */
|
|
|
| -// 4018: signed/unsigned mismatch is common (and ok for signed_i < unsigned_i)
|
| -// 4244: otherwise we get problems when substracting two size_t's to an int
|
| -// 4288: VC++7 gets confused when a var is defined in a loop and then after it
|
| -// 4267: too many false positives for "conversion gives possible data loss"
|
| -// 4290: it's ok windows ignores the "throw" directive
|
| -// 4996: Yes, we're ok using "unsafe" functions like vsnprintf and getenv()
|
| +/*
|
| + * 4018: signed/unsigned mismatch is common (and ok for signed_i < unsigned_i)
|
| + * 4244: otherwise we get problems when substracting two size_t's to an int
|
| + * 4288: VC++7 gets confused when a var is defined in a loop and then after it
|
| + * 4267: too many false positives for "conversion gives possible data loss"
|
| + * 4290: it's ok windows ignores the "throw" directive
|
| + * 4996: Yes, we're ok using "unsafe" functions like vsnprintf and getenv()
|
| + */
|
| #ifdef _MSC_VER
|
| #pragma warning(disable:4018 4244 4288 4267 4290 4996)
|
| #endif
|
|
|
| -// ----------------------------------- BASIC TYPES
|
| +#ifndef __cplusplus
|
| +/* MSVC does not support C99 */
|
| +# if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
|
| +# ifdef _MSC_VER
|
| +# define inline __inline
|
| +# else
|
| +# define inline static
|
| +# endif
|
| +# endif
|
| +#endif
|
|
|
| +#ifdef __cplusplus
|
| +# define EXTERN_C extern "C"
|
| +#else
|
| +# define EXTERN_C extern
|
| +#endif
|
| +
|
| +/* ----------------------------------- BASIC TYPES */
|
| +
|
| #ifndef HAVE_STDINT_H
|
| #ifndef HAVE___INT64 /* we need to have all the __intX names */
|
| # error Do not know how to set up type aliases. Edit port.h for your system.
|
| @@ -83,53 +107,78 @@
|
| typedef unsigned __int16 uint16_t;
|
| typedef unsigned __int32 uint32_t;
|
| typedef unsigned __int64 uint64_t;
|
| -#endif // #ifndef HAVE_STDINT_H
|
| +#endif /* #ifndef HAVE_STDINT_H */
|
|
|
| -// I guess MSVC's <types.h> doesn't include ssize_t by default?
|
| +/* I guess MSVC's <types.h> doesn't include ssize_t by default? */
|
| #ifdef _MSC_VER
|
| typedef intptr_t ssize_t;
|
| #endif
|
|
|
| -// ----------------------------------- THREADS
|
| +/* ----------------------------------- THREADS */
|
|
|
| -#ifndef HAVE_PTHREAD // not true for MSVC, but may be true for MSYS
|
| +#ifndef HAVE_PTHREAD /* not true for MSVC, but may be true for MSYS */
|
| typedef DWORD pthread_t;
|
| typedef DWORD pthread_key_t;
|
| typedef LONG pthread_once_t;
|
| -enum { PTHREAD_ONCE_INIT = 0 }; // important that this be 0! for SpinLock
|
| -#define pthread_self GetCurrentThreadId
|
| -#define pthread_equal(pthread_t_1, pthread_t_2) ((pthread_t_1)==(pthread_t_2))
|
| +enum { PTHREAD_ONCE_INIT = 0 }; /* important that this be 0! for SpinLock */
|
|
|
| +inline pthread_t pthread_self(void) {
|
| + return GetCurrentThreadId();
|
| +}
|
| +
|
| #ifdef __cplusplus
|
| -// This replaces maybe_threads.{h,cc}
|
| -extern pthread_key_t PthreadKeyCreate(void (*destr_fn)(void*)); // in port.cc
|
| -#define perftools_pthread_key_create(pkey, destr_fn) \
|
| - *(pkey) = PthreadKeyCreate(destr_fn)
|
| +inline bool pthread_equal(pthread_t left, pthread_t right) {
|
| + return left == right;
|
| +}
|
| +
|
| +/* This replaces maybe_threads.{h,cc} */
|
| +EXTERN_C pthread_key_t PthreadKeyCreate(void (*destr_fn)(void*)); /* port.cc */
|
| +
|
| +inline int perftools_pthread_key_create(pthread_key_t *pkey,
|
| + void (*destructor)(void*)) {
|
| + pthread_key_t key = PthreadKeyCreate(destructor);
|
| + if (key != TLS_OUT_OF_INDEXES) {
|
| + *(pkey) = key;
|
| + return 0;
|
| + } else {
|
| + return GetLastError();
|
| + }
|
| +}
|
| +
|
| inline void* perftools_pthread_getspecific(DWORD key) {
|
| DWORD err = GetLastError();
|
| void* rv = TlsGetValue(key);
|
| if (err) SetLastError(err);
|
| return rv;
|
| }
|
| -#define perftools_pthread_setspecific(key, val) \
|
| - TlsSetValue((key), (val))
|
| -// NOTE: this is Win2K and later. For Win98 we could use a CRITICAL_SECTION...
|
| -#define perftools_pthread_once(once, init) do { \
|
| - if (InterlockedCompareExchange(once, 1, 0) == 0) (init)(); \
|
| -} while (0)
|
| -#endif // __cplusplus
|
| -#endif // HAVE_PTHREAD
|
|
|
| -// __declspec(thread) isn't usable in a dll opened via LoadLibrary().
|
| -// But it doesn't work to LoadLibrary() us anyway, because of all the
|
| -// things we need to do before main()! So this kind of TLS is safe for us.
|
| +inline int perftools_pthread_setspecific(pthread_key_t key, const void *value) {
|
| + if (TlsSetValue(key, (LPVOID)value))
|
| + return 0;
|
| + else
|
| + return GetLastError();
|
| +}
|
| +
|
| +EXTERN_C int perftools_pthread_once(pthread_once_t *once_control,
|
| + void (*init_routine)(void));
|
| +
|
| +#endif /* __cplusplus */
|
| +#endif /* HAVE_PTHREAD */
|
| +
|
| +/*
|
| + * __declspec(thread) isn't usable in a dll opened via LoadLibrary().
|
| + * But it doesn't work to LoadLibrary() us anyway, because of all the
|
| + * things we need to do before main()! So this kind of TLS is safe for us.
|
| + */
|
| #define __thread __declspec(thread)
|
|
|
| -// This code is obsolete, but I keep it around in case we are ever in
|
| -// an environment where we can't or don't want to use google spinlocks
|
| -// (from base/spinlock.{h,cc}). In that case, uncommenting this out,
|
| -// and removing spinlock.cc from the build, should be enough to revert
|
| -// back to using native spinlocks.
|
| +/*
|
| + * This code is obsolete, but I keep it around in case we are ever in
|
| + * an environment where we can't or don't want to use google spinlocks
|
| + * (from base/spinlock.{h,cc}). In that case, uncommenting this out,
|
| + * and removing spinlock.cc from the build, should be enough to revert
|
| + * back to using native spinlocks.
|
| + */
|
| #if 0
|
| // Windows uses a spinlock internally for its mutexes, making our life easy!
|
| // However, the Windows spinlock must always be initialized, making life hard,
|
| @@ -197,52 +246,81 @@
|
| // This keeps us from using base/spinlock.h's implementation of SpinLock.
|
| #define BASE_SPINLOCK_H_ 1
|
|
|
| -#endif // #if 0
|
| +#endif /* #if 0 */
|
|
|
| -// This replaces testutil.{h,cc}
|
| -extern PERFTOOLS_DLL_DECL void RunInThread(void (*fn)());
|
| -extern PERFTOOLS_DLL_DECL void RunManyInThread(void (*fn)(), int count);
|
| -extern PERFTOOLS_DLL_DECL void RunManyInThreadWithId(void (*fn)(int), int count,
|
| - int stacksize);
|
| +/* ----------------------------------- MMAP and other memory allocation */
|
|
|
| -
|
| -// ----------------------------------- MMAP and other memory allocation
|
| -
|
| -#ifndef HAVE_MMAP // not true for MSVC, but may be true for msys
|
| +#ifndef HAVE_MMAP /* not true for MSVC, but may be true for msys */
|
| #define MAP_FAILED 0
|
| -#define MREMAP_FIXED 2 // the value in linux, though it doesn't really matter
|
| -// These, when combined with the mmap invariants below, yield the proper action
|
| +#define MREMAP_FIXED 2 /* the value in linux, though it doesn't really matter */
|
| +/* These, when combined with the mmap invariants below, yield the proper action */
|
| #define PROT_READ PAGE_READWRITE
|
| #define PROT_WRITE PAGE_READWRITE
|
| #define MAP_ANONYMOUS MEM_RESERVE
|
| #define MAP_PRIVATE MEM_COMMIT
|
| -#define MAP_SHARED MEM_RESERVE // value of this #define is 100% arbitrary
|
| +#define MAP_SHARED MEM_RESERVE /* value of this #define is 100% arbitrary */
|
|
|
| -// VirtualAlloc is only a replacement for mmap when certain invariants are kept
|
| -#define mmap(start, length, prot, flags, fd, offset) \
|
| - ( (start) == NULL && (fd) == -1 && (offset) == 0 && \
|
| - (prot) == (PROT_READ|PROT_WRITE) && (flags) == (MAP_PRIVATE|MAP_ANONYMOUS)\
|
| - ? VirtualAlloc(0, length, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE) \
|
| - : NULL )
|
| +#if __STDC__
|
| +typedef _off_t off_t;
|
| +#endif
|
|
|
| -#define munmap(start, length) (VirtualFree(start, 0, MEM_RELEASE) ? 0 : -1)
|
| -#endif // HAVE_MMAP
|
| +/* VirtualAlloc only replaces for mmap when certain invariants are kept. */
|
| +inline void *mmap(void *addr, size_t length, int prot, int flags,
|
| + int fd, off_t offset) {
|
| + if (addr == NULL && fd == -1 && offset == 0 &&
|
| + prot == (PROT_READ|PROT_WRITE) && flags == (MAP_PRIVATE|MAP_ANONYMOUS)) {
|
| + return VirtualAlloc(0, length, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
| + } else {
|
| + return NULL;
|
| + }
|
| +}
|
|
|
| -// We could maybe use VirtualAlloc for sbrk as well, but no need
|
| -#define sbrk(increment) ( (void*)-1 ) // sbrk returns -1 on failure
|
| +inline int munmap(void *addr, size_t length) {
|
| + return VirtualFree(addr, 0, MEM_RELEASE) ? 0 : -1;
|
| +}
|
| +#endif /* HAVE_MMAP */
|
|
|
| +/* We could maybe use VirtualAlloc for sbrk as well, but no need */
|
| +inline void *sbrk(intptr_t increment) {
|
| + // sbrk returns -1 on failure
|
| + return (void*)-1;
|
| +}
|
|
|
| -// ----------------------------------- STRING ROUTINES
|
|
|
| -// We can't just use _vsnprintf and _snprintf as drop-in-replacements,
|
| -// because they don't always NUL-terminate. :-( We also can't use the
|
| -// name vsnprintf, since windows defines that (but not snprintf (!)).
|
| -extern PERFTOOLS_DLL_DECL int snprintf(char *str, size_t size,
|
| - const char *format, ...);
|
| -extern PERFTOOLS_DLL_DECL int safe_vsnprintf(char *str, size_t size,
|
| - const char *format, va_list ap);
|
| -#define vsnprintf(str, size, format, ap) safe_vsnprintf(str, size, format, ap)
|
| +/* ----------------------------------- STRING ROUTINES */
|
|
|
| +/*
|
| + * We can't just use _vsnprintf and _snprintf as drop-in-replacements,
|
| + * because they don't always NUL-terminate. :-( We also can't use the
|
| + * name vsnprintf, since windows defines that (but not snprintf (!)).
|
| + */
|
| +#if defined(_MSC_VER) && _MSC_VER >= 1400
|
| +/* We can use safe CRT functions, which the required functionality */
|
| +inline int perftools_vsnprintf(char *str, size_t size, const char *format,
|
| + va_list ap) {
|
| + return vsnprintf_s(str, size, _TRUNCATE, format, ap);
|
| +}
|
| +#else
|
| +inline int perftools_vsnprintf(char *str, size_t size, const char *format,
|
| + va_list ap) {
|
| + if (size == 0) /* not even room for a \0? */
|
| + return -1; /* not what C99 says to do, but what windows does */
|
| + str[size-1] = '\0';
|
| + return _vsnprintf(str, size-1, format, ap);
|
| +}
|
| +#endif
|
| +
|
| +#ifndef HAVE_SNPRINTF
|
| +inline int snprintf(char *str, size_t size, const char *format, ...) {
|
| + va_list ap;
|
| + int r;
|
| + va_start(ap, format);
|
| + r = perftools_vsnprintf(str, size, format, ap);
|
| + va_end(ap);
|
| + return r;
|
| +}
|
| +#endif
|
| +
|
| #define PRIx64 "I64x"
|
| #define SCNx64 "I64x"
|
| #define PRId64 "I64d"
|
| @@ -256,79 +334,132 @@
|
| # define PRIxPTR "lx"
|
| #endif
|
|
|
| -// ----------------------------------- FILE IO
|
| +/* ----------------------------------- FILE IO */
|
| +
|
| #ifndef PATH_MAX
|
| #define PATH_MAX 1024
|
| #endif
|
| #ifndef __MINGW32__
|
| enum { STDIN_FILENO = 0, STDOUT_FILENO = 1, STDERR_FILENO = 2 };
|
| #endif
|
| -#define getcwd _getcwd
|
| -#define access _access
|
| -#define open _open
|
| -#define read _read
|
| -#define write _write
|
| -#define lseek _lseek
|
| -#define close _close
|
| -#define popen _popen
|
| -#define pclose _pclose
|
| -#define mkdir(dirname, mode) _mkdir(dirname)
|
| #ifndef O_RDONLY
|
| #define O_RDONLY _O_RDONLY
|
| #endif
|
|
|
| -// ----------------------------------- SYSTEM/PROCESS
|
| +#if __STDC__ && !defined(__MINGW32__)
|
| +/* These functions are considered non-standard */
|
| +inline int access(const char *pathname, int mode) {
|
| + return _access(pathname, mode);
|
| +}
|
| +inline int open(const char *pathname, int flags, int mode = 0) {
|
| + return _open(pathname, flags, mode);
|
| +}
|
| +inline int close(int fd) {
|
| + return _close(fd);
|
| +}
|
| +inline ssize_t read(int fd, void *buf, size_t count) {
|
| + return _read(fd, buf, count);
|
| +}
|
| +inline ssize_t write(int fd, const void *buf, size_t count) {
|
| + return _write(fd, buf, count);
|
| +}
|
| +inline off_t lseek(int fd, off_t offset, int whence) {
|
| + return _lseek(fd, offset, whence);
|
| +}
|
| +inline char *getcwd(char *buf, size_t size) {
|
| + return _getcwd(buf, size);
|
| +}
|
| +inline int mkdir(const char *pathname, int) {
|
| + return _mkdir(pathname);
|
| +}
|
| +#endif
|
| +
|
| +inline FILE *popen(const char *command, const char *type) {
|
| + return _popen(command, type);
|
| +}
|
| +inline int pclose(FILE *stream) {
|
| + return _pclose(stream);
|
| +}
|
| +
|
| +EXTERN_C PERFTOOLS_DLL_DECL void WriteToStderr(const char* buf, int len);
|
| +
|
| +/* ----------------------------------- SYSTEM/PROCESS */
|
| +
|
| typedef int pid_t;
|
| -#define getpid _getpid
|
| -#define getppid() (0)
|
| +#if __STDC__
|
| +inline pid_t getpid(void) { return _getpid(); }
|
| +#endif
|
| +inline pid_t getppid(void) { return 0; }
|
|
|
| -// Handle case when poll is used to simulate sleep.
|
| -#define poll(r, w, t) \
|
| - do { \
|
| - assert(r == 0); \
|
| - assert(w == 0); \
|
| - Sleep(t); \
|
| - } while(0)
|
| +/* Handle case when poll is used to simulate sleep. */
|
| +inline int poll(struct pollfd* fds, int nfds, int timeout) {
|
| + assert(fds == NULL);
|
| + assert(nfds == 0);
|
| + Sleep(timeout);
|
| + return 0;
|
| +}
|
|
|
| -extern PERFTOOLS_DLL_DECL int getpagesize(); // in port.cc
|
| +EXTERN_C int getpagesize(); /* in port.cc */
|
|
|
| -// ----------------------------------- OTHER
|
| +/* ----------------------------------- OTHER */
|
|
|
| -#define srandom srand
|
| -#define random rand
|
| -#define sleep(t) Sleep(t * 1000)
|
| +inline void srandom(unsigned int seed) { srand(seed); }
|
| +inline long random(void) { return rand(); }
|
| +inline unsigned int sleep(unsigned int seconds) {
|
| + Sleep(seconds * 1000);
|
| + return 0;
|
| +}
|
|
|
| struct timespec {
|
| int tv_sec;
|
| int tv_nsec;
|
| };
|
|
|
| -#define nanosleep(tm_ptr, ignored) \
|
| - Sleep((tm_ptr)->tv_sec * 1000 + (tm_ptr)->tv_nsec / 1000000)
|
| +inline int nanosleep(const struct timespec *req, struct timespec *rem) {
|
| + Sleep(req->tv_sec * 1000 + req->tv_nsec / 1000000);
|
| + return 0;
|
| +}
|
|
|
| #ifndef __MINGW32__
|
| -#define strtoq _strtoi64
|
| -#define strtouq _strtoui64
|
| -#define strtoll _strtoi64
|
| -#define strtoull _strtoui64
|
| -#define atoll _atoi64
|
| +inline long long int strtoll(const char *nptr, char **endptr, int base) {
|
| + return _strtoi64(nptr, endptr, base);
|
| +}
|
| +inline unsigned long long int strtoull(const char *nptr, char **endptr,
|
| + int base) {
|
| + return _strtoui64(nptr, endptr, base);
|
| +}
|
| +inline long long int strtoq(const char *nptr, char **endptr, int base) {
|
| + return _strtoi64(nptr, endptr, base);
|
| +}
|
| +inline unsigned long long int strtouq(const char *nptr, char **endptr,
|
| + int base) {
|
| + return _strtoui64(nptr, endptr, base);
|
| +}
|
| +inline long long atoll(const char *nptr) {
|
| + return _atoi64(nptr);
|
| +}
|
| #endif
|
|
|
| #define __THROW throw()
|
|
|
| -// ----------------------------------- TCMALLOC-SPECIFIC
|
| +/* ----------------------------------- TCMALLOC-SPECIFIC */
|
|
|
| -// tcmalloc.cc calls this so we can patch VirtualAlloc() et al.
|
| -extern PERFTOOLS_DLL_DECL void PatchWindowsFunctions();
|
| +/* tcmalloc.cc calls this so we can patch VirtualAlloc() et al. */
|
| +extern void PatchWindowsFunctions();
|
|
|
| // ----------------------------------- BUILD-SPECIFIC
|
|
|
| -// windows/port.h defines compatibility APIs for several .h files, which
|
| -// we therefore shouldn't be #including directly. This hack keeps us from
|
| -// doing so. TODO(csilvers): do something more principled.
|
| +/*
|
| + * windows/port.h defines compatibility APIs for several .h files, which
|
| + * we therefore shouldn't be #including directly. This hack keeps us from
|
| + * doing so. TODO(csilvers): do something more principled.
|
| + */
|
| #define GOOGLE_MAYBE_THREADS_H_ 1
|
|
|
|
|
| #endif /* _WIN32 */
|
|
|
| +#undef inline
|
| +#undef EXTERN_C
|
| +
|
| #endif /* GOOGLE_BASE_WINDOWS_H_ */
|
|
|