Home | History | Annotate | Download | only in port
      1 // 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 // This file contains the specification, but not the implementations,
      6 // of the types/operations/etc. that should be defined by a platform
      7 // specific port_<platform>.h file.  Use this file as a reference for
      8 // how to port this package to a new platform.
      9 
     10 #ifndef STORAGE_LEVELDB_PORT_PORT_EXAMPLE_H_
     11 #define STORAGE_LEVELDB_PORT_PORT_EXAMPLE_H_
     12 
     13 namespace leveldb {
     14 namespace port {
     15 
     16 // TODO(jorlow): Many of these belong more in the environment class rather than
     17 //               here. We should try moving them and see if it affects perf.
     18 
     19 // The following boolean constant must be true on a little-endian machine
     20 // and false otherwise.
     21 static const bool kLittleEndian = true /* or some other expression */;
     22 
     23 // ------------------ Threading -------------------
     24 
     25 // A Mutex represents an exclusive lock.
     26 class Mutex {
     27  public:
     28   Mutex();
     29   ~Mutex();
     30 
     31   // Lock the mutex.  Waits until other lockers have exited.
     32   // Will deadlock if the mutex is already locked by this thread.
     33   void Lock();
     34 
     35   // Unlock the mutex.
     36   // REQUIRES: This mutex was locked by this thread.
     37   void Unlock();
     38 
     39   // Optionally crash if this thread does not hold this mutex.
     40   // The implementation must be fast, especially if NDEBUG is
     41   // defined.  The implementation is allowed to skip all checks.
     42   void AssertHeld();
     43 };
     44 
     45 class CondVar {
     46  public:
     47   explicit CondVar(Mutex* mu);
     48   ~CondVar();
     49 
     50   // Atomically release *mu and block on this condition variable until
     51   // either a call to SignalAll(), or a call to Signal() that picks
     52   // this thread to wakeup.
     53   // REQUIRES: this thread holds *mu
     54   void Wait();
     55 
     56   // If there are some threads waiting, wake up at least one of them.
     57   void Signal();
     58 
     59   // Wake up all waiting threads.
     60   void SignallAll();
     61 };
     62 
     63 // Thread-safe initialization.
     64 // Used as follows:
     65 //      static port::OnceType init_control = LEVELDB_ONCE_INIT;
     66 //      static void Initializer() { ... do something ...; }
     67 //      ...
     68 //      port::InitOnce(&init_control, &Initializer);
     69 typedef intptr_t OnceType;
     70 #define LEVELDB_ONCE_INIT 0
     71 extern void InitOnce(port::OnceType*, void (*initializer)());
     72 
     73 // A type that holds a pointer that can be read or written atomically
     74 // (i.e., without word-tearing.)
     75 class AtomicPointer {
     76  private:
     77   intptr_t rep_;
     78  public:
     79   // Initialize to arbitrary value
     80   AtomicPointer();
     81 
     82   // Initialize to hold v
     83   explicit AtomicPointer(void* v) : rep_(v) { }
     84 
     85   // Read and return the stored pointer with the guarantee that no
     86   // later memory access (read or write) by this thread can be
     87   // reordered ahead of this read.
     88   void* Acquire_Load() const;
     89 
     90   // Set v as the stored pointer with the guarantee that no earlier
     91   // memory access (read or write) by this thread can be reordered
     92   // after this store.
     93   void Release_Store(void* v);
     94 
     95   // Read the stored pointer with no ordering guarantees.
     96   void* NoBarrier_Load() const;
     97 
     98   // Set va as the stored pointer with no ordering guarantees.
     99   void NoBarrier_Store(void* v);
    100 };
    101 
    102 // ------------------ Compression -------------------
    103 
    104 // Store the snappy compression of "input[0,input_length-1]" in *output.
    105 // Returns false if snappy is not supported by this port.
    106 extern bool Snappy_Compress(const char* input, size_t input_length,
    107                             std::string* output);
    108 
    109 // If input[0,input_length-1] looks like a valid snappy compressed
    110 // buffer, store the size of the uncompressed data in *result and
    111 // return true.  Else return false.
    112 extern bool Snappy_GetUncompressedLength(const char* input, size_t length,
    113                                          size_t* result);
    114 
    115 // Attempt to snappy uncompress input[0,input_length-1] into *output.
    116 // Returns true if successful, false if the input is invalid lightweight
    117 // compressed data.
    118 //
    119 // REQUIRES: at least the first "n" bytes of output[] must be writable
    120 // where "n" is the result of a successful call to
    121 // Snappy_GetUncompressedLength.
    122 extern bool Snappy_Uncompress(const char* input_data, size_t input_length,
    123                               char* output);
    124 
    125 // ------------------ Miscellaneous -------------------
    126 
    127 // If heap profiling is not supported, returns false.
    128 // Else repeatedly calls (*func)(arg, data, n) and then returns true.
    129 // The concatenation of all "data[0,n-1]" fragments is the heap profile.
    130 extern bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg);
    131 
    132 }  // namespace port
    133 }  // namespace leveldb
    134 
    135 #endif  // STORAGE_LEVELDB_PORT_PORT_EXAMPLE_H_
    136