mesh-rb 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/ext/mesh/extconf.rb +22 -4
  4. data/ext/mesh/mesh.tar.gz +0 -0
  5. data/lib/mesh/version.rb +1 -1
  6. data/mesh.gemspec +3 -2
  7. metadata +4 -120
  8. data/ext/mesh/mesh/.bazelrc +0 -20
  9. data/ext/mesh/mesh/.bazelversion +0 -1
  10. data/ext/mesh/mesh/.clang-format +0 -15
  11. data/ext/mesh/mesh/.dockerignore +0 -5
  12. data/ext/mesh/mesh/.editorconfig +0 -16
  13. data/ext/mesh/mesh/.gitattributes +0 -4
  14. data/ext/mesh/mesh/.github/workflows/main.yml +0 -144
  15. data/ext/mesh/mesh/.gitignore +0 -51
  16. data/ext/mesh/mesh/AUTHORS +0 -5
  17. data/ext/mesh/mesh/CMakeLists.txt +0 -270
  18. data/ext/mesh/mesh/CODE_OF_CONDUCT.md +0 -77
  19. data/ext/mesh/mesh/Dockerfile +0 -30
  20. data/ext/mesh/mesh/LICENSE +0 -201
  21. data/ext/mesh/mesh/Makefile +0 -81
  22. data/ext/mesh/mesh/README.md +0 -97
  23. data/ext/mesh/mesh/WORKSPACE +0 -50
  24. data/ext/mesh/mesh/bazel +0 -350
  25. data/ext/mesh/mesh/mesh-pldi19-powers.pdf +0 -0
  26. data/ext/mesh/mesh/src/BUILD +0 -222
  27. data/ext/mesh/mesh/src/CMakeLists.txt +0 -85
  28. data/ext/mesh/mesh/src/bitmap.h +0 -590
  29. data/ext/mesh/mesh/src/cheap_heap.h +0 -170
  30. data/ext/mesh/mesh/src/common.h +0 -377
  31. data/ext/mesh/mesh/src/copts.bzl +0 -31
  32. data/ext/mesh/mesh/src/d_assert.cc +0 -75
  33. data/ext/mesh/mesh/src/fixed_array.h +0 -124
  34. data/ext/mesh/mesh/src/global_heap.cc +0 -547
  35. data/ext/mesh/mesh/src/global_heap.h +0 -569
  36. data/ext/mesh/mesh/src/gnu_wrapper.cc +0 -75
  37. data/ext/mesh/mesh/src/internal.h +0 -356
  38. data/ext/mesh/mesh/src/libmesh.cc +0 -239
  39. data/ext/mesh/mesh/src/mac_wrapper.cc +0 -528
  40. data/ext/mesh/mesh/src/measure_rss.cc +0 -44
  41. data/ext/mesh/mesh/src/measure_rss.h +0 -20
  42. data/ext/mesh/mesh/src/meshable_arena.cc +0 -776
  43. data/ext/mesh/mesh/src/meshable_arena.h +0 -309
  44. data/ext/mesh/mesh/src/meshing.h +0 -60
  45. data/ext/mesh/mesh/src/mini_heap.h +0 -532
  46. data/ext/mesh/mesh/src/mmap_heap.h +0 -104
  47. data/ext/mesh/mesh/src/one_way_mmap_heap.h +0 -77
  48. data/ext/mesh/mesh/src/partitioned_heap.h +0 -111
  49. data/ext/mesh/mesh/src/plasma/mesh.h +0 -33
  50. data/ext/mesh/mesh/src/real.cc +0 -52
  51. data/ext/mesh/mesh/src/real.h +0 -36
  52. data/ext/mesh/mesh/src/rng/mwc.h +0 -296
  53. data/ext/mesh/mesh/src/rng/mwc64.h +0 -58
  54. data/ext/mesh/mesh/src/rpl_printf.c +0 -1991
  55. data/ext/mesh/mesh/src/runtime.cc +0 -393
  56. data/ext/mesh/mesh/src/runtime.h +0 -114
  57. data/ext/mesh/mesh/src/shuffle_vector.h +0 -287
  58. data/ext/mesh/mesh/src/size_classes.def +0 -251
  59. data/ext/mesh/mesh/src/static/if.h +0 -36
  60. data/ext/mesh/mesh/src/static/log.h +0 -43
  61. data/ext/mesh/mesh/src/testing/benchmark/local_refill.cc +0 -103
  62. data/ext/mesh/mesh/src/testing/big-alloc.c +0 -28
  63. data/ext/mesh/mesh/src/testing/fragmenter.cc +0 -128
  64. data/ext/mesh/mesh/src/testing/global-large-stress.cc +0 -25
  65. data/ext/mesh/mesh/src/testing/local-alloc.c +0 -16
  66. data/ext/mesh/mesh/src/testing/meshing_benchmark.cc +0 -189
  67. data/ext/mesh/mesh/src/testing/thread.cc +0 -35
  68. data/ext/mesh/mesh/src/testing/unit/alignment.cc +0 -56
  69. data/ext/mesh/mesh/src/testing/unit/bitmap_test.cc +0 -274
  70. data/ext/mesh/mesh/src/testing/unit/concurrent_mesh_test.cc +0 -185
  71. data/ext/mesh/mesh/src/testing/unit/mesh_test.cc +0 -143
  72. data/ext/mesh/mesh/src/testing/unit/rng_test.cc +0 -22
  73. data/ext/mesh/mesh/src/testing/unit/size_class_test.cc +0 -66
  74. data/ext/mesh/mesh/src/testing/unit/triple_mesh_test.cc +0 -285
  75. data/ext/mesh/mesh/src/testing/userfaultfd-kernel-copy.cc +0 -164
  76. data/ext/mesh/mesh/src/thread_local_heap.cc +0 -163
  77. data/ext/mesh/mesh/src/thread_local_heap.h +0 -268
  78. data/ext/mesh/mesh/src/wrapper.cc +0 -433
  79. data/ext/mesh/mesh/support/export_mesh.cmake +0 -28
  80. data/ext/mesh/mesh/support/gen-size-classes +0 -57
  81. data/ext/mesh/mesh/support/install_all_configs +0 -33
  82. data/ext/mesh/mesh/support/remove_export_mesh.cmake +0 -48
  83. data/ext/mesh/mesh/support/update-bazelisk +0 -8
  84. data/ext/mesh/mesh/theory/32m80.png +0 -0
  85. data/ext/mesh/mesh/theory/64m80ind.png +0 -0
  86. data/ext/mesh/mesh/theory/bound_comparison.py +0 -67
  87. data/ext/mesh/mesh/theory/bounds/impdeg+1 +0 -135
  88. data/ext/mesh/mesh/theory/choose.py +0 -43
  89. data/ext/mesh/mesh/theory/common.py +0 -42
  90. data/ext/mesh/mesh/theory/compute_exp_Y.py +0 -134
  91. data/ext/mesh/mesh/theory/createRandomString.py +0 -69
  92. data/ext/mesh/mesh/theory/deg_bound_check.py +0 -100
  93. data/ext/mesh/mesh/theory/degcheck.py +0 -47
  94. data/ext/mesh/mesh/theory/dumps/32,1,80,dumb.txt +0 -81
  95. data/ext/mesh/mesh/theory/dumps/32,2,80,dumb.txt +0 -81
  96. data/ext/mesh/mesh/theory/dumps/32,3,80,dumb.txt +0 -81
  97. data/ext/mesh/mesh/theory/dumps/32,4,80,dumb.txt +0 -81
  98. data/ext/mesh/mesh/theory/dumps/32,5,80,dumb.txt +0 -81
  99. data/ext/mesh/mesh/theory/dumps/32,6,80,dumb.txt +0 -81
  100. data/ext/mesh/mesh/theory/dumps/32,7,80,dumb.txt +0 -81
  101. data/ext/mesh/mesh/theory/dumps/32,8,80,dumb.txt +0 -81
  102. data/ext/mesh/mesh/theory/dumps/32,9,80,dumb.txt +0 -81
  103. data/ext/mesh/mesh/theory/experiment.py +0 -303
  104. data/ext/mesh/mesh/theory/experiment_raw_results/.gitignore +0 -0
  105. data/ext/mesh/mesh/theory/greedy_experiment.py +0 -66
  106. data/ext/mesh/mesh/theory/greedy_experiment_copy.py +0 -46
  107. data/ext/mesh/mesh/theory/greedy_experiment_q.py +0 -75
  108. data/ext/mesh/mesh/theory/makeGraph.py +0 -64
  109. data/ext/mesh/mesh/theory/manyreps.png +0 -0
  110. data/ext/mesh/mesh/theory/manystrings.png +0 -0
  111. data/ext/mesh/mesh/theory/match_vs_color_experiment.py +0 -94
  112. data/ext/mesh/mesh/theory/maxmatch_vs_E[Y].py +0 -162
  113. data/ext/mesh/mesh/theory/maxmatch_vs_greedymatch.py +0 -96
  114. data/ext/mesh/mesh/theory/maxvdeg+1imp++32,80.png +0 -0
  115. data/ext/mesh/mesh/theory/mesh_util.py +0 -322
  116. data/ext/mesh/mesh/theory/meshers.py +0 -452
  117. data/ext/mesh/mesh/theory/meshingBenchmark.py +0 -96
  118. data/ext/mesh/mesh/theory/occupancyComparison.py +0 -133
  119. data/ext/mesh/mesh/theory/randmatch_vs_greedymatch.py +0 -97
  120. data/ext/mesh/mesh/theory/randmatch_vs_greedymatch_q.py +0 -103
  121. data/ext/mesh/mesh/theory/randmatch_vs_greedymatch_time.py +0 -117
  122. data/ext/mesh/mesh/theory/read_mesh_dump.py +0 -82
  123. data/ext/mesh/mesh/theory/test.py +0 -70
  124. data/ext/mesh/mesh/tools/bazel +0 -1
