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_