1732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang/* Copyright (c) 2007, Google Inc.
2732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * All rights reserved.
3732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang *
4732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * Redistribution and use in source and binary forms, with or without
5732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * modification, are permitted provided that the following conditions are
6732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * met:
7732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang *
8732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang *     * Redistributions of source code must retain the above copyright
9732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * notice, this list of conditions and the following disclaimer.
10732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang *     * Redistributions in binary form must reproduce the above
11732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * copyright notice, this list of conditions and the following disclaimer
12732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * in the documentation and/or other materials provided with the
13732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * distribution.
14732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang *     * Neither the name of Google Inc. nor the names of its
15732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * contributors may be used to endorse or promote products derived from
16732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * this software without specific prior written permission.
17732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang *
18732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
191bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
237f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26e623a0f6e3caa9cafec913cf826e946628833517Andy Huang * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
275c765b9c5dd8a9a9421260ba8b46d06073391c73Mindy Pereira * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira *
305f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy * ---
315f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy * Author: Craig Silverstein
32ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira *
331367d09b1cb2ea08f2e105672262ade08e1f5895Paul Westbrook * These are some portability typedefs and defines to make it a bit
345f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy * easier to compile this code under VC++.
359e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang *
369e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang * Several of these are taken from glib:
37a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank *    http://developer.gnome.org/doc/API/glib/glib-windows-compatability-functions.html
38a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank */
39440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal
40440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal#ifndef GOOGLE_BASE_WINDOWS_H_
41b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang#define GOOGLE_BASE_WINDOWS_H_
42440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal
43732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang/* You should never include this file directly, but always include it
44f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank   from either config.h (MSVC) or mingw.h (MinGW/msys). */
45732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang#if !defined(GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_) && \
469e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang    !defined(GOOGLE_PERFTOOLS_WINDOWS_MINGW_H_)
479e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang# error "port.h should only be included from config.h or mingw.h"
48820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook#endif
49820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook
50e623a0f6e3caa9cafec913cf826e946628833517Andy Huang#ifdef _WIN32
51e623a0f6e3caa9cafec913cf826e946628833517Andy Huang
52e623a0f6e3caa9cafec913cf826e946628833517Andy Huang#ifndef NOMINMAX
53edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#define NOMINMAX             /* Do not define min and max macros. */
54e623a0f6e3caa9cafec913cf826e946628833517Andy Huang#endif
55e623a0f6e3caa9cafec913cf826e946628833517Andy Huang#ifndef WIN32_LEAN_AND_MEAN
56e623a0f6e3caa9cafec913cf826e946628833517Andy Huang#define WIN32_LEAN_AND_MEAN  /* We always want minimal includes */
57edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#endif
58e623a0f6e3caa9cafec913cf826e946628833517Andy Huang#include <windows.h>
59e623a0f6e3caa9cafec913cf826e946628833517Andy Huang#include <io.h>              /* because we so often use open/close/etc */
60e623a0f6e3caa9cafec913cf826e946628833517Andy Huang#include <direct.h>          /* for _getcwd */
61edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#include <process.h>         /* for _getpid */
62e623a0f6e3caa9cafec913cf826e946628833517Andy Huang#include <limits.h>          /* for PATH_MAX */
63e623a0f6e3caa9cafec913cf826e946628833517Andy Huang#include <stdarg.h>          /* for va_list */
64e623a0f6e3caa9cafec913cf826e946628833517Andy Huang#include <stdio.h>           /* need this to override stdio's (v)snprintf */
65edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#include <sys/types.h>       /* for _off_t */
66e623a0f6e3caa9cafec913cf826e946628833517Andy Huang#include <assert.h>
67e623a0f6e3caa9cafec913cf826e946628833517Andy Huang#include <stdlib.h>          /* for rand, srand, _strtoxxx */
68e623a0f6e3caa9cafec913cf826e946628833517Andy Huang
69edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler/*
70e623a0f6e3caa9cafec913cf826e946628833517Andy Huang * 4018: signed/unsigned mismatch is common (and ok for signed_i < unsigned_i)
71e623a0f6e3caa9cafec913cf826e946628833517Andy Huang * 4244: otherwise we get problems when subtracting two size_t's to an int
72e623a0f6e3caa9cafec913cf826e946628833517Andy Huang * 4288: VC++7 gets confused when a var is defined in a loop and then after it
73edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler * 4267: too many false positives for "conversion gives possible data loss"
74e623a0f6e3caa9cafec913cf826e946628833517Andy Huang * 4290: it's ok windows ignores the "throw" directive
75e623a0f6e3caa9cafec913cf826e946628833517Andy Huang * 4996: Yes, we're ok using "unsafe" functions like vsnprintf and getenv()
76e623a0f6e3caa9cafec913cf826e946628833517Andy Huang * 4146: internal_logging.cc intentionally negates an unsigned value
77edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler */
78e623a0f6e3caa9cafec913cf826e946628833517Andy Huang#ifdef _MSC_VER
79e623a0f6e3caa9cafec913cf826e946628833517Andy Huang#pragma warning(disable:4018 4244 4288 4267 4290 4996 4146)
80e623a0f6e3caa9cafec913cf826e946628833517Andy Huang#endif
814db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira
82e623a0f6e3caa9cafec913cf826e946628833517Andy Huang#ifndef __cplusplus
83e623a0f6e3caa9cafec913cf826e946628833517Andy Huang/* MSVC does not support C99 */
84e623a0f6e3caa9cafec913cf826e946628833517Andy Huang# if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
85c8a994227b9c686d88ee05840544162711a85712Marc Blank#  ifdef _MSC_VER
86e623a0f6e3caa9cafec913cf826e946628833517Andy Huang#    define inline __inline
87d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy#  else
88d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy#    define inline static
89d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy#  endif
90d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy# endif
91e623a0f6e3caa9cafec913cf826e946628833517Andy Huang#endif
92e623a0f6e3caa9cafec913cf826e946628833517Andy Huang
93c8a994227b9c686d88ee05840544162711a85712Marc Blank#ifdef __cplusplus
94e623a0f6e3caa9cafec913cf826e946628833517Andy Huang# define EXTERN_C  extern "C"
95e623a0f6e3caa9cafec913cf826e946628833517Andy Huang#else
96e623a0f6e3caa9cafec913cf826e946628833517Andy Huang# define EXTERN_C  extern
97b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang#endif
98e623a0f6e3caa9cafec913cf826e946628833517Andy Huang
99e623a0f6e3caa9cafec913cf826e946628833517Andy Huang/* ----------------------------------- BASIC TYPES */
100e623a0f6e3caa9cafec913cf826e946628833517Andy Huang
10122657529437c160dec072115c5982409306c1313Mindy Pereira#ifndef HAVE_STDINT_H
102e623a0f6e3caa9cafec913cf826e946628833517Andy Huang#ifndef HAVE___INT64    /* we need to have all the __intX names */
103e623a0f6e3caa9cafec913cf826e946628833517Andy Huang# error  Do not know how to set up type aliases.  Edit port.h for your system.
104e623a0f6e3caa9cafec913cf826e946628833517Andy Huang#endif
105edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
106e623a0f6e3caa9cafec913cf826e946628833517Andy Huangtypedef __int8 int8_t;
107e623a0f6e3caa9cafec913cf826e946628833517Andy Huangtypedef __int16 int16_t;
108e623a0f6e3caa9cafec913cf826e946628833517Andy Huangtypedef __int32 int32_t;
109edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlertypedef __int64 int64_t;
110e623a0f6e3caa9cafec913cf826e946628833517Andy Huangtypedef unsigned __int8 uint8_t;
111e623a0f6e3caa9cafec913cf826e946628833517Andy Huangtypedef unsigned __int16 uint16_t;
112e623a0f6e3caa9cafec913cf826e946628833517Andy Huangtypedef unsigned __int32 uint32_t;
113edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlertypedef unsigned __int64 uint64_t;
114e623a0f6e3caa9cafec913cf826e946628833517Andy Huang#endif  /* #ifndef HAVE_STDINT_H */
11576b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook
11676b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook/* I guess MSVC's <types.h> doesn't include ssize_t by default? */
117edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#ifdef _MSC_VER
11876b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrooktypedef intptr_t ssize_t;
119e623a0f6e3caa9cafec913cf826e946628833517Andy Huang#endif
120e623a0f6e3caa9cafec913cf826e946628833517Andy Huang
121edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler/* ----------------------------------- THREADS */
122e623a0f6e3caa9cafec913cf826e946628833517Andy Huang
123e623a0f6e3caa9cafec913cf826e946628833517Andy Huang#ifndef HAVE_PTHREAD   /* not true for MSVC, but may be true for MSYS */
124e623a0f6e3caa9cafec913cf826e946628833517Andy Huangtypedef DWORD pthread_t;
125edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlertypedef DWORD pthread_key_t;
126648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereiratypedef LONG pthread_once_t;
127648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereiraenum { PTHREAD_ONCE_INIT = 0 };   /* important that this be 0! for SpinLock */
128648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira
129edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline pthread_t pthread_self(void) {
13041dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook  return GetCurrentThreadId();
131cebcc64fbd69618ff89f9fac0bfe9b9e7d7ce104Paul Westbrook}
13241dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook
133edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#ifdef __cplusplus
134f98bc898cbc7014a203c35a13427d3f949bce705Andy Huanginline bool pthread_equal(pthread_t left, pthread_t right) {
135f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang  return left == right;
136f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang}
137edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
138c92dc65f64e8b09ee78ba2fa799d7d3627373913Alan Lau/* This replaces maybe_threads.{h,cc} */
139c92dc65f64e8b09ee78ba2fa799d7d3627373913Alan LauEXTERN_C pthread_key_t PthreadKeyCreate(void (*destr_fn)(void*));  /* port.cc */
140c92dc65f64e8b09ee78ba2fa799d7d3627373913Alan Lau
141c92dc65f64e8b09ee78ba2fa799d7d3627373913Alan Lauinline int perftools_pthread_key_create(pthread_key_t *pkey,
14222657529437c160dec072115c5982409306c1313Mindy Pereira                                        void (*destructor)(void*)) {
143dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy  pthread_key_t key = PthreadKeyCreate(destructor);
144dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy  if (key != TLS_OUT_OF_INDEXES) {
145dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy    *(pkey) = key;
146dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy    return 0;
147dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy  } else {
148dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy    return GetLastError();
149dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy  }
150dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy}
151f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank
152648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereirainline void* perftools_pthread_getspecific(DWORD key) {
153648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira  DWORD err = GetLastError();
154648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira  void* rv = TlsGetValue(key);
155648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira  if (err) SetLastError(err);
156ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank  return rv;
157732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang}
158cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang
159cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huanginline int perftools_pthread_setspecific(pthread_key_t key, const void *value) {
160928308d6b10d353493492ad05e0227f960ddaa7eJames Lemieux  if (TlsSetValue(key, (LPVOID)value))
1612909b7442130800d6c6c20c1227d65295262f03emindyp    return 0;
162e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank  else
163648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    return GetLastError();
164648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira}
165648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira
166e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc BlankEXTERN_C int perftools_pthread_once(pthread_once_t *once_control,
167e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank                                    void (*init_routine)(void));
168440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal
169440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal#endif  /* __cplusplus */
170440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal#endif  /* HAVE_PTHREAD */
171732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
172732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huanginline void sched_yield(void) {
173732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang  Sleep(0);
174732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang}
175732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
176732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang/*
177732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * __declspec(thread) isn't usable in a dll opened via LoadLibrary().
178732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * But it doesn't work to LoadLibrary() us anyway, because of all the
179c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank * things we need to do before main()!  So this kind of TLS is safe for us.
180732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang */
181732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang#define __thread __declspec(thread)
182f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang
183cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira/*
1844db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira * This code is obsolete, but I keep it around in case we are ever in
1854db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira * an environment where we can't or don't want to use google spinlocks
186f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang * (from base/spinlock.{h,cc}).  In that case, uncommenting this out,
187d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy * and removing spinlock.cc from the build, should be enough to revert
188f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang * back to using native spinlocks.
189b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang */
19022657529437c160dec072115c5982409306c1313Mindy Pereira#if 0
19122657529437c160dec072115c5982409306c1313Mindy Pereira// Windows uses a spinlock internally for its mutexes, making our life easy!
192863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira// However, the Windows spinlock must always be initialized, making life hard,
19376b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook// since we want LINKER_INITIALIZED.  We work around this by having the
194863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira// linker initialize a bool to 0, and check that before accessing the mutex.
19592939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank// This replaces spinlock.{h,cc}, and all the stuff it depends on (atomicops)
196a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank#ifdef __cplusplus
197351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huangclass SpinLock {
19841dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook public:
199f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang  SpinLock() : initialize_token_(PTHREAD_ONCE_INIT) {}
200c92dc65f64e8b09ee78ba2fa799d7d3627373913Alan Lau  // Used for global SpinLock vars (see base/spinlock.h for more details).
201732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang  enum StaticInitializer { LINKER_INITIALIZED };
202732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang  explicit SpinLock(StaticInitializer) : initialize_token_(PTHREAD_ONCE_INIT) {
203351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang    perftools_pthread_once(&initialize_token_, InitializeMutex);
204732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang  }
205c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank
206732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang  // It's important SpinLock not have a destructor: otherwise we run
207732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang  // into problems when the main thread has exited, but other threads
208f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang  // are still running and try to access a main-thread spinlock.  This
209cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira  // means we leak mutex_ (we should call DeleteCriticalSection()
2104db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira  // here).  However, I've verified that all SpinLocks used in
2114db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira  // perftools have program-long scope anyway, so the leak is
212f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang  // perfectly fine.  But be aware of this for the future!
213d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy
214f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang  void Lock() {
215b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang    // You'd thionk this would be unnecessary, since we call
21622657529437c160dec072115c5982409306c1313Mindy Pereira    // InitializeMutex() in our constructor.  But sometimes Lock() can
21722657529437c160dec072115c5982409306c1313Mindy Pereira    // be called before our constructor is!  This can only happen in
218863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira    // global constructors, when this is a global.  If we live in
21976b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook    // bar.cc, and some global constructor in foo.cc calls a routine
220863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira    // in bar.cc that calls this->Lock(), then Lock() may well run
22192939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank    // before our global constructor does.  To protect against that,
222a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank    // we do this check.  For SpinLock objects created after main()
223f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank    // has started, this pthread_once call will always be a noop.
224ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank    perftools_pthread_once(&initialize_token_, InitializeMutex);
225351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang    EnterCriticalSection(&mutex_);
22641dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook  }
227f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang  void Unlock() {
228c92dc65f64e8b09ee78ba2fa799d7d3627373913Alan Lau    LeaveCriticalSection(&mutex_);
229732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang  }
230732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
231732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang  // Used in assertion checks: assert(lock.IsHeld()) (see base/spinlock.h).
232732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang  inline bool IsHeld() const {
2339e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang    // This works, but probes undocumented internals, so I've commented it out.
2349e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang    // c.f. http://msdn.microsoft.com/msdnmag/issues/03/12/CriticalSections/
2359e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang    //return mutex_.LockCount>=0 && mutex_.OwningThread==GetCurrentThreadId();
2369e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang    return true;
2379e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang  }
2389e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang private:
2399e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang  void InitializeMutex() { InitializeCriticalSection(&mutex_); }
2409e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang
2419e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang  pthread_once_t initialize_token_;
242732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang  CRITICAL_SECTION mutex_;
243732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang};
244351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang
245351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huangclass SpinLockHolder {  // Acquires a spinlock for as long as the scope lasts
246732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang private:
247732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang  SpinLock* lock_;
248732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang public:
249351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang  inline explicit SpinLockHolder(SpinLock* l) : lock_(l) { l->Lock(); }
250351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang  inline ~SpinLockHolder() { lock_->Unlock(); }
251351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang};
252351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang#endif  // #ifdef __cplusplus
253351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang
254351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang// This keeps us from using base/spinlock.h's implementation of SpinLock.
255732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang#define BASE_SPINLOCK_H_ 1
256732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
257732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang#endif  /* #if 0 */
258732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
259732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang/* ----------------------------------- MMAP and other memory allocation */
260732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
261732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang#ifndef HAVE_MMAP   /* not true for MSVC, but may be true for msys */
262732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang#define MAP_FAILED  0
263732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang#define MREMAP_FIXED  2  /* the value in linux, though it doesn't really matter */
264acf6039a23382f18c35f6b487d90d53cb67b5858Mindy Pereira/* These, when combined with the mmap invariants below, yield the proper action */
265acf6039a23382f18c35f6b487d90d53cb67b5858Mindy Pereira#define PROT_READ      PAGE_READWRITE
266ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira#define PROT_WRITE     PAGE_READWRITE
267ae7e6a0786a2d890b77c783d7ac39a90523b8154mindyp#define MAP_ANONYMOUS  MEM_RESERVE
268ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira#define MAP_PRIVATE    MEM_COMMIT
26900ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira#define MAP_SHARED     MEM_RESERVE   /* value of this #define is 100% arbitrary */
270ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira
271a831b2f1ba6d3c18d5e54563df8bae1f589c4257Mindy Pereira#if __STDC__ && !defined(__MINGW32__)
272edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlertypedef _off_t off_t;
273edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#endif
274edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
275edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler/* VirtualAlloc only replaces for mmap when certain invariants are kept. */
276edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline void *mmap(void *addr, size_t length, int prot, int flags,
277edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler                  int fd, off_t offset) {
278edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  if (addr == NULL && fd == -1 && offset == 0 &&
279edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler      prot == (PROT_READ|PROT_WRITE) && flags == (MAP_PRIVATE|MAP_ANONYMOUS)) {
280edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler    return VirtualAlloc(0, length, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
281edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  } else {
282edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler    return NULL;
283edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  }
284732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang}
285edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
286edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline int munmap(void *addr, size_t length) {
287edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  return VirtualFree(addr, 0, MEM_RELEASE) ? 0 : -1;
288edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler}
289edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#endif  /* HAVE_MMAP */
290edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
291edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler/* We could maybe use VirtualAlloc for sbrk as well, but no need */
292edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline void *sbrk(intptr_t increment) {
293edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  // sbrk returns -1 on failure
294edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  return (void*)-1;
295edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler}
296edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
297edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
298edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler/* ----------------------------------- STRING ROUTINES */
299edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
300edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler/*
301edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler * We can't just use _vsnprintf and _snprintf as drop-in-replacements,
302edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler * because they don't always NUL-terminate. :-(  We also can't use the
303edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler * name vsnprintf, since windows defines that (but not snprintf (!)).
304edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler */
305edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#if defined(_MSC_VER) && _MSC_VER >= 1400
306edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler/* We can use safe CRT functions, which the required functionality */
307edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline int perftools_vsnprintf(char *str, size_t size, const char *format,
308edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler                               va_list ap) {
309edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  return vsnprintf_s(str, size, _TRUNCATE, format, ap);
310edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler}
311edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#else
312edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline int perftools_vsnprintf(char *str, size_t size, const char *format,
313c92dc65f64e8b09ee78ba2fa799d7d3627373913Alan Lau                               va_list ap) {
314732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang  if (size == 0)        /* not even room for a \0? */
315732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    return -1;        /* not what C99 says to do, but what windows does */
3161bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang  str[size-1] = '\0';
3171bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang  return _vsnprintf(str, size-1, format, ap);
318edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler}
3191bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang#endif
3201bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang
3211bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang#ifndef HAVE_SNPRINTF
3221bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huanginline int snprintf(char *str, size_t size, const char *format, ...) {
3231bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang  va_list ap;
3241bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang  int r;
3251bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang  va_start(ap, format);
3261bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang  r = perftools_vsnprintf(str, size, format, ap);
3271bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang  va_end(ap);
3281bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang  return r;
3291bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang}
3301bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang#endif
3311bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang
3321bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang#define PRIx64  "I64x"
3331bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang#define SCNx64  "I64x"
3341bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang#define PRId64  "I64d"
3351bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang#define SCNd64  "I64d"
3361bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang#define PRIu64  "I64u"
3371bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang#ifdef _WIN64
3381bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang# define PRIuPTR "llu"
3391bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang# define PRIxPTR "llx"
3401bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang#else
3411bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang# define PRIuPTR "lu"
3421bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang# define PRIxPTR "lx"
3431bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang#endif
3441bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang
3451bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang/* ----------------------------------- FILE IO */
3461bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang
347c92dc65f64e8b09ee78ba2fa799d7d3627373913Alan Lau#ifndef PATH_MAX
3481bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang#define PATH_MAX 1024
3491bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang#endif
350f59d01c3116dc2adde97a5b52aa6094144c2d315Andrew Sapperstein#ifndef __MINGW32__
351edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerenum { STDIN_FILENO = 0, STDOUT_FILENO = 1, STDERR_FILENO = 2 };
352edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#endif
353d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy#ifndef O_RDONLY
354d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy#define O_RDONLY  _O_RDONLY
355479505d71969e26b0785d8e0e1b81108731cf827Mark Wei#endif
3560e29e769c74e385342fc5dc8e9c85517771aaa34James Lemieux
357edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#if __STDC__ && !defined(__MINGW32__)
358edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler/* These functions are considered non-standard */
359edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline int access(const char *pathname, int mode) {
360edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  return _access(pathname, mode);
361edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler}
362edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline int open(const char *pathname, int flags, int mode = 0) {
363edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  return _open(pathname, flags, mode);
364edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler}
365edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline int close(int fd) {
366edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  return _close(fd);
367edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler}
368edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline ssize_t read(int fd, void *buf, size_t count) {
369edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  return _read(fd, buf, count);
370edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler}
371edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline ssize_t write(int fd, const void *buf, size_t count) {
372edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  return _write(fd, buf, count);
373edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler}
374edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline off_t lseek(int fd, off_t offset, int whence) {
375edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  return _lseek(fd, offset, whence);
376edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler}
377edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline char *getcwd(char *buf, size_t size) {
378edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  return _getcwd(buf, size);
379edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler}
380edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline int mkdir(const char *pathname, int) {
381edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  return _mkdir(pathname);
382c92dc65f64e8b09ee78ba2fa799d7d3627373913Alan Lau}
383edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
384edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline FILE *popen(const char *command, const char *type) {
385edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  return _popen(command, type);
386edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler}
387edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline int pclose(FILE *stream) {
388edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  return _pclose(stream);
389edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler}
390edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#endif
391edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
392edd6c1a2807d2ade930dfd4622707298dc470d64Tony MantlerEXTERN_C PERFTOOLS_DLL_DECL void WriteToStderr(const char* buf, int len);
393edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
394edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler/* ----------------------------------- SYSTEM/PROCESS */
395edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
396edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlertypedef int pid_t;
397edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#if __STDC__ && !defined(__MINGW32__)
398edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline pid_t getpid(void) { return _getpid(); }
399edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#endif
400edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline pid_t getppid(void) { return 0; }
401edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
402edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler/* Handle case when poll is used to simulate sleep. */
403edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline int poll(struct pollfd* fds, int nfds, int timeout) {
404edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  assert(fds == NULL);
405edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  assert(nfds == 0);
406edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  Sleep(timeout);
407f59d01c3116dc2adde97a5b52aa6094144c2d315Andrew Sapperstein  return 0;
408c92dc65f64e8b09ee78ba2fa799d7d3627373913Alan Lau}
409edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
410edd6c1a2807d2ade930dfd4622707298dc470d64Tony MantlerEXTERN_C int getpagesize();   /* in port.cc */
411edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
412edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler/* ----------------------------------- OTHER */
413edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
414edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline void srandom(unsigned int seed) { srand(seed); }
415edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline long random(void) { return rand(); }
416edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline unsigned int sleep(unsigned int seconds) {
417edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  Sleep(seconds * 1000);
418edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  return 0;
419edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler}
420edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
421edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler// mingw64 seems to define timespec (though mingw.org mingw doesn't),
422edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler// protected by the _TIMESPEC_DEFINED macro.
423edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#ifndef _TIMESPEC_DEFINED
424edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerstruct timespec {
425edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  int tv_sec;
426edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  int tv_nsec;
427edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler};
428edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#endif
429edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
430edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline int nanosleep(const struct timespec *req, struct timespec *rem) {
431edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  Sleep(req->tv_sec * 1000 + req->tv_nsec / 1000000);
432edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  return 0;
433edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler}
434edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
435edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#ifndef __MINGW32__
436edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#if _MSC_VER < 1800  // Not required >= VS2013.
437edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline long long int strtoll(const char *nptr, char **endptr, int base) {
438edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler    return _strtoi64(nptr, endptr, base);
439edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler}
440edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline unsigned long long int strtoull(const char *nptr, char **endptr,
441edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler                                       int base) {
442edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler    return _strtoui64(nptr, endptr, base);
443edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler}
444edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline long long int strtoq(const char *nptr, char **endptr, int base) {
445edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler    return _strtoi64(nptr, endptr, base);
446edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler}
447edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#endif
448edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline unsigned long long int strtouq(const char *nptr, char **endptr,
449edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler                                      int base) {
450edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler    return _strtoui64(nptr, endptr, base);
451edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler}
452edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerinline long long atoll(const char *nptr) {
453edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler  return _atoi64(nptr);
454edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler}
455edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#endif
456edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
457edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#define __THROW throw()
458edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
459edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler/* ----------------------------------- TCMALLOC-SPECIFIC */
460edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
461edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler/* tcmalloc.cc calls this so we can patch VirtualAlloc() et al. */
462edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantlerextern void PatchWindowsFunctions();
463edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
464edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler// ----------------------------------- BUILD-SPECIFIC
465edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
466edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler/*
467edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler * windows/port.h defines compatibility APIs for several .h files, which
468edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler * we therefore shouldn't be #including directly.  This hack keeps us from
469edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler * doing so.  TODO(csilvers): do something more principled.
470edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler */
471edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#define GOOGLE_MAYBE_THREADS_H_ 1
472edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
473edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
474edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#endif  /* _WIN32 */
475edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
476edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#undef inline
477edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#undef EXTERN_C
478edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler
479edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler#endif  /* GOOGLE_BASE_WINDOWS_H_ */
480edd6c1a2807d2ade930dfd4622707298dc470d64Tony Mantler