1179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Use of this source code is governed by a BSD-style license that can be 3179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// found in the LICENSE file. See the AUTHORS file for names of contributors. 4179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// 5179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// This file contains the specification, but not the implementations, 6179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// of the types/operations/etc. that should be defined by a platform 7179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// specific port_<platform>.h file. Use this file as a reference for 8179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// how to port this package to a new platform. 9179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 10179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#ifndef STORAGE_LEVELDB_PORT_PORT_EXAMPLE_H_ 11179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#define STORAGE_LEVELDB_PORT_PORT_EXAMPLE_H_ 12179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 13179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgnamespace leveldb { 14179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgnamespace port { 15179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 16179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// TODO(jorlow): Many of these belong more in the environment class rather than 17179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// here. We should try moving them and see if it affects perf. 18179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 19179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// The following boolean constant must be true on a little-endian machine 20179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// and false otherwise. 21179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstatic const bool kLittleEndian = true /* or some other expression */; 22179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 23179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// ------------------ Threading ------------------- 24179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 25179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// A Mutex represents an exclusive lock. 26179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgclass Mutex { 27179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org public: 28179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Mutex(); 29179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ~Mutex(); 30179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 31179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Lock the mutex. Waits until other lockers have exited. 32179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Will deadlock if the mutex is already locked by this thread. 33179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org void Lock(); 34179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 35179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Unlock the mutex. 36179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // REQUIRES: This mutex was locked by this thread. 37179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org void Unlock(); 38179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 39179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Optionally crash if this thread does not hold this mutex. 40179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // The implementation must be fast, especially if NDEBUG is 41179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // defined. The implementation is allowed to skip all checks. 42179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org void AssertHeld(); 43179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}; 44179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 45179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgclass CondVar { 46179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org public: 47179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org explicit CondVar(Mutex* mu); 48179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ~CondVar(); 49179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 50179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Atomically release *mu and block on this condition variable until 51179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // either a call to SignalAll(), or a call to Signal() that picks 52179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // this thread to wakeup. 53179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // REQUIRES: this thread holds *mu 54179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org void Wait(); 55179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 56179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // If there are some threads waiting, wake up at least one of them. 57179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org void Signal(); 58179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 59179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Wake up all waiting threads. 60179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org void SignallAll(); 61179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}; 62179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 63158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com// Thread-safe initialization. 64158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com// Used as follows: 65158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com// static port::OnceType init_control = LEVELDB_ONCE_INIT; 66158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com// static void Initializer() { ... do something ...; } 67158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com// ... 68158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com// port::InitOnce(&init_control, &Initializer); 69158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.comtypedef intptr_t OnceType; 70158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com#define LEVELDB_ONCE_INIT 0 71158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.comextern void InitOnce(port::OnceType*, void (*initializer)()); 72158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com 73179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// A type that holds a pointer that can be read or written atomically 74179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// (i.e., without word-tearing.) 75179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgclass AtomicPointer { 76179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org private: 77179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org intptr_t rep_; 78179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org public: 79179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Initialize to arbitrary value 80179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org AtomicPointer(); 81179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 82179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Initialize to hold v 83179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org explicit AtomicPointer(void* v) : rep_(v) { } 84179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 85179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Read and return the stored pointer with the guarantee that no 86179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // later memory access (read or write) by this thread can be 87179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // reordered ahead of this read. 88179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org void* Acquire_Load() const; 89179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 90179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Set v as the stored pointer with the guarantee that no earlier 91179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // memory access (read or write) by this thread can be reordered 92179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // after this store. 93179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org void Release_Store(void* v); 94179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 95179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Read the stored pointer with no ordering guarantees. 96179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org void* NoBarrier_Load() const; 97179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 98179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Set va as the stored pointer with no ordering guarantees. 99179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org void NoBarrier_Store(void* v); 100179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}; 101179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 102179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// ------------------ Compression ------------------- 103179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 10407f3bcfb9764be2a339cc02cf0a0d6edb151defbjorlow@chromium.org// Store the snappy compression of "input[0,input_length-1]" in *output. 10507f3bcfb9764be2a339cc02cf0a0d6edb151defbjorlow@chromium.org// Returns false if snappy is not supported by this port. 10607f3bcfb9764be2a339cc02cf0a0d6edb151defbjorlow@chromium.orgextern bool Snappy_Compress(const char* input, size_t input_length, 10707f3bcfb9764be2a339cc02cf0a0d6edb151defbjorlow@chromium.org std::string* output); 108179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 109f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com// If input[0,input_length-1] looks like a valid snappy compressed 110f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com// buffer, store the size of the uncompressed data in *result and 111f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com// return true. Else return false. 112f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.comextern bool Snappy_GetUncompressedLength(const char* input, size_t length, 113f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com size_t* result); 114f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com 11507f3bcfb9764be2a339cc02cf0a0d6edb151defbjorlow@chromium.org// Attempt to snappy uncompress input[0,input_length-1] into *output. 116179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Returns true if successful, false if the input is invalid lightweight 117179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// compressed data. 118f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com// 119f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com// REQUIRES: at least the first "n" bytes of output[] must be writable 120f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com// where "n" is the result of a successful call to 121f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com// Snappy_GetUncompressedLength. 12207f3bcfb9764be2a339cc02cf0a0d6edb151defbjorlow@chromium.orgextern bool Snappy_Uncompress(const char* input_data, size_t input_length, 123f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com char* output); 124179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 125179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// ------------------ Miscellaneous ------------------- 126179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 127179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// If heap profiling is not supported, returns false. 128179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Else repeatedly calls (*func)(arg, data, n) and then returns true. 129179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// The concatenation of all "data[0,n-1]" fragments is the heap profile. 130179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgextern bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg); 131179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 13245b9940be332834440bd5299419f396e38085ebehans@chromium.org} // namespace port 13345b9940be332834440bd5299419f396e38085ebehans@chromium.org} // namespace leveldb 134179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 135179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#endif // STORAGE_LEVELDB_PORT_PORT_EXAMPLE_H_ 136