Permalink
Browse files

Pull from FB rev 63ce89e2f2301e6bba44a111cc7d4218022156f6

jdelong committed Jun 2, 2012
1 parent 59de307 commit 27494a20393fa45072e7d526d358835f3abe312a
Showing with 42,799 additions and 0 deletions.
  1. +84 −0 folly/Arena-inl.h
  2. +227 −0 folly/Arena.h
  3. +366 −0 folly/AtomicHashArray-inl.h
  4. +283 −0 folly/AtomicHashArray.h
  5. +402 −0 folly/AtomicHashMap-inl.h
  6. +393 −0 folly/AtomicHashMap.h
  7. +393 −0 folly/Benchmark.cpp
  8. +375 −0 folly/Benchmark.h
  9. +519 −0 folly/Bits.h
  10. +220 −0 folly/ConcurrentSkipList-inl.h
  11. +852 −0 folly/ConcurrentSkipList.h
  12. +136 −0 folly/Conv.cpp
  13. +844 −0 folly/Conv.h
  14. +221 −0 folly/DiscriminatedPtr.h
  15. +2,284 −0 folly/FBString.h
  16. +936 −0 folly/FBVector.h
  17. +260 −0 folly/Foreach.h
  18. +1,078 −0 folly/Format-inl.h
  19. +137 −0 folly/Format.cpp
  20. +272 −0 folly/Format.h
  21. +255 −0 folly/FormatArg.h
  22. +32 −0 folly/GroupVarint.cpp
  23. +600 −0 folly/GroupVarint.h
  24. +243 −0 folly/Hash.h
  25. +256 −0 folly/Histogram-inl.h
  26. +381 −0 folly/Histogram.h
  27. +135 −0 folly/IntrusiveList.h
  28. +39 −0 folly/Likely.h
  29. +86 −0 folly/Makefile.am
  30. +192 −0 folly/Malloc.h
  31. +72 −0 folly/MapUtil.h
  32. +150 −0 folly/PackedSyncPtr.h
  33. +30 −0 folly/Portability.h
  34. +70 −0 folly/Preprocessor.h
  35. +128 −0 folly/ProducerConsumerQueue.h
  36. +73 −0 folly/README
  37. +735 −0 folly/RWSpinLock.h
  38. +35 −0 folly/Random.cpp
  39. +31 −0 folly/Random.h
  40. +37 −0 folly/Range.cpp
  41. +552 −0 folly/Range.h
  42. +21 −0 folly/SConstruct.double-conversion
  43. +157 −0 folly/ScopeGuard.h
  44. +284 −0 folly/SmallLocks.h
  45. +126 −0 folly/StlAllocator.h
  46. +323 −0 folly/String-inl.h
  47. +313 −0 folly/String.cpp
  48. +292 −0 folly/String.h
  49. +653 −0 folly/Synchronized.h
  50. +43 −0 folly/ThreadCachedArena.cpp
  51. +81 −0 folly/ThreadCachedArena.h
  52. +176 −0 folly/ThreadCachedInt.h
  53. +346 −0 folly/ThreadLocal.h
  54. +76 −0 folly/TimeoutQueue.cpp
  55. +132 −0 folly/TimeoutQueue.h
  56. +236 −0 folly/Traits.h
  57. +54 −0 folly/Unicode.cpp
  58. +39 −0 folly/Unicode.h
  59. +91 −0 folly/build/generate_escape_tables.py
  60. +79 −0 folly/build/generate_format_tables.py
  61. +106 −0 folly/build/generate_varint_tables.py
  62. +92 −0 folly/configure.ac
  63. +37 −0 folly/detail/AtomicHashUtils.h
  64. +93 −0 folly/detail/BitIteratorDetail.h
  65. +165 −0 folly/detail/DiscriminatedPtrDetail.h
  66. +104 −0 folly/detail/GroupVarintDetail.h
  67. +321 −0 folly/detail/ThreadLocalDetail.h
  68. +1 −0 folly/docs/.gitignore
  69. +134 −0 folly/docs/AtomicHashMap.md
  70. +281 −0 folly/docs/Benchmark.md
  71. +217 −0 folly/docs/Conv.md
  72. +189 −0 folly/docs/Dynamic.md
  73. +46 −0 folly/docs/FBString.md
  74. +242 −0 folly/docs/FBVector.md
  75. BIN folly/docs/Fbvector--graphical_solutions.png
  76. +181 −0 folly/docs/Format.md
  77. +46 −0 folly/docs/GroupVarint.md
  78. +104 −0 folly/docs/Histogram.md
  79. +33 −0 folly/docs/Makefile
  80. +259 −0 folly/docs/Overview.md
  81. +77 −0 folly/docs/PackedSyncPtr.md
  82. +40 −0 folly/docs/ProducerConsumerQueue.md
  83. +24 −0 folly/docs/SmallLocks.md
  84. +606 −0 folly/docs/Synchronized.md
  85. +98 −0 folly/docs/ThreadCachedInt.md
  86. +106 −0 folly/docs/ThreadLocal.md
  87. +69 −0 folly/docs/small_vector.md
  88. +7 −0 folly/docs/style.css
  89. +850 −0 folly/dynamic-inl.h
  90. +40 −0 folly/dynamic.cpp
  91. +485 −0 folly/dynamic.h
  92. +79 −0 folly/eventfd.h
  93. +134 −0 folly/experimental/Bits.h
  94. +97 −0 folly/experimental/TestUtil.cpp
  95. +63 −0 folly/experimental/TestUtil.h
  96. +411 −0 folly/experimental/io/Cursor.h
  97. +600 −0 folly/experimental/io/IOBuf.cpp
  98. +972 −0 folly/experimental/io/IOBuf.h
  99. +226 −0 folly/experimental/io/IOBufQueue.cpp
  100. +176 −0 folly/experimental/io/IOBufQueue.h
  101. +342 −0 folly/experimental/io/test/IOBufCursorTest.cpp
  102. +231 −0 folly/experimental/io/test/IOBufQueueTest.cpp
  103. +525 −0 folly/experimental/io/test/IOBufTest.cpp
  104. +12 −0 folly/experimental/io/test/Makefile.am
  105. +172 −0 folly/experimental/io/test/NetworkBenchmark.cpp
  106. +59 −0 folly/experimental/test/BitsTest.cpp
  107. +52 −0 folly/experimental/test/TestUtilTest.cpp
  108. +303 −0 folly/folly-config.h
  109. +696 −0 folly/json.cpp
  110. +118 −0 folly/json.h
  111. +110 −0 folly/m4/ac_cxx_compile_stdcxx_0x.m4
  112. +258 −0 folly/m4/ax_boost_base.m4
  113. +111 −0 folly/m4/ax_boost_regex.m4
  114. +149 −0 folly/m4/ax_boost_thread.m4
  115. +209 −0 folly/m4/ax_prefix_config.m4
  116. +1,189 −0 folly/small_vector.h
  117. +606 −0 folly/sorted_vector_types.h
  118. +95 −0 folly/test/AtomicHashArrayTest.cpp
  119. +807 −0 folly/test/AtomicHashMapTest.cpp
  120. +74 −0 folly/test/BenchmarkTest.cpp
  121. +187 −0 folly/test/BitIteratorTest.cpp
  122. +157 −0 folly/test/BitsTest.cpp
  123. +696 −0 folly/test/ConcurrentSkipListBenchmark.cpp
  124. +329 −0 folly/test/ConcurrentSkipListTest.cpp
  125. +692 −0 folly/test/ConvTest.cpp
  126. +125 −0 folly/test/DiscriminatedPtrTest.cpp
  127. +274 −0 folly/test/DynamicTest.cpp
  128. +65 −0 folly/test/EndianTest.cpp
  129. +73 −0 folly/test/EventFDTest.cpp
  130. +24 −0 folly/test/FBStringLibstdcxxStdexceptTest.cpp
  131. +1,057 −0 folly/test/FBStringTest.cpp
  132. +224 −0 folly/test/FBStringTestBenchmarks.cpp.h
  133. +259 −0 folly/test/FBVectorTest.cpp
  134. +379 −0 folly/test/FBVectorTestBenchmarks.cpp.h
  135. +269 −0 folly/test/ForeachTest.cpp
  136. +410 −0 folly/test/FormatTest.cpp
  137. +261 −0 folly/test/GroupVarintTest.cpp
  138. +137 −0 folly/test/HashTest.cpp
  139. +204 −0 folly/test/HistogramTest.cpp
  140. +355 −0 folly/test/JsonTest.cpp
  141. +131 −0 folly/test/Makefile.am
  142. +34 −0 folly/test/MapUtilTest.cpp
  143. +133 −0 folly/test/PackedSyncPtrTest.cpp
  144. +224 −0 folly/test/ProducerConsumerQueueTest.cpp
  145. +247 −0 folly/test/RWSpinLockTest.cpp
  146. +140 −0 folly/test/RangeTest.cpp
  147. +258 −0 folly/test/ScopeGuardTest.cpp
  148. +142 −0 folly/test/SmallLocksTest.cpp
  149. +645 −0 folly/test/StringTest.cpp
  150. +106 −0 folly/test/SynchronizedTest.cpp
  151. +291 −0 folly/test/SynchronizedTestLib-inl.h
  152. +47 −0 folly/test/SynchronizedTestLib.h
  153. +265 −0 folly/test/ThreadCachedArenaTest.cpp
  154. +282 −0 folly/test/ThreadCachedIntTest.cpp
  155. +359 −0 folly/test/ThreadLocalTest.cpp
  156. +113 −0 folly/test/TimeoutQueueTest.cpp
  157. +11 −0 folly/test/function_benchmark/Makefile.am
  158. +36 −0 folly/test/function_benchmark/benchmark_impl.cpp
  159. +35 −0 folly/test/function_benchmark/benchmark_impl.h
  160. +196 −0 folly/test/function_benchmark/main.cpp
  161. +19 −0 folly/test/function_benchmark/test_functions.cpp
  162. +18 −0 folly/test/function_benchmark/test_functions.h
  163. +752 −0 folly/test/small_vector_test.cpp
  164. +273 −0 folly/test/sorted_vector_test.cpp
