15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Copyright (c) 2007, Google Inc.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * All rights reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * modification, are permitted provided that the following conditions are
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * met:
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *     * Redistributions of source code must retain the above copyright
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * notice, this list of conditions and the following disclaimer.
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *     * Redistributions in binary form must reproduce the above
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in the documentation and/or other materials provided with the
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * distribution.
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *     * Neither the name of Google Inc. nor the names of its
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * contributors may be used to endorse or promote products derived from
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this software without specific prior written permission.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ---
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Author: Craig Silverstein
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * These are some portability typedefs and defines to make it a bit
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * easier to compile this code under VC++.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Several of these are taken from glib:
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *    http://developer.gnome.org/doc/API/glib/glib-windows-compatability-functions.html
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef GOOGLE_BASE_WINDOWS_H_
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GOOGLE_BASE_WINDOWS_H_
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* You should never include this file directly, but always include it
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   from either config.h (MSVC) or mingw.h (MinGW/msys). */
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_) && \
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    !defined(GOOGLE_PERFTOOLS_WINDOWS_MINGW_H_)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# error "port.h should only be included from config.h or mingw.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _WIN32
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef WIN32_LEAN_AND_MEAN
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WIN32_LEAN_AND_MEAN  /* We always want minimal includes */
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <io.h>              /* because we so often use open/close/etc */
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <direct.h>          /* for _getcwd */
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <process.h>         /* for _getpid */
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits.h>          /* for PATH_MAX */
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdarg.h>          /* for va_list */
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h>           /* need this to override stdio's (v)snprintf */
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h>       /* for _off_t */
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <assert.h>
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h>          /* for rand, srand, _strtoxxx */
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4018: signed/unsigned mismatch is common (and ok for signed_i < unsigned_i)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4244: otherwise we get problems when subtracting two size_t's to an int
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4288: VC++7 gets confused when a var is defined in a loop and then after it
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4267: too many false positives for "conversion gives possible data loss"
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4290: it's ok windows ignores the "throw" directive
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4996: Yes, we're ok using "unsafe" functions like vsnprintf and getenv()
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4146: internal_logging.cc intentionally negates an unsigned value
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _MSC_VER
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma warning(disable:4018 4244 4288 4267 4290 4996 4146)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __cplusplus
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* MSVC does not support C99 */
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  ifdef _MSC_VER
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#    define inline __inline
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  else
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#    define inline static
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  endif
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# endif
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __cplusplus
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define EXTERN_C  extern "C"
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define EXTERN_C  extern
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ----------------------------------- BASIC TYPES */
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HAVE_STDINT_H
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HAVE___INT64    /* we need to have all the __intX names */
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# error  Do not know how to set up type aliases.  Edit port.h for your system.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef __int8 int8_t;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef __int16 int16_t;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef __int32 int32_t;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef __int64 int64_t;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef unsigned __int8 uint8_t;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef unsigned __int16 uint16_t;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef unsigned __int32 uint32_t;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef unsigned __int64 uint64_t;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  /* #ifndef HAVE_STDINT_H */
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* I guess MSVC's <types.h> doesn't include ssize_t by default? */
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _MSC_VER
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef intptr_t ssize_t;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ----------------------------------- THREADS */
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HAVE_PTHREAD   /* not true for MSVC, but may be true for MSYS */
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef DWORD pthread_t;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef DWORD pthread_key_t;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef LONG pthread_once_t;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum { PTHREAD_ONCE_INIT = 0 };   /* important that this be 0! for SpinLock */
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline pthread_t pthread_self(void) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetCurrentThreadId();
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __cplusplus
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline bool pthread_equal(pthread_t left, pthread_t right) {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return left == right;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* This replaces maybe_threads.{h,cc} */
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EXTERN_C pthread_key_t PthreadKeyCreate(void (*destr_fn)(void*));  /* port.cc */
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline int perftools_pthread_key_create(pthread_key_t *pkey,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        void (*destructor)(void*)) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pthread_key_t key = PthreadKeyCreate(destructor);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (key != TLS_OUT_OF_INDEXES) {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(pkey) = key;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GetLastError();
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline void* perftools_pthread_getspecific(DWORD key) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD err = GetLastError();
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* rv = TlsGetValue(key);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (err) SetLastError(err);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rv;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline int perftools_pthread_setspecific(pthread_key_t key, const void *value) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (TlsSetValue(key, (LPVOID)value))
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GetLastError();
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EXTERN_C int perftools_pthread_once(pthread_once_t *once_control,
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    void (*init_routine)(void));
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  /* __cplusplus */
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  /* HAVE_PTHREAD */
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline void sched_yield(void) {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Sleep(0);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * __declspec(thread) isn't usable in a dll opened via LoadLibrary().
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * But it doesn't work to LoadLibrary() us anyway, because of all the
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * things we need to do before main()!  So this kind of TLS is safe for us.
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __thread __declspec(thread)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This code is obsolete, but I keep it around in case we are ever in
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * an environment where we can't or don't want to use google spinlocks
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (from base/spinlock.{h,cc}).  In that case, uncommenting this out,
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and removing spinlock.cc from the build, should be enough to revert
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * back to using native spinlocks.
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Windows uses a spinlock internally for its mutexes, making our life easy!
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// However, the Windows spinlock must always be initialized, making life hard,
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// since we want LINKER_INITIALIZED.  We work around this by having the
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// linker initialize a bool to 0, and check that before accessing the mutex.
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This replaces spinlock.{h,cc}, and all the stuff it depends on (atomicops)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __cplusplus
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SpinLock {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpinLock() : initialize_token_(PTHREAD_ONCE_INIT) {}
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used for global SpinLock vars (see base/spinlock.h for more details).
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum StaticInitializer { LINKER_INITIALIZED };
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit SpinLock(StaticInitializer) : initialize_token_(PTHREAD_ONCE_INIT) {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    perftools_pthread_once(&initialize_token_, InitializeMutex);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It's important SpinLock not have a destructor: otherwise we run
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // into problems when the main thread has exited, but other threads
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are still running and try to access a main-thread spinlock.  This
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // means we leak mutex_ (we should call DeleteCriticalSection()
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // here).  However, I've verified that all SpinLocks used in
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // perftools have program-long scope anyway, so the leak is
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // perfectly fine.  But be aware of this for the future!
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Lock() {
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // You'd thionk this would be unnecessary, since we call
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // InitializeMutex() in our constructor.  But sometimes Lock() can
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be called before our constructor is!  This can only happen in
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // global constructors, when this is a global.  If we live in
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // bar.cc, and some global constructor in foo.cc calls a routine
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // in bar.cc that calls this->Lock(), then Lock() may well run
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // before our global constructor does.  To protect against that,
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // we do this check.  For SpinLock objects created after main()
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // has started, this pthread_once call will always be a noop.
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    perftools_pthread_once(&initialize_token_, InitializeMutex);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EnterCriticalSection(&mutex_);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Unlock() {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LeaveCriticalSection(&mutex_);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used in assertion checks: assert(lock.IsHeld()) (see base/spinlock.h).
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline bool IsHeld() const {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This works, but probes undocumented internals, so I've commented it out.
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // c.f. http://msdn.microsoft.com/msdnmag/issues/03/12/CriticalSections/
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //return mutex_.LockCount>=0 && mutex_.OwningThread==GetCurrentThreadId();
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InitializeMutex() { InitializeCriticalSection(&mutex_); }
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pthread_once_t initialize_token_;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CRITICAL_SECTION mutex_;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SpinLockHolder {  // Acquires a spinlock for as long as the scope lasts
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpinLock* lock_;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline explicit SpinLockHolder(SpinLock* l) : lock_(l) { l->Lock(); }
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline ~SpinLockHolder() { lock_->Unlock(); }
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // #ifdef __cplusplus
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This keeps us from using base/spinlock.h's implementation of SpinLock.
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_SPINLOCK_H_ 1
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  /* #if 0 */
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ----------------------------------- MMAP and other memory allocation */
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HAVE_MMAP   /* not true for MSVC, but may be true for msys */
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAP_FAILED  0
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MREMAP_FIXED  2  /* the value in linux, though it doesn't really matter */
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* These, when combined with the mmap invariants below, yield the proper action */
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PROT_READ      PAGE_READWRITE
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PROT_WRITE     PAGE_READWRITE
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAP_ANONYMOUS  MEM_RESERVE
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAP_PRIVATE    MEM_COMMIT
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAP_SHARED     MEM_RESERVE   /* value of this #define is 100% arbitrary */
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if __STDC__ && !defined(__MINGW32__)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef _off_t off_t;
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* VirtualAlloc only replaces for mmap when certain invariants are kept. */
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline void *mmap(void *addr, size_t length, int prot, int flags,
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  int fd, off_t offset) {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (addr == NULL && fd == -1 && offset == 0 &&
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prot == (PROT_READ|PROT_WRITE) && flags == (MAP_PRIVATE|MAP_ANONYMOUS)) {
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return VirtualAlloc(0, length, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline int munmap(void *addr, size_t length) {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return VirtualFree(addr, 0, MEM_RELEASE) ? 0 : -1;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  /* HAVE_MMAP */
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* We could maybe use VirtualAlloc for sbrk as well, but no need */
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline void *sbrk(intptr_t increment) {
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // sbrk returns -1 on failure
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (void*)-1;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ----------------------------------- STRING ROUTINES */
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * We can't just use _vsnprintf and _snprintf as drop-in-replacements,
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * because they don't always NUL-terminate. :-(  We also can't use the
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * name vsnprintf, since windows defines that (but not snprintf (!)).
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(_MSC_VER) && _MSC_VER >= 1400
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* We can use safe CRT functions, which the required functionality */
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline int perftools_vsnprintf(char *str, size_t size, const char *format,
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               va_list ap) {
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return vsnprintf_s(str, size, _TRUNCATE, format, ap);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline int perftools_vsnprintf(char *str, size_t size, const char *format,
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               va_list ap) {
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (size == 0)        /* not even room for a \0? */
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return -1;        /* not what C99 says to do, but what windows does */
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  str[size-1] = '\0';
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return _vsnprintf(str, size-1, format, ap);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HAVE_SNPRINTF
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline int snprintf(char *str, size_t size, const char *format, ...) {
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  va_list ap;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int r;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  va_start(ap, format);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  r = perftools_vsnprintf(str, size, format, ap);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  va_end(ap);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return r;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PRIx64  "I64x"
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SCNx64  "I64x"
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PRId64  "I64d"
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SCNd64  "I64d"
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PRIu64  "I64u"
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _WIN64
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define PRIuPTR "llu"
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define PRIxPTR "llx"
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define PRIuPTR "lu"
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define PRIxPTR "lx"
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ----------------------------------- FILE IO */
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef PATH_MAX
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PATH_MAX 1024
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __MINGW32__
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum { STDIN_FILENO = 0, STDOUT_FILENO = 1, STDERR_FILENO = 2 };
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef O_RDONLY
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define O_RDONLY  _O_RDONLY
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if __STDC__ && !defined(__MINGW32__)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* These functions are considered non-standard */
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline int access(const char *pathname, int mode) {
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return _access(pathname, mode);
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline int open(const char *pathname, int flags, int mode = 0) {
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return _open(pathname, flags, mode);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline int close(int fd) {
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return _close(fd);
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline ssize_t read(int fd, void *buf, size_t count) {
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return _read(fd, buf, count);
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline ssize_t write(int fd, const void *buf, size_t count) {
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return _write(fd, buf, count);
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline off_t lseek(int fd, off_t offset, int whence) {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return _lseek(fd, offset, whence);
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline char *getcwd(char *buf, size_t size) {
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return _getcwd(buf, size);
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline int mkdir(const char *pathname, int) {
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return _mkdir(pathname);
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline FILE *popen(const char *command, const char *type) {
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return _popen(command, type);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline int pclose(FILE *stream) {
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return _pclose(stream);
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EXTERN_C PERFTOOLS_DLL_DECL void WriteToStderr(const char* buf, int len);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ----------------------------------- SYSTEM/PROCESS */
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef int pid_t;
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if __STDC__ && !defined(__MINGW32__)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline pid_t getpid(void) { return _getpid(); }
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline pid_t getppid(void) { return 0; }
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Handle case when poll is used to simulate sleep. */
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline int poll(struct pollfd* fds, int nfds, int timeout) {
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(fds == NULL);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(nfds == 0);
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Sleep(timeout);
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EXTERN_C int getpagesize();   /* in port.cc */
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ----------------------------------- OTHER */
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline void srandom(unsigned int seed) { srand(seed); }
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline long random(void) { return rand(); }
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline unsigned int sleep(unsigned int seconds) {
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Sleep(seconds * 1000);
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// mingw64 seems to define timespec (though mingw.org mingw doesn't),
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// protected by the _TIMESPEC_DEFINED macro.
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef _TIMESPEC_DEFINED
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct timespec {
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int tv_sec;
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int tv_nsec;
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline int nanosleep(const struct timespec *req, struct timespec *rem) {
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Sleep(req->tv_sec * 1000 + req->tv_nsec / 1000000);
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __MINGW32__
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline long long int strtoll(const char *nptr, char **endptr, int base) {
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return _strtoi64(nptr, endptr, base);
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline unsigned long long int strtoull(const char *nptr, char **endptr,
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       int base) {
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return _strtoui64(nptr, endptr, base);
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline long long int strtoq(const char *nptr, char **endptr, int base) {
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return _strtoi64(nptr, endptr, base);
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline unsigned long long int strtouq(const char *nptr, char **endptr,
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      int base) {
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return _strtoui64(nptr, endptr, base);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline long long atoll(const char *nptr) {
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return _atoi64(nptr);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __THROW throw()
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ----------------------------------- TCMALLOC-SPECIFIC */
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* tcmalloc.cc calls this so we can patch VirtualAlloc() et al. */
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern void PatchWindowsFunctions();
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ----------------------------------- BUILD-SPECIFIC
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * windows/port.h defines compatibility APIs for several .h files, which
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * we therefore shouldn't be #including directly.  This hack keeps us from
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * doing so.  TODO(csilvers): do something more principled.
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GOOGLE_MAYBE_THREADS_H_ 1
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  /* _WIN32 */
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef inline
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef EXTERN_C
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  /* GOOGLE_BASE_WINDOWS_H_ */
475