@@ -1,170 +0,0 @@
1
- // -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil -*-
2
- // Copyright 2019 The Mesh Authors. All rights reserved.
3
- // Use of this source code is governed by the Apache License,
4
- // Version 2.0, that can be found in the LICENSE file.
5
-
6
- #pragma once
7
- #ifndef MESH_CHEAP_HEAP_H
8
- #define MESH_CHEAP_HEAP_H
9
-
10
- #include "internal.h"
11
- #include "one_way_mmap_heap.h"
12
-
13
- namespace mesh {
14
-
15
- // Fast allocation for a single size-class
16
- template <size_t allocSize, size_t maxCount>
17
- class CheapHeap : public OneWayMmapHeap {
18
- private:
19
- DISALLOW_COPY_AND_ASSIGN(CheapHeap);
20
- typedef OneWayMmapHeap SuperHeap;
21
-
22
- static_assert(maxCount <= (1 << 30), "expected maxCount <= 2^30");
23
- static_assert(allocSize % 2 == 0, "expected allocSize to be even");
24
-
25
- public:
26
- // cacheline-sized alignment
27
- enum { Alignment = 64 };
28
-
29
- CheapHeap() : SuperHeap() {
30
- // TODO: check allocSize + maxCount doesn't overflow?
31
- _arena = reinterpret_cast<char *>(SuperHeap::malloc(allocSize * maxCount));
32
- _freelist = reinterpret_cast<void **>(SuperHeap::malloc(maxCount * sizeof(void *)));
33
- hard_assert(_arena != nullptr);
34
- hard_assert(_freelist != nullptr);
35
- d_assert(reinterpret_cast<uintptr_t>(_arena) % Alignment == 0);
36
- d_assert(reinterpret_cast<uintptr_t>(_freelist) % Alignment == 0);
37
- }
38
-
39
- inline void *alloc() {
40
- if (likely(_freelistOff >= 0)) {
41
- const auto ptr = _freelist[_freelistOff];
42
- _freelistOff--;
43
- return ptr;
44
- }
45
-
46
- const auto off = _arenaOff++;
47
- const auto ptr = ptrFromOffset(off);
48
- hard_assert(ptr < arenaEnd());
49
- return ptr;
50
- }
51
-
52
- constexpr size_t getSize(void *ATTRIBUTE_UNUSED ptr) const {
53
- return allocSize;
54
- }
55
-
56
- inline void free(void *ptr) {
57
- d_assert(ptr >= _arena);
58
- d_assert(ptr < arenaEnd());
59
-
60
- _freelistOff++;
61
- _freelist[_freelistOff] = ptr;
62
- }
63
-
64
- inline char *arenaBegin() const {
65
- return _arena;
66
- }
67
-
68
- inline uint32_t offsetFor(const void *ptr) const {
69
- const uintptr_t ptrval = reinterpret_cast<uintptr_t>(ptr);
70
- const uintptr_t arena = reinterpret_cast<uintptr_t>(_arena);
71
- d_assert(ptrval >= arena);
72
- return (ptrval - arena) / allocSize;
73
- }
74
-
75
- inline char *ptrFromOffset(size_t off) const {
76
- d_assert(off < _arenaOff);
77
- return _arena + off * allocSize;
78
- }
79
-
80
- inline char *arenaEnd() const {
81
- return _arena + allocSize * maxCount;
82
- }
83
-
84
- protected:
85
- char *_arena{nullptr};
86
- void **_freelist{nullptr};
87
- size_t _arenaOff{1};
88
- ssize_t _freelistOff{-1};
89
- };
90
-
91
- class DynCheapHeap : public OneWayMmapHeap {
92
- private:
93
- DISALLOW_COPY_AND_ASSIGN(DynCheapHeap);
94
- typedef OneWayMmapHeap SuperHeap;
95
-
96
- public:
97
- // cacheline-sized alignment
98
- enum { Alignment = 64 };
99
-
100
- DynCheapHeap() : SuperHeap() {
101
- d_assert(_allocSize % 2 == 0);
102
- }
103
-
104
- inline void init(size_t allocSize, size_t maxCount, char *arena, void **freelist) {
105
- _arena = arena;
106
- _freelist = freelist;
107
- _allocSize = allocSize;
108
- _maxCount = maxCount;
109
- hard_assert(_arena != nullptr);
110
- hard_assert(_freelist != nullptr);
111
- hard_assert(reinterpret_cast<uintptr_t>(_arena) % Alignment == 0);
112
- hard_assert(reinterpret_cast<uintptr_t>(_freelist) % Alignment == 0);
113
- }
114
-
115
- inline void *alloc() {
116
- if (likely(_freelistOff >= 0)) {
117
- const auto ptr = _freelist[_freelistOff];
118
- _freelistOff--;
119
- return ptr;
120
- }
121
-
122
- const auto off = _arenaOff++;
123
- const auto ptr = ptrFromOffset(off);
124
- hard_assert(ptr < arenaEnd());
125
- return ptr;
126
- }
127
-
128
- size_t getSize(void *ATTRIBUTE_UNUSED ptr) const {
129
- return _allocSize;
130
- }
131
-
132
- inline void free(void *ptr) {
133
- d_assert(ptr >= _arena);
134
- d_assert(ptr < arenaEnd());
135
-
136
- _freelistOff++;
137
- _freelist[_freelistOff] = ptr;
138
- }
139
-
140
- inline char *arenaBegin() const {
141
- return _arena;
142
- }
143
-
144
- inline uint32_t offsetFor(const void *ptr) const {
145
- const uintptr_t ptrval = reinterpret_cast<uintptr_t>(ptr);
146
- const uintptr_t arena = reinterpret_cast<uintptr_t>(_arena);
147
- d_assert(ptrval >= arena);
148
- return (ptrval - arena) / _allocSize;
149
- }
150
-
151
- inline char *ptrFromOffset(size_t off) const {
152
- d_assert(off < _arenaOff);
153
- return _arena + off * _allocSize;
154
- }
155
-
156
- inline char *arenaEnd() const {
157
- return _arena + _allocSize * _maxCount;
158
- }
159
-
160
- protected:
161
- char *_arena{nullptr};
162
- void **_freelist{nullptr};
163
- size_t _arenaOff{1};
164
- ssize_t _freelistOff{-1};
165
- size_t _allocSize{0};
166
- size_t _maxCount{0};
167
- };
168
- } // namespace mesh
169
-
170
- #endif // MESH_CHEAP_HEAP_H
@@ -1,377 +0,0 @@
1
- // -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil -*-
2
- // Copyright 2019 The Mesh Authors. All rights reserved.
3
- // Use of this source code is governed by the Apache License,
4
- // Version 2.0, that can be found in the LICENSE file.
5
-
6
- #pragma once
7
- #ifndef MESH_COMMON_H
8
- #define MESH_COMMON_H
9
-
10
- #include <cstddef>
11
- #include <cstdint>
12
- #include <ctime>
13
-
14
- #include <fcntl.h>
15
-
16
- #if !defined(_WIN32)
17
- #ifdef __APPLE__
18
- #define _DARWIN_C_SOURCE // exposes MAP_ANONYMOUS and MAP_NORESERVE
19
- #endif
20
- #include <sys/mman.h>
21
- #include <sys/stat.h>
22
- #include <sys/types.h>
23
- #include <unistd.h>
24
- #endif
25
-
26
- #include <chrono>
27
- #include <condition_variable>
28
- #include <functional>
29
- #include <mutex>
30
- #include <random>
31
- #include <unordered_map>
32
- #include <vector>
33
-
34
- // #include "config.h"
35
-
36
- #include "static/log.h"
37
-
38
- // from Heap Layers
39
- #include "utility/ilog2.h"
40
-
41
- #ifdef __linux__
42
- #define MESH_THROW throw()
43
- #else
44
- #define MESH_THROW
45
- #endif
46
-
47
- // MESH_HAVE_TLS is defined to 1 when __thread should be supported.
48
- // We assume __thread is supported on Linux when compiled with Clang or compiled
49
- // against libstdc++ with _GLIBCXX_HAVE_TLS defined. (this check is from Abseil)
50
- #ifdef MESH_HAVE_TLS
51
- #error MESH_HAVE_TLS cannot be directly set
52
- #elif defined(__linux__) && (defined(__clang__) || defined(_GLIBCXX_HAVE_TLS))
53
- #define MESH_HAVE_TLS 1
54
- #endif
55
-
56
- namespace mesh {
57
-
58
- static constexpr bool kMeshingEnabled = MESHING_ENABLED == 1;
59
-
60
- #if defined(_WIN32)
61
- // FIXME(EDB)
62
- static constexpr int kMapShared = 1;
63
- #else
64
- static constexpr int kMapShared = kMeshingEnabled ? MAP_SHARED : MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE;
65
- #endif
66
-
67
- static constexpr size_t kMinObjectSize = 16;
68
- static constexpr size_t kMaxSize = 16384;
69
- static constexpr size_t kClassSizesMax = 25;
70
- static constexpr size_t kAlignment = 8;
71
- static constexpr int kMinAlign = 16;
72
- static constexpr uint64_t kPageSize = 4096;
73
- static constexpr size_t kMaxFastLargeSize = 256 * 1024; // 256Kb
74
-
75
- static constexpr size_t kMaxSplitListSize = 16384;
76
- static constexpr size_t kMaxMergeSets = 4096;
77
-
78
- // cutoff to be considered for meshing
79
- static constexpr double kOccupancyCutoff = .8;
80
-
81
- // if we have, e.g. a kernel-imposed max_map_count of 2^16 (65k) we
82
- // can only safely have about 30k meshes before we are at risk of
83
- // hitting the max_map_count limit. Must smaller than 1/3, because
84
- // when meshing, in the worst case, 1 map would become 3. (A high
85
- // load server can easily trigger this worst case)
86
- static constexpr double kMeshesPerMap = .33;
87
-
88
- static constexpr size_t kDefaultMaxMeshCount = 30000;
89
- static constexpr size_t kMaxMeshesPerIteration = 2500;
90
-
91
- // maximum number of dirty pages to hold onto before we flush them
92
- // back to the OS (via MeshableArena::scavenge()
93
- static constexpr size_t kMaxDirtyPageThreshold = 1 << 14; // 64 MB in pages
94
- static constexpr size_t kMinDirtyPageThreshold = 32; // 128 KB in pages
95
-
96
- static constexpr uint32_t kSpanClassCount = 256;
97
-
98
- static constexpr int kNumBins = 25; // 16Kb max object size
99
- static constexpr int kDefaultMeshPeriod = 10000;
100
-
101
- static constexpr size_t kMinArenaExpansion = 4096; // 16 MB in pages
102
-
103
- // ensures we amortize the cost of going to the global heap enough
104
- static constexpr uint64_t kMinStringLen = 8;
105
- static constexpr size_t kMiniheapRefillGoalSize = 4 * 1024;
106
- static constexpr size_t kMaxMiniheapsPerShuffleVector = 24;
107
-
108
- // shuffle vector features
109
- static constexpr int16_t kMaxShuffleVectorLength = 256; // sizeof(uint8_t) << 8
110
- static constexpr bool kEnableShuffleOnInit = SHUFFLE_ON_INIT == 1;
111
- static constexpr bool kEnableShuffleOnFree = SHUFFLE_ON_FREE == 1;
112
-
113
- // madvise(DONTDUMP) the heap to make reasonable coredumps
114
- static constexpr bool kAdviseDump = false;
115
-
116
- static constexpr std::chrono::milliseconds kZeroMs{0};
117
- static constexpr std::chrono::milliseconds kMeshPeriodMs{100}; // 100 ms
118
-
119
- // controls aspects of miniheaps
120
- static constexpr size_t kMaxMeshes = 256; // 1 per bit
121
- #ifdef __APPLE__
122
- static constexpr size_t kArenaSize = 32ULL * 1024ULL * 1024ULL * 1024ULL; // 16 GB
123
- #else
124
- static constexpr size_t kArenaSize = 64ULL * 1024ULL * 1024ULL * 1024ULL; // 64 GB
125
- #endif
126
- static constexpr size_t kAltStackSize = 16 * 1024UL; // 16k sigaltstacks
127
- #define SIGQUIESCE (SIGRTMIN + 7)
128
- #define SIGDUMP (SIGRTMIN + 8)
129
-
130
- // BinnedTracker
131
- static constexpr size_t kBinnedTrackerBinCount = 1;
132
- static constexpr size_t kBinnedTrackerMaxEmpty = 128;
133
-
134
- static inline constexpr size_t PageCount(size_t sz) {
135
- return (sz + (kPageSize - 1)) / kPageSize;
136
- }
137
-
138
- static inline constexpr size_t RoundUpToPage(size_t sz) {
139
- return kPageSize * PageCount(sz);
140
- }
141
-
142
- namespace powerOfTwo {
143
- static constexpr size_t kMinObjectSize = 8;
144
-
145
- inline constexpr size_t ByteSizeForClass(const int i) {
146
- return static_cast<size_t>(1ULL << (i + staticlog(kMinObjectSize)));
147
- }
148
-
149
- inline constexpr int ClassForByteSize(const size_t sz) {
150
- return static_cast<int>(HL::ilog2((sz < 8) ? 8 : sz) - staticlog(kMinObjectSize));
151
- }
152
- } // namespace powerOfTwo
153
-
154
- } // namespace mesh
155
-
156
- using std::condition_variable;
157
- using std::function;
158
- using std::lock_guard;
159
- using std::mt19937_64;
160
- using std::mutex;
161
- // using std::shared_lock;
162
- // using std::shared_mutex;
163
- using std::unique_lock;
164
-
165
- #define likely(x) __builtin_expect(!!(x), 1)
166
- #define unlikely(x) __builtin_expect(!!(x), 0)
167
-
168
- #define ATTRIBUTE_UNUSED __attribute__((unused))
169
- #define ATTRIBUTE_NEVER_INLINE __attribute__((noinline))
170
- #define ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline))
171
- #define ATTRIBUTE_NORETURN __attribute__((noreturn))
172
- #define ATTRIBUTE_ALIGNED(s) __attribute__((aligned(s)))
173
- #define CACHELINE_SIZE 64
174
- #define CACHELINE_ALIGNED ATTRIBUTE_ALIGNED(CACHELINE_SIZE)
175
- #define CACHELINE_ALIGNED_FN CACHELINE_ALIGNED
176
- #define PAGE_ALIGNED ATTRIBUTE_ALIGNED(kPageSize)
177
-
178
- #define MESH_EXPORT __attribute__((visibility("default")))
179
-
180
- #define ATTR_INITIAL_EXEC __attribute__((tls_model("initial-exec")))
181
-
182
- #define DISALLOW_COPY_AND_ASSIGN(TypeName) \
183
- TypeName(const TypeName &); \
184
- void operator=(const TypeName &)
185
-
186
- // runtime debug-level asserts
187
- #ifndef NDEBUG
188
- #define d_assert_msg(expr, fmt, ...) \
189
- ((likely(expr)) \
190
- ? static_cast<void>(0) \
191
- : mesh::internal::__mesh_assert_fail(#expr, __FILE__, __PRETTY_FUNCTION__, __LINE__, fmt, __VA_ARGS__))
192
-
193
- #define d_assert(expr) \
194
- ((likely(expr)) ? static_cast<void>(0) \
195
- : mesh::internal::__mesh_assert_fail(#expr, __FILE__, __PRETTY_FUNCTION__, __LINE__, ""))
196
- #else
197
- #define d_assert_msg(expr, fmt, ...)
198
- #define d_assert(expr)
199
- #endif
200
-
201
- // like d_assert, but still executed in release builds
202
- #define hard_assert_msg(expr, fmt, ...) \
203
- ((likely(expr)) \
204
- ? static_cast<void>(0) \
205
- : mesh::internal::__mesh_assert_fail(#expr, __FILE__, __PRETTY_FUNCTION__, __LINE__, fmt, __VA_ARGS__))
206
- #define hard_assert(expr) \
207
- ((likely(expr)) ? static_cast<void>(0) \
208
- : mesh::internal::__mesh_assert_fail(#expr, __FILE__, __PRETTY_FUNCTION__, __LINE__, ""))
209
-
210
- namespace mesh {
211
-
212
- // logging
213
- void debug(const char *fmt, ...);
214
-
215
- namespace internal {
216
- // assertions that don't attempt to recursively malloc
217
- void __attribute__((noreturn))
218
- __mesh_assert_fail(const char *assertion, const char *file, const char *func, int line, const char *fmt, ...);
219
-
220
- inline static mutex *getSeedMutex() {
221
- static char muBuf[sizeof(mutex)];
222
- static mutex *mu = new (muBuf) mutex();
223
- return mu;
224
- }
225
-
226
- // we must re-initialize our seed on program startup and after fork.
227
- // Must be called with getSeedMutex() held
228
- inline mt19937_64 *initSeed() {
229
- static char mtBuf[sizeof(mt19937_64)];
230
-
231
- static_assert(sizeof(mt19937_64::result_type) == sizeof(uint64_t), "expected 64-bit result_type for PRNG");
232
-
233
- // seed this Mersenne Twister PRNG with entropy from the host OS
234
- int fd = open("/dev/urandom", O_RDONLY);
235
- unsigned long buf;
236
- auto sz = read(fd, (void *)&buf, sizeof(unsigned long));
237
- hard_assert(sz == sizeof(unsigned long));
238
- // std::random_device rd;
239
- // return new (mtBuf) std::mt19937_64(rd());
240
- return new (mtBuf) std::mt19937_64(buf);
241
- }
242
-
243
- // cryptographically-strong thread-safe PRNG seed
244
- inline uint64_t seed() {
245
- static mt19937_64 *mt = NULL;
246
-
247
- lock_guard<mutex> lock(*getSeedMutex());
248
-
249
- if (unlikely(mt == nullptr))
250
- mt = initSeed();
251
-
252
- return (*mt)();
253
- }
254
- } // namespace internal
255
-
256
- namespace time {
257
- using clock = std::chrono::high_resolution_clock;
258
- using time_point = std::chrono::time_point<clock>;
259
-
260
- inline time_point ATTRIBUTE_ALWAYS_INLINE now() {
261
- #ifdef __linux__
262
- using namespace std::chrono;
263
- struct timespec tp;
264
- auto err = clock_gettime(CLOCK_MONOTONIC_COARSE, &tp);
265
- hard_assert(err == 0);
266
- return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));
267
- #else
268
- return std::chrono::high_resolution_clock::now();
269
- #endif
270
- }
271
- } // namespace time
272
-
273
- #define PREDICT_TRUE likely
274
-
275
- // from tcmalloc/gperftools
276
- class SizeMap {
277
- private:
278
- //-------------------------------------------------------------------
279
- // Mapping from size to size_class and vice versa
280
- //-------------------------------------------------------------------
281
-
282
- // Sizes <= 1024 have an alignment >= 8. So for such sizes we have an
283
- // array indexed by ceil(size/8). Sizes > 1024 have an alignment >= 128.
284
- // So for these larger sizes we have an array indexed by ceil(size/128).
285
- //
286
- // We flatten both logical arrays into one physical array and use
287
- // arithmetic to compute an appropriate index. The constants used by
288
- // ClassIndex() were selected to make the flattening work.
289
- //
290
- // Examples:
291
- // Size Expression Index
292
- // -------------------------------------------------------
293
- // 0 (0 + 7) / 8 0
294
- // 1 (1 + 7) / 8 1
295
- // ...
296
- // 1024 (1024 + 7) / 8 128
297
- // 1025 (1025 + 127 + (120<<7)) / 128 129
298
- // ...
299
- // 32768 (32768 + 127 + (120<<7)) / 128 376
300
- static const int kMaxSmallSize = 1024;
301
- static const size_t kClassArraySize = ((kMaxSize + 127 + (120 << 7)) >> 7) + 1;
302
- static const unsigned char class_array_[kClassArraySize];
303
-
304
- static inline size_t SmallSizeClass(size_t s) {
305
- return (static_cast<uint32_t>(s) + 7) >> 3;
306
- }
307
-
308
- static inline size_t LargeSizeClass(size_t s) {
309
- return (static_cast<uint32_t>(s) + 127 + (120 << 7)) >> 7;
310
- }
311
-
312
- // If size is no more than kMaxSize, compute index of the
313
- // class_array[] entry for it, putting the class index in output
314
- // parameter idx and returning true. Otherwise return false.
315
- static inline bool ATTRIBUTE_ALWAYS_INLINE ClassIndexMaybe(size_t s, uint32_t *idx) {
316
- if (PREDICT_TRUE(s <= kMaxSmallSize)) {
317
- *idx = (static_cast<uint32_t>(s) + 7) >> 3;
318
- return true;
319
- } else if (s <= kMaxSize) {
320
- *idx = (static_cast<uint32_t>(s) + 127 + (120 << 7)) >> 7;
321
- return true;
322
- }
323
- return false;
324
- }
325
-
326
- // Compute index of the class_array[] entry for a given size
327
- static inline size_t ClassIndex(size_t s) {
328
- // Use unsigned arithmetic to avoid unnecessary sign extensions.
329
- d_assert(s <= kMaxSize);
330
- if (PREDICT_TRUE(s <= kMaxSmallSize)) {
331
- return SmallSizeClass(s);
332
- } else {
333
- return LargeSizeClass(s);
334
- }
335
- }
336
-
337
- // Mapping from size class to max size storable in that class
338
- static const int32_t class_to_size_[kClassSizesMax];
339
-
340
- public:
341
- static constexpr size_t num_size_classes = 25;
342
-
343
- // Constructor should do nothing since we rely on explicit Init()
344
- // call, which may or may not be called before the constructor runs.
345
- SizeMap() {
346
- }
347
-
348
- static inline int SizeClass(size_t size) {
349
- return class_array_[ClassIndex(size)];
350
- }
351
-
352
- // Check if size is small enough to be representable by a size
353
- // class, and if it is, put matching size class into *cl. Returns
354
- // true iff matching size class was found.
355
- static inline bool ATTRIBUTE_ALWAYS_INLINE GetSizeClass(size_t size, uint32_t *cl) {
356
- uint32_t idx;
357
- if (!ClassIndexMaybe(size, &idx)) {
358
- return false;
359
- }
360
- *cl = class_array_[idx];
361
- return true;
362
- }
363
-
364
- // Get the byte-size for a specified class
365
- // static inline int32_t ATTRIBUTE_ALWAYS_INLINE ByteSizeForClass(uint32_t cl) {
366
- static inline size_t ATTRIBUTE_ALWAYS_INLINE ByteSizeForClass(int32_t cl) {
367
- return class_to_size_[static_cast<uint32_t>(cl)];
368
- }
369
-
370
- // Mapping from size class to max size storable in that class
371
- static inline int32_t class_to_size(uint32_t cl) {
372
- return class_to_size_[cl];
373
- }
374
- };
375
- } // namespace mesh
376
-
377
- #endif // MESH_COMMON_H