View
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2012 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FOLLY_ARENA_H_
+#error This file may only be included from Arena.h
+#endif
+
+// Implementation of Arena.h functions
+
+namespace folly {
+
+template <class Alloc>
+std::pair<typename Arena<Alloc>::Block*, size_t>
+Arena<Alloc>::Block::allocate(Alloc& alloc, size_t size, bool allowSlack) {
+ size_t allocSize = sizeof(Block) + size;
+ if (allowSlack) {
+ allocSize = ArenaAllocatorTraits<Alloc>::goodSize(alloc, allocSize);
+ }
+
+ void* mem = alloc.allocate(allocSize);
+ assert(isAligned(mem));
+ return std::make_pair(new (mem) Block(), allocSize - sizeof(Block));
+}
+
+template <class Alloc>
+void Arena<Alloc>::Block::deallocate(Alloc& alloc) {
+ this->~Block();
+ alloc.deallocate(this);
+}
+
+template <class Alloc>
+void* Arena<Alloc>::allocateSlow(size_t size) {
+ std::pair<Block*, size_t> p;
+ char* start;
+ if (size > minBlockSize()) {
+ // Allocate a large block for this chunk only, put it at the back of the
+ // list so it doesn't get used for small allocations; don't change ptr_
+ // and end_, let them point into a normal block (or none, if they're
+ // null)
+ p = Block::allocate(alloc(), size, false);
+ start = p.first->start();
+ blocks_.push_back(*p.first);
+ } else {
+ // Allocate a normal sized block and carve out size bytes from it
+ p = Block::allocate(alloc(), minBlockSize(), true);
+ start = p.first->start();
+ blocks_.push_front(*p.first);
+ ptr_ = start + size;
+ end_ = start + p.second;
+ }
+
+ assert(p.second >= size);
+ return start;
+}
+
+template <class Alloc>
+void Arena<Alloc>::merge(Arena<Alloc>&& other) {
+ blocks_.splice_after(blocks_.before_begin(), other.blocks_);
+ other.blocks_.clear();
+ other.ptr_ = other.end_ = nullptr;
+}
+
+template <class Alloc>
+Arena<Alloc>::~Arena() {
+ auto disposer = [this] (Block* b) { b->deallocate(this->alloc()); };
+ while (!blocks_.empty()) {
+ blocks_.pop_front_and_dispose(disposer);
+ }
+}
+
+} // namespace folly
View
@@ -0,0 +1,227 @@
+/*
+ * Copyright 2012 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FOLLY_ARENA_H_
+#define FOLLY_ARENA_H_
+
+#include <cassert>
+#include <utility>
+#include <limits>
+#include <boost/intrusive/slist.hpp>
+
+#include "folly/Likely.h"
+#include "folly/Malloc.h"
+
+namespace folly {
+
+/**
+ * Simple arena: allocate memory which gets freed when the arena gets
+ * destroyed.
+ *
+ * The arena itself allocates memory using a custom allocator which provides
+ * the following interface (same as required by StlAllocator in StlAllocator.h)
+ *
+ * void* allocate(size_t size);
+ * Allocate a block of size bytes, properly aligned to the maximum
+ * alignment required on your system; throw std::bad_alloc if the
+ * allocation can't be satisfied.
+ *
+ * void deallocate(void* ptr);
+ * Deallocate a previously allocated block.
+ *
+ * You may also specialize ArenaAllocatorTraits for your allocator type to
+ * provide:
+ *
+ * size_t goodSize(const Allocator& alloc, size_t size) const;
+ * Return a size (>= the provided size) that is considered "good" for your
+ * allocator (for example, if your allocator allocates memory in 4MB
+ * chunks, size should be rounded up to 4MB). The provided value is
+ * guaranteed to be rounded up to a multiple of the maximum alignment
+ * required on your system; the returned value must be also.
+ *
+ * An implementation that uses malloc() / free() is defined below, see
+ * SysAlloc / SysArena.
+ */
+template <class Alloc> struct ArenaAllocatorTraits;
+template <class Alloc>
+class Arena {
+ public:
+ explicit Arena(const Alloc& alloc,
+ size_t minBlockSize = kDefaultMinBlockSize)
+ : allocAndSize_(alloc, minBlockSize),
+ ptr_(nullptr),
+ end_(nullptr) {
+ }
+
+ ~Arena();
+
+ void* allocate(size_t size) {
+ size = roundUp(size);
+
+ if (LIKELY(end_ - ptr_ >= size)) {
+ // Fast path: there's enough room in the current block
+ char* r = ptr_;
+ ptr_ += size;
+ assert(isAligned(r));
+ return r;
+ }
+
+ // Not enough room in the current block
+ void* r = allocateSlow(size);
+ assert(isAligned(r));
+ return r;
+ }
+
+ void deallocate(void* p) {
+ // Deallocate? Never!
+ }
+
+ // Transfer ownership of all memory allocated from "other" to "this".
+ void merge(Arena&& other);
+
+ private:
+ // not copyable
+ Arena(const Arena&) = delete;
+ Arena& operator=(const Arena&) = delete;
+
+ // movable
+ Arena(Arena&&) = default;
+ Arena& operator=(Arena&&) = default;
+
+ struct Block;
+ typedef boost::intrusive::slist_member_hook<
+ boost::intrusive::tag<Arena>> BlockLink;
+
+ struct Block {
+ BlockLink link;
+
+ // Allocate a block with at least size bytes of storage.
+ // If allowSlack is true, allocate more than size bytes if convenient
+ // (via ArenaAllocatorTraits::goodSize()) as we'll try to pack small
+ // allocations in this block.
+ static std::pair<Block*, size_t> allocate(
+ Alloc& alloc, size_t size, bool allowSlack);
+ void deallocate(Alloc& alloc);
+
+ char* start() {
+ return reinterpret_cast<char*>(this + 1);
+ }
+
+ private:
+ Block() { }
+ ~Block() { }
+ } __attribute__((aligned));
+ // This should be alignas(std::max_align_t) but neither alignas nor
+ // max_align_t are supported by gcc 4.6.2.
+
+ public:
+ static constexpr size_t kDefaultMinBlockSize = 4096 - sizeof(Block);
+
+ private:
+ static constexpr size_t maxAlign = alignof(Block);
+ static constexpr bool isAligned(uintptr_t address) {
+ return (address & (maxAlign - 1)) == 0;
+ }
+ static bool isAligned(void* p) {
+ return isAligned(reinterpret_cast<uintptr_t>(p));
+ }
+
+ // Round up size so it's properly aligned
+ static constexpr size_t roundUp(size_t size) {
+ return (size + maxAlign - 1) & ~(maxAlign - 1);
+ }
+
+ // cache_last<true> makes the list keep a pointer to the last element, so we
+ // have push_back() and constant time splice_after()
+ typedef boost::intrusive::slist<
+ Block,
+ boost::intrusive::member_hook<Block, BlockLink, &Block::link>,
+ boost::intrusive::constant_time_size<false>,
+ boost::intrusive::cache_last<true>> BlockList;
+
+ void* allocateSlow(size_t size);
+
+ // Empty member optimization: package Alloc with a non-empty member
+ // in case Alloc is empty (as it is in the case of SysAlloc).
+ struct AllocAndSize : public Alloc {
+ explicit AllocAndSize(const Alloc& a, size_t s)
+ : Alloc(a), minBlockSize(s) {
+ }
+
+ size_t minBlockSize;
+ };
+
+ size_t minBlockSize() const {
+ return allocAndSize_.minBlockSize;
+ }
+ Alloc& alloc() { return allocAndSize_; }
+ const Alloc& alloc() const { return allocAndSize_; }
+
+ AllocAndSize allocAndSize_;
+ BlockList blocks_;
+ char* ptr_;
+ char* end_;
+};
+
+/**
+ * By default, don't pad the given size.
+ */
+template <class Alloc>
+struct ArenaAllocatorTraits {
+ static size_t goodSize(const Alloc& alloc, size_t size) {
+ return size;
+ }
+};
+
+/**
+ * Arena-compatible allocator that calls malloc() and free(); see
+ * goodMallocSize() in Malloc.h for goodSize().
+ */
+class SysAlloc {
+ public:
+ void* allocate(size_t size) {
+ void* mem = malloc(size);
+ if (!mem) throw std::bad_alloc();
+ return mem;
+ }
+
+ void deallocate(void* p) {
+ free(p);
+ }
+};
+
+template <>
+struct ArenaAllocatorTraits<SysAlloc> {
+ static size_t goodSize(const SysAlloc& alloc, size_t size) {
+ return goodMallocSize(size);
+ }
+};
+
+/**
+ * Arena that uses the system allocator (malloc / free)
+ */
+class SysArena : public Arena<SysAlloc> {
+ public:
+ explicit SysArena(size_t minBlockSize = kDefaultMinBlockSize)
+ : Arena<SysAlloc>(SysAlloc(), minBlockSize) {
+ }
+};
+
+} // namespace folly
+
+#include "folly/Arena-inl.h"
+
+#endif /* FOLLY_ARENA_H_ */
Oops, something went wrong.

3 comments on commit 27494a2

Inscrutable huge changesets like this one tend to undermine the "open-source-ness" of this effort. Would it be possible to get the actual change history in here?

Hi Dave -- this is the initial commit. Some of the files have a long history that is mostly internal to Facebook and peppered with commit information that has sensitive tidbits, so we decided to make the initial commit without a history. Going forward we're looking at ways to make fine-grained commit information available.

Oh! The other commit was marked "initial." Sorry for the noise.

Please sign in to comment.