1 | // Copyright (c) 2018 The LevelDB Authors. All rights reserved. |
2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. |
4 | |
5 | #ifndef STORAGE_LEVELDB_PORT_PORT_STDCXX_H_ |
6 | #define STORAGE_LEVELDB_PORT_PORT_STDCXX_H_ |
7 | |
8 | // port/port_config.h availability is automatically detected via __has_include |
9 | // in newer compilers. If LEVELDB_HAS_PORT_CONFIG_H is defined, it overrides the |
10 | // configuration detection. |
11 | #if defined(LEVELDB_HAS_PORT_CONFIG_H) |
12 | |
13 | #if LEVELDB_HAS_PORT_CONFIG_H |
14 | #include "port/port_config.h" |
15 | #endif // LEVELDB_HAS_PORT_CONFIG_H |
16 | |
17 | #elif defined(__has_include) |
18 | |
19 | #if __has_include("port/port_config.h") |
20 | #include "port/port_config.h" |
21 | #endif // __has_include("port/port_config.h") |
22 | |
23 | #endif // defined(LEVELDB_HAS_PORT_CONFIG_H) |
24 | |
25 | #if HAVE_CRC32C |
26 | #include <crc32c/crc32c.h> |
27 | #endif // HAVE_CRC32C |
28 | #if HAVE_SNAPPY |
29 | #include <snappy.h> |
30 | #endif // HAVE_SNAPPY |
31 | |
32 | #include <cassert> |
33 | #include <condition_variable> // NOLINT |
34 | #include <cstddef> |
35 | #include <cstdint> |
36 | #include <mutex> // NOLINT |
37 | #include <string> |
38 | |
39 | #include "port/thread_annotations.h" |
40 | |
41 | namespace leveldb { |
42 | namespace port { |
43 | |
44 | class CondVar; |
45 | |
46 | // Thinly wraps std::mutex. |
47 | class LOCKABLE Mutex { |
48 | public: |
49 | Mutex() = default; |
50 | ~Mutex() = default; |
51 | |
52 | Mutex(const Mutex&) = delete; |
53 | Mutex& operator=(const Mutex&) = delete; |
54 | |
55 | void Lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.lock(); } |
56 | void Unlock() UNLOCK_FUNCTION() { mu_.unlock(); } |
57 | void AssertHeld() ASSERT_EXCLUSIVE_LOCK() {} |
58 | |
59 | private: |
60 | friend class CondVar; |
61 | std::mutex mu_; |
62 | }; |
63 | |
64 | // Thinly wraps std::condition_variable. |
65 | class CondVar { |
66 | public: |
67 | explicit CondVar(Mutex* mu) : mu_(mu) { assert(mu != nullptr); } |
68 | ~CondVar() = default; |
69 | |
70 | CondVar(const CondVar&) = delete; |
71 | CondVar& operator=(const CondVar&) = delete; |
72 | |
73 | void Wait() { |
74 | std::unique_lock<std::mutex> lock(mu_->mu_, std::adopt_lock); |
75 | cv_.wait(lock); |
76 | lock.release(); |
77 | } |
78 | void Signal() { cv_.notify_one(); } |
79 | void SignalAll() { cv_.notify_all(); } |
80 | |
81 | private: |
82 | std::condition_variable cv_; |
83 | Mutex* const mu_; |
84 | }; |
85 | |
86 | inline bool Snappy_Compress(const char* input, size_t length, |
87 | std::string* output) { |
88 | #if HAVE_SNAPPY |
89 | output->resize(snappy::MaxCompressedLength(length)); |
90 | size_t outlen; |
91 | snappy::RawCompress(input, length, &(*output)[0], &outlen); |
92 | output->resize(outlen); |
93 | return true; |
94 | #else |
95 | // Silence compiler warnings about unused arguments. |
96 | (void)input; |
97 | (void)length; |
98 | (void)output; |
99 | #endif // HAVE_SNAPPY |
100 | |
101 | return false; |
102 | } |
103 | |
104 | inline bool Snappy_GetUncompressedLength(const char* input, size_t length, |
105 | size_t* result) { |
106 | #if HAVE_SNAPPY |
107 | return snappy::GetUncompressedLength(input, length, result); |
108 | #else |
109 | // Silence compiler warnings about unused arguments. |
110 | (void)input; |
111 | (void)length; |
112 | (void)result; |
113 | return false; |
114 | #endif // HAVE_SNAPPY |
115 | } |
116 | |
117 | inline bool Snappy_Uncompress(const char* input, size_t length, char* output) { |
118 | #if HAVE_SNAPPY |
119 | return snappy::RawUncompress(input, length, output); |
120 | #else |
121 | // Silence compiler warnings about unused arguments. |
122 | (void)input; |
123 | (void)length; |
124 | (void)output; |
125 | return false; |
126 | #endif // HAVE_SNAPPY |
127 | } |
128 | |
129 | inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) { |
130 | // Silence compiler warnings about unused arguments. |
131 | (void)func; |
132 | (void)arg; |
133 | return false; |
134 | } |
135 | |
136 | inline uint32_t AcceleratedCRC32C(uint32_t crc, const char* buf, size_t size) { |
137 | #if HAVE_CRC32C |
138 | return ::crc32c::Extend(crc, reinterpret_cast<const uint8_t*>(buf), size); |
139 | #else |
140 | // Silence compiler warnings about unused arguments. |
141 | (void)crc; |
142 | (void)buf; |
143 | (void)size; |
144 | return 0; |
145 | #endif // HAVE_CRC32C |
146 | } |
147 | |
148 | } // namespace port |
149 | } // namespace leveldb |
150 | |
151 | #endif // STORAGE_LEVELDB_PORT_PORT_STDCXX_H_ |
152 | |