github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/database/leveldb.chai2010/include/port/port_windows.h (about) 1 // LevelDB Copyright (c) 2011 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 // See port_example.h for documentation for the following types/functions. 6 7 // Redistribution and use in source and binary forms, with or without 8 // modification, are permitted provided that the following conditions are met: 9 // 10 // * Redistributions of source code must retain the above copyright 11 // notice, this list of conditions and the following disclaimer. 12 // * Redistributions in binary form must reproduce the above copyright 13 // notice, this list of conditions and the following disclaimer in the 14 // documentation and/or other materials provided with the distribution. 15 // * Neither the name of the University of California, Berkeley nor the 16 // names of its contributors may be used to endorse or promote products 17 // derived from this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY 20 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 // DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 23 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 // 30 31 #ifndef STORAGE_LEVELDB_PORT_PORT_WINDOWS_H_ 32 #define STORAGE_LEVELDB_PORT_PORT_WINDOWS_H_ 33 34 #if defined(_MSC_VER) 35 #include <BaseTsd.h> 36 typedef SSIZE_T ssize_t; 37 #define snprintf _snprintf 38 #endif 39 40 #ifdef SNAPPY 41 #include <snappy.h> 42 #endif 43 44 #include <windows.h> 45 // Undo various #define in windows headers that interfere with the code 46 #ifdef min 47 #undef min 48 #endif 49 #ifdef small 50 #undef small 51 #endif 52 #ifdef DeleteFile 53 #undef DeleteFile 54 #endif 55 56 #include <string> 57 58 #include <stdint.h> 59 60 namespace leveldb { 61 namespace port { 62 63 // Windows is little endian (for now :p) 64 static const bool kLittleEndian = true; 65 66 // based on lock_impl_win.cc from chrome: 67 // http://src.chromium.org/viewvc/chrome/trunk/src/base/synchronization/lock_impl_win.cc?revision=70363&view=markup 68 class Mutex { 69 public: 70 Mutex() { 71 // The second parameter is the spin count, for short-held locks it avoid the 72 // contending thread from going to sleep which helps performance greatly. 73 ::InitializeCriticalSectionAndSpinCount(&os_lock_, 2000); 74 } 75 76 ~Mutex(){ 77 ::DeleteCriticalSection(&os_lock_); 78 } 79 80 void Lock() { 81 ::EnterCriticalSection(&os_lock_); 82 } 83 84 void Unlock() { 85 ::LeaveCriticalSection(&os_lock_); 86 } 87 88 void AssertHeld() { } 89 90 private: 91 CRITICAL_SECTION os_lock_; 92 93 // No copying 94 Mutex(const Mutex&); 95 void operator=(const Mutex&); 96 }; 97 98 // based on condition_variable_win.cc from chrome: 99 // http://src.chromium.org/viewvc/chrome/trunk/src/base/synchronization/condition_variable_win.cc?revision=70363&view=markup 100 class CondVar { 101 public: 102 explicit CondVar(Mutex* user_lock); 103 ~CondVar(); 104 105 void Wait() { 106 // Default to "wait forever" timing, which means have to get a Signal() 107 // or SignalAll() to come out of this wait state. 108 TimedWait(INFINITE); 109 } 110 111 void TimedWait(const int64_t max_time_in_ms); 112 void Signal(); 113 void SignalAll(); 114 private: 115 // Define Event class that is used to form circularly linked lists. 116 // The list container is an element with NULL as its handle_ value. 117 // The actual list elements have a non-zero handle_ value. 118 // All calls to methods MUST be done under protection of a lock so that links 119 // can be validated. Without the lock, some links might asynchronously 120 // change, and the assertions would fail (as would list change operations). 121 class Event { 122 public: 123 // Default constructor with no arguments creates a list container. 124 Event(); 125 ~Event(); 126 127 // InitListElement transitions an instance from a container, to an element. 128 void InitListElement(); 129 130 // Methods for use on lists. 131 bool IsEmpty() const; 132 void PushBack(Event* other); 133 Event* PopFront(); 134 Event* PopBack(); 135 136 // Methods for use on list elements. 137 // Accessor method. 138 HANDLE handle() const; 139 // Pull an element from a list (if it's in one). 140 Event* Extract(); 141 142 // Method for use on a list element or on a list. 143 bool IsSingleton() const; 144 145 private: 146 // Provide pre/post conditions to validate correct manipulations. 147 bool ValidateAsDistinct(Event* other) const; 148 bool ValidateAsItem() const; 149 bool ValidateAsList() const; 150 bool ValidateLinks() const; 151 152 HANDLE handle_; 153 Event* next_; 154 Event* prev_; 155 //DISALLOW_COPY_AND_ASSIGN(Event); 156 }; 157 158 // Note that RUNNING is an unlikely number to have in RAM by accident. 159 // This helps with defensive destructor coding in the face of user error. 160 enum RunState { SHUTDOWN = 0, RUNNING = 64213 }; 161 162 // Internal implementation methods supporting Wait(). 163 Event* GetEventForWaiting(); 164 void RecycleEvent(Event* used_event); 165 166 RunState run_state_; 167 168 // Private critical section for access to member data. 169 Mutex internal_lock_; 170 171 // Lock that is acquired before calling Wait(). 172 Mutex& user_lock_; 173 174 // Events that threads are blocked on. 175 Event waiting_list_; 176 177 // Free list for old events. 178 Event recycling_list_; 179 int recycling_list_size_; 180 181 // The number of allocated, but not yet deleted events. 182 int allocation_counter_; 183 }; 184 185 // Storage for a lock-free pointer 186 class AtomicPointer { 187 private: 188 void * rep_; 189 public: 190 AtomicPointer() : rep_(NULL) { } 191 explicit AtomicPointer(void* v) { 192 Release_Store(v); 193 } 194 void* Acquire_Load() const { 195 void * p = NULL; 196 InterlockedExchangePointer(&p, rep_); 197 return p; 198 } 199 200 void Release_Store(void* v) { 201 InterlockedExchangePointer(&rep_, v); 202 } 203 204 void* NoBarrier_Load() const { 205 return rep_; 206 } 207 208 void NoBarrier_Store(void* v) { 209 rep_ = v; 210 } 211 }; 212 213 typedef volatile long OnceType; 214 #define LEVELDB_ONCE_INIT (0) 215 extern void InitOnce(OnceType* once, void (*initializer)()); 216 217 inline bool Snappy_Compress(const char* input, size_t length, 218 ::std::string* output) { 219 #ifdef SNAPPY 220 output->resize(snappy::MaxCompressedLength(length)); 221 size_t outlen; 222 snappy::RawCompress(input, length, &(*output)[0], &outlen); 223 output->resize(outlen); 224 return true; 225 #endif 226 227 return false; 228 } 229 230 inline bool Snappy_GetUncompressedLength(const char* input, size_t length, 231 size_t* result) { 232 #ifdef SNAPPY 233 return snappy::GetUncompressedLength(input, length, result); 234 #else 235 return false; 236 #endif 237 } 238 239 inline bool Snappy_Uncompress(const char* input, size_t length, 240 char* output) { 241 #ifdef SNAPPY 242 return snappy::RawUncompress(input, length, output); 243 #else 244 return false; 245 #endif 246 } 247 248 inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) { 249 return false; 250 } 251 252 } 253 } 254 255 #endif // STORAGE_LEVELDB_PORT_PORT_WINDOWS_H_