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
Binary file
|
data/ext/mesh/mesh/src/BUILD
DELETED
@@ -1,222 +0,0 @@
|
|
1
|
-
# Copyright 2020 The Mesh Authors. All rights reserved.
|
2
|
-
# Use of this source code is governed by the Apache License,
|
3
|
-
# Version 2.0, that can be found in the LICENSE file.
|
4
|
-
|
5
|
-
load("//src:copts.bzl", "MESH_DEFAULT_COPTS")
|
6
|
-
|
7
|
-
package(default_visibility = ["//visibility:private"])
|
8
|
-
|
9
|
-
licenses(["notice"]) # Apache 2.0
|
10
|
-
|
11
|
-
# used in copts.bzl to set llvm/gcc-only flags
|
12
|
-
config_setting(
|
13
|
-
name = "llvm",
|
14
|
-
flag_values = {
|
15
|
-
"@bazel_tools//tools/cpp:compiler": "llvm",
|
16
|
-
},
|
17
|
-
visibility = ["//visibility:private"],
|
18
|
-
)
|
19
|
-
|
20
|
-
config_setting(
|
21
|
-
name = "disable_meshing",
|
22
|
-
values = {
|
23
|
-
"define": "disable_meshing=true",
|
24
|
-
},
|
25
|
-
visibility = ["//visibility:private"],
|
26
|
-
)
|
27
|
-
|
28
|
-
config_setting(
|
29
|
-
name = "disable_randomization",
|
30
|
-
values = {
|
31
|
-
"define": "disable_randomization=true",
|
32
|
-
},
|
33
|
-
visibility = ["//visibility:private"],
|
34
|
-
)
|
35
|
-
|
36
|
-
config_setting(
|
37
|
-
name = "shuffle_on_free",
|
38
|
-
values = {
|
39
|
-
"define": "shuffle_on_free=true",
|
40
|
-
},
|
41
|
-
visibility = ["//visibility:private"],
|
42
|
-
)
|
43
|
-
|
44
|
-
NO_BUILTIN_MALLOC = [
|
45
|
-
"-fno-builtin-malloc",
|
46
|
-
"-fno-builtin-free",
|
47
|
-
]
|
48
|
-
|
49
|
-
COMMON_DEFINES = [] + select({
|
50
|
-
":disable_meshing": ["MESHING_ENABLED=0"],
|
51
|
-
"//conditions:default": ["MESHING_ENABLED=1"],
|
52
|
-
}) + select({
|
53
|
-
":disable_randomization": ["SHUFFLE_ON_INIT=0"],
|
54
|
-
"//conditions:default": ["SHUFFLE_ON_INIT=1"],
|
55
|
-
}) + select({
|
56
|
-
":shuffle_on_free": ["SHUFFLE_ON_FREE=1"],
|
57
|
-
"//conditions:default": ["SHUFFLE_ON_FREE=0"],
|
58
|
-
}) + select({
|
59
|
-
"@bazel_tools//src/conditions:linux_x86_64": [
|
60
|
-
# "_FORTIFY_SOURCE=2", # TODO: only in release; but I think Bazel takes care of this?
|
61
|
-
"_DEFAULT_SOURCE",
|
62
|
-
"_BSD_SOURCE",
|
63
|
-
"_XOPEN_SOURCE=700",
|
64
|
-
],
|
65
|
-
"//conditions:default": [],
|
66
|
-
})
|
67
|
-
|
68
|
-
COMMON_LINKOPTS = [
|
69
|
-
"-lm",
|
70
|
-
"-lpthread",
|
71
|
-
"-ldl",
|
72
|
-
] + select({
|
73
|
-
"@bazel_tools//src/conditions:linux_x86_64": [
|
74
|
-
"-Wl,--no-as-needed",
|
75
|
-
"-Wl,--no-add-needed",
|
76
|
-
"-Wl,--sort-common",
|
77
|
-
"-Wl,--hash-style=both",
|
78
|
-
"-Wl,--no-undefined",
|
79
|
-
"-Wl,-Bsymbolic-functions",
|
80
|
-
"-Wl,-z,now,-z,relro",
|
81
|
-
"-Wl,--exclude-libs=libc++.a",
|
82
|
-
"-Wl,--exclude-libs=libc++abi.a",
|
83
|
-
"-Wl,--exclude-libs=libunwind.a",
|
84
|
-
],
|
85
|
-
"//conditions:default": [],
|
86
|
-
})
|
87
|
-
|
88
|
-
cc_library(
|
89
|
-
name = "mesh-core",
|
90
|
-
srcs = [
|
91
|
-
"d_assert.cc",
|
92
|
-
"global_heap.cc",
|
93
|
-
"measure_rss.cc",
|
94
|
-
"meshable_arena.cc",
|
95
|
-
"real.cc",
|
96
|
-
"runtime.cc",
|
97
|
-
"thread_local_heap.cc",
|
98
|
-
],
|
99
|
-
hdrs = glob([
|
100
|
-
"*.h",
|
101
|
-
"plasma/*.h",
|
102
|
-
"rng/*.h",
|
103
|
-
"gnu_wrapper.cc",
|
104
|
-
"mac_wrapper.cc",
|
105
|
-
"rpl_printf.c",
|
106
|
-
"static/*.h",
|
107
|
-
"size_classes.def",
|
108
|
-
]),
|
109
|
-
copts = NO_BUILTIN_MALLOC + MESH_DEFAULT_COPTS,
|
110
|
-
defines = COMMON_DEFINES,
|
111
|
-
linkopts = COMMON_LINKOPTS,
|
112
|
-
linkstatic = True,
|
113
|
-
visibility = ["//visibility:private"],
|
114
|
-
deps = [
|
115
|
-
"@org_heaplayers",
|
116
|
-
],
|
117
|
-
)
|
118
|
-
|
119
|
-
cc_library(
|
120
|
-
name = "mesh-lib",
|
121
|
-
srcs = [
|
122
|
-
"libmesh.cc",
|
123
|
-
],
|
124
|
-
hdrs = glob([
|
125
|
-
"*.h",
|
126
|
-
"plasma/*.h",
|
127
|
-
"rng/*.h",
|
128
|
-
"gnu_wrapper.cc",
|
129
|
-
"mac_wrapper.cc",
|
130
|
-
"static/*.h",
|
131
|
-
"size_classes.def",
|
132
|
-
"wrapper.cc",
|
133
|
-
]),
|
134
|
-
# TODO: config options here too
|
135
|
-
copts = NO_BUILTIN_MALLOC + MESH_DEFAULT_COPTS,
|
136
|
-
defines = COMMON_DEFINES,
|
137
|
-
linkopts = COMMON_LINKOPTS,
|
138
|
-
linkstatic = True,
|
139
|
-
visibility = ["//visibility:private"],
|
140
|
-
deps = [
|
141
|
-
"@org_heaplayers",
|
142
|
-
],
|
143
|
-
)
|
144
|
-
|
145
|
-
cc_library(
|
146
|
-
name = "mesh",
|
147
|
-
srcs = [
|
148
|
-
"d_assert.cc",
|
149
|
-
"global_heap.cc",
|
150
|
-
"libmesh.cc",
|
151
|
-
"measure_rss.cc",
|
152
|
-
"meshable_arena.cc",
|
153
|
-
"real.cc",
|
154
|
-
"runtime.cc",
|
155
|
-
"thread_local_heap.cc",
|
156
|
-
],
|
157
|
-
hdrs = glob([
|
158
|
-
"*.h",
|
159
|
-
"plasma/*.h",
|
160
|
-
"rng/*.h",
|
161
|
-
"gnu_wrapper.cc",
|
162
|
-
"mac_wrapper.cc",
|
163
|
-
"wrapper.cc",
|
164
|
-
"rpl_printf.c",
|
165
|
-
"static/*.h",
|
166
|
-
"size_classes.def",
|
167
|
-
]),
|
168
|
-
copts = NO_BUILTIN_MALLOC + MESH_DEFAULT_COPTS,
|
169
|
-
defines = COMMON_DEFINES,
|
170
|
-
linkopts = COMMON_LINKOPTS + select({
|
171
|
-
"@bazel_tools//src/conditions:darwin": [
|
172
|
-
"-install_name /usr/local/lib/libmesh.dylib",
|
173
|
-
"-compatibility_version 1",
|
174
|
-
"-current_version 1",
|
175
|
-
"-ldl",
|
176
|
-
],
|
177
|
-
"//conditions:default": [],
|
178
|
-
}),
|
179
|
-
linkstatic = False,
|
180
|
-
visibility = ["//visibility:public"],
|
181
|
-
# disabled, as we directly specify the source files above.
|
182
|
-
# this is to work around a bazel bug on macOS where if we
|
183
|
-
# specify only deps, it produces an empty dylib
|
184
|
-
# deps = [
|
185
|
-
# ":mesh-core",
|
186
|
-
# ":mesh-lib",
|
187
|
-
# ],
|
188
|
-
deps = [
|
189
|
-
"@org_heaplayers",
|
190
|
-
],
|
191
|
-
# only valid for cc_library
|
192
|
-
alwayslink = 1,
|
193
|
-
)
|
194
|
-
|
195
|
-
cc_test(
|
196
|
-
name = "unit-tests",
|
197
|
-
srcs = glob([
|
198
|
-
"testing/unit/*.cc",
|
199
|
-
]),
|
200
|
-
copts = [
|
201
|
-
"-Isrc",
|
202
|
-
] + MESH_DEFAULT_COPTS,
|
203
|
-
linkopts = COMMON_LINKOPTS,
|
204
|
-
deps = [
|
205
|
-
":mesh-core",
|
206
|
-
"@com_google_googletest//:gtest_main",
|
207
|
-
],
|
208
|
-
)
|
209
|
-
|
210
|
-
cc_test(
|
211
|
-
name = "local-refill-benchmark",
|
212
|
-
srcs = ["testing/benchmark/local_refill.cc"],
|
213
|
-
copts = [
|
214
|
-
"-Isrc",
|
215
|
-
] + NO_BUILTIN_MALLOC + MESH_DEFAULT_COPTS,
|
216
|
-
linkopts = COMMON_LINKOPTS,
|
217
|
-
deps = [
|
218
|
-
":mesh-core",
|
219
|
-
"@com_google_benchmark//:benchmark",
|
220
|
-
"@com_google_googletest//:gtest_main",
|
221
|
-
],
|
222
|
-
)
|
@@ -1,85 +0,0 @@
|
|
1
|
-
#Include current folder to guarantee headers are found by files
|
2
|
-
include_directories(./)
|
3
|
-
include_directories(${CMAKE_CURRENT_BINARY_DIR}/../heap_layers-src)
|
4
|
-
# include_directories(./vendor/Heap-Layers)
|
5
|
-
|
6
|
-
#Create a common set of source files
|
7
|
-
set(common_src
|
8
|
-
d_assert.cc
|
9
|
-
global_heap.cc
|
10
|
-
runtime.cc
|
11
|
-
real.cc
|
12
|
-
meshable_arena.cc
|
13
|
-
measure_rss.cc
|
14
|
-
thread_local_heap.cc
|
15
|
-
)
|
16
|
-
|
17
|
-
#Create the set of source files for the mesh library
|
18
|
-
set(mesh_src
|
19
|
-
${common_src}
|
20
|
-
libmesh.cc
|
21
|
-
)
|
22
|
-
#Add a target for the mesh shared library
|
23
|
-
add_library(mesh SHARED ${mesh_src})
|
24
|
-
target_link_libraries(mesh PRIVATE -pthread -ldl)
|
25
|
-
|
26
|
-
#Create a set of source files for the unit tests
|
27
|
-
set(unit_src
|
28
|
-
${common_src}
|
29
|
-
${google_src}
|
30
|
-
testing/unit/alignment.cc
|
31
|
-
testing/unit/bitmap_test.cc
|
32
|
-
testing/unit/concurrent_mesh_test.cc
|
33
|
-
testing/unit/mesh_test.cc
|
34
|
-
testing/unit/rng_test.cc
|
35
|
-
testing/unit/size_class_test.cc
|
36
|
-
testing/unit/triple_mesh_test.cc
|
37
|
-
)
|
38
|
-
#Add a target to the unit tests executable
|
39
|
-
add_executable(unit.test ${unit_src})
|
40
|
-
target_link_libraries(unit.test PRIVATE -ldl -pthread )
|
41
|
-
|
42
|
-
set(GTEST_DIR ${CMAKE_CURRENT_BINARY_DIR}/../googletest-src/googletest)
|
43
|
-
|
44
|
-
ExternalProject_Get_Property(googletest binary_dir)
|
45
|
-
set(GTEST_LIBRARY_PATH ${binary_dir}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gtest.a)
|
46
|
-
target_link_libraries(unit.test PRIVATE ${GTEST_LIBRARY_PATH})
|
47
|
-
|
48
|
-
set(GTEST_MAIN_LIBRARY_PATH ${binary_dir}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gtest_main.a)
|
49
|
-
target_link_libraries(unit.test PRIVATE ${GTEST_MAIN_LIBRARY_PATH})
|
50
|
-
|
51
|
-
#Include header file paths to the unit tests
|
52
|
-
target_include_directories(unit.test SYSTEM PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../googletest-src/googletest/include)
|
53
|
-
|
54
|
-
#Set specific compiler flags for the unit tests
|
55
|
-
target_compile_definitions(unit.test PRIVATE -DGTEST_HAS_PTHREAD=1)
|
56
|
-
target_compile_options(unit.test PRIVATE -Wno-unused-const-variable -Wno-unused-variable)
|
57
|
-
|
58
|
-
#Deal with coverage
|
59
|
-
if(${GCOV})
|
60
|
-
add_custom_target(coverage_gcc
|
61
|
-
COMMAND cd ${CMAKE_BINARY_DIR}/src/CMakeFiles/unit.test.dir/ && ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unit.test
|
62
|
-
COMMAND lcov -o app.info -c --directory ${CMAKE_BINARY_DIR}/src/CMakeFiles/unit.test.dir/
|
63
|
-
COMMAND genhtml app.info
|
64
|
-
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/coverage/
|
65
|
-
DEPENDS unit.test)
|
66
|
-
endif()
|
67
|
-
|
68
|
-
#todo
|
69
|
-
if(${CLANGCOV})
|
70
|
-
add_custom_target(coverage_clang
|
71
|
-
COMMAND cd ${CMAKE_BINARY_DIR}/src/CMakeFiles/unit.test.dir/ && ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unit.test
|
72
|
-
COMMAND lcov -o app.info -c --directory ${CMAKE_BINARY_DIR}/src/CMakeFiles/unit.test.dir/
|
73
|
-
COMMAND genhtml app.info
|
74
|
-
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/coverage/
|
75
|
-
DEPENDS unit.test)
|
76
|
-
#add_custom_target(coverage_clang
|
77
|
-
# COMMAND rm -f unit.test.profdata
|
78
|
-
# COMMAND LLVM_PROFILE_FILE=default.profraw ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unit.test
|
79
|
-
# COMMAND llvm-profdata merge -sparse default.profraw -o unit.test.profdata
|
80
|
-
# COMMAND "llvm-cov show -format=html -instr-profile=unit.test.profdata ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unit.test -ignore-filename-regex=\\'.*(vendor|unit)/.*\\' >index.html"
|
81
|
-
# COMMAND "llvm-cov report -instr-profile=unit.test.profdata ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unit.test -ignore-filename-regex='.*(vendor|unit)/.*' -use-color"
|
82
|
-
# COMMAND rm -f default.profraw
|
83
|
-
# WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/coverage/
|
84
|
-
# DEPENDS unit.test)
|
85
|
-
endif()
|
data/ext/mesh/mesh/src/bitmap.h
DELETED
@@ -1,590 +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_BITMAP_H
|
8
|
-
#define MESH_BITMAP_H
|
9
|
-
|
10
|
-
#include <atomic>
|
11
|
-
#include <cstdint>
|
12
|
-
#include <cstdlib>
|
13
|
-
#include <cstring>
|
14
|
-
|
15
|
-
#include "common.h"
|
16
|
-
#include "internal.h"
|
17
|
-
|
18
|
-
#include "static/log.h"
|
19
|
-
|
20
|
-
#include "heaplayers.h"
|
21
|
-
|
22
|
-
namespace mesh {
|
23
|
-
namespace bitmap {
|
24
|
-
|
25
|
-
static constexpr size_t kWordBits = sizeof(size_t) * 8;
|
26
|
-
static constexpr size_t kWordBytes = sizeof(size_t);
|
27
|
-
/// The log of the number of bits in a size_t, for shifting.
|
28
|
-
static constexpr size_t kWordBitshift = staticlog(kWordBits);
|
29
|
-
// number of bytes used to store the bitmap -- rounds up to nearest sizeof(size_t)
|
30
|
-
static inline constexpr size_t ATTRIBUTE_ALWAYS_INLINE representationSize(size_t bitCount) {
|
31
|
-
return kWordBits * ((bitCount + kWordBits - 1) / kWordBits) / 8;
|
32
|
-
}
|
33
|
-
static inline constexpr size_t ATTRIBUTE_ALWAYS_INLINE wordCount(size_t byteCount) {
|
34
|
-
return byteCount / kWordBytes;
|
35
|
-
}
|
36
|
-
/// To find the bit in a word, do this: word & getMask(bitPosition)
|
37
|
-
/// @return a "mask" for the given position.
|
38
|
-
static inline constexpr size_t ATTRIBUTE_ALWAYS_INLINE getMask(uint64_t pos) {
|
39
|
-
return 1UL << pos;
|
40
|
-
}
|
41
|
-
|
42
|
-
using std::atomic_compare_exchange_weak_explicit;
|
43
|
-
using std::atomic_size_t;
|
44
|
-
|
45
|
-
// enables iteration through the set bits of the bitmap
|
46
|
-
template <typename Container>
|
47
|
-
class BitmapIter : public std::iterator<std::forward_iterator_tag, size_t> {
|
48
|
-
public:
|
49
|
-
BitmapIter(const Container &a, const size_t i) : _i(i), _cont(a) {
|
50
|
-
}
|
51
|
-
BitmapIter &operator++() {
|
52
|
-
if (unlikely(_i + 1 >= _cont.bitCount())) {
|
53
|
-
_i = _cont.bitCount();
|
54
|
-
return *this;
|
55
|
-
}
|
56
|
-
|
57
|
-
_i = _cont.lowestSetBitAt(_i + 1);
|
58
|
-
return *this;
|
59
|
-
}
|
60
|
-
bool operator==(const BitmapIter &rhs) const {
|
61
|
-
return _cont.bits() == rhs._cont.bits() && _i == rhs._i;
|
62
|
-
}
|
63
|
-
bool operator!=(const BitmapIter &rhs) const {
|
64
|
-
return _cont.bits() != rhs._cont.bits() || _i != rhs._i;
|
65
|
-
}
|
66
|
-
size_t &operator*() {
|
67
|
-
return _i;
|
68
|
-
}
|
69
|
-
|
70
|
-
private:
|
71
|
-
size_t _i;
|
72
|
-
const Container &_cont;
|
73
|
-
};
|
74
|
-
|
75
|
-
template <size_t maxBits>
|
76
|
-
class AtomicBitmapBase {
|
77
|
-
private:
|
78
|
-
DISALLOW_COPY_AND_ASSIGN(AtomicBitmapBase);
|
79
|
-
|
80
|
-
public:
|
81
|
-
typedef atomic_size_t word_t;
|
82
|
-
|
83
|
-
enum { MaxBitCount = maxBits };
|
84
|
-
|
85
|
-
protected:
|
86
|
-
AtomicBitmapBase(size_t bitCount) {
|
87
|
-
d_assert_msg(bitCount <= maxBits, "max bits (%zu) exceeded: %zu", maxBits, bitCount);
|
88
|
-
|
89
|
-
static_assert(wordCount(representationSize(maxBits)) == 4, "unexpected representation size");
|
90
|
-
// for (size_t i = 0; i < wordCount(representationSize(maxBits)); i++) {
|
91
|
-
// _bits[i].store(0, std::memory_order_relaxed);
|
92
|
-
// }
|
93
|
-
_bits[0].store(0, std::memory_order_relaxed);
|
94
|
-
_bits[1].store(0, std::memory_order_relaxed);
|
95
|
-
_bits[2].store(0, std::memory_order_relaxed);
|
96
|
-
_bits[3].store(0, std::memory_order_relaxed);
|
97
|
-
std::atomic_thread_fence(std::memory_order_release);
|
98
|
-
}
|
99
|
-
|
100
|
-
~AtomicBitmapBase() {
|
101
|
-
}
|
102
|
-
|
103
|
-
inline void ATTRIBUTE_ALWAYS_INLINE setAndExchangeAll(size_t *oldBits, const size_t *newBits) {
|
104
|
-
// for (size_t i = 0; i < wordCount(representationSize(maxBits)); i++) {
|
105
|
-
// oldBits[i] = _bits[i].exchange(newBits[i]);
|
106
|
-
// }
|
107
|
-
oldBits[0] = _bits[0].exchange(newBits[0], std::memory_order_acq_rel);
|
108
|
-
oldBits[1] = _bits[1].exchange(newBits[1], std::memory_order_acq_rel);
|
109
|
-
oldBits[2] = _bits[2].exchange(newBits[2], std::memory_order_acq_rel);
|
110
|
-
oldBits[3] = _bits[3].exchange(newBits[3], std::memory_order_acq_rel);
|
111
|
-
}
|
112
|
-
|
113
|
-
public:
|
114
|
-
inline bool ATTRIBUTE_ALWAYS_INLINE setAt(uint32_t item, uint32_t position) {
|
115
|
-
const auto mask = getMask(position);
|
116
|
-
|
117
|
-
size_t oldValue = _bits[item].load(std::memory_order_relaxed);
|
118
|
-
while (!atomic_compare_exchange_weak_explicit(&_bits[item], // address of word
|
119
|
-
&oldValue, // old val
|
120
|
-
oldValue | mask, // new val
|
121
|
-
std::memory_order_release, // success mem model
|
122
|
-
std::memory_order_relaxed)) {
|
123
|
-
}
|
124
|
-
|
125
|
-
return !(oldValue & mask);
|
126
|
-
}
|
127
|
-
|
128
|
-
inline bool ATTRIBUTE_ALWAYS_INLINE unsetAt(uint32_t item, uint32_t position) {
|
129
|
-
const auto mask = getMask(position);
|
130
|
-
|
131
|
-
size_t oldValue = _bits[item].load(std::memory_order_relaxed);
|
132
|
-
while (!atomic_compare_exchange_weak_explicit(&_bits[item], // address of word
|
133
|
-
&oldValue, // old val
|
134
|
-
oldValue & ~mask, // new val
|
135
|
-
std::memory_order_release, // success mem model
|
136
|
-
std::memory_order_relaxed)) {
|
137
|
-
}
|
138
|
-
|
139
|
-
return !(oldValue & mask);
|
140
|
-
}
|
141
|
-
|
142
|
-
inline uint32_t ATTRIBUTE_ALWAYS_INLINE inUseCount() const {
|
143
|
-
return __builtin_popcountl(_bits[0]) + __builtin_popcountl(_bits[1]) + __builtin_popcountl(_bits[2]) +
|
144
|
-
__builtin_popcountl(_bits[3]);
|
145
|
-
}
|
146
|
-
|
147
|
-
protected:
|
148
|
-
inline void nullBits() {
|
149
|
-
}
|
150
|
-
|
151
|
-
inline size_t ATTRIBUTE_ALWAYS_INLINE bitCount() const {
|
152
|
-
return maxBits;
|
153
|
-
}
|
154
|
-
|
155
|
-
word_t _bits[wordCount(representationSize(maxBits))] = {};
|
156
|
-
};
|
157
|
-
|
158
|
-
class RelaxedBitmapBase {
|
159
|
-
private:
|
160
|
-
// we explicitly want this
|
161
|
-
// DISALLOW_COPY_AND_ASSIGN(RelaxedBitmapBase);
|
162
|
-
|
163
|
-
public:
|
164
|
-
typedef size_t word_t;
|
165
|
-
|
166
|
-
enum { MaxBitCount = std::numeric_limits<uint64_t>::max() };
|
167
|
-
|
168
|
-
protected:
|
169
|
-
RelaxedBitmapBase(size_t bitCount)
|
170
|
-
: _bitCount(bitCount),
|
171
|
-
_isDynamicallyAllocated(1),
|
172
|
-
_bits(reinterpret_cast<word_t *>(internal::Heap().malloc(representationSize(bitCount)))) {
|
173
|
-
d_assert(_bits != nullptr);
|
174
|
-
clear();
|
175
|
-
}
|
176
|
-
|
177
|
-
RelaxedBitmapBase(size_t bitCount, char *backingMemory, bool clear)
|
178
|
-
: _bitCount(bitCount), _isDynamicallyAllocated(0), _bits(reinterpret_cast<word_t *>(backingMemory)) {
|
179
|
-
d_assert(_bits != nullptr);
|
180
|
-
if (clear) {
|
181
|
-
this->clear();
|
182
|
-
}
|
183
|
-
}
|
184
|
-
|
185
|
-
~RelaxedBitmapBase() {
|
186
|
-
if (_isDynamicallyAllocated && _bits) {
|
187
|
-
internal::Heap().free(_bits);
|
188
|
-
}
|
189
|
-
_bits = nullptr;
|
190
|
-
}
|
191
|
-
|
192
|
-
public:
|
193
|
-
inline void invert() {
|
194
|
-
const size_t numWords = wordCount(representationSize(_bitCount));
|
195
|
-
for (size_t i = 0; i < numWords; i++) {
|
196
|
-
_bits[i] = ~_bits[i];
|
197
|
-
}
|
198
|
-
}
|
199
|
-
|
200
|
-
inline void setAll(uint64_t bitCount) {
|
201
|
-
for (size_t i = 0; bitCount > 0; i++) {
|
202
|
-
if (bitCount >= 64) {
|
203
|
-
_bits[i] = (unsigned long)-1;
|
204
|
-
bitCount -= 64;
|
205
|
-
} else {
|
206
|
-
_bits[i] = (1ULL << bitCount) - 1;
|
207
|
-
bitCount = 0;
|
208
|
-
}
|
209
|
-
}
|
210
|
-
}
|
211
|
-
|
212
|
-
inline bool setAt(uint32_t item, uint32_t position) {
|
213
|
-
const auto mask = getMask(position);
|
214
|
-
|
215
|
-
size_t oldValue = _bits[item];
|
216
|
-
_bits[item] = oldValue | mask;
|
217
|
-
|
218
|
-
return !(oldValue & mask);
|
219
|
-
}
|
220
|
-
|
221
|
-
/// Clears the bit at the given index.
|
222
|
-
inline bool unsetAt(uint32_t item, uint32_t position) {
|
223
|
-
const auto mask = getMask(position);
|
224
|
-
|
225
|
-
size_t oldValue = _bits[item];
|
226
|
-
_bits[item] = oldValue & ~mask;
|
227
|
-
|
228
|
-
return !(oldValue & mask);
|
229
|
-
}
|
230
|
-
|
231
|
-
inline uint32_t inUseCount() const {
|
232
|
-
const auto wordCount = representationSize(_bitCount) / sizeof(size_t);
|
233
|
-
uint32_t count = 0;
|
234
|
-
for (size_t i = 0; i < wordCount; i++) {
|
235
|
-
count += __builtin_popcountl(_bits[i]);
|
236
|
-
}
|
237
|
-
return count;
|
238
|
-
}
|
239
|
-
|
240
|
-
protected:
|
241
|
-
inline void nullBits() {
|
242
|
-
_bits = nullptr;
|
243
|
-
}
|
244
|
-
|
245
|
-
void clear() {
|
246
|
-
memset(_bits, 0, representationSize(bitCount()));
|
247
|
-
}
|
248
|
-
|
249
|
-
inline size_t ATTRIBUTE_ALWAYS_INLINE bitCount() const {
|
250
|
-
return _bitCount;
|
251
|
-
}
|
252
|
-
|
253
|
-
const size_t _bitCount : 63;
|
254
|
-
const size_t _isDynamicallyAllocated : 1;
|
255
|
-
word_t *_bits;
|
256
|
-
};
|
257
|
-
|
258
|
-
template <size_t maxBits>
|
259
|
-
class RelaxedFixedBitmapBase {
|
260
|
-
private:
|
261
|
-
// we explicitly want to be able to copy these around
|
262
|
-
// DISALLOW_COPY_AND_ASSIGN(RelaxedFixedBitmapBase);
|
263
|
-
|
264
|
-
public:
|
265
|
-
typedef size_t word_t;
|
266
|
-
|
267
|
-
enum { MaxBitCount = maxBits };
|
268
|
-
|
269
|
-
protected:
|
270
|
-
RelaxedFixedBitmapBase(size_t bitCount) {
|
271
|
-
clear();
|
272
|
-
}
|
273
|
-
|
274
|
-
public:
|
275
|
-
inline void ATTRIBUTE_ALWAYS_INLINE invert() {
|
276
|
-
// constexpr size_t numWords = wordCount(representationSize(maxBits));
|
277
|
-
// for (size_t i = 0; i < numWords; i++) {
|
278
|
-
// _bits[i] = ~_bits[i];
|
279
|
-
// }
|
280
|
-
_bits[0] = ~_bits[0];
|
281
|
-
_bits[1] = ~_bits[1];
|
282
|
-
_bits[2] = ~_bits[2];
|
283
|
-
_bits[3] = ~_bits[3];
|
284
|
-
}
|
285
|
-
|
286
|
-
inline void ATTRIBUTE_ALWAYS_INLINE setAll(uint64_t bitCount) {
|
287
|
-
for (size_t i = 0; bitCount > 0; i++) {
|
288
|
-
if (bitCount >= 64) {
|
289
|
-
_bits[i] = (unsigned long)-1;
|
290
|
-
bitCount -= 64;
|
291
|
-
} else {
|
292
|
-
_bits[i] = (1ULL << bitCount) - 1;
|
293
|
-
bitCount = 0;
|
294
|
-
}
|
295
|
-
}
|
296
|
-
}
|
297
|
-
|
298
|
-
inline bool ATTRIBUTE_ALWAYS_INLINE setAt(uint32_t item, uint32_t position) {
|
299
|
-
const auto mask = getMask(position);
|
300
|
-
|
301
|
-
size_t oldValue = _bits[item];
|
302
|
-
_bits[item] = oldValue | mask;
|
303
|
-
|
304
|
-
return !(oldValue & mask);
|
305
|
-
}
|
306
|
-
|
307
|
-
/// Clears the bit at the given index.
|
308
|
-
inline bool ATTRIBUTE_ALWAYS_INLINE unsetAt(uint32_t item, uint32_t position) {
|
309
|
-
const auto mask = getMask(position);
|
310
|
-
|
311
|
-
size_t oldValue = _bits[item];
|
312
|
-
_bits[item] = oldValue & ~mask;
|
313
|
-
|
314
|
-
return !(oldValue & mask);
|
315
|
-
}
|
316
|
-
|
317
|
-
inline uint64_t ATTRIBUTE_ALWAYS_INLINE inUseCount() const {
|
318
|
-
constexpr auto wordCount = representationSize(maxBits) / sizeof(size_t);
|
319
|
-
uint32_t count = 0;
|
320
|
-
// for (size_t i = 0; i < wordCount; i++) {
|
321
|
-
// count += __builtin_popcountl(_bits[i]);
|
322
|
-
// }
|
323
|
-
count += __builtin_popcountl(_bits[0]);
|
324
|
-
count += __builtin_popcountl(_bits[1]);
|
325
|
-
count += __builtin_popcountl(_bits[2]);
|
326
|
-
count += __builtin_popcountl(_bits[3]);
|
327
|
-
return count;
|
328
|
-
}
|
329
|
-
|
330
|
-
protected:
|
331
|
-
inline void nullBits() {
|
332
|
-
}
|
333
|
-
|
334
|
-
void ATTRIBUTE_ALWAYS_INLINE clear() {
|
335
|
-
_bits[0] = 0;
|
336
|
-
_bits[1] = 0;
|
337
|
-
_bits[2] = 0;
|
338
|
-
_bits[3] = 0;
|
339
|
-
}
|
340
|
-
|
341
|
-
inline size_t ATTRIBUTE_ALWAYS_INLINE bitCount() const {
|
342
|
-
return maxBits;
|
343
|
-
}
|
344
|
-
|
345
|
-
word_t _bits[wordCount(representationSize(maxBits))] = {};
|
346
|
-
};
|
347
|
-
|
348
|
-
template <typename Super>
|
349
|
-
class BitmapBase : public Super {
|
350
|
-
public:
|
351
|
-
typedef typename Super::word_t word_t;
|
352
|
-
|
353
|
-
private:
|
354
|
-
DISALLOW_COPY_AND_ASSIGN(BitmapBase);
|
355
|
-
|
356
|
-
// typedef AtomicBitmapBase Super;
|
357
|
-
// typedef RelaxedBitmapBase Super;
|
358
|
-
typedef BitmapBase<Super> Bitmap;
|
359
|
-
|
360
|
-
static_assert(sizeof(size_t) == sizeof(atomic_size_t), "no overhead atomics");
|
361
|
-
static_assert(sizeof(word_t) == sizeof(size_t), "word_t should be size_t");
|
362
|
-
|
363
|
-
BitmapBase() = delete;
|
364
|
-
|
365
|
-
public:
|
366
|
-
typedef BitmapIter<Bitmap> iterator;
|
367
|
-
typedef BitmapIter<Bitmap> const const_iterator;
|
368
|
-
|
369
|
-
explicit BitmapBase(size_t bitCount) : Super(bitCount) {
|
370
|
-
}
|
371
|
-
|
372
|
-
explicit BitmapBase(size_t bitCount, char *backingMemory, bool clear = true) : Super(bitCount, backingMemory, clear) {
|
373
|
-
}
|
374
|
-
|
375
|
-
explicit BitmapBase(const std::string &str) : Super(str.length()) {
|
376
|
-
for (size_t i = 0; i < str.length(); ++i) {
|
377
|
-
char c = str[i];
|
378
|
-
d_assert_msg(c == '0' || c == '1', "expected 0 or 1 in bitstring, not %c ('%s')", c, str.c_str());
|
379
|
-
if (c == '1')
|
380
|
-
tryToSet(i);
|
381
|
-
}
|
382
|
-
}
|
383
|
-
|
384
|
-
explicit BitmapBase(const internal::string &str) : Super(str.length()) {
|
385
|
-
for (size_t i = 0; i < str.length(); ++i) {
|
386
|
-
char c = str[i];
|
387
|
-
d_assert_msg(c == '0' || c == '1', "expected 0 or 1 in bitstring, not %c ('%s')", c, str.c_str());
|
388
|
-
if (c == '1')
|
389
|
-
tryToSet(i);
|
390
|
-
}
|
391
|
-
}
|
392
|
-
|
393
|
-
BitmapBase(Bitmap &&rhs) : Super(rhs) {
|
394
|
-
rhs.Super::nullBits();
|
395
|
-
}
|
396
|
-
|
397
|
-
internal::string to_string(ssize_t bitCount = -1) const {
|
398
|
-
if (bitCount == -1)
|
399
|
-
bitCount = this->bitCount();
|
400
|
-
d_assert(0 <= bitCount && static_cast<size_t>(bitCount) <= this->bitCount());
|
401
|
-
|
402
|
-
internal::string s(bitCount + 1, 0);
|
403
|
-
|
404
|
-
for (ssize_t i = 0; i < bitCount; i++) {
|
405
|
-
s[i] = isSet(i) ? '1' : '0';
|
406
|
-
}
|
407
|
-
|
408
|
-
return s;
|
409
|
-
}
|
410
|
-
|
411
|
-
// number of bytes used to store the bitmap -- rounds up to nearest sizeof(size_t)
|
412
|
-
inline size_t byteCount() const {
|
413
|
-
return representationSize(bitCount());
|
414
|
-
}
|
415
|
-
|
416
|
-
inline size_t ATTRIBUTE_ALWAYS_INLINE bitCount() const {
|
417
|
-
return Super::bitCount();
|
418
|
-
}
|
419
|
-
|
420
|
-
inline uint64_t setFirstEmpty(uint64_t startingAt = 0) {
|
421
|
-
uint32_t startWord, off;
|
422
|
-
computeItemPosition(startingAt, startWord, off);
|
423
|
-
|
424
|
-
const size_t words = byteCount();
|
425
|
-
// const auto words = byteCount() / sizeof(size_t);
|
426
|
-
for (size_t i = startWord; i < words; i++) {
|
427
|
-
const size_t bits = Super::_bits[i];
|
428
|
-
if (bits == ~0UL) {
|
429
|
-
off = 0;
|
430
|
-
continue;
|
431
|
-
}
|
432
|
-
|
433
|
-
d_assert(off <= 63U);
|
434
|
-
size_t unsetBits = ~bits;
|
435
|
-
d_assert(unsetBits != 0);
|
436
|
-
|
437
|
-
// if the offset is 3, we want to mark the first 3 bits as 'set'
|
438
|
-
// or 'unavailable'.
|
439
|
-
unsetBits &= ~((1UL << off) - 1);
|
440
|
-
|
441
|
-
// if, after we've masked off everything below our offset there
|
442
|
-
// are no free bits, continue
|
443
|
-
if (unsetBits == 0) {
|
444
|
-
off = 0;
|
445
|
-
continue;
|
446
|
-
}
|
447
|
-
|
448
|
-
// debug("unset bits: %zx (off: %u, startingAt: %llu", unsetBits, off, startingAt);
|
449
|
-
|
450
|
-
size_t off = __builtin_ffsll(unsetBits) - 1;
|
451
|
-
const bool ok = Super::setAt(i, off);
|
452
|
-
// if we couldn't set the bit, we raced with a different thread. try again.
|
453
|
-
if (!ok) {
|
454
|
-
off++;
|
455
|
-
continue;
|
456
|
-
}
|
457
|
-
|
458
|
-
return kWordBits * i + off;
|
459
|
-
}
|
460
|
-
|
461
|
-
debug("mesh: bitmap completely full, aborting.\n");
|
462
|
-
abort();
|
463
|
-
}
|
464
|
-
|
465
|
-
/// @return true iff the bit was not set (but it is now).
|
466
|
-
inline bool ATTRIBUTE_ALWAYS_INLINE tryToSet(uint64_t index) {
|
467
|
-
uint32_t item, position;
|
468
|
-
computeItemPosition(index, item, position);
|
469
|
-
return Super::setAt(item, position);
|
470
|
-
}
|
471
|
-
|
472
|
-
/// Clears the bit at the given index.
|
473
|
-
inline bool ATTRIBUTE_ALWAYS_INLINE unset(uint64_t index) {
|
474
|
-
uint32_t item, position;
|
475
|
-
computeItemPosition(index, item, position);
|
476
|
-
|
477
|
-
return Super::unsetAt(item, position);
|
478
|
-
}
|
479
|
-
|
480
|
-
// FIXME: who uses this? bad idea with atomics
|
481
|
-
inline bool ATTRIBUTE_ALWAYS_INLINE isSet(uint64_t index) const {
|
482
|
-
uint32_t item, position;
|
483
|
-
computeItemPosition(index, item, position);
|
484
|
-
|
485
|
-
return Super::_bits[item] & getMask(position);
|
486
|
-
}
|
487
|
-
|
488
|
-
const word_t *bits() const {
|
489
|
-
return Super::_bits;
|
490
|
-
}
|
491
|
-
|
492
|
-
word_t *mut_bits() {
|
493
|
-
return Super::_bits;
|
494
|
-
}
|
495
|
-
|
496
|
-
iterator begin() {
|
497
|
-
return iterator(*this, lowestSetBitAt(0));
|
498
|
-
}
|
499
|
-
iterator end() {
|
500
|
-
return iterator(*this, bitCount());
|
501
|
-
}
|
502
|
-
const_iterator begin() const {
|
503
|
-
return iterator(*this, lowestSetBitAt(0));
|
504
|
-
}
|
505
|
-
const_iterator end() const {
|
506
|
-
return iterator(*this, bitCount());
|
507
|
-
}
|
508
|
-
const_iterator cbegin() const {
|
509
|
-
return iterator(*this, lowestSetBitAt(0));
|
510
|
-
}
|
511
|
-
const_iterator cend() const {
|
512
|
-
return iterator(*this, bitCount());
|
513
|
-
}
|
514
|
-
|
515
|
-
size_t lowestSetBitAt(uint64_t startingAt) const {
|
516
|
-
uint32_t startWord, startOff;
|
517
|
-
computeItemPosition(startingAt, startWord, startOff);
|
518
|
-
|
519
|
-
const auto wordCount = byteCount() / sizeof(size_t);
|
520
|
-
for (size_t i = startWord; i < wordCount; i++) {
|
521
|
-
const auto mask = ~((1UL << startOff) - 1);
|
522
|
-
const auto bits = Super::_bits[i] & mask;
|
523
|
-
startOff = 0;
|
524
|
-
|
525
|
-
if (bits == 0ULL)
|
526
|
-
continue;
|
527
|
-
|
528
|
-
const size_t off = __builtin_ffsl(bits) - 1;
|
529
|
-
|
530
|
-
const auto bit = kWordBits * i + off;
|
531
|
-
return bit < bitCount() ? bit : bitCount();
|
532
|
-
}
|
533
|
-
|
534
|
-
return bitCount();
|
535
|
-
}
|
536
|
-
|
537
|
-
size_t highestSetBitBeforeOrAt(uint64_t startingAt) const {
|
538
|
-
uint32_t startWord, startOff;
|
539
|
-
computeItemPosition(startingAt, startWord, startOff);
|
540
|
-
|
541
|
-
const auto wordCount = byteCount() / sizeof(size_t);
|
542
|
-
for (ssize_t i = startWord; i >= 0; i--) {
|
543
|
-
uint64_t mask = (1UL << (startOff + 1)) - 1;
|
544
|
-
if (startOff == 63) {
|
545
|
-
mask = ~0UL;
|
546
|
-
}
|
547
|
-
const auto bits = Super::_bits[i] & mask;
|
548
|
-
const auto origStartOff = startOff;
|
549
|
-
startOff = 63;
|
550
|
-
|
551
|
-
if (bits == 0ULL)
|
552
|
-
continue;
|
553
|
-
|
554
|
-
const size_t off = 64 - __builtin_clzl(bits) - 1;
|
555
|
-
|
556
|
-
const auto bit = kWordBits * i + off;
|
557
|
-
return bit < bitCount() ? bit : bitCount();
|
558
|
-
}
|
559
|
-
|
560
|
-
return 0;
|
561
|
-
}
|
562
|
-
|
563
|
-
inline void setAndExchangeAll(size_t *oldBits, const size_t *newBits) {
|
564
|
-
Super::setAndExchangeAll(oldBits, newBits);
|
565
|
-
}
|
566
|
-
|
567
|
-
private:
|
568
|
-
/// Given an index, compute its item (word) and position within the word.
|
569
|
-
inline void ATTRIBUTE_ALWAYS_INLINE computeItemPosition(uint64_t index, uint32_t &item, uint32_t &position) const {
|
570
|
-
d_assert(index < bitCount());
|
571
|
-
item = index >> kWordBitshift;
|
572
|
-
position = index & (kWordBits - 1);
|
573
|
-
d_assert(position == index - (item << kWordBitshift));
|
574
|
-
d_assert(item < byteCount() / 8);
|
575
|
-
}
|
576
|
-
};
|
577
|
-
} // namespace bitmap
|
578
|
-
|
579
|
-
namespace internal {
|
580
|
-
typedef bitmap::BitmapBase<bitmap::AtomicBitmapBase<256>> Bitmap;
|
581
|
-
typedef bitmap::BitmapBase<bitmap::RelaxedFixedBitmapBase<256>> RelaxedFixedBitmap;
|
582
|
-
typedef bitmap::BitmapBase<bitmap::RelaxedBitmapBase> RelaxedBitmap;
|
583
|
-
|
584
|
-
static_assert(sizeof(Bitmap) == sizeof(size_t) * 4, "Bitmap unexpected size");
|
585
|
-
static_assert(sizeof(RelaxedFixedBitmap) == sizeof(size_t) * 4, "Bitmap unexpected size");
|
586
|
-
static_assert(sizeof(RelaxedBitmap) == sizeof(size_t) * 2, "Bitmap unexpected size");
|
587
|
-
} // namespace internal
|
588
|
-
} // namespace mesh
|
589
|
-
|
590
|
-
#endif // MESH_BITMAP_H
|