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,75 +0,0 @@
|
|
1
|
-
// -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil -*-
|
2
|
-
// Copyright 2019 The Heap-Layers and 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
|
-
#ifndef __GNUC__
|
7
|
-
#error "This file requires the GNU compiler."
|
8
|
-
#endif
|
9
|
-
|
10
|
-
#include <errno.h>
|
11
|
-
#include <malloc.h>
|
12
|
-
#include <pthread.h>
|
13
|
-
#include <stdio.h>
|
14
|
-
#include <stdlib.h>
|
15
|
-
#include <string.h>
|
16
|
-
#include <new>
|
17
|
-
|
18
|
-
/*
|
19
|
-
To use this library,
|
20
|
-
you only need to define the following allocation functions:
|
21
|
-
|
22
|
-
- xxmalloc
|
23
|
-
- xxfree
|
24
|
-
- xxmalloc_usable_size
|
25
|
-
- xxmalloc_lock
|
26
|
-
- xxmalloc_unlock
|
27
|
-
|
28
|
-
See the extern "C" block below for function prototypes and more
|
29
|
-
details. YOU SHOULD NOT NEED TO MODIFY ANY OF THE CODE HERE TO
|
30
|
-
SUPPORT ANY ALLOCATOR.
|
31
|
-
|
32
|
-
|
33
|
-
LIMITATIONS:
|
34
|
-
|
35
|
-
- This wrapper assumes that the underlying allocator will do "the
|
36
|
-
right thing" when xxfree() is called with a pointer internal to an
|
37
|
-
allocated object. Header-based allocators, for example, need not
|
38
|
-
apply.
|
39
|
-
|
40
|
-
*/
|
41
|
-
|
42
|
-
#define WEAK(x) __attribute__((weak, alias(#x)))
|
43
|
-
#ifndef __THROW
|
44
|
-
#define __THROW
|
45
|
-
#endif
|
46
|
-
|
47
|
-
#ifndef CACHELINE_ALIGNED_FN
|
48
|
-
#define ATTRIBUTE_ALIGNED(s) __attribute__((aligned(s)))
|
49
|
-
#define CACHELINE_SIZE 64
|
50
|
-
#define CACHELINE_ALIGNED_FN ATTRIBUTE_ALIGNED(CACHELINE_SIZE)
|
51
|
-
#endif
|
52
|
-
|
53
|
-
#define CUSTOM_PREFIX(x) mesh_##x
|
54
|
-
|
55
|
-
#define WEAK_REDEF1(type, fname, arg1) MESH_EXPORT type fname(arg1) __THROW WEAK(mesh_##fname)
|
56
|
-
#define WEAK_REDEF2(type, fname, arg1, arg2) MESH_EXPORT type fname(arg1, arg2) __THROW WEAK(mesh_##fname)
|
57
|
-
#define WEAK_REDEF3(type, fname, arg1, arg2, arg3) MESH_EXPORT type fname(arg1, arg2, arg3) __THROW WEAK(mesh_##fname)
|
58
|
-
|
59
|
-
extern "C" {
|
60
|
-
WEAK_REDEF1(void *, malloc, size_t);
|
61
|
-
WEAK_REDEF1(void, free, void *);
|
62
|
-
WEAK_REDEF1(void, cfree, void *);
|
63
|
-
WEAK_REDEF2(void *, calloc, size_t, size_t);
|
64
|
-
WEAK_REDEF2(void *, realloc, void *, size_t);
|
65
|
-
WEAK_REDEF2(void *, memalign, size_t, size_t);
|
66
|
-
WEAK_REDEF3(int, posix_memalign, void **, size_t, size_t);
|
67
|
-
WEAK_REDEF2(void *, aligned_alloc, size_t, size_t);
|
68
|
-
WEAK_REDEF1(size_t, malloc_usable_size, void *);
|
69
|
-
}
|
70
|
-
|
71
|
-
#include "wrapper.cc"
|
72
|
-
#ifdef __GLIBC__
|
73
|
-
// don't do this under musl
|
74
|
-
#include "wrappers/gnuwrapper-hooks.cpp"
|
75
|
-
#endif
|
@@ -1,356 +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_INTERNAL_H
|
8
|
-
#define MESH_INTERNAL_H
|
9
|
-
|
10
|
-
#ifdef __linux__
|
11
|
-
#include <sys/syscall.h>
|
12
|
-
#include <unistd.h>
|
13
|
-
#endif
|
14
|
-
|
15
|
-
#include <atomic>
|
16
|
-
#include <unordered_set>
|
17
|
-
|
18
|
-
#include <signal.h>
|
19
|
-
#include <stdint.h>
|
20
|
-
|
21
|
-
#include "common.h"
|
22
|
-
#include "rng/mwc.h"
|
23
|
-
|
24
|
-
// never allocate executable heap
|
25
|
-
#define HL_MMAP_PROTECTION_MASK (PROT_READ | PROT_WRITE)
|
26
|
-
#define MALLOC_TRACE 0
|
27
|
-
|
28
|
-
#include "heaplayers.h"
|
29
|
-
|
30
|
-
#include "partitioned_heap.h"
|
31
|
-
|
32
|
-
#ifdef __linux__
|
33
|
-
inline pid_t gettid(void) {
|
34
|
-
return syscall(__NR_gettid);
|
35
|
-
}
|
36
|
-
#endif
|
37
|
-
#ifdef __APPLE__
|
38
|
-
inline pid_t gettid(void) {
|
39
|
-
uint64_t tid;
|
40
|
-
pthread_threadid_np(NULL, &tid);
|
41
|
-
return static_cast<uint32_t>(tid);
|
42
|
-
}
|
43
|
-
#endif
|
44
|
-
|
45
|
-
namespace mesh {
|
46
|
-
|
47
|
-
namespace internal {
|
48
|
-
enum PageType {
|
49
|
-
Clean = 0,
|
50
|
-
Dirty = 1,
|
51
|
-
Meshed = 2,
|
52
|
-
Unknown = 3,
|
53
|
-
};
|
54
|
-
} // namespace internal
|
55
|
-
|
56
|
-
class MiniHeapID {
|
57
|
-
public:
|
58
|
-
MiniHeapID() noexcept : _id{0} {
|
59
|
-
}
|
60
|
-
|
61
|
-
explicit constexpr MiniHeapID(uint32_t id) : _id{id} {
|
62
|
-
}
|
63
|
-
|
64
|
-
MiniHeapID(const MiniHeapID &rhs) = default;
|
65
|
-
|
66
|
-
constexpr MiniHeapID(MiniHeapID &&rhs) = default;
|
67
|
-
|
68
|
-
MiniHeapID &operator=(const MiniHeapID &rhs) = default;
|
69
|
-
|
70
|
-
bool operator!=(const MiniHeapID &rhs) const {
|
71
|
-
return _id != rhs._id;
|
72
|
-
}
|
73
|
-
|
74
|
-
bool operator==(const MiniHeapID &rhs) const {
|
75
|
-
return _id == rhs._id;
|
76
|
-
}
|
77
|
-
|
78
|
-
bool hasValue() const {
|
79
|
-
return _id != 0;
|
80
|
-
}
|
81
|
-
|
82
|
-
uint32_t value() const {
|
83
|
-
return _id;
|
84
|
-
}
|
85
|
-
|
86
|
-
private:
|
87
|
-
uint32_t _id;
|
88
|
-
};
|
89
|
-
|
90
|
-
namespace list {
|
91
|
-
static constexpr MiniHeapID Head{UINT32_MAX};
|
92
|
-
// TODO: add a type to represent this
|
93
|
-
static constexpr uint8_t Full = 0;
|
94
|
-
static constexpr uint8_t Partial = 1;
|
95
|
-
static constexpr uint8_t Empty = 2;
|
96
|
-
static constexpr uint8_t Attached = 3;
|
97
|
-
static constexpr uint8_t Max = 4;
|
98
|
-
} // namespace list
|
99
|
-
|
100
|
-
class MiniHeap;
|
101
|
-
MiniHeap *GetMiniHeap(const MiniHeapID id);
|
102
|
-
MiniHeapID GetMiniHeapID(const MiniHeap *mh);
|
103
|
-
|
104
|
-
typedef std::array<MiniHeap *, kMaxSplitListSize> SplitArray;
|
105
|
-
typedef std::array<std::pair<MiniHeap *, MiniHeap *>, kMaxMergeSets> MergeSetArray;
|
106
|
-
|
107
|
-
template <typename Object, typename ID>
|
108
|
-
class ListEntry {
|
109
|
-
public:
|
110
|
-
typedef ListEntry<Object, ID> Entry;
|
111
|
-
|
112
|
-
ListEntry() noexcept : _prev{}, _next{} {
|
113
|
-
}
|
114
|
-
|
115
|
-
explicit constexpr ListEntry(ID prev, ID next) : _prev{prev}, _next{next} {
|
116
|
-
}
|
117
|
-
|
118
|
-
ListEntry(const ListEntry &rhs) = default;
|
119
|
-
ListEntry &operator=(const ListEntry &) = default;
|
120
|
-
|
121
|
-
inline bool empty() const {
|
122
|
-
return !_prev.hasValue() || !_next.hasValue();
|
123
|
-
}
|
124
|
-
|
125
|
-
inline ID next() const {
|
126
|
-
return _next;
|
127
|
-
}
|
128
|
-
|
129
|
-
inline ID prev() const {
|
130
|
-
return _prev;
|
131
|
-
}
|
132
|
-
|
133
|
-
inline void setNext(ID next) {
|
134
|
-
// mesh::debug("%p.setNext: %u\n", this, next);
|
135
|
-
_next = next;
|
136
|
-
}
|
137
|
-
|
138
|
-
inline void setPrev(ID prev) {
|
139
|
-
_prev = prev;
|
140
|
-
}
|
141
|
-
|
142
|
-
// add calls remove for you
|
143
|
-
void add(Entry *listHead, uint8_t listId, ID selfId, Object *newEntry) {
|
144
|
-
const uint8_t oldId = newEntry->freelistId();
|
145
|
-
d_assert(oldId != listId);
|
146
|
-
d_assert(!newEntry->isLargeAlloc());
|
147
|
-
|
148
|
-
Entry *newEntryFreelist = newEntry->getFreelist();
|
149
|
-
if (likely(newEntryFreelist->next().hasValue())) {
|
150
|
-
// we will be part of a list every time except the first time add is called after alloc
|
151
|
-
newEntryFreelist->remove(listHead);
|
152
|
-
}
|
153
|
-
|
154
|
-
newEntry->setFreelistId(listId);
|
155
|
-
|
156
|
-
const ID newEntryId = GetMiniHeapID(newEntry);
|
157
|
-
ID lastId = prev();
|
158
|
-
Entry *prevList = nullptr;
|
159
|
-
if (lastId == list::Head) {
|
160
|
-
prevList = this;
|
161
|
-
} else {
|
162
|
-
Object *last = GetMiniHeap(lastId);
|
163
|
-
prevList = last->getFreelist();
|
164
|
-
}
|
165
|
-
prevList->setNext(newEntryId);
|
166
|
-
*newEntry->getFreelist() = ListEntry{lastId, selfId};
|
167
|
-
this->setPrev(newEntryId);
|
168
|
-
}
|
169
|
-
|
170
|
-
void remove(Entry *listHead) {
|
171
|
-
ID prevId = _prev;
|
172
|
-
ID nextId = _next;
|
173
|
-
// we may have just been created + not added to any freelist yet
|
174
|
-
if (!prevId.hasValue() || !nextId.hasValue()) {
|
175
|
-
return;
|
176
|
-
}
|
177
|
-
Entry *prev = nullptr;
|
178
|
-
if (prevId == list::Head) {
|
179
|
-
prev = listHead;
|
180
|
-
} else {
|
181
|
-
Object *mh = GetMiniHeap(prevId);
|
182
|
-
d_assert(mh != nullptr);
|
183
|
-
prev = mh->getFreelist();
|
184
|
-
}
|
185
|
-
Entry *next = nullptr;
|
186
|
-
if (nextId == list::Head) {
|
187
|
-
next = listHead;
|
188
|
-
} else {
|
189
|
-
Object *mh = GetMiniHeap(nextId);
|
190
|
-
d_assert(mh != nullptr);
|
191
|
-
next = mh->getFreelist();
|
192
|
-
}
|
193
|
-
|
194
|
-
prev->setNext(nextId);
|
195
|
-
next->setPrev(prevId);
|
196
|
-
_prev = MiniHeapID{};
|
197
|
-
_next = MiniHeapID{};
|
198
|
-
}
|
199
|
-
|
200
|
-
private:
|
201
|
-
MiniHeapID _prev{};
|
202
|
-
MiniHeapID _next{};
|
203
|
-
};
|
204
|
-
|
205
|
-
typedef ListEntry<MiniHeap, MiniHeapID> MiniHeapListEntry;
|
206
|
-
|
207
|
-
typedef uint32_t Offset;
|
208
|
-
typedef uint32_t Length;
|
209
|
-
|
210
|
-
struct Span {
|
211
|
-
// offset and length are in pages
|
212
|
-
explicit Span(Offset _offset, Length _length) : offset(_offset), length(_length) {
|
213
|
-
}
|
214
|
-
|
215
|
-
Span(const Span &rhs) : offset(rhs.offset), length(rhs.length) {
|
216
|
-
}
|
217
|
-
|
218
|
-
Span &operator=(const Span &rhs) {
|
219
|
-
offset = rhs.offset;
|
220
|
-
length = rhs.length;
|
221
|
-
return *this;
|
222
|
-
}
|
223
|
-
|
224
|
-
Span(Span &&rhs) : offset(rhs.offset), length(rhs.length) {
|
225
|
-
}
|
226
|
-
|
227
|
-
bool empty() const {
|
228
|
-
return length == 0;
|
229
|
-
}
|
230
|
-
|
231
|
-
// reduce the size of this span to pageCount, return another span
|
232
|
-
// with the rest of the pages.
|
233
|
-
Span splitAfter(Length pageCount) {
|
234
|
-
d_assert(pageCount <= length);
|
235
|
-
auto restPageCount = length - pageCount;
|
236
|
-
length = pageCount;
|
237
|
-
return Span(offset + pageCount, restPageCount);
|
238
|
-
}
|
239
|
-
|
240
|
-
uint32_t spanClass() const {
|
241
|
-
return std::min(length, kSpanClassCount) - 1;
|
242
|
-
}
|
243
|
-
|
244
|
-
size_t byteLength() const {
|
245
|
-
return length * kPageSize;
|
246
|
-
}
|
247
|
-
|
248
|
-
inline bool operator==(const Span &rhs) {
|
249
|
-
return offset == rhs.offset && length == rhs.length;
|
250
|
-
}
|
251
|
-
|
252
|
-
inline bool operator!=(const Span &rhs) {
|
253
|
-
return !(*this == rhs);
|
254
|
-
}
|
255
|
-
|
256
|
-
Offset offset;
|
257
|
-
Length length;
|
258
|
-
};
|
259
|
-
|
260
|
-
// keep in-sync with the version in plasma/mesh.h
|
261
|
-
enum BitType {
|
262
|
-
MESH_BIT_0,
|
263
|
-
MESH_BIT_1,
|
264
|
-
MESH_BIT_2,
|
265
|
-
MESH_BIT_3,
|
266
|
-
MESH_BIT_COUNT,
|
267
|
-
};
|
268
|
-
|
269
|
-
namespace internal {
|
270
|
-
|
271
|
-
// return the kernel's perspective on our proportional set size
|
272
|
-
size_t measurePssKiB();
|
273
|
-
|
274
|
-
inline void *MaskToPage(const void *ptr) {
|
275
|
-
const auto ptrval = reinterpret_cast<uintptr_t>(ptr);
|
276
|
-
return reinterpret_cast<void *>(ptrval & (uintptr_t) ~(CPUInfo::PageSize - 1));
|
277
|
-
}
|
278
|
-
|
279
|
-
// efficiently copy data from srcFd to dstFd
|
280
|
-
int copyFile(int dstFd, int srcFd, off_t off, size_t sz);
|
281
|
-
|
282
|
-
// for mesh-internal data structures, like heap metadata
|
283
|
-
class Heap : public ExactlyOneHeap<LockedHeap<PosixLockType, PartitionedHeap>> {
|
284
|
-
private:
|
285
|
-
typedef ExactlyOneHeap<LockedHeap<PosixLockType, PartitionedHeap>> SuperHeap;
|
286
|
-
|
287
|
-
public:
|
288
|
-
Heap() : SuperHeap() {
|
289
|
-
static_assert(Alignment % 16 == 0, "16-byte alignment");
|
290
|
-
}
|
291
|
-
};
|
292
|
-
|
293
|
-
// make a shared pointer allocated from our internal heap that will
|
294
|
-
// also free to the internal heap when all references have been
|
295
|
-
// dropped.
|
296
|
-
template <typename T, class... Args>
|
297
|
-
inline std::shared_ptr<T> make_shared(Args &&...args) {
|
298
|
-
// FIXME: somehow centralize this static.
|
299
|
-
static STLAllocator<T, Heap> heap;
|
300
|
-
return std::allocate_shared<T, STLAllocator<T, Heap>, Args...>(heap, std::forward<Args>(args)...);
|
301
|
-
}
|
302
|
-
|
303
|
-
extern STLAllocator<char, Heap> allocator;
|
304
|
-
|
305
|
-
template <typename K, typename V>
|
306
|
-
using unordered_map = std::unordered_map<K, V, hash<K>, equal_to<K>, STLAllocator<pair<const K, V>, Heap>>;
|
307
|
-
|
308
|
-
template <typename K>
|
309
|
-
using unordered_set = std::unordered_set<K, hash<K>, equal_to<K>, STLAllocator<K, Heap>>;
|
310
|
-
|
311
|
-
template <typename K, typename V>
|
312
|
-
using map = std::map<K, V, std::less<K>, STLAllocator<pair<const K, V>, Heap>>;
|
313
|
-
|
314
|
-
typedef std::basic_string<char, std::char_traits<char>, STLAllocator<char, Heap>> string;
|
315
|
-
|
316
|
-
template <typename T>
|
317
|
-
using vector = std::vector<T, STLAllocator<T, Heap>>;
|
318
|
-
|
319
|
-
// https://stackoverflow.com/questions/529831/returning-the-greatest-key-strictly-less-than-the-given-key-in-a-c-map
|
320
|
-
template <typename Map>
|
321
|
-
typename Map::const_iterator greatest_leq(Map const &m, typename Map::key_type const &k) {
|
322
|
-
typename Map::const_iterator it = m.upper_bound(k);
|
323
|
-
if (it != m.begin()) {
|
324
|
-
return --it;
|
325
|
-
}
|
326
|
-
return m.end();
|
327
|
-
}
|
328
|
-
|
329
|
-
// https://stackoverflow.com/questions/529831/returning-the-greatest-key-strictly-less-than-the-given-key-in-a-c-map
|
330
|
-
template <typename Map>
|
331
|
-
typename Map::iterator greatest_leq(Map &m, typename Map::key_type const &k) {
|
332
|
-
typename Map::iterator it = m.upper_bound(k);
|
333
|
-
if (it != m.begin()) {
|
334
|
-
return --it;
|
335
|
-
}
|
336
|
-
return m.end();
|
337
|
-
}
|
338
|
-
|
339
|
-
// based on LLVM's libcxx std::shuffle
|
340
|
-
template <class _RandomAccessIterator, class _RNG>
|
341
|
-
inline void mwcShuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, _RNG &__rng) {
|
342
|
-
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
|
343
|
-
|
344
|
-
difference_type __d = __last - __first;
|
345
|
-
if (__d > 1) {
|
346
|
-
for (--__last, --__d; __first < __last; ++__first, --__d) {
|
347
|
-
difference_type __i = __rng.inRange(0, __d);
|
348
|
-
if (__i != difference_type(0))
|
349
|
-
swap(*__first, *(__first + __i));
|
350
|
-
}
|
351
|
-
}
|
352
|
-
}
|
353
|
-
} // namespace internal
|
354
|
-
} // namespace mesh
|
355
|
-
|
356
|
-
#endif // MESH_INTERNAL_H
|
@@ -1,239 +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
|
-
#include <stdlib.h>
|
7
|
-
|
8
|
-
#include "runtime.h"
|
9
|
-
#include "thread_local_heap.h"
|
10
|
-
|
11
|
-
using namespace mesh;
|
12
|
-
|
13
|
-
static __attribute__((constructor)) void libmesh_init() {
|
14
|
-
mesh::real::init();
|
15
|
-
|
16
|
-
runtime().createSignalFd();
|
17
|
-
runtime().installSegfaultHandler();
|
18
|
-
runtime().initMaxMapCount();
|
19
|
-
|
20
|
-
char *meshPeriodStr = getenv("MESH_PERIOD_MS");
|
21
|
-
if (meshPeriodStr) {
|
22
|
-
long period = strtol(meshPeriodStr, nullptr, 10);
|
23
|
-
if (period < 0) {
|
24
|
-
period = 0;
|
25
|
-
}
|
26
|
-
runtime().setMeshPeriodMs(std::chrono::milliseconds{period});
|
27
|
-
}
|
28
|
-
|
29
|
-
char *bgThread = getenv("MESH_BACKGROUND_THREAD");
|
30
|
-
if (!bgThread)
|
31
|
-
return;
|
32
|
-
|
33
|
-
int shouldThread = atoi(bgThread);
|
34
|
-
if (shouldThread) {
|
35
|
-
runtime().startBgThread();
|
36
|
-
}
|
37
|
-
}
|
38
|
-
|
39
|
-
static __attribute__((destructor)) void libmesh_fini() {
|
40
|
-
char *mstats = getenv("MALLOCSTATS");
|
41
|
-
if (!mstats)
|
42
|
-
return;
|
43
|
-
|
44
|
-
int mlevel = atoi(mstats);
|
45
|
-
if (mlevel < 0)
|
46
|
-
mlevel = 0;
|
47
|
-
else if (mlevel > 2)
|
48
|
-
mlevel = 2;
|
49
|
-
|
50
|
-
runtime().heap().dumpStats(mlevel, false);
|
51
|
-
}
|
52
|
-
|
53
|
-
namespace mesh {
|
54
|
-
ATTRIBUTE_NEVER_INLINE
|
55
|
-
static void *allocSlowpath(size_t sz) {
|
56
|
-
ThreadLocalHeap *localHeap = ThreadLocalHeap::GetHeap();
|
57
|
-
return localHeap->malloc(sz);
|
58
|
-
}
|
59
|
-
|
60
|
-
ATTRIBUTE_NEVER_INLINE
|
61
|
-
static void *cxxNewSlowpath(size_t sz) {
|
62
|
-
ThreadLocalHeap *localHeap = ThreadLocalHeap::GetHeap();
|
63
|
-
return localHeap->cxxNew(sz);
|
64
|
-
}
|
65
|
-
|
66
|
-
ATTRIBUTE_NEVER_INLINE
|
67
|
-
static void freeSlowpath(void *ptr) {
|
68
|
-
// instead of instantiating a thread-local heap on free, just free
|
69
|
-
// to the global heap directly
|
70
|
-
runtime().heap().free(ptr);
|
71
|
-
}
|
72
|
-
|
73
|
-
ATTRIBUTE_NEVER_INLINE
|
74
|
-
static void *reallocSlowpath(void *oldPtr, size_t newSize) {
|
75
|
-
ThreadLocalHeap *localHeap = ThreadLocalHeap::GetHeap();
|
76
|
-
return localHeap->realloc(oldPtr, newSize);
|
77
|
-
}
|
78
|
-
|
79
|
-
ATTRIBUTE_NEVER_INLINE
|
80
|
-
static void *callocSlowpath(size_t count, size_t size) {
|
81
|
-
ThreadLocalHeap *localHeap = ThreadLocalHeap::GetHeap();
|
82
|
-
return localHeap->calloc(count, size);
|
83
|
-
}
|
84
|
-
|
85
|
-
ATTRIBUTE_NEVER_INLINE
|
86
|
-
static size_t usableSizeSlowpath(void *ptr) {
|
87
|
-
ThreadLocalHeap *localHeap = ThreadLocalHeap::GetHeap();
|
88
|
-
return localHeap->getSize(ptr);
|
89
|
-
}
|
90
|
-
|
91
|
-
ATTRIBUTE_NEVER_INLINE
|
92
|
-
static void *memalignSlowpath(size_t alignment, size_t size) {
|
93
|
-
ThreadLocalHeap *localHeap = ThreadLocalHeap::GetHeap();
|
94
|
-
return localHeap->memalign(alignment, size);
|
95
|
-
}
|
96
|
-
} // namespace mesh
|
97
|
-
|
98
|
-
extern "C" MESH_EXPORT CACHELINE_ALIGNED_FN void *mesh_malloc(size_t sz) {
|
99
|
-
ThreadLocalHeap *localHeap = ThreadLocalHeap::GetHeapIfPresent();
|
100
|
-
if (unlikely(localHeap == nullptr)) {
|
101
|
-
return mesh::allocSlowpath(sz);
|
102
|
-
}
|
103
|
-
|
104
|
-
return localHeap->malloc(sz);
|
105
|
-
}
|
106
|
-
#define xxmalloc mesh_malloc
|
107
|
-
|
108
|
-
extern "C" MESH_EXPORT CACHELINE_ALIGNED_FN void mesh_free(void *ptr) {
|
109
|
-
ThreadLocalHeap *localHeap = ThreadLocalHeap::GetHeapIfPresent();
|
110
|
-
if (unlikely(localHeap == nullptr)) {
|
111
|
-
mesh::freeSlowpath(ptr);
|
112
|
-
return;
|
113
|
-
}
|
114
|
-
|
115
|
-
return localHeap->free(ptr);
|
116
|
-
}
|
117
|
-
#define xxfree mesh_free
|
118
|
-
|
119
|
-
extern "C" MESH_EXPORT CACHELINE_ALIGNED_FN void mesh_sized_free(void *ptr, size_t sz) {
|
120
|
-
ThreadLocalHeap *localHeap = ThreadLocalHeap::GetHeapIfPresent();
|
121
|
-
if (unlikely(localHeap == nullptr)) {
|
122
|
-
mesh::freeSlowpath(ptr);
|
123
|
-
return;
|
124
|
-
}
|
125
|
-
|
126
|
-
return localHeap->sizedFree(ptr, sz);
|
127
|
-
}
|
128
|
-
|
129
|
-
extern "C" MESH_EXPORT CACHELINE_ALIGNED_FN void *mesh_realloc(void *oldPtr, size_t newSize) {
|
130
|
-
ThreadLocalHeap *localHeap = ThreadLocalHeap::GetHeapIfPresent();
|
131
|
-
if (unlikely(localHeap == nullptr)) {
|
132
|
-
return mesh::reallocSlowpath(oldPtr, newSize);
|
133
|
-
}
|
134
|
-
|
135
|
-
return localHeap->realloc(oldPtr, newSize);
|
136
|
-
}
|
137
|
-
|
138
|
-
extern "C" MESH_EXPORT CACHELINE_ALIGNED_FN size_t mesh_malloc_usable_size(void *ptr) {
|
139
|
-
ThreadLocalHeap *localHeap = ThreadLocalHeap::GetHeapIfPresent();
|
140
|
-
if (unlikely(localHeap == nullptr)) {
|
141
|
-
return mesh::usableSizeSlowpath(ptr);
|
142
|
-
}
|
143
|
-
|
144
|
-
return localHeap->getSize(ptr);
|
145
|
-
}
|
146
|
-
#define xxmalloc_usable_size mesh_malloc_usable_size
|
147
|
-
|
148
|
-
extern "C" MESH_EXPORT CACHELINE_ALIGNED_FN void *mesh_memalign(size_t alignment, size_t size)
|
149
|
-
#if !defined(__FreeBSD__) && !defined(__SVR4)
|
150
|
-
throw()
|
151
|
-
#endif
|
152
|
-
{
|
153
|
-
ThreadLocalHeap *localHeap = ThreadLocalHeap::GetHeapIfPresent();
|
154
|
-
if (unlikely(localHeap == nullptr)) {
|
155
|
-
return mesh::memalignSlowpath(alignment, size);
|
156
|
-
}
|
157
|
-
|
158
|
-
return localHeap->memalign(alignment, size);
|
159
|
-
}
|
160
|
-
|
161
|
-
extern "C" MESH_EXPORT CACHELINE_ALIGNED_FN void *mesh_calloc(size_t count, size_t size) {
|
162
|
-
ThreadLocalHeap *localHeap = ThreadLocalHeap::GetHeapIfPresent();
|
163
|
-
if (unlikely(localHeap == nullptr)) {
|
164
|
-
return mesh::callocSlowpath(count, size);
|
165
|
-
}
|
166
|
-
|
167
|
-
return localHeap->calloc(count, size);
|
168
|
-
}
|
169
|
-
|
170
|
-
extern "C" {
|
171
|
-
#ifdef __linux__
|
172
|
-
size_t MESH_EXPORT mesh_usable_size(void *ptr) __attribute__((weak, alias("mesh_malloc_usable_size")));
|
173
|
-
#else
|
174
|
-
// aliases are not supported on darwin
|
175
|
-
size_t MESH_EXPORT mesh_usable_size(void *ptr) {
|
176
|
-
return mesh_malloc_usable_size(ptr);
|
177
|
-
}
|
178
|
-
#endif // __linux__
|
179
|
-
|
180
|
-
// ensure we don't concurrently allocate/mess with internal heap data
|
181
|
-
// structures while forking. This is not normally invoked when
|
182
|
-
// libmesh is dynamically linked or LD_PRELOADed into a binary.
|
183
|
-
void MESH_EXPORT xxmalloc_lock(void) {
|
184
|
-
mesh::runtime().lock();
|
185
|
-
}
|
186
|
-
|
187
|
-
// ensure we don't concurrently allocate/mess with internal heap data
|
188
|
-
// structures while forking. This is not normally invoked when
|
189
|
-
// libmesh is dynamically linked or LD_PRELOADed into a binary.
|
190
|
-
void MESH_EXPORT xxmalloc_unlock(void) {
|
191
|
-
mesh::runtime().unlock();
|
192
|
-
}
|
193
|
-
|
194
|
-
int MESH_EXPORT sigaction(int signum, const struct sigaction *act, struct sigaction *oldact) MESH_THROW {
|
195
|
-
return mesh::runtime().sigaction(signum, act, oldact);
|
196
|
-
}
|
197
|
-
|
198
|
-
int MESH_EXPORT sigprocmask(int how, const sigset_t *set, sigset_t *oldset) MESH_THROW {
|
199
|
-
return mesh::runtime().sigprocmask(how, set, oldset);
|
200
|
-
}
|
201
|
-
|
202
|
-
// we need to wrap pthread_create and pthread_exit so that we can
|
203
|
-
// install our segfault handler and cleanup thread-local heaps.
|
204
|
-
int MESH_EXPORT pthread_create(pthread_t *thread, const pthread_attr_t *attr, mesh::PthreadFn startRoutine,
|
205
|
-
void *arg) MESH_THROW {
|
206
|
-
return mesh::runtime().createThread(thread, attr, startRoutine, arg);
|
207
|
-
}
|
208
|
-
|
209
|
-
void MESH_EXPORT ATTRIBUTE_NORETURN pthread_exit(void *retval) {
|
210
|
-
mesh::runtime().exitThread(retval);
|
211
|
-
}
|
212
|
-
|
213
|
-
// Same API as je_mallctl, allows a program to query stats and set
|
214
|
-
// allocator-related options.
|
215
|
-
int MESH_EXPORT mesh_mallctl(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
|
216
|
-
return mesh::runtime().heap().mallctl(name, oldp, oldlenp, newp, newlen);
|
217
|
-
}
|
218
|
-
|
219
|
-
#ifdef __linux__
|
220
|
-
|
221
|
-
int MESH_EXPORT epoll_wait(int __epfd, struct epoll_event *__events, int __maxevents, int __timeout) {
|
222
|
-
return mesh::runtime().epollWait(__epfd, __events, __maxevents, __timeout);
|
223
|
-
}
|
224
|
-
|
225
|
-
int MESH_EXPORT epoll_pwait(int __epfd, struct epoll_event *__events, int __maxevents, int __timeout,
|
226
|
-
const __sigset_t *__ss) {
|
227
|
-
return mesh::runtime().epollPwait(__epfd, __events, __maxevents, __timeout, __ss);
|
228
|
-
}
|
229
|
-
|
230
|
-
#endif
|
231
|
-
}
|
232
|
-
|
233
|
-
#if defined(__linux__)
|
234
|
-
#include "gnu_wrapper.cc"
|
235
|
-
#elif defined(__APPLE__)
|
236
|
-
#include "mac_wrapper.cc"
|
237
|
-
#else
|
238
|
-
#error "only linux and macOS support for now"
|
239
|
-
#endif
|