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// See port_example.h for documentation for the following types/functions.
6
7#ifndef STORAGE_LEVELDB_PORT_PORT_POSIX_H_
8#define STORAGE_LEVELDB_PORT_PORT_POSIX_H_
9
10#undef PLATFORM_IS_LITTLE_ENDIAN
11#if defined(OS_MACOSX)
12  #include <machine/endian.h>
13  #if defined(__DARWIN_LITTLE_ENDIAN) && defined(__DARWIN_BYTE_ORDER)
14    #define PLATFORM_IS_LITTLE_ENDIAN \
15        (__DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN)
16  #endif
17#elif defined(OS_SOLARIS)
18  #include <sys/isa_defs.h>
19  #ifdef _LITTLE_ENDIAN
20    #define PLATFORM_IS_LITTLE_ENDIAN true
21  #else
22    #define PLATFORM_IS_LITTLE_ENDIAN false
23  #endif
24#elif defined(OS_FREEBSD)
25  #include <sys/types.h>
26  #include <sys/endian.h>
27  #define PLATFORM_IS_LITTLE_ENDIAN (_BYTE_ORDER == _LITTLE_ENDIAN)
28#elif defined(OS_OPENBSD) || defined(OS_NETBSD) ||\
29      defined(OS_DRAGONFLYBSD)
30  #include <sys/types.h>
31  #include <sys/endian.h>
32#elif defined(OS_HPUX)
33  #define PLATFORM_IS_LITTLE_ENDIAN false
34#elif defined(OS_ANDROID)
35  // Due to a bug in the NDK x86 <sys/endian.h> definition,
36  // _BYTE_ORDER must be used instead of __BYTE_ORDER on Android.
37  // See http://code.google.com/p/android/issues/detail?id=39824
38  #include <endian.h>
39  #define PLATFORM_IS_LITTLE_ENDIAN  (_BYTE_ORDER == _LITTLE_ENDIAN)
40#else
41  #include <endian.h>
42#endif
43
44#include <pthread.h>
45#ifdef SNAPPY
46#include <snappy.h>
47#endif
48#include <stdint.h>
49#include <string>
50#include "port/atomic_pointer.h"
51
52#ifndef PLATFORM_IS_LITTLE_ENDIAN
53#define PLATFORM_IS_LITTLE_ENDIAN (__BYTE_ORDER == __LITTLE_ENDIAN)
54#endif
55
56#if defined(OS_MACOSX) || defined(OS_SOLARIS) || defined(OS_FREEBSD) ||\
57    defined(OS_NETBSD) || defined(OS_OPENBSD) || defined(OS_DRAGONFLYBSD) ||\
58    defined(OS_ANDROID) || defined(OS_HPUX)
59// Use fread/fwrite/fflush on platforms without _unlocked variants
60#define fread_unlocked fread
61#define fwrite_unlocked fwrite
62#define fflush_unlocked fflush
63#endif
64
65#if defined(OS_MACOSX) || defined(OS_FREEBSD) ||\
66    defined(OS_OPENBSD) || defined(OS_DRAGONFLYBSD)
67// Use fsync() on platforms without fdatasync()
68#define fdatasync fsync
69#endif
70
71#if defined(OS_ANDROID) && __ANDROID_API__ < 9
72// fdatasync() was only introduced in API level 9 on Android. Use fsync()
73// when targetting older platforms.
74#define fdatasync fsync
75#endif
76
77namespace leveldb {
78namespace port {
79
80static const bool kLittleEndian = PLATFORM_IS_LITTLE_ENDIAN;
81#undef PLATFORM_IS_LITTLE_ENDIAN
82
83class CondVar;
84
85class Mutex {
86 public:
87  Mutex();
88  ~Mutex();
89
90  void Lock();
91  void Unlock();
92  void AssertHeld() { }
93
94 private:
95  friend class CondVar;
96  pthread_mutex_t mu_;
97
98  // No copying
99  Mutex(const Mutex&);
100  void operator=(const Mutex&);
101};
102
103class CondVar {
104 public:
105  explicit CondVar(Mutex* mu);
106  ~CondVar();
107  void Wait();
108  void Signal();
109  void SignalAll();
110 private:
111  pthread_cond_t cv_;
112  Mutex* mu_;
113};
114
115typedef pthread_once_t OnceType;
116#define LEVELDB_ONCE_INIT PTHREAD_ONCE_INIT
117extern void InitOnce(OnceType* once, void (*initializer)());
118
119inline bool Snappy_Compress(const char* input, size_t length,
120                            ::std::string* output) {
121#ifdef SNAPPY
122  output->resize(snappy::MaxCompressedLength(length));
123  size_t outlen;
124  snappy::RawCompress(input, length, &(*output)[0], &outlen);
125  output->resize(outlen);
126  return true;
127#endif
128
129  return false;
130}
131
132inline bool Snappy_GetUncompressedLength(const char* input, size_t length,
133                                         size_t* result) {
134#ifdef SNAPPY
135  return snappy::GetUncompressedLength(input, length, result);
136#else
137  return false;
138#endif
139}
140
141inline bool Snappy_Uncompress(const char* input, size_t length,
142                              char* output) {
143#ifdef SNAPPY
144  return snappy::RawUncompress(input, length, output);
145#else
146  return false;
147#endif
148}
149
150inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) {
151  return false;
152}
153
154} // namespace port
155} // namespace leveldb
156
157#endif  // STORAGE_LEVELDB_PORT_PORT_POSIX_H_
158