port_posix.h 5.9 KB
Newer Older
1
//  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
S
Siying Dong 已提交
2 3 4
//  This source code is licensed under both the GPLv2 (found in the
//  COPYING file in the root directory) and Apache 2.0 License
//  (found in the LICENSE.Apache file in the root directory).
5
//
J
jorlow@chromium.org 已提交
6 7 8 9 10 11
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.
//
// See port_example.h for documentation for the following types/functions.

12
#pragma once
J
jorlow@chromium.org 已提交
13

D
Dmitri Smirnov 已提交
14
#include <thread>
15 16 17

#include "rocksdb/rocksdb_namespace.h"

S
sdong 已提交
18 19
// size_t printf formatting named in the manner of C99 standard formatting
// strings such as PRIu64
D
Dmitri Smirnov 已提交
20 21 22
// in fact, we could use that one
#define ROCKSDB_PRIszt "zu"

D
Dmitri Smirnov 已提交
23 24
#define __declspec(S)

D
Dmitri Smirnov 已提交
25
#define ROCKSDB_NOEXCEPT noexcept
26

H
heyongqiang 已提交
27
#undef PLATFORM_IS_LITTLE_ENDIAN
28
#if defined(OS_MACOSX)
29
  #include <machine/endian.h>
H
heyongqiang 已提交
30 31 32 33
  #if defined(__DARWIN_LITTLE_ENDIAN) && defined(__DARWIN_BYTE_ORDER)
    #define PLATFORM_IS_LITTLE_ENDIAN \
        (__DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN)
  #endif
34 35 36
#elif defined(OS_SOLARIS)
  #include <sys/isa_defs.h>
  #ifdef _LITTLE_ENDIAN
H
heyongqiang 已提交
37
    #define PLATFORM_IS_LITTLE_ENDIAN true
38
  #else
H
heyongqiang 已提交
39
    #define PLATFORM_IS_LITTLE_ENDIAN false
40
  #endif
T
Tomas Kolda 已提交
41 42 43 44 45 46
  #include <alloca.h>
#elif defined(OS_AIX)
  #include <sys/types.h>
  #include <arpa/nameser_compat.h>
  #define PLATFORM_IS_LITTLE_ENDIAN (BYTE_ORDER == LITTLE_ENDIAN)
  #include <alloca.h>
I
Islam AbdelRahman 已提交
47 48
#elif defined(OS_FREEBSD) || defined(OS_OPENBSD) || defined(OS_NETBSD) || \
    defined(OS_DRAGONFLYBSD) || defined(OS_ANDROID)
I
Islam AbdelRahman 已提交
49 50 51
  #include <sys/endian.h>
  #include <sys/types.h>
  #define PLATFORM_IS_LITTLE_ENDIAN (_BYTE_ORDER == _LITTLE_ENDIAN)
52 53 54
#else
  #include <endian.h>
#endif
J
jorlow@chromium.org 已提交
55
#include <pthread.h>
A
Albert Strasheim 已提交
56

J
jorlow@chromium.org 已提交
57
#include <stdint.h>
H
heyongqiang 已提交
58
#include <string.h>
59 60
#include <limits>
#include <string>
61

H
heyongqiang 已提交
62 63
#ifndef PLATFORM_IS_LITTLE_ENDIAN
#define PLATFORM_IS_LITTLE_ENDIAN (__BYTE_ORDER == __LITTLE_ENDIAN)
64 65
#endif

66
#if defined(OS_MACOSX) || defined(OS_SOLARIS) || defined(OS_FREEBSD) ||\
H
heyongqiang 已提交
67
    defined(OS_NETBSD) || defined(OS_OPENBSD) || defined(OS_DRAGONFLYBSD) ||\
T
Tomas Kolda 已提交
68
    defined(OS_ANDROID) || defined(CYGWIN) || defined(OS_AIX)
69
// Use fread/fwrite/fflush on platforms without _unlocked variants
70 71 72 73 74
#define fread_unlocked fread
#define fwrite_unlocked fwrite
#define fflush_unlocked fflush
#endif

75 76 77
#if defined(OS_MACOSX) || defined(OS_FREEBSD) ||\
    defined(OS_OPENBSD) || defined(OS_DRAGONFLYBSD)
// Use fsync() on platforms without fdatasync()
78 79
#define fdatasync fsync
#endif
J
jorlow@chromium.org 已提交
80

H
heyongqiang 已提交
81 82
#if defined(OS_ANDROID) && __ANDROID_API__ < 9
// fdatasync() was only introduced in API level 9 on Android. Use fsync()
C
charsyam 已提交
83
// when targeting older platforms.
H
heyongqiang 已提交
84 85 86
#define fdatasync fsync
#endif

