mesh-rb 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/ext/mesh/extconf.rb +22 -4
  4. data/ext/mesh/mesh.tar.gz +0 -0
  5. data/lib/mesh/version.rb +1 -1
  6. data/mesh.gemspec +3 -2
  7. metadata +4 -120
  8. data/ext/mesh/mesh/.bazelrc +0 -20
  9. data/ext/mesh/mesh/.bazelversion +0 -1
  10. data/ext/mesh/mesh/.clang-format +0 -15
  11. data/ext/mesh/mesh/.dockerignore +0 -5
  12. data/ext/mesh/mesh/.editorconfig +0 -16
  13. data/ext/mesh/mesh/.gitattributes +0 -4
  14. data/ext/mesh/mesh/.github/workflows/main.yml +0 -144
  15. data/ext/mesh/mesh/.gitignore +0 -51
  16. data/ext/mesh/mesh/AUTHORS +0 -5
  17. data/ext/mesh/mesh/CMakeLists.txt +0 -270
  18. data/ext/mesh/mesh/CODE_OF_CONDUCT.md +0 -77
  19. data/ext/mesh/mesh/Dockerfile +0 -30
  20. data/ext/mesh/mesh/LICENSE +0 -201
  21. data/ext/mesh/mesh/Makefile +0 -81
  22. data/ext/mesh/mesh/README.md +0 -97
  23. data/ext/mesh/mesh/WORKSPACE +0 -50
  24. data/ext/mesh/mesh/bazel +0 -350
  25. data/ext/mesh/mesh/mesh-pldi19-powers.pdf +0 -0
  26. data/ext/mesh/mesh/src/BUILD +0 -222
  27. data/ext/mesh/mesh/src/CMakeLists.txt +0 -85
  28. data/ext/mesh/mesh/src/bitmap.h +0 -590
  29. data/ext/mesh/mesh/src/cheap_heap.h +0 -170
  30. data/ext/mesh/mesh/src/common.h +0 -377
  31. data/ext/mesh/mesh/src/copts.bzl +0 -31
  32. data/ext/mesh/mesh/src/d_assert.cc +0 -75
  33. data/ext/mesh/mesh/src/fixed_array.h +0 -124
  34. data/ext/mesh/mesh/src/global_heap.cc +0 -547
  35. data/ext/mesh/mesh/src/global_heap.h +0 -569
  36. data/ext/mesh/mesh/src/gnu_wrapper.cc +0 -75
  37. data/ext/mesh/mesh/src/internal.h +0 -356
  38. data/ext/mesh/mesh/src/libmesh.cc +0 -239
  39. data/ext/mesh/mesh/src/mac_wrapper.cc +0 -528
  40. data/ext/mesh/mesh/src/measure_rss.cc +0 -44
  41. data/ext/mesh/mesh/src/measure_rss.h +0 -20
  42. data/ext/mesh/mesh/src/meshable_arena.cc +0 -776
  43. data/ext/mesh/mesh/src/meshable_arena.h +0 -309
  44. data/ext/mesh/mesh/src/meshing.h +0 -60
  45. data/ext/mesh/mesh/src/mini_heap.h +0 -532
  46. data/ext/mesh/mesh/src/mmap_heap.h +0 -104
  47. data/ext/mesh/mesh/src/one_way_mmap_heap.h +0 -77
  48. data/ext/mesh/mesh/src/partitioned_heap.h +0 -111
  49. data/ext/mesh/mesh/src/plasma/mesh.h +0 -33
  50. data/ext/mesh/mesh/src/real.cc +0 -52
  51. data/ext/mesh/mesh/src/real.h +0 -36
  52. data/ext/mesh/mesh/src/rng/mwc.h +0 -296
  53. data/ext/mesh/mesh/src/rng/mwc64.h +0 -58
  54. data/ext/mesh/mesh/src/rpl_printf.c +0 -1991
  55. data/ext/mesh/mesh/src/runtime.cc +0 -393
  56. data/ext/mesh/mesh/src/runtime.h +0 -114
  57. data/ext/mesh/mesh/src/shuffle_vector.h +0 -287
  58. data/ext/mesh/mesh/src/size_classes.def +0 -251
  59. data/ext/mesh/mesh/src/static/if.h +0 -36
  60. data/ext/mesh/mesh/src/static/log.h +0 -43
  61. data/ext/mesh/mesh/src/testing/benchmark/local_refill.cc +0 -103
  62. data/ext/mesh/mesh/src/testing/big-alloc.c +0 -28
  63. data/ext/mesh/mesh/src/testing/fragmenter.cc +0 -128
  64. data/ext/mesh/mesh/src/testing/global-large-stress.cc +0 -25
  65. data/ext/mesh/mesh/src/testing/local-alloc.c +0 -16
  66. data/ext/mesh/mesh/src/testing/meshing_benchmark.cc +0 -189
  67. data/ext/mesh/mesh/src/testing/thread.cc +0 -35
  68. data/ext/mesh/mesh/src/testing/unit/alignment.cc +0 -56
  69. data/ext/mesh/mesh/src/testing/unit/bitmap_test.cc +0 -274
  70. data/ext/mesh/mesh/src/testing/unit/concurrent_mesh_test.cc +0 -185
  71. data/ext/mesh/mesh/src/testing/unit/mesh_test.cc +0 -143
  72. data/ext/mesh/mesh/src/testing/unit/rng_test.cc +0 -22
  73. data/ext/mesh/mesh/src/testing/unit/size_class_test.cc +0 -66
  74. data/ext/mesh/mesh/src/testing/unit/triple_mesh_test.cc +0 -285
  75. data/ext/mesh/mesh/src/testing/userfaultfd-kernel-copy.cc +0 -164
  76. data/ext/mesh/mesh/src/thread_local_heap.cc +0 -163
  77. data/ext/mesh/mesh/src/thread_local_heap.h +0 -268
  78. data/ext/mesh/mesh/src/wrapper.cc +0 -433
  79. data/ext/mesh/mesh/support/export_mesh.cmake +0 -28
  80. data/ext/mesh/mesh/support/gen-size-classes +0 -57
  81. data/ext/mesh/mesh/support/install_all_configs +0 -33
  82. data/ext/mesh/mesh/support/remove_export_mesh.cmake +0 -48
  83. data/ext/mesh/mesh/support/update-bazelisk +0 -8
  84. data/ext/mesh/mesh/theory/32m80.png +0 -0
  85. data/ext/mesh/mesh/theory/64m80ind.png +0 -0
  86. data/ext/mesh/mesh/theory/bound_comparison.py +0 -67
  87. data/ext/mesh/mesh/theory/bounds/impdeg+1 +0 -135
  88. data/ext/mesh/mesh/theory/choose.py +0 -43
  89. data/ext/mesh/mesh/theory/common.py +0 -42
  90. data/ext/mesh/mesh/theory/compute_exp_Y.py +0 -134
  91. data/ext/mesh/mesh/theory/createRandomString.py +0 -69
  92. data/ext/mesh/mesh/theory/deg_bound_check.py +0 -100
  93. data/ext/mesh/mesh/theory/degcheck.py +0 -47
  94. data/ext/mesh/mesh/theory/dumps/32,1,80,dumb.txt +0 -81
  95. data/ext/mesh/mesh/theory/dumps/32,2,80,dumb.txt +0 -81
  96. data/ext/mesh/mesh/theory/dumps/32,3,80,dumb.txt +0 -81
  97. data/ext/mesh/mesh/theory/dumps/32,4,80,dumb.txt +0 -81
  98. data/ext/mesh/mesh/theory/dumps/32,5,80,dumb.txt +0 -81
  99. data/ext/mesh/mesh/theory/dumps/32,6,80,dumb.txt +0 -81
  100. data/ext/mesh/mesh/theory/dumps/32,7,80,dumb.txt +0 -81
  101. data/ext/mesh/mesh/theory/dumps/32,8,80,dumb.txt +0 -81
  102. data/ext/mesh/mesh/theory/dumps/32,9,80,dumb.txt +0 -81
  103. data/ext/mesh/mesh/theory/experiment.py +0 -303
  104. data/ext/mesh/mesh/theory/experiment_raw_results/.gitignore +0 -0
  105. data/ext/mesh/mesh/theory/greedy_experiment.py +0 -66
  106. data/ext/mesh/mesh/theory/greedy_experiment_copy.py +0 -46
  107. data/ext/mesh/mesh/theory/greedy_experiment_q.py +0 -75
  108. data/ext/mesh/mesh/theory/makeGraph.py +0 -64
  109. data/ext/mesh/mesh/theory/manyreps.png +0 -0
  110. data/ext/mesh/mesh/theory/manystrings.png +0 -0
  111. data/ext/mesh/mesh/theory/match_vs_color_experiment.py +0 -94
  112. data/ext/mesh/mesh/theory/maxmatch_vs_E[Y].py +0 -162
  113. data/ext/mesh/mesh/theory/maxmatch_vs_greedymatch.py +0 -96
  114. data/ext/mesh/mesh/theory/maxvdeg+1imp++32,80.png +0 -0
  115. data/ext/mesh/mesh/theory/mesh_util.py +0 -322
  116. data/ext/mesh/mesh/theory/meshers.py +0 -452
  117. data/ext/mesh/mesh/theory/meshingBenchmark.py +0 -96
  118. data/ext/mesh/mesh/theory/occupancyComparison.py +0 -133
  119. data/ext/mesh/mesh/theory/randmatch_vs_greedymatch.py +0 -97
  120. data/ext/mesh/mesh/theory/randmatch_vs_greedymatch_q.py +0 -103
  121. data/ext/mesh/mesh/theory/randmatch_vs_greedymatch_time.py +0 -117
  122. data/ext/mesh/mesh/theory/read_mesh_dump.py +0 -82
  123. data/ext/mesh/mesh/theory/test.py +0 -70
  124. data/ext/mesh/mesh/tools/bazel +0 -1
Binary file
@@ -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()
@@ -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