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
Lock()55 void Lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.lock(); }
Unlock()56 void Unlock() UNLOCK_FUNCTION() { mu_.unlock(); }
AssertHeld()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:
CondVar(Mutex * mu)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
Wait()73 void Wait() {
74 std::unique_lock<std::mutex> lock(mu_->mu_, std::adopt_lock);
75 cv_.wait(lock);
76 lock.release();
77 }
Signal()78 void Signal() { cv_.notify_one(); }
SignalAll()79 void SignalAll() { cv_.notify_all(); }
80
81 private:
82 std::condition_variable cv_;
83 Mutex* const mu_;
84 };
85
Snappy_Compress(const char * input,size_t length,std::string * output)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
Snappy_GetUncompressedLength(const char * input,size_t length,size_t * result)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
Snappy_Uncompress(const char * input,size_t length,char * output)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
GetHeapProfile(void (* func)(void *,const char *,int),void * arg)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
AcceleratedCRC32C(uint32_t crc,const char * buf,size_t size)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