87
namespace ROCKSDB_NAMESPACE {
88 89 90

extern const bool kDefaultToAdaptiveMutex;

J
jorlow@chromium.org 已提交
91 92
namespace port {

93
// For use at db/file_indexer.h kLevelMaxIndex
94
const uint32_t kMaxUint32 = std::numeric_limits<uint32_t>::max();
95
const int kMaxInt32 = std::numeric_limits<int32_t>::max();
Z
Zhongyi Xie 已提交
96
const int kMinInt32 = std::numeric_limits<int32_t>::min();
97
const uint64_t kMaxUint64 = std::numeric_limits<uint64_t>::max();
98
const int64_t kMaxInt64 = std::numeric_limits<int64_t>::max();
Z
Zhongyi Xie 已提交
99
const int64_t kMinInt64 = std::numeric_limits<int64_t>::min();
100
const size_t kMaxSizet = std::numeric_limits<size_t>::max();
101

102
constexpr bool kLittleEndian = PLATFORM_IS_LITTLE_ENDIAN;
H
heyongqiang 已提交
103
#undef PLATFORM_IS_LITTLE_ENDIAN
J
jorlow@chromium.org 已提交
104 105 106 107 108

class CondVar;

class Mutex {
 public:
109
  explicit Mutex(bool adaptive = kDefaultToAdaptiveMutex);
110 111 112 113
  // No copying
  Mutex(const Mutex&) = delete;
  void operator=(const Mutex&) = delete;

J
jorlow@chromium.org 已提交
114 115 116 117
  ~Mutex();

  void Lock();
  void Unlock();
118 119
  // this will assert if the mutex is not locked
  // it does NOT verify that mutex is held by a calling thread
I
Igor Canadi 已提交
120
  void AssertHeld();
J
jorlow@chromium.org 已提交
121 122 123 124

 private:
  friend class CondVar;
  pthread_mutex_t mu_;
I
Igor Canadi 已提交
125
#ifndef NDEBUG
126
  bool locked_;
I
Igor Canadi 已提交
127
#endif
J
jorlow@chromium.org 已提交
128 129
};

130 131 132
class RWMutex {
 public:
  RWMutex();
133 134 135 136
  // No copying allowed
  RWMutex(const RWMutex&) = delete;
  void operator=(const RWMutex&) = delete;

137 138 139 140
  ~RWMutex();

  void ReadLock();
  void WriteLock();
141 142
  void ReadUnlock();
  void WriteUnlock();
143 144 145 146 147 148
  void AssertHeld() { }

 private:
  pthread_rwlock_t mu_; // the underlying platform mutex
};

J
jorlow@chromium.org 已提交
149 150 151 152 153
class CondVar {
 public:
  explicit CondVar(Mutex* mu);
  ~CondVar();
  void Wait();
154 155
  // Timed condition wait.  Returns true if timeout occurred.
  bool TimedWait(uint64_t abs_time_us);
J
jorlow@chromium.org 已提交
156 157 158 159 160 161 162
  void Signal();
  void SignalAll();
 private:
  pthread_cond_t cv_;
  Mutex* mu_;
};

D
Dmitri Smirnov 已提交
163 164
using Thread = std::thread;

165 166 167 168 169 170 171 172 173 174 175 176 177 178
static inline void AsmVolatilePause() {
#if defined(__i386__) || defined(__x86_64__)
  asm volatile("pause");
#elif defined(__aarch64__)
  asm volatile("wfe");
#elif defined(__powerpc64__)
  asm volatile("or 27,27,27");
#endif
  // it's okay for other platforms to be no-ops
}

// Returns -1 if not available on this platform
extern int PhysicalCoreID();

H
heyongqiang 已提交
179 180 181 182
typedef pthread_once_t OnceType;
#define LEVELDB_ONCE_INIT PTHREAD_ONCE_INIT
extern void InitOnce(OnceType* once, void (*initializer)());

183
#ifndef CACHE_LINE_SIZE
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
// To test behavior with non-native cache line size, e.g. for
// Bloom filters, set TEST_CACHE_LINE_SIZE to the desired test size.
// This disables ALIGN_AS to keep it from failing compilation.
#ifdef TEST_CACHE_LINE_SIZE
#define CACHE_LINE_SIZE TEST_CACHE_LINE_SIZE
#define ALIGN_AS(n) /*empty*/
#else
#if defined(__s390__)
#define CACHE_LINE_SIZE 256U
#elif defined(__powerpc__) || defined(__aarch64__)
#define CACHE_LINE_SIZE 128U
#else
#define CACHE_LINE_SIZE 64U
#endif
#define ALIGN_AS(n) alignas(n)
#endif
200
#endif
L
Lei Jin 已提交
201

202 203
static_assert((CACHE_LINE_SIZE & (CACHE_LINE_SIZE - 1)) == 0,
              "Cache line size must be a power of 2 number of bytes");
204 205 206 207 208

extern void *cacheline_aligned_alloc(size_t size);

extern void cacheline_aligned_free(void *memblock);

209 210
#define PREFETCH(addr, rw, locality) __builtin_prefetch(addr, rw, locality)

211
extern void Crash(const std::string& srcfile, int srcline);
I
Igor Canadi 已提交
212 213 214

extern int GetMaxOpenFiles();

215 216
extern const size_t kPageSize;

217
} // namespace port
218
}  // namespace ROCKSDB_NAMESPACE