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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/ext/mesh/extconf.rb +22 -4
- data/ext/mesh/mesh.tar.gz +0 -0
- data/lib/mesh/version.rb +1 -1
- data/mesh.gemspec +3 -2
- metadata +4 -120
- data/ext/mesh/mesh/.bazelrc +0 -20
- data/ext/mesh/mesh/.bazelversion +0 -1
- data/ext/mesh/mesh/.clang-format +0 -15
- data/ext/mesh/mesh/.dockerignore +0 -5
- data/ext/mesh/mesh/.editorconfig +0 -16
- data/ext/mesh/mesh/.gitattributes +0 -4
- data/ext/mesh/mesh/.github/workflows/main.yml +0 -144
- data/ext/mesh/mesh/.gitignore +0 -51
- data/ext/mesh/mesh/AUTHORS +0 -5
- data/ext/mesh/mesh/CMakeLists.txt +0 -270
- data/ext/mesh/mesh/CODE_OF_CONDUCT.md +0 -77
- data/ext/mesh/mesh/Dockerfile +0 -30
- data/ext/mesh/mesh/LICENSE +0 -201
- data/ext/mesh/mesh/Makefile +0 -81
- data/ext/mesh/mesh/README.md +0 -97
- data/ext/mesh/mesh/WORKSPACE +0 -50
- data/ext/mesh/mesh/bazel +0 -350
- data/ext/mesh/mesh/mesh-pldi19-powers.pdf +0 -0
- data/ext/mesh/mesh/src/BUILD +0 -222
- data/ext/mesh/mesh/src/CMakeLists.txt +0 -85
- data/ext/mesh/mesh/src/bitmap.h +0 -590
- data/ext/mesh/mesh/src/cheap_heap.h +0 -170
- data/ext/mesh/mesh/src/common.h +0 -377
- data/ext/mesh/mesh/src/copts.bzl +0 -31
- data/ext/mesh/mesh/src/d_assert.cc +0 -75
- data/ext/mesh/mesh/src/fixed_array.h +0 -124
- data/ext/mesh/mesh/src/global_heap.cc +0 -547
- data/ext/mesh/mesh/src/global_heap.h +0 -569
- data/ext/mesh/mesh/src/gnu_wrapper.cc +0 -75
- data/ext/mesh/mesh/src/internal.h +0 -356
- data/ext/mesh/mesh/src/libmesh.cc +0 -239
- data/ext/mesh/mesh/src/mac_wrapper.cc +0 -528
- data/ext/mesh/mesh/src/measure_rss.cc +0 -44
- data/ext/mesh/mesh/src/measure_rss.h +0 -20
- data/ext/mesh/mesh/src/meshable_arena.cc +0 -776
- data/ext/mesh/mesh/src/meshable_arena.h +0 -309
- data/ext/mesh/mesh/src/meshing.h +0 -60
- data/ext/mesh/mesh/src/mini_heap.h +0 -532
- data/ext/mesh/mesh/src/mmap_heap.h +0 -104
- data/ext/mesh/mesh/src/one_way_mmap_heap.h +0 -77
- data/ext/mesh/mesh/src/partitioned_heap.h +0 -111
- data/ext/mesh/mesh/src/plasma/mesh.h +0 -33
- data/ext/mesh/mesh/src/real.cc +0 -52
- data/ext/mesh/mesh/src/real.h +0 -36
- data/ext/mesh/mesh/src/rng/mwc.h +0 -296
- data/ext/mesh/mesh/src/rng/mwc64.h +0 -58
- data/ext/mesh/mesh/src/rpl_printf.c +0 -1991
- data/ext/mesh/mesh/src/runtime.cc +0 -393
- data/ext/mesh/mesh/src/runtime.h +0 -114
- data/ext/mesh/mesh/src/shuffle_vector.h +0 -287
- data/ext/mesh/mesh/src/size_classes.def +0 -251
- data/ext/mesh/mesh/src/static/if.h +0 -36
- data/ext/mesh/mesh/src/static/log.h +0 -43
- data/ext/mesh/mesh/src/testing/benchmark/local_refill.cc +0 -103
- data/ext/mesh/mesh/src/testing/big-alloc.c +0 -28
- data/ext/mesh/mesh/src/testing/fragmenter.cc +0 -128
- data/ext/mesh/mesh/src/testing/global-large-stress.cc +0 -25
- data/ext/mesh/mesh/src/testing/local-alloc.c +0 -16
- data/ext/mesh/mesh/src/testing/meshing_benchmark.cc +0 -189
- data/ext/mesh/mesh/src/testing/thread.cc +0 -35
- data/ext/mesh/mesh/src/testing/unit/alignment.cc +0 -56
- data/ext/mesh/mesh/src/testing/unit/bitmap_test.cc +0 -274
- data/ext/mesh/mesh/src/testing/unit/concurrent_mesh_test.cc +0 -185
- data/ext/mesh/mesh/src/testing/unit/mesh_test.cc +0 -143
- data/ext/mesh/mesh/src/testing/unit/rng_test.cc +0 -22
- data/ext/mesh/mesh/src/testing/unit/size_class_test.cc +0 -66
- data/ext/mesh/mesh/src/testing/unit/triple_mesh_test.cc +0 -285
- data/ext/mesh/mesh/src/testing/userfaultfd-kernel-copy.cc +0 -164
- data/ext/mesh/mesh/src/thread_local_heap.cc +0 -163
- data/ext/mesh/mesh/src/thread_local_heap.h +0 -268
- data/ext/mesh/mesh/src/wrapper.cc +0 -433
- data/ext/mesh/mesh/support/export_mesh.cmake +0 -28
- data/ext/mesh/mesh/support/gen-size-classes +0 -57
- data/ext/mesh/mesh/support/install_all_configs +0 -33
- data/ext/mesh/mesh/support/remove_export_mesh.cmake +0 -48
- data/ext/mesh/mesh/support/update-bazelisk +0 -8
- data/ext/mesh/mesh/theory/32m80.png +0 -0
- data/ext/mesh/mesh/theory/64m80ind.png +0 -0
- data/ext/mesh/mesh/theory/bound_comparison.py +0 -67
- data/ext/mesh/mesh/theory/bounds/impdeg+1 +0 -135
- data/ext/mesh/mesh/theory/choose.py +0 -43
- data/ext/mesh/mesh/theory/common.py +0 -42
- data/ext/mesh/mesh/theory/compute_exp_Y.py +0 -134
- data/ext/mesh/mesh/theory/createRandomString.py +0 -69
- data/ext/mesh/mesh/theory/deg_bound_check.py +0 -100
- data/ext/mesh/mesh/theory/degcheck.py +0 -47
- data/ext/mesh/mesh/theory/dumps/32,1,80,dumb.txt +0 -81
- data/ext/mesh/mesh/theory/dumps/32,2,80,dumb.txt +0 -81
- data/ext/mesh/mesh/theory/dumps/32,3,80,dumb.txt +0 -81
- data/ext/mesh/mesh/theory/dumps/32,4,80,dumb.txt +0 -81
- data/ext/mesh/mesh/theory/dumps/32,5,80,dumb.txt +0 -81
- data/ext/mesh/mesh/theory/dumps/32,6,80,dumb.txt +0 -81
- data/ext/mesh/mesh/theory/dumps/32,7,80,dumb.txt +0 -81
- data/ext/mesh/mesh/theory/dumps/32,8,80,dumb.txt +0 -81
- data/ext/mesh/mesh/theory/dumps/32,9,80,dumb.txt +0 -81
- data/ext/mesh/mesh/theory/experiment.py +0 -303
- data/ext/mesh/mesh/theory/experiment_raw_results/.gitignore +0 -0
- data/ext/mesh/mesh/theory/greedy_experiment.py +0 -66
- data/ext/mesh/mesh/theory/greedy_experiment_copy.py +0 -46
- data/ext/mesh/mesh/theory/greedy_experiment_q.py +0 -75
- data/ext/mesh/mesh/theory/makeGraph.py +0 -64
- data/ext/mesh/mesh/theory/manyreps.png +0 -0
- data/ext/mesh/mesh/theory/manystrings.png +0 -0
- data/ext/mesh/mesh/theory/match_vs_color_experiment.py +0 -94
- data/ext/mesh/mesh/theory/maxmatch_vs_E[Y].py +0 -162
- data/ext/mesh/mesh/theory/maxmatch_vs_greedymatch.py +0 -96
- data/ext/mesh/mesh/theory/maxvdeg+1imp++32,80.png +0 -0
- data/ext/mesh/mesh/theory/mesh_util.py +0 -322
- data/ext/mesh/mesh/theory/meshers.py +0 -452
- data/ext/mesh/mesh/theory/meshingBenchmark.py +0 -96
- data/ext/mesh/mesh/theory/occupancyComparison.py +0 -133
- data/ext/mesh/mesh/theory/randmatch_vs_greedymatch.py +0 -97
- data/ext/mesh/mesh/theory/randmatch_vs_greedymatch_q.py +0 -103
- data/ext/mesh/mesh/theory/randmatch_vs_greedymatch_time.py +0 -117
- data/ext/mesh/mesh/theory/read_mesh_dump.py +0 -82
- data/ext/mesh/mesh/theory/test.py +0 -70
- 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
|
data/ext/mesh/mesh/src/common.h
DELETED
@@ -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
|