wuxing0105 commited on
Commit
9a0ccd9
·
verified ·
1 Parent(s): 84bcf84

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. weight/_dep/abseil-cpp/absl/base/BUILD.bazel +880 -0
  2. weight/_dep/abseil-cpp/absl/base/call_once_test.cc +107 -0
  3. weight/_dep/abseil-cpp/absl/base/casts.h +180 -0
  4. weight/_dep/abseil-cpp/absl/base/internal/cmake_thread_test.cc +22 -0
  5. weight/_dep/abseil-cpp/absl/base/internal/cycleclock.h +144 -0
  6. weight/_dep/abseil-cpp/absl/base/internal/dynamic_annotations.h +398 -0
  7. weight/_dep/abseil-cpp/absl/base/internal/exception_safety_testing.cc +79 -0
  8. weight/_dep/abseil-cpp/absl/base/internal/fast_type_id_test.cc +123 -0
  9. weight/_dep/abseil-cpp/absl/base/internal/low_level_alloc.cc +631 -0
  10. weight/_dep/abseil-cpp/absl/base/internal/low_level_alloc.h +127 -0
  11. weight/_dep/abseil-cpp/absl/base/internal/low_level_scheduling.h +134 -0
  12. weight/_dep/abseil-cpp/absl/base/internal/nullability_impl.h +106 -0
  13. weight/_dep/abseil-cpp/absl/base/internal/pretty_function.h +33 -0
  14. weight/_dep/abseil-cpp/absl/base/internal/raw_logging.cc +280 -0
  15. weight/_dep/abseil-cpp/absl/base/internal/scheduling_mode.h +58 -0
  16. weight/_dep/abseil-cpp/absl/base/internal/scoped_set_env.cc +81 -0
  17. weight/_dep/abseil-cpp/absl/base/internal/scoped_set_env.h +45 -0
  18. weight/_dep/abseil-cpp/absl/base/internal/scoped_set_env_test.cc +99 -0
  19. weight/_dep/abseil-cpp/absl/base/internal/spinlock.cc +232 -0
  20. weight/_dep/abseil-cpp/absl/base/internal/spinlock.h +265 -0
  21. weight/_dep/abseil-cpp/absl/base/internal/spinlock_benchmark.cc +80 -0
  22. weight/_dep/abseil-cpp/absl/base/internal/spinlock_linux.inc +71 -0
  23. weight/_dep/abseil-cpp/absl/base/internal/spinlock_posix.inc +46 -0
  24. weight/_dep/abseil-cpp/absl/base/internal/spinlock_wait.cc +81 -0
  25. weight/_dep/abseil-cpp/absl/base/internal/spinlock_wait.h +95 -0
  26. weight/_dep/abseil-cpp/absl/base/internal/spinlock_win32.inc +40 -0
  27. weight/_dep/abseil-cpp/absl/base/internal/strerror.cc +88 -0
  28. weight/_dep/abseil-cpp/absl/base/internal/strerror.h +39 -0
  29. weight/_dep/abseil-cpp/absl/base/internal/strerror_benchmark.cc +29 -0
  30. weight/_dep/abseil-cpp/absl/base/internal/strerror_test.cc +88 -0
  31. weight/_dep/abseil-cpp/absl/base/internal/sysinfo.cc +489 -0
  32. weight/_dep/abseil-cpp/absl/base/internal/sysinfo.h +74 -0
  33. weight/_dep/abseil-cpp/absl/base/internal/sysinfo_test.cc +88 -0
  34. weight/_dep/abseil-cpp/absl/base/internal/thread_identity.cc +163 -0
  35. weight/_dep/abseil-cpp/absl/base/internal/thread_identity.h +269 -0
  36. weight/_dep/abseil-cpp/absl/base/internal/thread_identity_benchmark.cc +38 -0
  37. weight/_dep/abseil-cpp/absl/base/internal/thread_identity_test.cc +129 -0
  38. weight/_dep/abseil-cpp/absl/base/internal/throw_delegate.cc +203 -0
  39. weight/_dep/abseil-cpp/absl/base/internal/throw_delegate.h +75 -0
  40. weight/_dep/abseil-cpp/absl/base/internal/tsan_mutex_interface.h +68 -0
  41. weight/_dep/abseil-cpp/absl/base/internal/unaligned_access.h +89 -0
  42. weight/_dep/abseil-cpp/absl/base/internal/unique_small_name_test.cc +77 -0
  43. weight/_dep/abseil-cpp/absl/base/internal/unscaledcycleclock.cc +152 -0
  44. weight/_dep/abseil-cpp/absl/base/internal/unscaledcycleclock.h +96 -0
  45. weight/_dep/abseil-cpp/absl/base/port.h +25 -0
  46. weight/_dep/abseil-cpp/absl/base/prefetch.h +209 -0
  47. weight/_dep/abseil-cpp/absl/container/CMakeLists.txt +989 -0
  48. weight/_dep/abseil-cpp/absl/container/fixed_array.h +556 -0
  49. weight/_dep/abseil-cpp/absl/container/fixed_array_benchmark.cc +67 -0
  50. weight/_dep/abseil-cpp/absl/container/fixed_array_exception_safety_test.cc +201 -0
weight/_dep/abseil-cpp/absl/base/BUILD.bazel ADDED
@@ -0,0 +1,880 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #
2
+ # Copyright 2017 The Abseil Authors.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # https://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ load(
18
+ "//absl:copts/configure_copts.bzl",
19
+ "ABSL_DEFAULT_COPTS",
20
+ "ABSL_DEFAULT_LINKOPTS",
21
+ "ABSL_TEST_COPTS",
22
+ )
23
+
24
+ package(
25
+ default_visibility = ["//visibility:public"],
26
+ features = [
27
+ "header_modules",
28
+ "layering_check",
29
+ "parse_headers",
30
+ ],
31
+ )
32
+
33
+ licenses(["notice"])
34
+
35
+ cc_library(
36
+ name = "atomic_hook",
37
+ hdrs = ["internal/atomic_hook.h"],
38
+ copts = ABSL_DEFAULT_COPTS,
39
+ linkopts = ABSL_DEFAULT_LINKOPTS,
40
+ visibility = [
41
+ "//absl:__subpackages__",
42
+ ],
43
+ deps = [
44
+ ":config",
45
+ ":core_headers",
46
+ ],
47
+ )
48
+
49
+ cc_library(
50
+ name = "errno_saver",
51
+ hdrs = ["internal/errno_saver.h"],
52
+ copts = ABSL_DEFAULT_COPTS,
53
+ linkopts = ABSL_DEFAULT_LINKOPTS,
54
+ visibility = [
55
+ "//absl:__subpackages__",
56
+ ],
57
+ deps = [":config"],
58
+ )
59
+
60
+ cc_library(
61
+ name = "log_severity",
62
+ srcs = ["log_severity.cc"],
63
+ hdrs = ["log_severity.h"],
64
+ copts = ABSL_DEFAULT_COPTS,
65
+ linkopts = ABSL_DEFAULT_LINKOPTS,
66
+ deps = [
67
+ ":config",
68
+ ":core_headers",
69
+ ],
70
+ )
71
+
72
+ cc_library(
73
+ name = "no_destructor",
74
+ hdrs = ["no_destructor.h"],
75
+ copts = ABSL_DEFAULT_COPTS,
76
+ linkopts = ABSL_DEFAULT_LINKOPTS,
77
+ deps = [":config"],
78
+ )
79
+
80
+ cc_library(
81
+ name = "nullability",
82
+ srcs = ["internal/nullability_impl.h"],
83
+ hdrs = ["nullability.h"],
84
+ copts = ABSL_DEFAULT_COPTS,
85
+ linkopts = ABSL_DEFAULT_LINKOPTS,
86
+ deps = [
87
+ ":core_headers",
88
+ "//absl/meta:type_traits",
89
+ ],
90
+ )
91
+
92
+ cc_library(
93
+ name = "raw_logging_internal",
94
+ srcs = ["internal/raw_logging.cc"],
95
+ hdrs = ["internal/raw_logging.h"],
96
+ copts = ABSL_DEFAULT_COPTS,
97
+ linkopts = ABSL_DEFAULT_LINKOPTS,
98
+ visibility = [
99
+ "//absl:__subpackages__",
100
+ ],
101
+ deps = [
102
+ ":atomic_hook",
103
+ ":config",
104
+ ":core_headers",
105
+ ":errno_saver",
106
+ ":log_severity",
107
+ ],
108
+ )
109
+
110
+ cc_library(
111
+ name = "spinlock_wait",
112
+ srcs = [
113
+ "internal/spinlock_akaros.inc",
114
+ "internal/spinlock_linux.inc",
115
+ "internal/spinlock_posix.inc",
116
+ "internal/spinlock_wait.cc",
117
+ "internal/spinlock_win32.inc",
118
+ ],
119
+ hdrs = ["internal/spinlock_wait.h"],
120
+ copts = ABSL_DEFAULT_COPTS,
121
+ linkopts = ABSL_DEFAULT_LINKOPTS,
122
+ visibility = [
123
+ "//absl/base:__pkg__",
124
+ ],
125
+ deps = [
126
+ ":base_internal",
127
+ ":core_headers",
128
+ ":errno_saver",
129
+ ],
130
+ )
131
+
132
+ cc_library(
133
+ name = "config",
134
+ hdrs = [
135
+ "config.h",
136
+ "options.h",
137
+ "policy_checks.h",
138
+ ],
139
+ copts = ABSL_DEFAULT_COPTS,
140
+ linkopts = ABSL_DEFAULT_LINKOPTS,
141
+ )
142
+
143
+ cc_library(
144
+ name = "cycleclock_internal",
145
+ hdrs = [
146
+ "internal/cycleclock_config.h",
147
+ "internal/unscaledcycleclock_config.h",
148
+ ],
149
+ copts = ABSL_DEFAULT_COPTS,
150
+ linkopts = ABSL_DEFAULT_LINKOPTS,
151
+ visibility = [
152
+ "//absl:__subpackages__",
153
+ ],
154
+ deps = [
155
+ ":base_internal",
156
+ ":config",
157
+ ],
158
+ )
159
+
160
+ cc_library(
161
+ name = "dynamic_annotations",
162
+ srcs = [
163
+ "internal/dynamic_annotations.h",
164
+ ],
165
+ hdrs = [
166
+ "dynamic_annotations.h",
167
+ ],
168
+ copts = ABSL_DEFAULT_COPTS,
169
+ linkopts = ABSL_DEFAULT_LINKOPTS,
170
+ deps = [
171
+ ":config",
172
+ ":core_headers",
173
+ ],
174
+ )
175
+
176
+ cc_library(
177
+ name = "core_headers",
178
+ hdrs = [
179
+ "attributes.h",
180
+ "const_init.h",
181
+ "macros.h",
182
+ "optimization.h",
183
+ "port.h",
184
+ "thread_annotations.h",
185
+ ],
186
+ copts = ABSL_DEFAULT_COPTS,
187
+ linkopts = ABSL_DEFAULT_LINKOPTS,
188
+ deps = [
189
+ ":config",
190
+ ],
191
+ )
192
+
193
+ cc_library(
194
+ name = "malloc_internal",
195
+ srcs = [
196
+ "internal/low_level_alloc.cc",
197
+ ],
198
+ hdrs = [
199
+ "internal/direct_mmap.h",
200
+ "internal/low_level_alloc.h",
201
+ ],
202
+ copts = ABSL_DEFAULT_COPTS + select({
203
+ "//conditions:default": [],
204
+ }),
205
+ linkopts = select({
206
+ "//absl:msvc_compiler": [],
207
+ "//absl:clang-cl_compiler": [],
208
+ "//absl:wasm": [],
209
+ "//conditions:default": ["-pthread"],
210
+ }) + ABSL_DEFAULT_LINKOPTS,
211
+ visibility = [
212
+ "//visibility:public",
213
+ ],
214
+ deps = [
215
+ ":base",
216
+ ":base_internal",
217
+ ":config",
218
+ ":core_headers",
219
+ ":dynamic_annotations",
220
+ ":raw_logging_internal",
221
+ ],
222
+ )
223
+
224
+ cc_library(
225
+ name = "base_internal",
226
+ hdrs = [
227
+ "internal/hide_ptr.h",
228
+ "internal/identity.h",
229
+ "internal/inline_variable.h",
230
+ "internal/invoke.h",
231
+ "internal/scheduling_mode.h",
232
+ ],
233
+ copts = ABSL_DEFAULT_COPTS,
234
+ linkopts = ABSL_DEFAULT_LINKOPTS,
235
+ visibility = [
236
+ "//absl:__subpackages__",
237
+ ],
238
+ deps = [
239
+ ":config",
240
+ "//absl/meta:type_traits",
241
+ ],
242
+ )
243
+
244
+ cc_library(
245
+ name = "base",
246
+ srcs = [
247
+ "internal/cycleclock.cc",
248
+ "internal/spinlock.cc",
249
+ "internal/sysinfo.cc",
250
+ "internal/thread_identity.cc",
251
+ "internal/unscaledcycleclock.cc",
252
+ ],
253
+ hdrs = [
254
+ "call_once.h",
255
+ "casts.h",
256
+ "internal/cycleclock.h",
257
+ "internal/low_level_scheduling.h",
258
+ "internal/per_thread_tls.h",
259
+ "internal/spinlock.h",
260
+ "internal/sysinfo.h",
261
+ "internal/thread_identity.h",
262
+ "internal/tsan_mutex_interface.h",
263
+ "internal/unscaledcycleclock.h",
264
+ ],
265
+ copts = ABSL_DEFAULT_COPTS,
266
+ linkopts = select({
267
+ "//absl:msvc_compiler": [
268
+ "-DEFAULTLIB:advapi32.lib",
269
+ ],
270
+ "//absl:clang-cl_compiler": [
271
+ "-DEFAULTLIB:advapi32.lib",
272
+ ],
273
+ "//absl:mingw_compiler": [
274
+ "-DEFAULTLIB:advapi32.lib",
275
+ "-ladvapi32",
276
+ ],
277
+ "//absl:wasm": [],
278
+ "//conditions:default": ["-pthread"],
279
+ }) + ABSL_DEFAULT_LINKOPTS,
280
+ deps = [
281
+ ":atomic_hook",
282
+ ":base_internal",
283
+ ":config",
284
+ ":core_headers",
285
+ ":cycleclock_internal",
286
+ ":dynamic_annotations",
287
+ ":log_severity",
288
+ ":nullability",
289
+ ":raw_logging_internal",
290
+ ":spinlock_wait",
291
+ "//absl/meta:type_traits",
292
+ ],
293
+ )
294
+
295
+ cc_library(
296
+ name = "atomic_hook_test_helper",
297
+ testonly = 1,
298
+ srcs = ["internal/atomic_hook_test_helper.cc"],
299
+ hdrs = ["internal/atomic_hook_test_helper.h"],
300
+ copts = ABSL_DEFAULT_COPTS,
301
+ linkopts = ABSL_DEFAULT_LINKOPTS,
302
+ deps = [
303
+ ":atomic_hook",
304
+ ":core_headers",
305
+ ],
306
+ )
307
+
308
+ cc_test(
309
+ name = "atomic_hook_test",
310
+ size = "small",
311
+ srcs = ["internal/atomic_hook_test.cc"],
312
+ copts = ABSL_TEST_COPTS,
313
+ linkopts = ABSL_DEFAULT_LINKOPTS,
314
+ deps = [
315
+ ":atomic_hook",
316
+ ":atomic_hook_test_helper",
317
+ ":core_headers",
318
+ "@com_google_googletest//:gtest",
319
+ "@com_google_googletest//:gtest_main",
320
+ ],
321
+ )
322
+
323
+ cc_test(
324
+ name = "bit_cast_test",
325
+ size = "small",
326
+ srcs = [
327
+ "bit_cast_test.cc",
328
+ ],
329
+ copts = ABSL_TEST_COPTS,
330
+ linkopts = ABSL_DEFAULT_LINKOPTS,
331
+ deps = [
332
+ ":base",
333
+ ":core_headers",
334
+ "@com_google_googletest//:gtest",
335
+ "@com_google_googletest//:gtest_main",
336
+ ],
337
+ )
338
+
339
+ cc_library(
340
+ name = "throw_delegate",
341
+ srcs = ["internal/throw_delegate.cc"],
342
+ hdrs = ["internal/throw_delegate.h"],
343
+ copts = ABSL_DEFAULT_COPTS,
344
+ linkopts = ABSL_DEFAULT_LINKOPTS,
345
+ visibility = [
346
+ "//absl:__subpackages__",
347
+ ],
348
+ deps = [
349
+ ":config",
350
+ ":raw_logging_internal",
351
+ ],
352
+ )
353
+
354
+ cc_test(
355
+ name = "throw_delegate_test",
356
+ srcs = ["throw_delegate_test.cc"],
357
+ copts = ABSL_TEST_COPTS,
358
+ linkopts = ABSL_DEFAULT_LINKOPTS,
359
+ deps = [
360
+ ":config",
361
+ ":throw_delegate",
362
+ "@com_google_googletest//:gtest",
363
+ "@com_google_googletest//:gtest_main",
364
+ ],
365
+ )
366
+
367
+ cc_test(
368
+ name = "errno_saver_test",
369
+ size = "small",
370
+ srcs = ["internal/errno_saver_test.cc"],
371
+ copts = ABSL_TEST_COPTS,
372
+ linkopts = ABSL_DEFAULT_LINKOPTS,
373
+ deps = [
374
+ ":errno_saver",
375
+ ":strerror",
376
+ "@com_google_googletest//:gtest",
377
+ "@com_google_googletest//:gtest_main",
378
+ ],
379
+ )
380
+
381
+ cc_library(
382
+ name = "exception_testing",
383
+ testonly = 1,
384
+ hdrs = ["internal/exception_testing.h"],
385
+ copts = ABSL_TEST_COPTS,
386
+ linkopts = ABSL_DEFAULT_LINKOPTS,
387
+ visibility = [
388
+ "//absl:__subpackages__",
389
+ ],
390
+ deps = [
391
+ ":config",
392
+ "@com_google_googletest//:gtest",
393
+ ],
394
+ )
395
+
396
+ cc_library(
397
+ name = "pretty_function",
398
+ hdrs = ["internal/pretty_function.h"],
399
+ linkopts = ABSL_DEFAULT_LINKOPTS,
400
+ visibility = [
401
+ "//absl:__subpackages__",
402
+ ],
403
+ )
404
+
405
+ cc_library(
406
+ name = "exception_safety_testing",
407
+ testonly = 1,
408
+ srcs = ["internal/exception_safety_testing.cc"],
409
+ hdrs = ["internal/exception_safety_testing.h"],
410
+ copts = ABSL_TEST_COPTS,
411
+ linkopts = ABSL_DEFAULT_LINKOPTS,
412
+ deps = [
413
+ ":config",
414
+ ":pretty_function",
415
+ "//absl/memory",
416
+ "//absl/meta:type_traits",
417
+ "//absl/strings",
418
+ "//absl/utility",
419
+ "@com_google_googletest//:gtest",
420
+ ],
421
+ )
422
+
423
+ cc_test(
424
+ name = "exception_safety_testing_test",
425
+ srcs = ["exception_safety_testing_test.cc"],
426
+ copts = ABSL_TEST_COPTS,
427
+ linkopts = ABSL_DEFAULT_LINKOPTS,
428
+ deps = [
429
+ ":exception_safety_testing",
430
+ "//absl/memory",
431
+ "@com_google_googletest//:gtest",
432
+ "@com_google_googletest//:gtest_main",
433
+ ],
434
+ )
435
+
436
+ cc_test(
437
+ name = "inline_variable_test",
438
+ size = "small",
439
+ srcs = [
440
+ "inline_variable_test.cc",
441
+ "inline_variable_test_a.cc",
442
+ "inline_variable_test_b.cc",
443
+ "internal/inline_variable_testing.h",
444
+ ],
445
+ copts = ABSL_TEST_COPTS,
446
+ linkopts = ABSL_DEFAULT_LINKOPTS,
447
+ deps = [
448
+ ":base_internal",
449
+ "@com_google_googletest//:gtest",
450
+ "@com_google_googletest//:gtest_main",
451
+ ],
452
+ )
453
+
454
+ cc_test(
455
+ name = "invoke_test",
456
+ size = "small",
457
+ srcs = ["invoke_test.cc"],
458
+ copts = ABSL_TEST_COPTS,
459
+ linkopts = ABSL_DEFAULT_LINKOPTS,
460
+ deps = [
461
+ ":base_internal",
462
+ "//absl/memory",
463
+ "//absl/strings",
464
+ "@com_google_googletest//:gtest",
465
+ "@com_google_googletest//:gtest_main",
466
+ ],
467
+ )
468
+
469
+ # Common test library made available for use in non-absl code that overrides
470
+ # AbslInternalSpinLockDelay and AbslInternalSpinLockWake.
471
+ cc_library(
472
+ name = "spinlock_test_common",
473
+ testonly = 1,
474
+ srcs = ["spinlock_test_common.cc"],
475
+ copts = ABSL_TEST_COPTS,
476
+ linkopts = ABSL_DEFAULT_LINKOPTS,
477
+ deps = [
478
+ ":base",
479
+ ":base_internal",
480
+ ":config",
481
+ ":core_headers",
482
+ "//absl/synchronization",
483
+ "@com_google_googletest//:gtest",
484
+ ],
485
+ alwayslink = 1,
486
+ )
487
+
488
+ cc_test(
489
+ name = "spinlock_test",
490
+ size = "medium",
491
+ srcs = ["spinlock_test_common.cc"],
492
+ copts = ABSL_TEST_COPTS,
493
+ linkopts = ABSL_DEFAULT_LINKOPTS,
494
+ tags = [
495
+ "no_test_wasm",
496
+ ],
497
+ deps = [
498
+ ":base",
499
+ ":base_internal",
500
+ ":config",
501
+ ":core_headers",
502
+ "//absl/synchronization",
503
+ "@com_google_googletest//:gtest",
504
+ "@com_google_googletest//:gtest_main",
505
+ ],
506
+ )
507
+
508
+ cc_library(
509
+ name = "spinlock_benchmark_common",
510
+ testonly = 1,
511
+ srcs = ["internal/spinlock_benchmark.cc"],
512
+ copts = ABSL_TEST_COPTS,
513
+ linkopts = ABSL_DEFAULT_LINKOPTS,
514
+ visibility = [
515
+ "//absl/base:__pkg__",
516
+ ],
517
+ deps = [
518
+ ":base",
519
+ ":base_internal",
520
+ ":no_destructor",
521
+ ":raw_logging_internal",
522
+ "//absl/synchronization",
523
+ "@com_github_google_benchmark//:benchmark_main",
524
+ ],
525
+ alwayslink = 1,
526
+ )
527
+
528
+ cc_binary(
529
+ name = "spinlock_benchmark",
530
+ testonly = 1,
531
+ copts = ABSL_DEFAULT_COPTS,
532
+ linkopts = ABSL_DEFAULT_LINKOPTS,
533
+ tags = ["benchmark"],
534
+ visibility = ["//visibility:private"],
535
+ deps = [
536
+ ":spinlock_benchmark_common",
537
+ ],
538
+ )
539
+
540
+ cc_library(
541
+ name = "endian",
542
+ hdrs = [
543
+ "internal/endian.h",
544
+ "internal/unaligned_access.h",
545
+ ],
546
+ copts = ABSL_DEFAULT_COPTS,
547
+ linkopts = ABSL_DEFAULT_LINKOPTS,
548
+ deps = [
549
+ ":base",
550
+ ":config",
551
+ ":core_headers",
552
+ ":nullability",
553
+ ],
554
+ )
555
+
556
+ cc_test(
557
+ name = "endian_test",
558
+ srcs = ["internal/endian_test.cc"],
559
+ copts = ABSL_TEST_COPTS,
560
+ deps = [
561
+ ":config",
562
+ ":endian",
563
+ "@com_google_googletest//:gtest",
564
+ "@com_google_googletest//:gtest_main",
565
+ ],
566
+ )
567
+
568
+ cc_test(
569
+ name = "config_test",
570
+ srcs = ["config_test.cc"],
571
+ copts = ABSL_TEST_COPTS,
572
+ linkopts = ABSL_DEFAULT_LINKOPTS,
573
+ deps = [
574
+ ":config",
575
+ "//absl/synchronization:thread_pool",
576
+ "@com_google_googletest//:gtest",
577
+ "@com_google_googletest//:gtest_main",
578
+ ],
579
+ )
580
+
581
+ cc_test(
582
+ name = "call_once_test",
583
+ srcs = ["call_once_test.cc"],
584
+ copts = ABSL_TEST_COPTS,
585
+ linkopts = ABSL_DEFAULT_LINKOPTS,
586
+ deps = [
587
+ ":base",
588
+ ":core_headers",
589
+ "//absl/synchronization",
590
+ "@com_google_googletest//:gtest",
591
+ "@com_google_googletest//:gtest_main",
592
+ ],
593
+ )
594
+
595
+ cc_test(
596
+ name = "no_destructor_test",
597
+ srcs = ["no_destructor_test.cc"],
598
+ copts = ABSL_TEST_COPTS,
599
+ linkopts = ABSL_DEFAULT_LINKOPTS,
600
+ deps = [
601
+ ":config",
602
+ ":no_destructor",
603
+ ":raw_logging_internal",
604
+ "@com_google_googletest//:gtest",
605
+ "@com_google_googletest//:gtest_main",
606
+ ],
607
+ )
608
+
609
+ cc_binary(
610
+ name = "no_destructor_benchmark",
611
+ testonly = 1,
612
+ srcs = ["no_destructor_benchmark.cc"],
613
+ copts = ABSL_TEST_COPTS,
614
+ linkopts = ABSL_DEFAULT_LINKOPTS,
615
+ tags = ["benchmark"],
616
+ visibility = ["//visibility:private"],
617
+ deps = [
618
+ ":no_destructor",
619
+ ":raw_logging_internal",
620
+ "@com_github_google_benchmark//:benchmark_main",
621
+ ],
622
+ )
623
+
624
+ cc_test(
625
+ name = "nullability_test",
626
+ srcs = ["nullability_test.cc"],
627
+ deps = [
628
+ ":core_headers",
629
+ ":nullability",
630
+ "@com_google_googletest//:gtest",
631
+ "@com_google_googletest//:gtest_main",
632
+ ],
633
+ )
634
+
635
+ cc_test(
636
+ name = "raw_logging_test",
637
+ srcs = ["raw_logging_test.cc"],
638
+ copts = ABSL_TEST_COPTS,
639
+ linkopts = ABSL_DEFAULT_LINKOPTS,
640
+ deps = [
641
+ ":raw_logging_internal",
642
+ "//absl/strings",
643
+ "@com_google_googletest//:gtest",
644
+ "@com_google_googletest//:gtest_main",
645
+ ],
646
+ )
647
+
648
+ cc_test(
649
+ name = "sysinfo_test",
650
+ size = "small",
651
+ srcs = ["internal/sysinfo_test.cc"],
652
+ copts = ABSL_TEST_COPTS,
653
+ linkopts = ABSL_DEFAULT_LINKOPTS,
654
+ deps = [
655
+ ":base",
656
+ "//absl/synchronization",
657
+ "@com_google_googletest//:gtest",
658
+ "@com_google_googletest//:gtest_main",
659
+ ],
660
+ )
661
+
662
+ cc_test(
663
+ name = "low_level_alloc_test",
664
+ size = "medium",
665
+ srcs = ["internal/low_level_alloc_test.cc"],
666
+ copts = ABSL_TEST_COPTS,
667
+ linkopts = ABSL_DEFAULT_LINKOPTS,
668
+ tags = [
669
+ "no_test_ios_x86_64",
670
+ "no_test_wasm",
671
+ ],
672
+ deps = [
673
+ ":malloc_internal",
674
+ "//absl/container:node_hash_map",
675
+ ],
676
+ )
677
+
678
+ cc_test(
679
+ name = "thread_identity_test",
680
+ size = "small",
681
+ srcs = ["internal/thread_identity_test.cc"],
682
+ copts = ABSL_TEST_COPTS,
683
+ linkopts = ABSL_DEFAULT_LINKOPTS,
684
+ tags = [
685
+ "no_test_wasm",
686
+ ],
687
+ deps = [
688
+ ":base",
689
+ ":core_headers",
690
+ "//absl/synchronization",
691
+ "@com_google_googletest//:gtest",
692
+ "@com_google_googletest//:gtest_main",
693
+ ],
694
+ )
695
+
696
+ cc_test(
697
+ name = "thread_identity_benchmark",
698
+ srcs = ["internal/thread_identity_benchmark.cc"],
699
+ copts = ABSL_TEST_COPTS,
700
+ linkopts = ABSL_DEFAULT_LINKOPTS,
701
+ tags = ["benchmark"],
702
+ visibility = ["//visibility:private"],
703
+ deps = [
704
+ ":base",
705
+ "//absl/synchronization",
706
+ "@com_github_google_benchmark//:benchmark_main",
707
+ "@com_google_googletest//:gtest",
708
+ ],
709
+ )
710
+
711
+ cc_library(
712
+ name = "scoped_set_env",
713
+ testonly = 1,
714
+ srcs = ["internal/scoped_set_env.cc"],
715
+ hdrs = ["internal/scoped_set_env.h"],
716
+ linkopts = ABSL_DEFAULT_LINKOPTS,
717
+ visibility = [
718
+ "//absl:__subpackages__",
719
+ ],
720
+ deps = [
721
+ ":config",
722
+ ":raw_logging_internal",
723
+ ],
724
+ )
725
+
726
+ cc_test(
727
+ name = "scoped_set_env_test",
728
+ size = "small",
729
+ srcs = ["internal/scoped_set_env_test.cc"],
730
+ copts = ABSL_TEST_COPTS,
731
+ linkopts = ABSL_DEFAULT_LINKOPTS,
732
+ deps = [
733
+ ":scoped_set_env",
734
+ "@com_google_googletest//:gtest",
735
+ "@com_google_googletest//:gtest_main",
736
+ ],
737
+ )
738
+
739
+ cc_test(
740
+ name = "log_severity_test",
741
+ size = "small",
742
+ srcs = ["log_severity_test.cc"],
743
+ copts = ABSL_TEST_COPTS,
744
+ linkopts = ABSL_DEFAULT_LINKOPTS,
745
+ deps = [
746
+ ":log_severity",
747
+ "//absl/flags:flag_internal",
748
+ "//absl/flags:marshalling",
749
+ "//absl/strings",
750
+ "@com_google_googletest//:gtest",
751
+ "@com_google_googletest//:gtest_main",
752
+ ],
753
+ )
754
+
755
+ cc_library(
756
+ name = "strerror",
757
+ srcs = ["internal/strerror.cc"],
758
+ hdrs = ["internal/strerror.h"],
759
+ copts = ABSL_DEFAULT_COPTS,
760
+ linkopts = ABSL_DEFAULT_LINKOPTS,
761
+ visibility = [
762
+ "//absl:__subpackages__",
763
+ ],
764
+ deps = [
765
+ ":config",
766
+ ":core_headers",
767
+ ":errno_saver",
768
+ ],
769
+ )
770
+
771
+ cc_test(
772
+ name = "strerror_test",
773
+ size = "small",
774
+ srcs = ["internal/strerror_test.cc"],
775
+ copts = ABSL_TEST_COPTS,
776
+ linkopts = ABSL_DEFAULT_LINKOPTS,
777
+ deps = [
778
+ ":strerror",
779
+ "//absl/strings",
780
+ "@com_google_googletest//:gtest",
781
+ "@com_google_googletest//:gtest_main",
782
+ ],
783
+ )
784
+
785
+ cc_binary(
786
+ name = "strerror_benchmark",
787
+ testonly = 1,
788
+ srcs = ["internal/strerror_benchmark.cc"],
789
+ copts = ABSL_TEST_COPTS,
790
+ linkopts = ABSL_DEFAULT_LINKOPTS,
791
+ tags = ["benchmark"],
792
+ visibility = ["//visibility:private"],
793
+ deps = [
794
+ ":strerror",
795
+ "@com_github_google_benchmark//:benchmark_main",
796
+ ],
797
+ )
798
+
799
+ cc_library(
800
+ name = "fast_type_id",
801
+ hdrs = ["internal/fast_type_id.h"],
802
+ copts = ABSL_DEFAULT_COPTS,
803
+ linkopts = ABSL_DEFAULT_LINKOPTS,
804
+ visibility = [
805
+ "//absl:__subpackages__",
806
+ ],
807
+ deps = [
808
+ ":config",
809
+ ],
810
+ )
811
+
812
+ cc_test(
813
+ name = "fast_type_id_test",
814
+ size = "small",
815
+ srcs = ["internal/fast_type_id_test.cc"],
816
+ copts = ABSL_TEST_COPTS,
817
+ linkopts = ABSL_DEFAULT_LINKOPTS,
818
+ deps = [
819
+ ":fast_type_id",
820
+ "@com_google_googletest//:gtest",
821
+ "@com_google_googletest//:gtest_main",
822
+ ],
823
+ )
824
+
825
+ cc_library(
826
+ name = "prefetch",
827
+ hdrs = [
828
+ "prefetch.h",
829
+ ],
830
+ copts = ABSL_DEFAULT_COPTS,
831
+ linkopts = ABSL_DEFAULT_LINKOPTS,
832
+ deps = [
833
+ ":config",
834
+ ":core_headers",
835
+ ],
836
+ )
837
+
838
+ cc_test(
839
+ name = "prefetch_test",
840
+ size = "small",
841
+ srcs = [
842
+ "prefetch_test.cc",
843
+ ],
844
+ copts = ABSL_TEST_COPTS,
845
+ linkopts = ABSL_DEFAULT_LINKOPTS,
846
+ deps = [
847
+ ":prefetch",
848
+ "@com_google_googletest//:gtest",
849
+ "@com_google_googletest//:gtest_main",
850
+ ],
851
+ )
852
+
853
+ cc_test(
854
+ name = "unique_small_name_test",
855
+ size = "small",
856
+ srcs = ["internal/unique_small_name_test.cc"],
857
+ copts = ABSL_TEST_COPTS,
858
+ linkopts = ABSL_DEFAULT_LINKOPTS,
859
+ linkstatic = 1,
860
+ deps = [
861
+ ":core_headers",
862
+ "//absl/strings",
863
+ "@com_google_googletest//:gtest",
864
+ "@com_google_googletest//:gtest_main",
865
+ ],
866
+ )
867
+
868
+ cc_test(
869
+ name = "optimization_test",
870
+ size = "small",
871
+ srcs = ["optimization_test.cc"],
872
+ copts = ABSL_TEST_COPTS,
873
+ linkopts = ABSL_DEFAULT_LINKOPTS,
874
+ deps = [
875
+ ":core_headers",
876
+ "//absl/types:optional",
877
+ "@com_google_googletest//:gtest",
878
+ "@com_google_googletest//:gtest_main",
879
+ ],
880
+ )
weight/_dep/abseil-cpp/absl/base/call_once_test.cc ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include "absl/base/call_once.h"
16
+
17
+ #include <thread>
18
+ #include <vector>
19
+
20
+ #include "gtest/gtest.h"
21
+ #include "absl/base/attributes.h"
22
+ #include "absl/base/const_init.h"
23
+ #include "absl/base/thread_annotations.h"
24
+ #include "absl/synchronization/mutex.h"
25
+
26
+ namespace absl {
27
+ ABSL_NAMESPACE_BEGIN
28
+ namespace {
29
+
30
+ absl::once_flag once;
31
+
32
+ ABSL_CONST_INIT Mutex counters_mu(absl::kConstInit);
33
+
34
+ int running_thread_count ABSL_GUARDED_BY(counters_mu) = 0;
35
+ int call_once_invoke_count ABSL_GUARDED_BY(counters_mu) = 0;
36
+ int call_once_finished_count ABSL_GUARDED_BY(counters_mu) = 0;
37
+ int call_once_return_count ABSL_GUARDED_BY(counters_mu) = 0;
38
+ bool done_blocking ABSL_GUARDED_BY(counters_mu) = false;
39
+
40
+ // Function to be called from absl::call_once. Waits for a notification.
41
+ void WaitAndIncrement() {
42
+ counters_mu.Lock();
43
+ ++call_once_invoke_count;
44
+ counters_mu.Unlock();
45
+
46
+ counters_mu.LockWhen(Condition(&done_blocking));
47
+ ++call_once_finished_count;
48
+ counters_mu.Unlock();
49
+ }
50
+
51
+ void ThreadBody() {
52
+ counters_mu.Lock();
53
+ ++running_thread_count;
54
+ counters_mu.Unlock();
55
+
56
+ absl::call_once(once, WaitAndIncrement);
57
+
58
+ counters_mu.Lock();
59
+ ++call_once_return_count;
60
+ counters_mu.Unlock();
61
+ }
62
+
63
+ // Returns true if all threads are set up for the test.
64
+ bool ThreadsAreSetup(void*) ABSL_EXCLUSIVE_LOCKS_REQUIRED(counters_mu) {
65
+ // All ten threads must be running, and WaitAndIncrement should be blocked.
66
+ return running_thread_count == 10 && call_once_invoke_count == 1;
67
+ }
68
+
69
+ TEST(CallOnceTest, ExecutionCount) {
70
+ std::vector<std::thread> threads;
71
+
72
+ // Start 10 threads all calling call_once on the same once_flag.
73
+ for (int i = 0; i < 10; ++i) {
74
+ threads.emplace_back(ThreadBody);
75
+ }
76
+
77
+
78
+ // Wait until all ten threads have started, and WaitAndIncrement has been
79
+ // invoked.
80
+ counters_mu.LockWhen(Condition(ThreadsAreSetup, nullptr));
81
+
82
+ // WaitAndIncrement should have been invoked by exactly one call_once()
83
+ // instance. That thread should be blocking on a notification, and all other
84
+ // call_once instances should be blocking as well.
85
+ EXPECT_EQ(call_once_invoke_count, 1);
86
+ EXPECT_EQ(call_once_finished_count, 0);
87
+ EXPECT_EQ(call_once_return_count, 0);
88
+
89
+ // Allow WaitAndIncrement to finish executing. Once it does, the other
90
+ // call_once waiters will be unblocked.
91
+ done_blocking = true;
92
+ counters_mu.Unlock();
93
+
94
+ for (std::thread& thread : threads) {
95
+ thread.join();
96
+ }
97
+
98
+ counters_mu.Lock();
99
+ EXPECT_EQ(call_once_invoke_count, 1);
100
+ EXPECT_EQ(call_once_finished_count, 1);
101
+ EXPECT_EQ(call_once_return_count, 10);
102
+ counters_mu.Unlock();
103
+ }
104
+
105
+ } // namespace
106
+ ABSL_NAMESPACE_END
107
+ } // namespace absl
weight/_dep/abseil-cpp/absl/base/casts.h ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //
2
+ // Copyright 2017 The Abseil Authors.
3
+ //
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // you may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ //
8
+ // https://www.apache.org/licenses/LICENSE-2.0
9
+ //
10
+ // Unless required by applicable law or agreed to in writing, software
11
+ // distributed under the License is distributed on an "AS IS" BASIS,
12
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ // See the License for the specific language governing permissions and
14
+ // limitations under the License.
15
+ //
16
+ // -----------------------------------------------------------------------------
17
+ // File: casts.h
18
+ // -----------------------------------------------------------------------------
19
+ //
20
+ // This header file defines casting templates to fit use cases not covered by
21
+ // the standard casts provided in the C++ standard. As with all cast operations,
22
+ // use these with caution and only if alternatives do not exist.
23
+
24
+ #ifndef ABSL_BASE_CASTS_H_
25
+ #define ABSL_BASE_CASTS_H_
26
+
27
+ #include <cstring>
28
+ #include <memory>
29
+ #include <type_traits>
30
+ #include <utility>
31
+
32
+ #if defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L
33
+ #include <bit> // For std::bit_cast.
34
+ #endif // defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L
35
+
36
+ #include "absl/base/internal/identity.h"
37
+ #include "absl/base/macros.h"
38
+ #include "absl/meta/type_traits.h"
39
+
40
+ namespace absl {
41
+ ABSL_NAMESPACE_BEGIN
42
+
43
+ // implicit_cast()
44
+ //
45
+ // Performs an implicit conversion between types following the language
46
+ // rules for implicit conversion; if an implicit conversion is otherwise
47
+ // allowed by the language in the given context, this function performs such an
48
+ // implicit conversion.
49
+ //
50
+ // Example:
51
+ //
52
+ // // If the context allows implicit conversion:
53
+ // From from;
54
+ // To to = from;
55
+ //
56
+ // // Such code can be replaced by:
57
+ // implicit_cast<To>(from);
58
+ //
59
+ // An `implicit_cast()` may also be used to annotate numeric type conversions
60
+ // that, although safe, may produce compiler warnings (such as `long` to `int`).
61
+ // Additionally, an `implicit_cast()` is also useful within return statements to
62
+ // indicate a specific implicit conversion is being undertaken.
63
+ //
64
+ // Example:
65
+ //
66
+ // return implicit_cast<double>(size_in_bytes) / capacity_;
67
+ //
68
+ // Annotating code with `implicit_cast()` allows you to explicitly select
69
+ // particular overloads and template instantiations, while providing a safer
70
+ // cast than `reinterpret_cast()` or `static_cast()`.
71
+ //
72
+ // Additionally, an `implicit_cast()` can be used to allow upcasting within a
73
+ // type hierarchy where incorrect use of `static_cast()` could accidentally
74
+ // allow downcasting.
75
+ //
76
+ // Finally, an `implicit_cast()` can be used to perform implicit conversions
77
+ // from unrelated types that otherwise couldn't be implicitly cast directly;
78
+ // C++ will normally only implicitly cast "one step" in such conversions.
79
+ //
80
+ // That is, if C is a type which can be implicitly converted to B, with B being
81
+ // a type that can be implicitly converted to A, an `implicit_cast()` can be
82
+ // used to convert C to B (which the compiler can then implicitly convert to A
83
+ // using language rules).
84
+ //
85
+ // Example:
86
+ //
87
+ // // Assume an object C is convertible to B, which is implicitly convertible
88
+ // // to A
89
+ // A a = implicit_cast<B>(C);
90
+ //
91
+ // Such implicit cast chaining may be useful within template logic.
92
+ template <typename To>
93
+ constexpr To implicit_cast(typename absl::internal::type_identity_t<To> to) {
94
+ return to;
95
+ }
96
+
97
+ // bit_cast()
98
+ //
99
+ // Creates a value of the new type `Dest` whose representation is the same as
100
+ // that of the argument, which is of (deduced) type `Source` (a "bitwise cast";
101
+ // every bit in the value representation of the result is equal to the
102
+ // corresponding bit in the object representation of the source). Source and
103
+ // destination types must be of the same size, and both types must be trivially
104
+ // copyable.
105
+ //
106
+ // As with most casts, use with caution. A `bit_cast()` might be needed when you
107
+ // need to treat a value as the value of some other type, for example, to access
108
+ // the individual bits of an object which are not normally accessible through
109
+ // the object's type, such as for working with the binary representation of a
110
+ // floating point value:
111
+ //
112
+ // float f = 3.14159265358979;
113
+ // int i = bit_cast<int>(f);
114
+ // // i = 0x40490fdb
115
+ //
116
+ // Reinterpreting and accessing a value directly as a different type (as shown
117
+ // below) usually results in undefined behavior.
118
+ //
119
+ // Example:
120
+ //
121
+ // // WRONG
122
+ // float f = 3.14159265358979;
123
+ // int i = reinterpret_cast<int&>(f); // Wrong
124
+ // int j = *reinterpret_cast<int*>(&f); // Equally wrong
125
+ // int k = *bit_cast<int*>(&f); // Equally wrong
126
+ //
127
+ // Reinterpret-casting results in undefined behavior according to the ISO C++
128
+ // specification, section [basic.lval]. Roughly, this section says: if an object
129
+ // in memory has one type, and a program accesses it with a different type, the
130
+ // result is undefined behavior for most "different type".
131
+ //
132
+ // Using bit_cast on a pointer and then dereferencing it is no better than using
133
+ // reinterpret_cast. You should only use bit_cast on the value itself.
134
+ //
135
+ // Such casting results in type punning: holding an object in memory of one type
136
+ // and reading its bits back using a different type. A `bit_cast()` avoids this
137
+ // issue by copying the object representation to a new value, which avoids
138
+ // introducing this undefined behavior (since the original value is never
139
+ // accessed in the wrong way).
140
+ //
141
+ // The requirements of `absl::bit_cast` are more strict than that of
142
+ // `std::bit_cast` unless compiler support is available. Specifically, without
143
+ // compiler support, this implementation also requires `Dest` to be
144
+ // default-constructible. In C++20, `absl::bit_cast` is replaced by
145
+ // `std::bit_cast`.
146
+ #if defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L
147
+
148
+ using std::bit_cast;
149
+
150
+ #else // defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L
151
+
152
+ template <
153
+ typename Dest, typename Source,
154
+ typename std::enable_if<sizeof(Dest) == sizeof(Source) &&
155
+ std::is_trivially_copyable<Source>::value &&
156
+ std::is_trivially_copyable<Dest>::value
157
+ #if !ABSL_HAVE_BUILTIN(__builtin_bit_cast)
158
+ && std::is_default_constructible<Dest>::value
159
+ #endif // !ABSL_HAVE_BUILTIN(__builtin_bit_cast)
160
+ ,
161
+ int>::type = 0>
162
+ #if ABSL_HAVE_BUILTIN(__builtin_bit_cast)
163
+ inline constexpr Dest bit_cast(const Source& source) {
164
+ return __builtin_bit_cast(Dest, source);
165
+ }
166
+ #else // ABSL_HAVE_BUILTIN(__builtin_bit_cast)
167
+ inline Dest bit_cast(const Source& source) {
168
+ Dest dest;
169
+ memcpy(static_cast<void*>(std::addressof(dest)),
170
+ static_cast<const void*>(std::addressof(source)), sizeof(dest));
171
+ return dest;
172
+ }
173
+ #endif // ABSL_HAVE_BUILTIN(__builtin_bit_cast)
174
+
175
+ #endif // defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L
176
+
177
+ ABSL_NAMESPACE_END
178
+ } // namespace absl
179
+
180
+ #endif // ABSL_BASE_CASTS_H_
weight/_dep/abseil-cpp/absl/base/internal/cmake_thread_test.cc ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2018 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include <iostream>
16
+ #include "absl/base/internal/thread_identity.h"
17
+
18
+ int main() {
19
+ auto* tid = absl::base_internal::CurrentThreadIdentityIfPresent();
20
+ // Make sure the above call can't be optimized out
21
+ std::cout << (void*)tid << std::endl;
22
+ }
weight/_dep/abseil-cpp/absl/base/internal/cycleclock.h ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //
2
+ // Copyright 2017 The Abseil Authors.
3
+ //
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // you may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ //
8
+ // https://www.apache.org/licenses/LICENSE-2.0
9
+ //
10
+ // Unless required by applicable law or agreed to in writing, software
11
+ // distributed under the License is distributed on an "AS IS" BASIS,
12
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ // See the License for the specific language governing permissions and
14
+ // limitations under the License.
15
+ //
16
+
17
+ // -----------------------------------------------------------------------------
18
+ // File: cycleclock.h
19
+ // -----------------------------------------------------------------------------
20
+ //
21
+ // This header file defines a `CycleClock`, which yields the value and frequency
22
+ // of a cycle counter that increments at a rate that is approximately constant.
23
+ //
24
+ // NOTE:
25
+ //
26
+ // The cycle counter frequency is not necessarily related to the core clock
27
+ // frequency and should not be treated as such. That is, `CycleClock` cycles are
28
+ // not necessarily "CPU cycles" and code should not rely on that behavior, even
29
+ // if experimentally observed.
30
+ //
31
+ // An arbitrary offset may have been added to the counter at power on.
32
+ //
33
+ // On some platforms, the rate and offset of the counter may differ
34
+ // slightly when read from different CPUs of a multiprocessor. Usually,
35
+ // we try to ensure that the operating system adjusts values periodically
36
+ // so that values agree approximately. If you need stronger guarantees,
37
+ // consider using alternate interfaces.
38
+ //
39
+ // The CPU is not required to maintain the ordering of a cycle counter read
40
+ // with respect to surrounding instructions.
41
+
42
+ #ifndef ABSL_BASE_INTERNAL_CYCLECLOCK_H_
43
+ #define ABSL_BASE_INTERNAL_CYCLECLOCK_H_
44
+
45
+ #include <atomic>
46
+ #include <cstdint>
47
+
48
+ #include "absl/base/attributes.h"
49
+ #include "absl/base/config.h"
50
+ #include "absl/base/internal/cycleclock_config.h"
51
+ #include "absl/base/internal/unscaledcycleclock.h"
52
+
53
+ namespace absl {
54
+ ABSL_NAMESPACE_BEGIN
55
+ namespace base_internal {
56
+
57
+ using CycleClockSourceFunc = int64_t (*)();
58
+
59
+ // -----------------------------------------------------------------------------
60
+ // CycleClock
61
+ // -----------------------------------------------------------------------------
62
+ class CycleClock {
63
+ public:
64
+ // CycleClock::Now()
65
+ //
66
+ // Returns the value of a cycle counter that counts at a rate that is
67
+ // approximately constant.
68
+ static int64_t Now();
69
+
70
+ // CycleClock::Frequency()
71
+ //
72
+ // Returns the amount by which `CycleClock::Now()` increases per second. Note
73
+ // that this value may not necessarily match the core CPU clock frequency.
74
+ static double Frequency();
75
+
76
+ private:
77
+ #if ABSL_USE_UNSCALED_CYCLECLOCK
78
+ static CycleClockSourceFunc LoadCycleClockSource();
79
+
80
+ static constexpr int32_t kShift = kCycleClockShift;
81
+ static constexpr double kFrequencyScale = kCycleClockFrequencyScale;
82
+
83
+ ABSL_CONST_INIT static std::atomic<CycleClockSourceFunc> cycle_clock_source_;
84
+ #endif // ABSL_USE_UNSCALED_CYCLECLOC
85
+
86
+ CycleClock() = delete; // no instances
87
+ CycleClock(const CycleClock&) = delete;
88
+ CycleClock& operator=(const CycleClock&) = delete;
89
+
90
+ friend class CycleClockSource;
91
+ };
92
+
93
+ class CycleClockSource {
94
+ private:
95
+ // CycleClockSource::Register()
96
+ //
97
+ // Register a function that provides an alternate source for the unscaled CPU
98
+ // cycle count value. The source function must be async signal safe, must not
99
+ // call CycleClock::Now(), and must have a frequency that matches that of the
100
+ // unscaled clock used by CycleClock. A nullptr value resets CycleClock to use
101
+ // the default source.
102
+ static void Register(CycleClockSourceFunc source);
103
+ };
104
+
105
+ #if ABSL_USE_UNSCALED_CYCLECLOCK
106
+
107
+ inline CycleClockSourceFunc CycleClock::LoadCycleClockSource() {
108
+ #if !defined(__x86_64__)
109
+ // Optimize for the common case (no callback) by first doing a relaxed load;
110
+ // this is significantly faster on non-x86 platforms.
111
+ if (cycle_clock_source_.load(std::memory_order_relaxed) == nullptr) {
112
+ return nullptr;
113
+ }
114
+ #endif // !defined(__x86_64__)
115
+
116
+ // This corresponds to the store(std::memory_order_release) in
117
+ // CycleClockSource::Register, and makes sure that any updates made prior to
118
+ // registering the callback are visible to this thread before the callback
119
+ // is invoked.
120
+ return cycle_clock_source_.load(std::memory_order_acquire);
121
+ }
122
+
123
+ // Accessing globals in inlined code in Window DLLs is problematic.
124
+ #ifndef _WIN32
125
+ inline int64_t CycleClock::Now() {
126
+ auto fn = LoadCycleClockSource();
127
+ if (fn == nullptr) {
128
+ return base_internal::UnscaledCycleClock::Now() >> kShift;
129
+ }
130
+ return fn() >> kShift;
131
+ }
132
+ #endif
133
+
134
+ inline double CycleClock::Frequency() {
135
+ return kFrequencyScale * base_internal::UnscaledCycleClock::Frequency();
136
+ }
137
+
138
+ #endif // ABSL_USE_UNSCALED_CYCLECLOCK
139
+
140
+ } // namespace base_internal
141
+ ABSL_NAMESPACE_END
142
+ } // namespace absl
143
+
144
+ #endif // ABSL_BASE_INTERNAL_CYCLECLOCK_H_
weight/_dep/abseil-cpp/absl/base/internal/dynamic_annotations.h ADDED
@@ -0,0 +1,398 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ // This file defines dynamic annotations for use with dynamic analysis tool
16
+ // such as valgrind, PIN, etc.
17
+ //
18
+ // Dynamic annotation is a source code annotation that affects the generated
19
+ // code (that is, the annotation is not a comment). Each such annotation is
20
+ // attached to a particular instruction and/or to a particular object (address)
21
+ // in the program.
22
+ //
23
+ // The annotations that should be used by users are macros in all upper-case
24
+ // (e.g., ANNOTATE_THREAD_NAME).
25
+ //
26
+ // Actual implementation of these macros may differ depending on the dynamic
27
+ // analysis tool being used.
28
+ //
29
+ // This file supports the following configurations:
30
+ // - Dynamic Annotations enabled (with static thread-safety warnings disabled).
31
+ // In this case, macros expand to functions implemented by Thread Sanitizer,
32
+ // when building with TSan. When not provided an external implementation,
33
+ // dynamic_annotations.cc provides no-op implementations.
34
+ //
35
+ // - Static Clang thread-safety warnings enabled.
36
+ // When building with a Clang compiler that supports thread-safety warnings,
37
+ // a subset of annotations can be statically-checked at compile-time. We
38
+ // expand these macros to static-inline functions that can be analyzed for
39
+ // thread-safety, but afterwards elided when building the final binary.
40
+ //
41
+ // - All annotations are disabled.
42
+ // If neither Dynamic Annotations nor Clang thread-safety warnings are
43
+ // enabled, then all annotation-macros expand to empty.
44
+
45
+ #ifndef ABSL_BASE_INTERNAL_DYNAMIC_ANNOTATIONS_H_
46
+ #define ABSL_BASE_INTERNAL_DYNAMIC_ANNOTATIONS_H_
47
+
48
+ #include <stddef.h>
49
+
50
+ #include "absl/base/config.h"
51
+
52
+ // -------------------------------------------------------------------------
53
+ // Decide which features are enabled
54
+
55
+ #ifndef DYNAMIC_ANNOTATIONS_ENABLED
56
+ #define DYNAMIC_ANNOTATIONS_ENABLED 0
57
+ #endif
58
+
59
+ #if defined(__clang__) && !defined(SWIG)
60
+ #define ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED 1
61
+ #endif
62
+
63
+ #if DYNAMIC_ANNOTATIONS_ENABLED != 0
64
+
65
+ #define ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED 1
66
+ #define ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED 1
67
+ #define ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED 1
68
+ #define ABSL_INTERNAL_ANNOTALYSIS_ENABLED 0
69
+ #define ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED 1
70
+
71
+ #else
72
+
73
+ #define ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED 0
74
+ #define ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED 0
75
+ #define ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED 0
76
+
77
+ // Clang provides limited support for static thread-safety analysis through a
78
+ // feature called Annotalysis. We configure macro-definitions according to
79
+ // whether Annotalysis support is available. When running in opt-mode, GCC
80
+ // will issue a warning, if these attributes are compiled. Only include them
81
+ // when compiling using Clang.
82
+
83
+ // ANNOTALYSIS_ENABLED == 1 when IGNORE_READ_ATTRIBUTE_ENABLED == 1
84
+ #define ABSL_INTERNAL_ANNOTALYSIS_ENABLED \
85
+ defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED)
86
+ // Read/write annotations are enabled in Annotalysis mode; disabled otherwise.
87
+ #define ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED \
88
+ ABSL_INTERNAL_ANNOTALYSIS_ENABLED
89
+ #endif
90
+
91
+ // Memory annotations are also made available to LLVM's Memory Sanitizer
92
+ #if defined(ABSL_HAVE_MEMORY_SANITIZER) && !defined(__native_client__)
93
+ #define ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED 1
94
+ #endif
95
+
96
+ #ifndef ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED
97
+ #define ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED 0
98
+ #endif
99
+
100
+ #ifdef __cplusplus
101
+ #define ABSL_INTERNAL_BEGIN_EXTERN_C extern "C" {
102
+ #define ABSL_INTERNAL_END_EXTERN_C } // extern "C"
103
+ #define ABSL_INTERNAL_GLOBAL_SCOPED(F) ::F
104
+ #define ABSL_INTERNAL_STATIC_INLINE inline
105
+ #else
106
+ #define ABSL_INTERNAL_BEGIN_EXTERN_C // empty
107
+ #define ABSL_INTERNAL_END_EXTERN_C // empty
108
+ #define ABSL_INTERNAL_GLOBAL_SCOPED(F) F
109
+ #define ABSL_INTERNAL_STATIC_INLINE static inline
110
+ #endif
111
+
112
+ // -------------------------------------------------------------------------
113
+ // Define race annotations.
114
+
115
+ #if ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED == 1
116
+
117
+ // -------------------------------------------------------------
118
+ // Annotations that suppress errors. It is usually better to express the
119
+ // program's synchronization using the other annotations, but these can be used
120
+ // when all else fails.
121
+
122
+ // Report that we may have a benign race at `pointer`, with size
123
+ // "sizeof(*(pointer))". `pointer` must be a non-void* pointer. Insert at the
124
+ // point where `pointer` has been allocated, preferably close to the point
125
+ // where the race happens. See also ANNOTATE_BENIGN_RACE_STATIC.
126
+ #define ANNOTATE_BENIGN_RACE(pointer, description) \
127
+ ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateBenignRaceSized) \
128
+ (__FILE__, __LINE__, pointer, sizeof(*(pointer)), description)
129
+
130
+ // Same as ANNOTATE_BENIGN_RACE(`address`, `description`), but applies to
131
+ // the memory range [`address`, `address`+`size`).
132
+ #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \
133
+ ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateBenignRaceSized) \
134
+ (__FILE__, __LINE__, address, size, description)
135
+
136
+ // Enable (`enable`!=0) or disable (`enable`==0) race detection for all threads.
137
+ // This annotation could be useful if you want to skip expensive race analysis
138
+ // during some period of program execution, e.g. during initialization.
139
+ #define ANNOTATE_ENABLE_RACE_DETECTION(enable) \
140
+ ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateEnableRaceDetection) \
141
+ (__FILE__, __LINE__, enable)
142
+
143
+ // -------------------------------------------------------------
144
+ // Annotations useful for debugging.
145
+
146
+ // Report the current thread `name` to a race detector.
147
+ #define ANNOTATE_THREAD_NAME(name) \
148
+ ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateThreadName)(__FILE__, __LINE__, name)
149
+
150
+ // -------------------------------------------------------------
151
+ // Annotations useful when implementing locks. They are not normally needed by
152
+ // modules that merely use locks. The `lock` argument is a pointer to the lock
153
+ // object.
154
+
155
+ // Report that a lock has been created at address `lock`.
156
+ #define ANNOTATE_RWLOCK_CREATE(lock) \
157
+ ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockCreate)(__FILE__, __LINE__, lock)
158
+
159
+ // Report that a linker initialized lock has been created at address `lock`.
160
+ #ifdef ABSL_HAVE_THREAD_SANITIZER
161
+ #define ANNOTATE_RWLOCK_CREATE_STATIC(lock) \
162
+ ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockCreateStatic) \
163
+ (__FILE__, __LINE__, lock)
164
+ #else
165
+ #define ANNOTATE_RWLOCK_CREATE_STATIC(lock) ANNOTATE_RWLOCK_CREATE(lock)
166
+ #endif
167
+
168
+ // Report that the lock at address `lock` is about to be destroyed.
169
+ #define ANNOTATE_RWLOCK_DESTROY(lock) \
170
+ ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockDestroy)(__FILE__, __LINE__, lock)
171
+
172
+ // Report that the lock at address `lock` has been acquired.
173
+ // `is_w`=1 for writer lock, `is_w`=0 for reader lock.
174
+ #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \
175
+ ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockAcquired) \
176
+ (__FILE__, __LINE__, lock, is_w)
177
+
178
+ // Report that the lock at address `lock` is about to be released.
179
+ // `is_w`=1 for writer lock, `is_w`=0 for reader lock.
180
+ #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) \
181
+ ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockReleased) \
182
+ (__FILE__, __LINE__, lock, is_w)
183
+
184
+ // Apply ANNOTATE_BENIGN_RACE_SIZED to a static variable `static_var`.
185
+ #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \
186
+ namespace { \
187
+ class static_var##_annotator { \
188
+ public: \
189
+ static_var##_annotator() { \
190
+ ANNOTATE_BENIGN_RACE_SIZED(&static_var, sizeof(static_var), \
191
+ #static_var ": " description); \
192
+ } \
193
+ }; \
194
+ static static_var##_annotator the##static_var##_annotator; \
195
+ } // namespace
196
+
197
+ #else // ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED == 0
198
+
199
+ #define ANNOTATE_RWLOCK_CREATE(lock) // empty
200
+ #define ANNOTATE_RWLOCK_CREATE_STATIC(lock) // empty
201
+ #define ANNOTATE_RWLOCK_DESTROY(lock) // empty
202
+ #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) // empty
203
+ #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) // empty
204
+ #define ANNOTATE_BENIGN_RACE(address, description) // empty
205
+ #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) // empty
206
+ #define ANNOTATE_THREAD_NAME(name) // empty
207
+ #define ANNOTATE_ENABLE_RACE_DETECTION(enable) // empty
208
+ #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) // empty
209
+
210
+ #endif // ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED
211
+
212
+ // -------------------------------------------------------------------------
213
+ // Define memory annotations.
214
+
215
+ #if ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED == 1
216
+
217
+ #include <sanitizer/msan_interface.h>
218
+
219
+ #define ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \
220
+ __msan_unpoison(address, size)
221
+
222
+ #define ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) \
223
+ __msan_allocated_memory(address, size)
224
+
225
+ #else // ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED == 0
226
+
227
+ #if DYNAMIC_ANNOTATIONS_ENABLED == 1
228
+ #define ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \
229
+ do { \
230
+ (void)(address); \
231
+ (void)(size); \
232
+ } while (0)
233
+ #define ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) \
234
+ do { \
235
+ (void)(address); \
236
+ (void)(size); \
237
+ } while (0)
238
+ #else
239
+ #define ANNOTATE_MEMORY_IS_INITIALIZED(address, size) // empty
240
+ #define ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) // empty
241
+ #endif
242
+
243
+ #endif // ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED
244
+
245
+ // -------------------------------------------------------------------------
246
+ // Define IGNORE_READS_BEGIN/_END attributes.
247
+
248
+ #if defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED)
249
+
250
+ #define ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE \
251
+ __attribute((exclusive_lock_function("*")))
252
+ #define ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE \
253
+ __attribute((unlock_function("*")))
254
+
255
+ #else // !defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED)
256
+
257
+ #define ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE // empty
258
+ #define ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE // empty
259
+
260
+ #endif // defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED)
261
+
262
+ // -------------------------------------------------------------------------
263
+ // Define IGNORE_READS_BEGIN/_END annotations.
264
+
265
+ #if ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED == 1
266
+
267
+ // Request the analysis tool to ignore all reads in the current thread until
268
+ // ANNOTATE_IGNORE_READS_END is called. Useful to ignore intentional racey
269
+ // reads, while still checking other reads and all writes.
270
+ // See also ANNOTATE_UNPROTECTED_READ.
271
+ #define ANNOTATE_IGNORE_READS_BEGIN() \
272
+ ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreReadsBegin)(__FILE__, __LINE__)
273
+
274
+ // Stop ignoring reads.
275
+ #define ANNOTATE_IGNORE_READS_END() \
276
+ ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreReadsEnd)(__FILE__, __LINE__)
277
+
278
+ #elif defined(ABSL_INTERNAL_ANNOTALYSIS_ENABLED)
279
+
280
+ // When Annotalysis is enabled without Dynamic Annotations, the use of
281
+ // static-inline functions allows the annotations to be read at compile-time,
282
+ // while still letting the compiler elide the functions from the final build.
283
+ //
284
+ // TODO(delesley) -- The exclusive lock here ignores writes as well, but
285
+ // allows IGNORE_READS_AND_WRITES to work properly.
286
+
287
+ #define ANNOTATE_IGNORE_READS_BEGIN() \
288
+ ABSL_INTERNAL_GLOBAL_SCOPED(AbslInternalAnnotateIgnoreReadsBegin)()
289
+
290
+ #define ANNOTATE_IGNORE_READS_END() \
291
+ ABSL_INTERNAL_GLOBAL_SCOPED(AbslInternalAnnotateIgnoreReadsEnd)()
292
+
293
+ #else
294
+
295
+ #define ANNOTATE_IGNORE_READS_BEGIN() // empty
296
+ #define ANNOTATE_IGNORE_READS_END() // empty
297
+
298
+ #endif
299
+
300
+ // -------------------------------------------------------------------------
301
+ // Define IGNORE_WRITES_BEGIN/_END annotations.
302
+
303
+ #if ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED == 1
304
+
305
+ // Similar to ANNOTATE_IGNORE_READS_BEGIN, but ignore writes instead.
306
+ #define ANNOTATE_IGNORE_WRITES_BEGIN() \
307
+ ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreWritesBegin)(__FILE__, __LINE__)
308
+
309
+ // Stop ignoring writes.
310
+ #define ANNOTATE_IGNORE_WRITES_END() \
311
+ ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreWritesEnd)(__FILE__, __LINE__)
312
+
313
+ #else
314
+
315
+ #define ANNOTATE_IGNORE_WRITES_BEGIN() // empty
316
+ #define ANNOTATE_IGNORE_WRITES_END() // empty
317
+
318
+ #endif
319
+
320
+ // -------------------------------------------------------------------------
321
+ // Define the ANNOTATE_IGNORE_READS_AND_WRITES_* annotations using the more
322
+ // primitive annotations defined above.
323
+ //
324
+ // Instead of doing
325
+ // ANNOTATE_IGNORE_READS_BEGIN();
326
+ // ... = x;
327
+ // ANNOTATE_IGNORE_READS_END();
328
+ // one can use
329
+ // ... = ANNOTATE_UNPROTECTED_READ(x);
330
+
331
+ #if defined(ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED)
332
+
333
+ // Start ignoring all memory accesses (both reads and writes).
334
+ #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \
335
+ do { \
336
+ ANNOTATE_IGNORE_READS_BEGIN(); \
337
+ ANNOTATE_IGNORE_WRITES_BEGIN(); \
338
+ } while (0)
339
+
340
+ // Stop ignoring both reads and writes.
341
+ #define ANNOTATE_IGNORE_READS_AND_WRITES_END() \
342
+ do { \
343
+ ANNOTATE_IGNORE_WRITES_END(); \
344
+ ANNOTATE_IGNORE_READS_END(); \
345
+ } while (0)
346
+
347
+ #ifdef __cplusplus
348
+ // ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads.
349
+ #define ANNOTATE_UNPROTECTED_READ(x) \
350
+ absl::base_internal::AnnotateUnprotectedRead(x)
351
+
352
+ #endif
353
+
354
+ #else
355
+
356
+ #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() // empty
357
+ #define ANNOTATE_IGNORE_READS_AND_WRITES_END() // empty
358
+ #define ANNOTATE_UNPROTECTED_READ(x) (x)
359
+
360
+ #endif
361
+
362
+ // -------------------------------------------------------------------------
363
+ // Address sanitizer annotations
364
+
365
+ #ifdef ABSL_HAVE_ADDRESS_SANITIZER
366
+ // Describe the current state of a contiguous container such as e.g.
367
+ // std::vector or std::string. For more details see
368
+ // sanitizer/common_interface_defs.h, which is provided by the compiler.
369
+ #include <sanitizer/common_interface_defs.h>
370
+
371
+ #define ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid) \
372
+ __sanitizer_annotate_contiguous_container(beg, end, old_mid, new_mid)
373
+ #define ADDRESS_SANITIZER_REDZONE(name) \
374
+ struct { \
375
+ char x[8] __attribute__((aligned(8))); \
376
+ } name
377
+
378
+ #else
379
+
380
+ #define ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid)
381
+ #define ADDRESS_SANITIZER_REDZONE(name) static_assert(true, "")
382
+
383
+ #endif // ABSL_HAVE_ADDRESS_SANITIZER
384
+
385
+ // -------------------------------------------------------------------------
386
+ // Undefine the macros intended only for this file.
387
+
388
+ #undef ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED
389
+ #undef ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED
390
+ #undef ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED
391
+ #undef ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED
392
+ #undef ABSL_INTERNAL_ANNOTALYSIS_ENABLED
393
+ #undef ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED
394
+ #undef ABSL_INTERNAL_BEGIN_EXTERN_C
395
+ #undef ABSL_INTERNAL_END_EXTERN_C
396
+ #undef ABSL_INTERNAL_STATIC_INLINE
397
+
398
+ #endif // ABSL_BASE_INTERNAL_DYNAMIC_ANNOTATIONS_H_
weight/_dep/abseil-cpp/absl/base/internal/exception_safety_testing.cc ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include "absl/base/internal/exception_safety_testing.h"
16
+
17
+ #ifdef ABSL_HAVE_EXCEPTIONS
18
+
19
+ #include "gtest/gtest.h"
20
+ #include "absl/meta/type_traits.h"
21
+
22
+ namespace testing {
23
+
24
+ exceptions_internal::NoThrowTag nothrow_ctor;
25
+
26
+ exceptions_internal::StrongGuaranteeTagType strong_guarantee;
27
+
28
+ exceptions_internal::ExceptionSafetyTestBuilder<> MakeExceptionSafetyTester() {
29
+ return {};
30
+ }
31
+
32
+ namespace exceptions_internal {
33
+
34
+ int countdown = -1;
35
+
36
+ ConstructorTracker* ConstructorTracker::current_tracker_instance_ = nullptr;
37
+
38
+ void MaybeThrow(absl::string_view msg, bool throw_bad_alloc) {
39
+ if (countdown-- == 0) {
40
+ if (throw_bad_alloc) throw TestBadAllocException(msg);
41
+ throw TestException(msg);
42
+ }
43
+ }
44
+
45
+ testing::AssertionResult FailureMessage(const TestException& e,
46
+ int countdown) noexcept {
47
+ return testing::AssertionFailure() << "Exception thrown from " << e.what();
48
+ }
49
+
50
+ std::string GetSpecString(TypeSpec spec) {
51
+ std::string out;
52
+ absl::string_view sep;
53
+ const auto append = [&](absl::string_view s) {
54
+ absl::StrAppend(&out, sep, s);
55
+ sep = " | ";
56
+ };
57
+ if (static_cast<bool>(TypeSpec::kNoThrowCopy & spec)) {
58
+ append("kNoThrowCopy");
59
+ }
60
+ if (static_cast<bool>(TypeSpec::kNoThrowMove & spec)) {
61
+ append("kNoThrowMove");
62
+ }
63
+ if (static_cast<bool>(TypeSpec::kNoThrowNew & spec)) {
64
+ append("kNoThrowNew");
65
+ }
66
+ return out;
67
+ }
68
+
69
+ std::string GetSpecString(AllocSpec spec) {
70
+ return static_cast<bool>(AllocSpec::kNoThrowAllocate & spec)
71
+ ? "kNoThrowAllocate"
72
+ : "";
73
+ }
74
+
75
+ } // namespace exceptions_internal
76
+
77
+ } // namespace testing
78
+
79
+ #endif // ABSL_HAVE_EXCEPTIONS
weight/_dep/abseil-cpp/absl/base/internal/fast_type_id_test.cc ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2020 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include "absl/base/internal/fast_type_id.h"
16
+
17
+ #include <cstdint>
18
+ #include <map>
19
+ #include <vector>
20
+
21
+ #include "gtest/gtest.h"
22
+
23
+ namespace {
24
+ namespace bi = absl::base_internal;
25
+
26
+ // NOLINTNEXTLINE
27
+ #define PRIM_TYPES(A) \
28
+ A(bool) \
29
+ A(short) \
30
+ A(unsigned short) \
31
+ A(int) \
32
+ A(unsigned int) \
33
+ A(long) \
34
+ A(unsigned long) \
35
+ A(long long) \
36
+ A(unsigned long long) \
37
+ A(float) \
38
+ A(double) \
39
+ A(long double)
40
+
41
+ TEST(FastTypeIdTest, PrimitiveTypes) {
42
+ bi::FastTypeIdType type_ids[] = {
43
+ #define A(T) bi::FastTypeId<T>(),
44
+ PRIM_TYPES(A)
45
+ #undef A
46
+ #define A(T) bi::FastTypeId<const T>(),
47
+ PRIM_TYPES(A)
48
+ #undef A
49
+ #define A(T) bi::FastTypeId<volatile T>(),
50
+ PRIM_TYPES(A)
51
+ #undef A
52
+ #define A(T) bi::FastTypeId<const volatile T>(),
53
+ PRIM_TYPES(A)
54
+ #undef A
55
+ };
56
+ size_t total_type_ids = sizeof(type_ids) / sizeof(bi::FastTypeIdType);
57
+
58
+ for (int i = 0; i < total_type_ids; ++i) {
59
+ EXPECT_EQ(type_ids[i], type_ids[i]);
60
+ for (int j = 0; j < i; ++j) {
61
+ EXPECT_NE(type_ids[i], type_ids[j]);
62
+ }
63
+ }
64
+ }
65
+
66
+ #define FIXED_WIDTH_TYPES(A) \
67
+ A(int8_t) \
68
+ A(uint8_t) \
69
+ A(int16_t) \
70
+ A(uint16_t) \
71
+ A(int32_t) \
72
+ A(uint32_t) \
73
+ A(int64_t) \
74
+ A(uint64_t)
75
+
76
+ TEST(FastTypeIdTest, FixedWidthTypes) {
77
+ bi::FastTypeIdType type_ids[] = {
78
+ #define A(T) bi::FastTypeId<T>(),
79
+ FIXED_WIDTH_TYPES(A)
80
+ #undef A
81
+ #define A(T) bi::FastTypeId<const T>(),
82
+ FIXED_WIDTH_TYPES(A)
83
+ #undef A
84
+ #define A(T) bi::FastTypeId<volatile T>(),
85
+ FIXED_WIDTH_TYPES(A)
86
+ #undef A
87
+ #define A(T) bi::FastTypeId<const volatile T>(),
88
+ FIXED_WIDTH_TYPES(A)
89
+ #undef A
90
+ };
91
+ size_t total_type_ids = sizeof(type_ids) / sizeof(bi::FastTypeIdType);
92
+
93
+ for (int i = 0; i < total_type_ids; ++i) {
94
+ EXPECT_EQ(type_ids[i], type_ids[i]);
95
+ for (int j = 0; j < i; ++j) {
96
+ EXPECT_NE(type_ids[i], type_ids[j]);
97
+ }
98
+ }
99
+ }
100
+
101
+ TEST(FastTypeIdTest, AliasTypes) {
102
+ using int_alias = int;
103
+ EXPECT_EQ(bi::FastTypeId<int_alias>(), bi::FastTypeId<int>());
104
+ }
105
+
106
+ TEST(FastTypeIdTest, TemplateSpecializations) {
107
+ EXPECT_NE(bi::FastTypeId<std::vector<int>>(),
108
+ bi::FastTypeId<std::vector<long>>());
109
+
110
+ EXPECT_NE((bi::FastTypeId<std::map<int, float>>()),
111
+ (bi::FastTypeId<std::map<int, double>>()));
112
+ }
113
+
114
+ struct Base {};
115
+ struct Derived : Base {};
116
+ struct PDerived : private Base {};
117
+
118
+ TEST(FastTypeIdTest, Inheritance) {
119
+ EXPECT_NE(bi::FastTypeId<Base>(), bi::FastTypeId<Derived>());
120
+ EXPECT_NE(bi::FastTypeId<Base>(), bi::FastTypeId<PDerived>());
121
+ }
122
+
123
+ } // namespace
weight/_dep/abseil-cpp/absl/base/internal/low_level_alloc.cc ADDED
@@ -0,0 +1,631 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ // A low-level allocator that can be used by other low-level
16
+ // modules without introducing dependency cycles.
17
+ // This allocator is slow and wasteful of memory;
18
+ // it should not be used when performance is key.
19
+
20
+ #include "absl/base/internal/low_level_alloc.h"
21
+
22
+ #include <type_traits>
23
+
24
+ #include "absl/base/call_once.h"
25
+ #include "absl/base/config.h"
26
+ #include "absl/base/internal/direct_mmap.h"
27
+ #include "absl/base/internal/scheduling_mode.h"
28
+ #include "absl/base/macros.h"
29
+ #include "absl/base/thread_annotations.h"
30
+
31
+ // LowLevelAlloc requires that the platform support low-level
32
+ // allocation of virtual memory. Platforms lacking this cannot use
33
+ // LowLevelAlloc.
34
+ #ifndef ABSL_LOW_LEVEL_ALLOC_MISSING
35
+
36
+ #ifndef _WIN32
37
+ #include <pthread.h>
38
+ #include <signal.h>
39
+ #include <sys/mman.h>
40
+ #include <unistd.h>
41
+ #else
42
+ #include <windows.h>
43
+ #endif
44
+
45
+ #ifdef __linux__
46
+ #include <sys/prctl.h>
47
+ #endif
48
+
49
+ #include <string.h>
50
+
51
+ #include <algorithm>
52
+ #include <atomic>
53
+ #include <cerrno>
54
+ #include <cstddef>
55
+ #include <new> // for placement-new
56
+
57
+ #include "absl/base/dynamic_annotations.h"
58
+ #include "absl/base/internal/raw_logging.h"
59
+ #include "absl/base/internal/spinlock.h"
60
+
61
+ #if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
62
+ #define MAP_ANONYMOUS MAP_ANON
63
+ #endif
64
+
65
+ namespace absl {
66
+ ABSL_NAMESPACE_BEGIN
67
+ namespace base_internal {
68
+
69
+ // A first-fit allocator with amortized logarithmic free() time.
70
+
71
+ // ---------------------------------------------------------------------------
72
+ static const int kMaxLevel = 30;
73
+
74
+ namespace {
75
+ // This struct describes one allocated block, or one free block.
76
+ struct AllocList {
77
+ struct Header {
78
+ // Size of entire region, including this field. Must be
79
+ // first. Valid in both allocated and unallocated blocks.
80
+ uintptr_t size;
81
+
82
+ // kMagicAllocated or kMagicUnallocated xor this.
83
+ uintptr_t magic;
84
+
85
+ // Pointer to parent arena.
86
+ LowLevelAlloc::Arena *arena;
87
+
88
+ // Aligns regions to 0 mod 2*sizeof(void*).
89
+ void *dummy_for_alignment;
90
+ } header;
91
+
92
+ // Next two fields: in unallocated blocks: freelist skiplist data
93
+ // in allocated blocks: overlaps with client data
94
+
95
+ // Levels in skiplist used.
96
+ int levels;
97
+
98
+ // Actually has levels elements. The AllocList node may not have room
99
+ // for all kMaxLevel entries. See max_fit in LLA_SkiplistLevels().
100
+ AllocList *next[kMaxLevel];
101
+ };
102
+ } // namespace
103
+
104
+ // ---------------------------------------------------------------------------
105
+ // A trivial skiplist implementation. This is used to keep the freelist
106
+ // in address order while taking only logarithmic time per insert and delete.
107
+
108
+ // An integer approximation of log2(size/base)
109
+ // Requires size >= base.
110
+ static int IntLog2(size_t size, size_t base) {
111
+ int result = 0;
112
+ for (size_t i = size; i > base; i >>= 1) { // i == floor(size/2**result)
113
+ result++;
114
+ }
115
+ // floor(size / 2**result) <= base < floor(size / 2**(result-1))
116
+ // => log2(size/(base+1)) <= result < 1+log2(size/base)
117
+ // => result ~= log2(size/base)
118
+ return result;
119
+ }
120
+
121
+ // Return a random integer n: p(n)=1/(2**n) if 1 <= n; p(n)=0 if n < 1.
122
+ static int Random(uint32_t *state) {
123
+ uint32_t r = *state;
124
+ int result = 1;
125
+ while ((((r = r * 1103515245 + 12345) >> 30) & 1) == 0) {
126
+ result++;
127
+ }
128
+ *state = r;
129
+ return result;
130
+ }
131
+
132
+ // Return a number of skiplist levels for a node of size bytes, where
133
+ // base is the minimum node size. Compute level=log2(size / base)+n
134
+ // where n is 1 if random is false and otherwise a random number generated with
135
+ // the standard distribution for a skiplist: See Random() above.
136
+ // Bigger nodes tend to have more skiplist levels due to the log2(size / base)
137
+ // term, so first-fit searches touch fewer nodes. "level" is clipped so
138
+ // level<kMaxLevel and next[level-1] will fit in the node.
139
+ // 0 < LLA_SkiplistLevels(x,y,false) <= LLA_SkiplistLevels(x,y,true) < kMaxLevel
140
+ static int LLA_SkiplistLevels(size_t size, size_t base, uint32_t *random) {
141
+ // max_fit is the maximum number of levels that will fit in a node for the
142
+ // given size. We can't return more than max_fit, no matter what the
143
+ // random number generator says.
144
+ size_t max_fit = (size - offsetof(AllocList, next)) / sizeof(AllocList *);
145
+ int level = IntLog2(size, base) + (random != nullptr ? Random(random) : 1);
146
+ if (static_cast<size_t>(level) > max_fit) level = static_cast<int>(max_fit);
147
+ if (level > kMaxLevel - 1) level = kMaxLevel - 1;
148
+ ABSL_RAW_CHECK(level >= 1, "block not big enough for even one level");
149
+ return level;
150
+ }
151
+
152
+ // Return "atleast", the first element of AllocList *head s.t. *atleast >= *e.
153
+ // For 0 <= i < head->levels, set prev[i] to "no_greater", where no_greater
154
+ // points to the last element at level i in the AllocList less than *e, or is
155
+ // head if no such element exists.
156
+ static AllocList *LLA_SkiplistSearch(AllocList *head, AllocList *e,
157
+ AllocList **prev) {
158
+ AllocList *p = head;
159
+ for (int level = head->levels - 1; level >= 0; level--) {
160
+ for (AllocList *n; (n = p->next[level]) != nullptr && n < e; p = n) {
161
+ }
162
+ prev[level] = p;
163
+ }
164
+ return (head->levels == 0) ? nullptr : prev[0]->next[0];
165
+ }
166
+
167
+ // Insert element *e into AllocList *head. Set prev[] as LLA_SkiplistSearch.
168
+ // Requires that e->levels be previously set by the caller (using
169
+ // LLA_SkiplistLevels())
170
+ static void LLA_SkiplistInsert(AllocList *head, AllocList *e,
171
+ AllocList **prev) {
172
+ LLA_SkiplistSearch(head, e, prev);
173
+ for (; head->levels < e->levels; head->levels++) { // extend prev pointers
174
+ prev[head->levels] = head; // to all *e's levels
175
+ }
176
+ for (int i = 0; i != e->levels; i++) { // add element to list
177
+ e->next[i] = prev[i]->next[i];
178
+ prev[i]->next[i] = e;
179
+ }
180
+ }
181
+
182
+ // Remove element *e from AllocList *head. Set prev[] as LLA_SkiplistSearch().
183
+ // Requires that e->levels be previous set by the caller (using
184
+ // LLA_SkiplistLevels())
185
+ static void LLA_SkiplistDelete(AllocList *head, AllocList *e,
186
+ AllocList **prev) {
187
+ AllocList *found = LLA_SkiplistSearch(head, e, prev);
188
+ ABSL_RAW_CHECK(e == found, "element not in freelist");
189
+ for (int i = 0; i != e->levels && prev[i]->next[i] == e; i++) {
190
+ prev[i]->next[i] = e->next[i];
191
+ }
192
+ while (head->levels > 0 && head->next[head->levels - 1] == nullptr) {
193
+ head->levels--; // reduce head->levels if level unused
194
+ }
195
+ }
196
+
197
+ // ---------------------------------------------------------------------------
198
+ // Arena implementation
199
+
200
+ // Metadata for an LowLevelAlloc arena instance.
201
+ struct LowLevelAlloc::Arena {
202
+ // Constructs an arena with the given LowLevelAlloc flags.
203
+ explicit Arena(uint32_t flags_value);
204
+
205
+ base_internal::SpinLock mu;
206
+ // Head of free list, sorted by address
207
+ AllocList freelist ABSL_GUARDED_BY(mu);
208
+ // Count of allocated blocks
209
+ int32_t allocation_count ABSL_GUARDED_BY(mu);
210
+ // flags passed to NewArena
211
+ const uint32_t flags;
212
+ // Result of sysconf(_SC_PAGESIZE)
213
+ const size_t pagesize;
214
+ // Lowest power of two >= max(16, sizeof(AllocList))
215
+ const size_t round_up;
216
+ // Smallest allocation block size
217
+ const size_t min_size;
218
+ // PRNG state
219
+ uint32_t random ABSL_GUARDED_BY(mu);
220
+ };
221
+
222
+ namespace {
223
+ // Static storage space for the lazily-constructed, default global arena
224
+ // instances. We require this space because the whole point of LowLevelAlloc
225
+ // is to avoid relying on malloc/new.
226
+ alignas(LowLevelAlloc::Arena) unsigned char default_arena_storage[sizeof(
227
+ LowLevelAlloc::Arena)];
228
+ alignas(LowLevelAlloc::Arena) unsigned char unhooked_arena_storage[sizeof(
229
+ LowLevelAlloc::Arena)];
230
+ #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
231
+ alignas(
232
+ LowLevelAlloc::Arena) unsigned char unhooked_async_sig_safe_arena_storage
233
+ [sizeof(LowLevelAlloc::Arena)];
234
+ #endif
235
+
236
+ // We must use LowLevelCallOnce here to construct the global arenas, rather than
237
+ // using function-level statics, to avoid recursively invoking the scheduler.
238
+ absl::once_flag create_globals_once;
239
+
240
+ void CreateGlobalArenas() {
241
+ new (&default_arena_storage)
242
+ LowLevelAlloc::Arena(LowLevelAlloc::kCallMallocHook);
243
+ new (&unhooked_arena_storage) LowLevelAlloc::Arena(0);
244
+ #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
245
+ new (&unhooked_async_sig_safe_arena_storage)
246
+ LowLevelAlloc::Arena(LowLevelAlloc::kAsyncSignalSafe);
247
+ #endif
248
+ }
249
+
250
+ // Returns a global arena that does not call into hooks. Used by NewArena()
251
+ // when kCallMallocHook is not set.
252
+ LowLevelAlloc::Arena *UnhookedArena() {
253
+ base_internal::LowLevelCallOnce(&create_globals_once, CreateGlobalArenas);
254
+ return reinterpret_cast<LowLevelAlloc::Arena *>(&unhooked_arena_storage);
255
+ }
256
+
257
+ #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
258
+ // Returns a global arena that is async-signal safe. Used by NewArena() when
259
+ // kAsyncSignalSafe is set.
260
+ LowLevelAlloc::Arena *UnhookedAsyncSigSafeArena() {
261
+ base_internal::LowLevelCallOnce(&create_globals_once, CreateGlobalArenas);
262
+ return reinterpret_cast<LowLevelAlloc::Arena *>(
263
+ &unhooked_async_sig_safe_arena_storage);
264
+ }
265
+ #endif
266
+
267
+ } // namespace
268
+
269
+ // Returns the default arena, as used by LowLevelAlloc::Alloc() and friends.
270
+ LowLevelAlloc::Arena *LowLevelAlloc::DefaultArena() {
271
+ base_internal::LowLevelCallOnce(&create_globals_once, CreateGlobalArenas);
272
+ return reinterpret_cast<LowLevelAlloc::Arena *>(&default_arena_storage);
273
+ }
274
+
275
+ // magic numbers to identify allocated and unallocated blocks
276
+ static const uintptr_t kMagicAllocated = 0x4c833e95U;
277
+ static const uintptr_t kMagicUnallocated = ~kMagicAllocated;
278
+
279
+ namespace {
280
+ class ABSL_SCOPED_LOCKABLE ArenaLock {
281
+ public:
282
+ explicit ArenaLock(LowLevelAlloc::Arena *arena)
283
+ ABSL_EXCLUSIVE_LOCK_FUNCTION(arena->mu)
284
+ : arena_(arena) {
285
+ #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
286
+ if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) != 0) {
287
+ sigset_t all;
288
+ sigfillset(&all);
289
+ mask_valid_ = pthread_sigmask(SIG_BLOCK, &all, &mask_) == 0;
290
+ }
291
+ #endif
292
+ arena_->mu.Lock();
293
+ }
294
+ ~ArenaLock() { ABSL_RAW_CHECK(left_, "haven't left Arena region"); }
295
+ void Leave() ABSL_UNLOCK_FUNCTION() {
296
+ arena_->mu.Unlock();
297
+ #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
298
+ if (mask_valid_) {
299
+ const int err = pthread_sigmask(SIG_SETMASK, &mask_, nullptr);
300
+ if (err != 0) {
301
+ ABSL_RAW_LOG(FATAL, "pthread_sigmask failed: %d", err);
302
+ }
303
+ }
304
+ #endif
305
+ left_ = true;
306
+ }
307
+
308
+ private:
309
+ bool left_ = false; // whether left region
310
+ #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
311
+ bool mask_valid_ = false;
312
+ sigset_t mask_; // old mask of blocked signals
313
+ #endif
314
+ LowLevelAlloc::Arena *arena_;
315
+ ArenaLock(const ArenaLock &) = delete;
316
+ ArenaLock &operator=(const ArenaLock &) = delete;
317
+ };
318
+ } // namespace
319
+
320
+ // create an appropriate magic number for an object at "ptr"
321
+ // "magic" should be kMagicAllocated or kMagicUnallocated
322
+ inline static uintptr_t Magic(uintptr_t magic, AllocList::Header *ptr) {
323
+ return magic ^ reinterpret_cast<uintptr_t>(ptr);
324
+ }
325
+
326
+ namespace {
327
+ size_t GetPageSize() {
328
+ #ifdef _WIN32
329
+ SYSTEM_INFO system_info;
330
+ GetSystemInfo(&system_info);
331
+ return std::max(system_info.dwPageSize, system_info.dwAllocationGranularity);
332
+ #elif defined(__wasm__) || defined(__asmjs__) || defined(__hexagon__)
333
+ return getpagesize();
334
+ #else
335
+ return static_cast<size_t>(sysconf(_SC_PAGESIZE));
336
+ #endif
337
+ }
338
+
339
+ size_t RoundedUpBlockSize() {
340
+ // Round up block sizes to a power of two close to the header size.
341
+ size_t round_up = 16;
342
+ while (round_up < sizeof(AllocList::Header)) {
343
+ round_up += round_up;
344
+ }
345
+ return round_up;
346
+ }
347
+
348
+ } // namespace
349
+
350
+ LowLevelAlloc::Arena::Arena(uint32_t flags_value)
351
+ : mu(base_internal::SCHEDULE_KERNEL_ONLY),
352
+ allocation_count(0),
353
+ flags(flags_value),
354
+ pagesize(GetPageSize()),
355
+ round_up(RoundedUpBlockSize()),
356
+ min_size(2 * round_up),
357
+ random(0) {
358
+ freelist.header.size = 0;
359
+ freelist.header.magic = Magic(kMagicUnallocated, &freelist.header);
360
+ freelist.header.arena = this;
361
+ freelist.levels = 0;
362
+ memset(freelist.next, 0, sizeof(freelist.next));
363
+ }
364
+
365
+ // L < meta_data_arena->mu
366
+ LowLevelAlloc::Arena *LowLevelAlloc::NewArena(uint32_t flags) {
367
+ Arena *meta_data_arena = DefaultArena();
368
+ #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
369
+ if ((flags & LowLevelAlloc::kAsyncSignalSafe) != 0) {
370
+ meta_data_arena = UnhookedAsyncSigSafeArena();
371
+ } else // NOLINT(readability/braces)
372
+ #endif
373
+ if ((flags & LowLevelAlloc::kCallMallocHook) == 0) {
374
+ meta_data_arena = UnhookedArena();
375
+ }
376
+ Arena *result =
377
+ new (AllocWithArena(sizeof(*result), meta_data_arena)) Arena(flags);
378
+ return result;
379
+ }
380
+
381
+ // L < arena->mu, L < arena->arena->mu
382
+ bool LowLevelAlloc::DeleteArena(Arena *arena) {
383
+ ABSL_RAW_CHECK(
384
+ arena != nullptr && arena != DefaultArena() && arena != UnhookedArena(),
385
+ "may not delete default arena");
386
+ ArenaLock section(arena);
387
+ if (arena->allocation_count != 0) {
388
+ section.Leave();
389
+ return false;
390
+ }
391
+ while (arena->freelist.next[0] != nullptr) {
392
+ AllocList *region = arena->freelist.next[0];
393
+ size_t size = region->header.size;
394
+ arena->freelist.next[0] = region->next[0];
395
+ ABSL_RAW_CHECK(
396
+ region->header.magic == Magic(kMagicUnallocated, &region->header),
397
+ "bad magic number in DeleteArena()");
398
+ ABSL_RAW_CHECK(region->header.arena == arena,
399
+ "bad arena pointer in DeleteArena()");
400
+ ABSL_RAW_CHECK(size % arena->pagesize == 0,
401
+ "empty arena has non-page-aligned block size");
402
+ ABSL_RAW_CHECK(reinterpret_cast<uintptr_t>(region) % arena->pagesize == 0,
403
+ "empty arena has non-page-aligned block");
404
+ int munmap_result;
405
+ #ifdef _WIN32
406
+ munmap_result = VirtualFree(region, 0, MEM_RELEASE);
407
+ ABSL_RAW_CHECK(munmap_result != 0,
408
+ "LowLevelAlloc::DeleteArena: VitualFree failed");
409
+ #else
410
+ #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
411
+ if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) == 0) {
412
+ munmap_result = munmap(region, size);
413
+ } else {
414
+ munmap_result = base_internal::DirectMunmap(region, size);
415
+ }
416
+ #else
417
+ munmap_result = munmap(region, size);
418
+ #endif // ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
419
+ if (munmap_result != 0) {
420
+ ABSL_RAW_LOG(FATAL, "LowLevelAlloc::DeleteArena: munmap failed: %d",
421
+ errno);
422
+ }
423
+ #endif // _WIN32
424
+ }
425
+ section.Leave();
426
+ arena->~Arena();
427
+ Free(arena);
428
+ return true;
429
+ }
430
+
431
+ // ---------------------------------------------------------------------------
432
+
433
+ // Addition, checking for overflow. The intent is to die if an external client
434
+ // manages to push through a request that would cause arithmetic to fail.
435
+ static inline uintptr_t CheckedAdd(uintptr_t a, uintptr_t b) {
436
+ uintptr_t sum = a + b;
437
+ ABSL_RAW_CHECK(sum >= a, "LowLevelAlloc arithmetic overflow");
438
+ return sum;
439
+ }
440
+
441
+ // Return value rounded up to next multiple of align.
442
+ // align must be a power of two.
443
+ static inline uintptr_t RoundUp(uintptr_t addr, uintptr_t align) {
444
+ return CheckedAdd(addr, align - 1) & ~(align - 1);
445
+ }
446
+
447
+ // Equivalent to "return prev->next[i]" but with sanity checking
448
+ // that the freelist is in the correct order, that it
449
+ // consists of regions marked "unallocated", and that no two regions
450
+ // are adjacent in memory (they should have been coalesced).
451
+ // L >= arena->mu
452
+ static AllocList *Next(int i, AllocList *prev, LowLevelAlloc::Arena *arena) {
453
+ ABSL_RAW_CHECK(i < prev->levels, "too few levels in Next()");
454
+ AllocList *next = prev->next[i];
455
+ if (next != nullptr) {
456
+ ABSL_RAW_CHECK(
457
+ next->header.magic == Magic(kMagicUnallocated, &next->header),
458
+ "bad magic number in Next()");
459
+ ABSL_RAW_CHECK(next->header.arena == arena, "bad arena pointer in Next()");
460
+ if (prev != &arena->freelist) {
461
+ ABSL_RAW_CHECK(prev < next, "unordered freelist");
462
+ ABSL_RAW_CHECK(reinterpret_cast<char *>(prev) + prev->header.size <
463
+ reinterpret_cast<char *>(next),
464
+ "malformed freelist");
465
+ }
466
+ }
467
+ return next;
468
+ }
469
+
470
+ // Coalesce list item "a" with its successor if they are adjacent.
471
+ static void Coalesce(AllocList *a) {
472
+ AllocList *n = a->next[0];
473
+ if (n != nullptr && reinterpret_cast<char *>(a) + a->header.size ==
474
+ reinterpret_cast<char *>(n)) {
475
+ LowLevelAlloc::Arena *arena = a->header.arena;
476
+ a->header.size += n->header.size;
477
+ n->header.magic = 0;
478
+ n->header.arena = nullptr;
479
+ AllocList *prev[kMaxLevel];
480
+ LLA_SkiplistDelete(&arena->freelist, n, prev);
481
+ LLA_SkiplistDelete(&arena->freelist, a, prev);
482
+ a->levels =
483
+ LLA_SkiplistLevels(a->header.size, arena->min_size, &arena->random);
484
+ LLA_SkiplistInsert(&arena->freelist, a, prev);
485
+ }
486
+ }
487
+
488
+ // Adds block at location "v" to the free list
489
+ // L >= arena->mu
490
+ static void AddToFreelist(void *v, LowLevelAlloc::Arena *arena) {
491
+ AllocList *f = reinterpret_cast<AllocList *>(reinterpret_cast<char *>(v) -
492
+ sizeof(f->header));
493
+ ABSL_RAW_CHECK(f->header.magic == Magic(kMagicAllocated, &f->header),
494
+ "bad magic number in AddToFreelist()");
495
+ ABSL_RAW_CHECK(f->header.arena == arena,
496
+ "bad arena pointer in AddToFreelist()");
497
+ f->levels =
498
+ LLA_SkiplistLevels(f->header.size, arena->min_size, &arena->random);
499
+ AllocList *prev[kMaxLevel];
500
+ LLA_SkiplistInsert(&arena->freelist, f, prev);
501
+ f->header.magic = Magic(kMagicUnallocated, &f->header);
502
+ Coalesce(f); // maybe coalesce with successor
503
+ Coalesce(prev[0]); // maybe coalesce with predecessor
504
+ }
505
+
506
+ // Frees storage allocated by LowLevelAlloc::Alloc().
507
+ // L < arena->mu
508
+ void LowLevelAlloc::Free(void *v) {
509
+ if (v != nullptr) {
510
+ AllocList *f = reinterpret_cast<AllocList *>(reinterpret_cast<char *>(v) -
511
+ sizeof(f->header));
512
+ LowLevelAlloc::Arena *arena = f->header.arena;
513
+ ArenaLock section(arena);
514
+ AddToFreelist(v, arena);
515
+ ABSL_RAW_CHECK(arena->allocation_count > 0, "nothing in arena to free");
516
+ arena->allocation_count--;
517
+ section.Leave();
518
+ }
519
+ }
520
+
521
+ // allocates and returns a block of size bytes, to be freed with Free()
522
+ // L < arena->mu
523
+ static void *DoAllocWithArena(size_t request, LowLevelAlloc::Arena *arena) {
524
+ void *result = nullptr;
525
+ if (request != 0) {
526
+ AllocList *s; // will point to region that satisfies request
527
+ ArenaLock section(arena);
528
+ // round up with header
529
+ size_t req_rnd =
530
+ RoundUp(CheckedAdd(request, sizeof(s->header)), arena->round_up);
531
+ for (;;) { // loop until we find a suitable region
532
+ // find the minimum levels that a block of this size must have
533
+ int i = LLA_SkiplistLevels(req_rnd, arena->min_size, nullptr) - 1;
534
+ if (i < arena->freelist.levels) { // potential blocks exist
535
+ AllocList *before = &arena->freelist; // predecessor of s
536
+ while ((s = Next(i, before, arena)) != nullptr &&
537
+ s->header.size < req_rnd) {
538
+ before = s;
539
+ }
540
+ if (s != nullptr) { // we found a region
541
+ break;
542
+ }
543
+ }
544
+ // we unlock before mmap() both because mmap() may call a callback hook,
545
+ // and because it may be slow.
546
+ arena->mu.Unlock();
547
+ // mmap generous 64K chunks to decrease
548
+ // the chances/impact of fragmentation:
549
+ size_t new_pages_size = RoundUp(req_rnd, arena->pagesize * 16);
550
+ void *new_pages;
551
+ #ifdef _WIN32
552
+ new_pages = VirtualAlloc(nullptr, new_pages_size,
553
+ MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
554
+ ABSL_RAW_CHECK(new_pages != nullptr, "VirtualAlloc failed");
555
+ #else
556
+ #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
557
+ if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) != 0) {
558
+ new_pages = base_internal::DirectMmap(nullptr, new_pages_size,
559
+ PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
560
+ } else {
561
+ new_pages = mmap(nullptr, new_pages_size, PROT_WRITE | PROT_READ,
562
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
563
+ }
564
+ #else
565
+ new_pages = mmap(nullptr, new_pages_size, PROT_WRITE | PROT_READ,
566
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
567
+ #endif // ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
568
+ if (new_pages == MAP_FAILED) {
569
+ ABSL_RAW_LOG(FATAL, "mmap error: %d", errno);
570
+ }
571
+
572
+ #ifdef __linux__
573
+ #if defined(PR_SET_VMA) && defined(PR_SET_VMA_ANON_NAME)
574
+ // Attempt to name the allocated address range in /proc/$PID/smaps on
575
+ // Linux.
576
+ //
577
+ // This invocation of prctl() may fail if the Linux kernel was not
578
+ // configured with the CONFIG_ANON_VMA_NAME option. This is OK since
579
+ // the naming of arenas is primarily a debugging aid.
580
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, new_pages, new_pages_size,
581
+ "absl");
582
+ #endif
583
+ #endif // __linux__
584
+ #endif // _WIN32
585
+ arena->mu.Lock();
586
+ s = reinterpret_cast<AllocList *>(new_pages);
587
+ s->header.size = new_pages_size;
588
+ // Pretend the block is allocated; call AddToFreelist() to free it.
589
+ s->header.magic = Magic(kMagicAllocated, &s->header);
590
+ s->header.arena = arena;
591
+ AddToFreelist(&s->levels, arena); // insert new region into free list
592
+ }
593
+ AllocList *prev[kMaxLevel];
594
+ LLA_SkiplistDelete(&arena->freelist, s, prev); // remove from free list
595
+ // s points to the first free region that's big enough
596
+ if (CheckedAdd(req_rnd, arena->min_size) <= s->header.size) {
597
+ // big enough to split
598
+ AllocList *n =
599
+ reinterpret_cast<AllocList *>(req_rnd + reinterpret_cast<char *>(s));
600
+ n->header.size = s->header.size - req_rnd;
601
+ n->header.magic = Magic(kMagicAllocated, &n->header);
602
+ n->header.arena = arena;
603
+ s->header.size = req_rnd;
604
+ AddToFreelist(&n->levels, arena);
605
+ }
606
+ s->header.magic = Magic(kMagicAllocated, &s->header);
607
+ ABSL_RAW_CHECK(s->header.arena == arena, "");
608
+ arena->allocation_count++;
609
+ section.Leave();
610
+ result = &s->levels;
611
+ }
612
+ ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(result, request);
613
+ return result;
614
+ }
615
+
616
+ void *LowLevelAlloc::Alloc(size_t request) {
617
+ void *result = DoAllocWithArena(request, DefaultArena());
618
+ return result;
619
+ }
620
+
621
+ void *LowLevelAlloc::AllocWithArena(size_t request, Arena *arena) {
622
+ ABSL_RAW_CHECK(arena != nullptr, "must pass a valid arena");
623
+ void *result = DoAllocWithArena(request, arena);
624
+ return result;
625
+ }
626
+
627
+ } // namespace base_internal
628
+ ABSL_NAMESPACE_END
629
+ } // namespace absl
630
+
631
+ #endif // ABSL_LOW_LEVEL_ALLOC_MISSING
weight/_dep/abseil-cpp/absl/base/internal/low_level_alloc.h ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+
16
+ #ifndef ABSL_BASE_INTERNAL_LOW_LEVEL_ALLOC_H_
17
+ #define ABSL_BASE_INTERNAL_LOW_LEVEL_ALLOC_H_
18
+
19
+ // A simple thread-safe memory allocator that does not depend on
20
+ // mutexes or thread-specific data. It is intended to be used
21
+ // sparingly, and only when malloc() would introduce an unwanted
22
+ // dependency, such as inside the heap-checker, or the Mutex
23
+ // implementation.
24
+
25
+ // IWYU pragma: private, include "base/low_level_alloc.h"
26
+
27
+ #include <sys/types.h>
28
+
29
+ #include <cstdint>
30
+
31
+ #include "absl/base/attributes.h"
32
+ #include "absl/base/config.h"
33
+
34
+ // LowLevelAlloc requires that the platform support low-level
35
+ // allocation of virtual memory. Platforms lacking this cannot use
36
+ // LowLevelAlloc.
37
+ #ifdef ABSL_LOW_LEVEL_ALLOC_MISSING
38
+ #error ABSL_LOW_LEVEL_ALLOC_MISSING cannot be directly set
39
+ #elif !defined(ABSL_HAVE_MMAP) && !defined(_WIN32)
40
+ #define ABSL_LOW_LEVEL_ALLOC_MISSING 1
41
+ #endif
42
+
43
+ // Using LowLevelAlloc with kAsyncSignalSafe isn't supported on Windows or
44
+ // asm.js / WebAssembly.
45
+ // See https://kripken.github.io/emscripten-site/docs/porting/pthreads.html
46
+ // for more information.
47
+ #ifdef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
48
+ #error ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING cannot be directly set
49
+ #elif defined(_WIN32) || defined(__asmjs__) || defined(__wasm__) || \
50
+ defined(__hexagon__)
51
+ #define ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING 1
52
+ #endif
53
+
54
+ #include <cstddef>
55
+
56
+ #include "absl/base/port.h"
57
+
58
+ namespace absl {
59
+ ABSL_NAMESPACE_BEGIN
60
+ namespace base_internal {
61
+
62
+ class LowLevelAlloc {
63
+ public:
64
+ struct Arena; // an arena from which memory may be allocated
65
+
66
+ // Returns a pointer to a block of at least "request" bytes
67
+ // that have been newly allocated from the specific arena.
68
+ // for Alloc() call the DefaultArena() is used.
69
+ // Returns 0 if passed request==0.
70
+ // Does not return 0 under other circumstances; it crashes if memory
71
+ // is not available.
72
+ static void *Alloc(size_t request) ABSL_ATTRIBUTE_SECTION(malloc_hook);
73
+ static void *AllocWithArena(size_t request, Arena *arena)
74
+ ABSL_ATTRIBUTE_SECTION(malloc_hook);
75
+
76
+ // Deallocates a region of memory that was previously allocated with
77
+ // Alloc(). Does nothing if passed 0. "s" must be either 0,
78
+ // or must have been returned from a call to Alloc() and not yet passed to
79
+ // Free() since that call to Alloc(). The space is returned to the arena
80
+ // from which it was allocated.
81
+ static void Free(void *s) ABSL_ATTRIBUTE_SECTION(malloc_hook);
82
+
83
+ // ABSL_ATTRIBUTE_SECTION(malloc_hook) for Alloc* and Free
84
+ // are to put all callers of MallocHook::Invoke* in this module
85
+ // into special section,
86
+ // so that MallocHook::GetCallerStackTrace can function accurately.
87
+
88
+ // Create a new arena.
89
+ // The root metadata for the new arena is allocated in the
90
+ // meta_data_arena; the DefaultArena() can be passed for meta_data_arena.
91
+ // These values may be ored into flags:
92
+ enum {
93
+ // Report calls to Alloc() and Free() via the MallocHook interface.
94
+ // Set in the DefaultArena.
95
+ kCallMallocHook = 0x0001,
96
+
97
+ #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
98
+ // Make calls to Alloc(), Free() be async-signal-safe. Not set in
99
+ // DefaultArena(). Not supported on all platforms.
100
+ kAsyncSignalSafe = 0x0002,
101
+ #endif
102
+ };
103
+ // Construct a new arena. The allocation of the underlying metadata honors
104
+ // the provided flags. For example, the call NewArena(kAsyncSignalSafe)
105
+ // is itself async-signal-safe, as well as generatating an arena that provides
106
+ // async-signal-safe Alloc/Free.
107
+ static Arena *NewArena(uint32_t flags);
108
+
109
+ // Destroys an arena allocated by NewArena and returns true,
110
+ // provided no allocated blocks remain in the arena.
111
+ // If allocated blocks remain in the arena, does nothing and
112
+ // returns false.
113
+ // It is illegal to attempt to destroy the DefaultArena().
114
+ static bool DeleteArena(Arena *arena);
115
+
116
+ // The default arena that always exists.
117
+ static Arena *DefaultArena();
118
+
119
+ private:
120
+ LowLevelAlloc(); // no instances
121
+ };
122
+
123
+ } // namespace base_internal
124
+ ABSL_NAMESPACE_END
125
+ } // namespace absl
126
+
127
+ #endif // ABSL_BASE_INTERNAL_LOW_LEVEL_ALLOC_H_
weight/_dep/abseil-cpp/absl/base/internal/low_level_scheduling.h ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+ // Core interfaces and definitions used by by low-level interfaces such as
16
+ // SpinLock.
17
+
18
+ #ifndef ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_
19
+ #define ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_
20
+
21
+ #include "absl/base/internal/raw_logging.h"
22
+ #include "absl/base/internal/scheduling_mode.h"
23
+ #include "absl/base/macros.h"
24
+
25
+ // The following two declarations exist so SchedulingGuard may friend them with
26
+ // the appropriate language linkage. These callbacks allow libc internals, such
27
+ // as function level statics, to schedule cooperatively when locking.
28
+ extern "C" bool __google_disable_rescheduling(void);
29
+ extern "C" void __google_enable_rescheduling(bool disable_result);
30
+
31
+ namespace absl {
32
+ ABSL_NAMESPACE_BEGIN
33
+ class CondVar;
34
+ class Mutex;
35
+
36
+ namespace synchronization_internal {
37
+ int MutexDelay(int32_t c, int mode);
38
+ } // namespace synchronization_internal
39
+
40
+ namespace base_internal {
41
+
42
+ class SchedulingHelper; // To allow use of SchedulingGuard.
43
+ class SpinLock; // To allow use of SchedulingGuard.
44
+
45
+ // SchedulingGuard
46
+ // Provides guard semantics that may be used to disable cooperative rescheduling
47
+ // of the calling thread within specific program blocks. This is used to
48
+ // protect resources (e.g. low-level SpinLocks or Domain code) that cooperative
49
+ // scheduling depends on.
50
+ //
51
+ // Domain implementations capable of rescheduling in reaction to involuntary
52
+ // kernel thread actions (e.g blocking due to a pagefault or syscall) must
53
+ // guarantee that an annotated thread is not allowed to (cooperatively)
54
+ // reschedule until the annotated region is complete.
55
+ //
56
+ // It is an error to attempt to use a cooperatively scheduled resource (e.g.
57
+ // Mutex) within a rescheduling-disabled region.
58
+ //
59
+ // All methods are async-signal safe.
60
+ class SchedulingGuard {
61
+ public:
62
+ // Returns true iff the calling thread may be cooperatively rescheduled.
63
+ static bool ReschedulingIsAllowed();
64
+ SchedulingGuard(const SchedulingGuard&) = delete;
65
+ SchedulingGuard& operator=(const SchedulingGuard&) = delete;
66
+
67
+ private:
68
+ // Disable cooperative rescheduling of the calling thread. It may still
69
+ // initiate scheduling operations (e.g. wake-ups), however, it may not itself
70
+ // reschedule. Nestable. The returned result is opaque, clients should not
71
+ // attempt to interpret it.
72
+ // REQUIRES: Result must be passed to a pairing EnableScheduling().
73
+ static bool DisableRescheduling();
74
+
75
+ // Marks the end of a rescheduling disabled region, previously started by
76
+ // DisableRescheduling().
77
+ // REQUIRES: Pairs with innermost call (and result) of DisableRescheduling().
78
+ static void EnableRescheduling(bool disable_result);
79
+
80
+ // A scoped helper for {Disable, Enable}Rescheduling().
81
+ // REQUIRES: destructor must run in same thread as constructor.
82
+ struct ScopedDisable {
83
+ ScopedDisable() { disabled = SchedulingGuard::DisableRescheduling(); }
84
+ ~ScopedDisable() { SchedulingGuard::EnableRescheduling(disabled); }
85
+
86
+ bool disabled;
87
+ };
88
+
89
+ // A scoped helper to enable rescheduling temporarily.
90
+ // REQUIRES: destructor must run in same thread as constructor.
91
+ class ScopedEnable {
92
+ public:
93
+ ScopedEnable();
94
+ ~ScopedEnable();
95
+
96
+ private:
97
+ int scheduling_disabled_depth_;
98
+ };
99
+
100
+ // Access to SchedulingGuard is explicitly permitted.
101
+ friend class absl::CondVar;
102
+ friend class absl::Mutex;
103
+ friend class SchedulingHelper;
104
+ friend class SpinLock;
105
+ friend int absl::synchronization_internal::MutexDelay(int32_t c, int mode);
106
+ };
107
+
108
+ //------------------------------------------------------------------------------
109
+ // End of public interfaces.
110
+ //------------------------------------------------------------------------------
111
+
112
+ inline bool SchedulingGuard::ReschedulingIsAllowed() {
113
+ return false;
114
+ }
115
+
116
+ inline bool SchedulingGuard::DisableRescheduling() {
117
+ return false;
118
+ }
119
+
120
+ inline void SchedulingGuard::EnableRescheduling(bool /* disable_result */) {
121
+ return;
122
+ }
123
+
124
+ inline SchedulingGuard::ScopedEnable::ScopedEnable()
125
+ : scheduling_disabled_depth_(0) {}
126
+ inline SchedulingGuard::ScopedEnable::~ScopedEnable() {
127
+ ABSL_RAW_CHECK(scheduling_disabled_depth_ == 0, "disable unused warning");
128
+ }
129
+
130
+ } // namespace base_internal
131
+ ABSL_NAMESPACE_END
132
+ } // namespace absl
133
+
134
+ #endif // ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_
weight/_dep/abseil-cpp/absl/base/internal/nullability_impl.h ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2023 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #ifndef ABSL_BASE_INTERNAL_NULLABILITY_IMPL_H_
16
+ #define ABSL_BASE_INTERNAL_NULLABILITY_IMPL_H_
17
+
18
+ #include <memory>
19
+ #include <type_traits>
20
+
21
+ #include "absl/base/attributes.h"
22
+ #include "absl/meta/type_traits.h"
23
+
24
+ namespace absl {
25
+
26
+ namespace nullability_internal {
27
+
28
+ // `IsNullabilityCompatible` checks whether its first argument is a class
29
+ // explicitly tagged as supporting nullability annotations. The tag is the type
30
+ // declaration `absl_nullability_compatible`.
31
+ template <typename, typename = void>
32
+ struct IsNullabilityCompatible : std::false_type {};
33
+
34
+ template <typename T>
35
+ struct IsNullabilityCompatible<
36
+ T, absl::void_t<typename T::absl_nullability_compatible>> : std::true_type {
37
+ };
38
+
39
+ template <typename T>
40
+ constexpr bool IsSupportedType = IsNullabilityCompatible<T>::value;
41
+
42
+ template <typename T>
43
+ constexpr bool IsSupportedType<T*> = true;
44
+
45
+ template <typename T, typename U>
46
+ constexpr bool IsSupportedType<T U::*> = true;
47
+
48
+ template <typename T, typename... Deleter>
49
+ constexpr bool IsSupportedType<std::unique_ptr<T, Deleter...>> = true;
50
+
51
+ template <typename T>
52
+ constexpr bool IsSupportedType<std::shared_ptr<T>> = true;
53
+
54
+ template <typename T>
55
+ struct EnableNullable {
56
+ static_assert(nullability_internal::IsSupportedType<std::remove_cv_t<T>>,
57
+ "Template argument must be a raw or supported smart pointer "
58
+ "type. See absl/base/nullability.h.");
59
+ using type = T;
60
+ };
61
+
62
+ template <typename T>
63
+ struct EnableNonnull {
64
+ static_assert(nullability_internal::IsSupportedType<std::remove_cv_t<T>>,
65
+ "Template argument must be a raw or supported smart pointer "
66
+ "type. See absl/base/nullability.h.");
67
+ using type = T;
68
+ };
69
+
70
+ template <typename T>
71
+ struct EnableNullabilityUnknown {
72
+ static_assert(nullability_internal::IsSupportedType<std::remove_cv_t<T>>,
73
+ "Template argument must be a raw or supported smart pointer "
74
+ "type. See absl/base/nullability.h.");
75
+ using type = T;
76
+ };
77
+
78
+ // Note: we do not apply Clang nullability attributes (e.g. _Nullable). These
79
+ // only support raw pointers, and conditionally enabling them only for raw
80
+ // pointers inhibits template arg deduction. Ideally, they would support all
81
+ // pointer-like types.
82
+ template <typename T, typename = typename EnableNullable<T>::type>
83
+ using NullableImpl
84
+ #if ABSL_HAVE_CPP_ATTRIBUTE(clang::annotate)
85
+ [[clang::annotate("Nullable")]]
86
+ #endif
87
+ = T;
88
+
89
+ template <typename T, typename = typename EnableNonnull<T>::type>
90
+ using NonnullImpl
91
+ #if ABSL_HAVE_CPP_ATTRIBUTE(clang::annotate)
92
+ [[clang::annotate("Nonnull")]]
93
+ #endif
94
+ = T;
95
+
96
+ template <typename T, typename = typename EnableNullabilityUnknown<T>::type>
97
+ using NullabilityUnknownImpl
98
+ #if ABSL_HAVE_CPP_ATTRIBUTE(clang::annotate)
99
+ [[clang::annotate("Nullability_Unspecified")]]
100
+ #endif
101
+ = T;
102
+
103
+ } // namespace nullability_internal
104
+ } // namespace absl
105
+
106
+ #endif // ABSL_BASE_INTERNAL_NULLABILITY_IMPL_H_
weight/_dep/abseil-cpp/absl/base/internal/pretty_function.h ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #ifndef ABSL_BASE_INTERNAL_PRETTY_FUNCTION_H_
16
+ #define ABSL_BASE_INTERNAL_PRETTY_FUNCTION_H_
17
+
18
+ // ABSL_PRETTY_FUNCTION
19
+ //
20
+ // In C++11, __func__ gives the undecorated name of the current function. That
21
+ // is, "main", not "int main()". Various compilers give extra macros to get the
22
+ // decorated function name, including return type and arguments, to
23
+ // differentiate between overload sets. ABSL_PRETTY_FUNCTION is a portable
24
+ // version of these macros which forwards to the correct macro on each compiler.
25
+ #if defined(_MSC_VER)
26
+ #define ABSL_PRETTY_FUNCTION __FUNCSIG__
27
+ #elif defined(__GNUC__)
28
+ #define ABSL_PRETTY_FUNCTION __PRETTY_FUNCTION__
29
+ #else
30
+ #error "Unsupported compiler"
31
+ #endif
32
+
33
+ #endif // ABSL_BASE_INTERNAL_PRETTY_FUNCTION_H_
weight/_dep/abseil-cpp/absl/base/internal/raw_logging.cc ADDED
@@ -0,0 +1,280 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include "absl/base/internal/raw_logging.h"
16
+
17
+ #include <cstdarg>
18
+ #include <cstddef>
19
+ #include <cstdio>
20
+ #include <cstdlib>
21
+ #include <cstring>
22
+ #include <string>
23
+
24
+ #ifdef __EMSCRIPTEN__
25
+ #include <emscripten/console.h>
26
+ #endif
27
+
28
+ #include "absl/base/attributes.h"
29
+ #include "absl/base/config.h"
30
+ #include "absl/base/internal/atomic_hook.h"
31
+ #include "absl/base/internal/errno_saver.h"
32
+ #include "absl/base/log_severity.h"
33
+
34
+ // We know how to perform low-level writes to stderr in POSIX and Windows. For
35
+ // these platforms, we define the token ABSL_LOW_LEVEL_WRITE_SUPPORTED.
36
+ // Much of raw_logging.cc becomes a no-op when we can't output messages,
37
+ // although a FATAL ABSL_RAW_LOG message will still abort the process.
38
+
39
+ // ABSL_HAVE_POSIX_WRITE is defined when the platform provides posix write()
40
+ // (as from unistd.h)
41
+ //
42
+ // This preprocessor token is also defined in raw_io.cc. If you need to copy
43
+ // this, consider moving both to config.h instead.
44
+ #if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \
45
+ defined(__hexagon__) || defined(__Fuchsia__) || \
46
+ defined(__native_client__) || defined(__OpenBSD__) || \
47
+ defined(__EMSCRIPTEN__) || defined(__ASYLO__)
48
+
49
+ #include <unistd.h>
50
+
51
+ #define ABSL_HAVE_POSIX_WRITE 1
52
+ #define ABSL_LOW_LEVEL_WRITE_SUPPORTED 1
53
+ #else
54
+ #undef ABSL_HAVE_POSIX_WRITE
55
+ #endif
56
+
57
+ // ABSL_HAVE_SYSCALL_WRITE is defined when the platform provides the syscall
58
+ // syscall(SYS_write, /*int*/ fd, /*char* */ buf, /*size_t*/ len);
59
+ // for low level operations that want to avoid libc.
60
+ #if (defined(__linux__) || defined(__FreeBSD__)) && !defined(__ANDROID__)
61
+ #include <sys/syscall.h>
62
+ #define ABSL_HAVE_SYSCALL_WRITE 1
63
+ #define ABSL_LOW_LEVEL_WRITE_SUPPORTED 1
64
+ #else
65
+ #undef ABSL_HAVE_SYSCALL_WRITE
66
+ #endif
67
+
68
+ #ifdef _WIN32
69
+ #include <io.h>
70
+
71
+ #define ABSL_HAVE_RAW_IO 1
72
+ #define ABSL_LOW_LEVEL_WRITE_SUPPORTED 1
73
+ #else
74
+ #undef ABSL_HAVE_RAW_IO
75
+ #endif
76
+
77
+ namespace absl {
78
+ ABSL_NAMESPACE_BEGIN
79
+ namespace raw_log_internal {
80
+ namespace {
81
+
82
+ // TODO(gfalcon): We want raw-logging to work on as many platforms as possible.
83
+ // Explicitly `#error` out when not `ABSL_LOW_LEVEL_WRITE_SUPPORTED`, except for
84
+ // a selected set of platforms for which we expect not to be able to raw log.
85
+
86
+ #ifdef ABSL_LOW_LEVEL_WRITE_SUPPORTED
87
+ constexpr char kTruncated[] = " ... (message truncated)\n";
88
+
89
+ // sprintf the format to the buffer, adjusting *buf and *size to reflect the
90
+ // consumed bytes, and return whether the message fit without truncation. If
91
+ // truncation occurred, if possible leave room in the buffer for the message
92
+ // kTruncated[].
93
+ bool VADoRawLog(char** buf, int* size, const char* format, va_list ap)
94
+ ABSL_PRINTF_ATTRIBUTE(3, 0);
95
+ bool VADoRawLog(char** buf, int* size, const char* format, va_list ap) {
96
+ if (*size < 0) return false;
97
+ int n = vsnprintf(*buf, static_cast<size_t>(*size), format, ap);
98
+ bool result = true;
99
+ if (n < 0 || n > *size) {
100
+ result = false;
101
+ if (static_cast<size_t>(*size) > sizeof(kTruncated)) {
102
+ n = *size - static_cast<int>(sizeof(kTruncated));
103
+ } else {
104
+ n = 0; // no room for truncation message
105
+ }
106
+ }
107
+ *size -= n;
108
+ *buf += n;
109
+ return result;
110
+ }
111
+ #endif // ABSL_LOW_LEVEL_WRITE_SUPPORTED
112
+
113
+ constexpr int kLogBufSize = 3000;
114
+
115
+ // CAVEAT: vsnprintf called from *DoRawLog below has some (exotic) code paths
116
+ // that invoke malloc() and getenv() that might acquire some locks.
117
+
118
+ // Helper for RawLog below.
119
+ // *DoRawLog writes to *buf of *size and move them past the written portion.
120
+ // It returns true iff there was no overflow or error.
121
+ bool DoRawLog(char** buf, int* size, const char* format, ...)
122
+ ABSL_PRINTF_ATTRIBUTE(3, 4);
123
+ bool DoRawLog(char** buf, int* size, const char* format, ...) {
124
+ if (*size < 0) return false;
125
+ va_list ap;
126
+ va_start(ap, format);
127
+ int n = vsnprintf(*buf, static_cast<size_t>(*size), format, ap);
128
+ va_end(ap);
129
+ if (n < 0 || n > *size) return false;
130
+ *size -= n;
131
+ *buf += n;
132
+ return true;
133
+ }
134
+
135
+ bool DefaultLogFilterAndPrefix(absl::LogSeverity, const char* file, int line,
136
+ char** buf, int* buf_size) {
137
+ DoRawLog(buf, buf_size, "[%s : %d] RAW: ", file, line);
138
+ return true;
139
+ }
140
+
141
+ ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES
142
+ absl::base_internal::AtomicHook<LogFilterAndPrefixHook>
143
+ log_filter_and_prefix_hook(DefaultLogFilterAndPrefix);
144
+ ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES
145
+ absl::base_internal::AtomicHook<AbortHook> abort_hook;
146
+
147
+ void RawLogVA(absl::LogSeverity severity, const char* file, int line,
148
+ const char* format, va_list ap) ABSL_PRINTF_ATTRIBUTE(4, 0);
149
+ void RawLogVA(absl::LogSeverity severity, const char* file, int line,
150
+ const char* format, va_list ap) {
151
+ char buffer[kLogBufSize];
152
+ char* buf = buffer;
153
+ int size = sizeof(buffer);
154
+ #ifdef ABSL_LOW_LEVEL_WRITE_SUPPORTED
155
+ bool enabled = true;
156
+ #else
157
+ bool enabled = false;
158
+ #endif
159
+
160
+ #ifdef ABSL_MIN_LOG_LEVEL
161
+ if (severity < static_cast<absl::LogSeverity>(ABSL_MIN_LOG_LEVEL) &&
162
+ severity < absl::LogSeverity::kFatal) {
163
+ enabled = false;
164
+ }
165
+ #endif
166
+
167
+ enabled = log_filter_and_prefix_hook(severity, file, line, &buf, &size);
168
+ const char* const prefix_end = buf;
169
+
170
+ #ifdef ABSL_LOW_LEVEL_WRITE_SUPPORTED
171
+ if (enabled) {
172
+ bool no_chop = VADoRawLog(&buf, &size, format, ap);
173
+ if (no_chop) {
174
+ DoRawLog(&buf, &size, "\n");
175
+ } else {
176
+ DoRawLog(&buf, &size, "%s", kTruncated);
177
+ }
178
+ AsyncSignalSafeWriteError(buffer, strlen(buffer));
179
+ }
180
+ #else
181
+ static_cast<void>(format);
182
+ static_cast<void>(ap);
183
+ static_cast<void>(enabled);
184
+ #endif
185
+
186
+ // Abort the process after logging a FATAL message, even if the output itself
187
+ // was suppressed.
188
+ if (severity == absl::LogSeverity::kFatal) {
189
+ abort_hook(file, line, buffer, prefix_end, buffer + kLogBufSize);
190
+ abort();
191
+ }
192
+ }
193
+
194
+ // Non-formatting version of RawLog().
195
+ //
196
+ // TODO(gfalcon): When string_view no longer depends on base, change this
197
+ // interface to take its message as a string_view instead.
198
+ void DefaultInternalLog(absl::LogSeverity severity, const char* file, int line,
199
+ const std::string& message) {
200
+ RawLog(severity, file, line, "%.*s", static_cast<int>(message.size()),
201
+ message.data());
202
+ }
203
+
204
+ } // namespace
205
+
206
+ void AsyncSignalSafeWriteError(const char* s, size_t len) {
207
+ if (!len) return;
208
+ absl::base_internal::ErrnoSaver errno_saver;
209
+ #if defined(__EMSCRIPTEN__)
210
+ // In WebAssembly, bypass filesystem emulation via fwrite.
211
+ if (s[len - 1] == '\n') {
212
+ // Skip a trailing newline character as emscripten_errn adds one itself.
213
+ len--;
214
+ }
215
+ // emscripten_errn was introduced in 3.1.41 but broken in standalone mode
216
+ // until 3.1.43.
217
+ #if ABSL_INTERNAL_EMSCRIPTEN_VERSION >= 3001043
218
+ emscripten_errn(s, len);
219
+ #else
220
+ char buf[kLogBufSize];
221
+ if (len >= kLogBufSize) {
222
+ len = kLogBufSize - 1;
223
+ constexpr size_t trunc_len = sizeof(kTruncated) - 2;
224
+ memcpy(buf + len - trunc_len, kTruncated, trunc_len);
225
+ buf[len] = '\0';
226
+ len -= trunc_len;
227
+ } else {
228
+ buf[len] = '\0';
229
+ }
230
+ memcpy(buf, s, len);
231
+ _emscripten_err(buf);
232
+ #endif
233
+ #elif defined(ABSL_HAVE_SYSCALL_WRITE)
234
+ // We prefer calling write via `syscall` to minimize the risk of libc doing
235
+ // something "helpful".
236
+ syscall(SYS_write, STDERR_FILENO, s, len);
237
+ #elif defined(ABSL_HAVE_POSIX_WRITE)
238
+ write(STDERR_FILENO, s, len);
239
+ #elif defined(ABSL_HAVE_RAW_IO)
240
+ _write(/* stderr */ 2, s, static_cast<unsigned>(len));
241
+ #else
242
+ // stderr logging unsupported on this platform
243
+ (void)s;
244
+ (void)len;
245
+ #endif
246
+ }
247
+
248
+ void RawLog(absl::LogSeverity severity, const char* file, int line,
249
+ const char* format, ...) {
250
+ va_list ap;
251
+ va_start(ap, format);
252
+ RawLogVA(severity, file, line, format, ap);
253
+ va_end(ap);
254
+ }
255
+
256
+ bool RawLoggingFullySupported() {
257
+ #ifdef ABSL_LOW_LEVEL_WRITE_SUPPORTED
258
+ return true;
259
+ #else // !ABSL_LOW_LEVEL_WRITE_SUPPORTED
260
+ return false;
261
+ #endif // !ABSL_LOW_LEVEL_WRITE_SUPPORTED
262
+ }
263
+
264
+ ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES ABSL_DLL
265
+ absl::base_internal::AtomicHook<InternalLogFunction>
266
+ internal_log_function(DefaultInternalLog);
267
+
268
+ void RegisterLogFilterAndPrefixHook(LogFilterAndPrefixHook func) {
269
+ log_filter_and_prefix_hook.Store(func);
270
+ }
271
+
272
+ void RegisterAbortHook(AbortHook func) { abort_hook.Store(func); }
273
+
274
+ void RegisterInternalLogFunction(InternalLogFunction func) {
275
+ internal_log_function.Store(func);
276
+ }
277
+
278
+ } // namespace raw_log_internal
279
+ ABSL_NAMESPACE_END
280
+ } // namespace absl
weight/_dep/abseil-cpp/absl/base/internal/scheduling_mode.h ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+ // Core interfaces and definitions used by by low-level interfaces such as
16
+ // SpinLock.
17
+
18
+ #ifndef ABSL_BASE_INTERNAL_SCHEDULING_MODE_H_
19
+ #define ABSL_BASE_INTERNAL_SCHEDULING_MODE_H_
20
+
21
+ #include "absl/base/config.h"
22
+
23
+ namespace absl {
24
+ ABSL_NAMESPACE_BEGIN
25
+ namespace base_internal {
26
+
27
+ // Used to describe how a thread may be scheduled. Typically associated with
28
+ // the declaration of a resource supporting synchronized access.
29
+ //
30
+ // SCHEDULE_COOPERATIVE_AND_KERNEL:
31
+ // Specifies that when waiting, a cooperative thread (e.g. a Fiber) may
32
+ // reschedule (using base::scheduling semantics); allowing other cooperative
33
+ // threads to proceed.
34
+ //
35
+ // SCHEDULE_KERNEL_ONLY: (Also described as "non-cooperative")
36
+ // Specifies that no cooperative scheduling semantics may be used, even if the
37
+ // current thread is itself cooperatively scheduled. This means that
38
+ // cooperative threads will NOT allow other cooperative threads to execute in
39
+ // their place while waiting for a resource of this type. Host operating system
40
+ // semantics (e.g. a futex) may still be used.
41
+ //
42
+ // When optional, clients should strongly prefer SCHEDULE_COOPERATIVE_AND_KERNEL
43
+ // by default. SCHEDULE_KERNEL_ONLY should only be used for resources on which
44
+ // base::scheduling (e.g. the implementation of a Scheduler) may depend.
45
+ //
46
+ // NOTE: Cooperative resources may not be nested below non-cooperative ones.
47
+ // This means that it is invalid to to acquire a SCHEDULE_COOPERATIVE_AND_KERNEL
48
+ // resource if a SCHEDULE_KERNEL_ONLY resource is already held.
49
+ enum SchedulingMode {
50
+ SCHEDULE_KERNEL_ONLY = 0, // Allow scheduling only the host OS.
51
+ SCHEDULE_COOPERATIVE_AND_KERNEL, // Also allow cooperative scheduling.
52
+ };
53
+
54
+ } // namespace base_internal
55
+ ABSL_NAMESPACE_END
56
+ } // namespace absl
57
+
58
+ #endif // ABSL_BASE_INTERNAL_SCHEDULING_MODE_H_
weight/_dep/abseil-cpp/absl/base/internal/scoped_set_env.cc ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2019 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include "absl/base/internal/scoped_set_env.h"
16
+
17
+ #ifdef _WIN32
18
+ #include <windows.h>
19
+ #endif
20
+
21
+ #include <cstdlib>
22
+
23
+ #include "absl/base/internal/raw_logging.h"
24
+
25
+ namespace absl {
26
+ ABSL_NAMESPACE_BEGIN
27
+ namespace base_internal {
28
+
29
+ namespace {
30
+
31
+ #ifdef _WIN32
32
+ const int kMaxEnvVarValueSize = 1024;
33
+ #endif
34
+
35
+ void SetEnvVar(const char* name, const char* value) {
36
+ #ifdef _WIN32
37
+ SetEnvironmentVariableA(name, value);
38
+ #else
39
+ if (value == nullptr) {
40
+ ::unsetenv(name);
41
+ } else {
42
+ ::setenv(name, value, 1);
43
+ }
44
+ #endif
45
+ }
46
+
47
+ } // namespace
48
+
49
+ ScopedSetEnv::ScopedSetEnv(const char* var_name, const char* new_value)
50
+ : var_name_(var_name), was_unset_(false) {
51
+ #ifdef _WIN32
52
+ char buf[kMaxEnvVarValueSize];
53
+ auto get_res = GetEnvironmentVariableA(var_name_.c_str(), buf, sizeof(buf));
54
+ ABSL_INTERNAL_CHECK(get_res < sizeof(buf), "value exceeds buffer size");
55
+
56
+ if (get_res == 0) {
57
+ was_unset_ = (GetLastError() == ERROR_ENVVAR_NOT_FOUND);
58
+ } else {
59
+ old_value_.assign(buf, get_res);
60
+ }
61
+
62
+ SetEnvironmentVariableA(var_name_.c_str(), new_value);
63
+ #else
64
+ const char* val = ::getenv(var_name_.c_str());
65
+ if (val == nullptr) {
66
+ was_unset_ = true;
67
+ } else {
68
+ old_value_ = val;
69
+ }
70
+ #endif
71
+
72
+ SetEnvVar(var_name_.c_str(), new_value);
73
+ }
74
+
75
+ ScopedSetEnv::~ScopedSetEnv() {
76
+ SetEnvVar(var_name_.c_str(), was_unset_ ? nullptr : old_value_.c_str());
77
+ }
78
+
79
+ } // namespace base_internal
80
+ ABSL_NAMESPACE_END
81
+ } // namespace absl
weight/_dep/abseil-cpp/absl/base/internal/scoped_set_env.h ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //
2
+ // Copyright 2019 The Abseil Authors.
3
+ //
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // you may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ //
8
+ // https://www.apache.org/licenses/LICENSE-2.0
9
+ //
10
+ // Unless required by applicable law or agreed to in writing, software
11
+ // distributed under the License is distributed on an "AS IS" BASIS,
12
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ // See the License for the specific language governing permissions and
14
+ // limitations under the License.
15
+ //
16
+
17
+ #ifndef ABSL_BASE_INTERNAL_SCOPED_SET_ENV_H_
18
+ #define ABSL_BASE_INTERNAL_SCOPED_SET_ENV_H_
19
+
20
+ #include <string>
21
+
22
+ #include "absl/base/config.h"
23
+
24
+ namespace absl {
25
+ ABSL_NAMESPACE_BEGIN
26
+ namespace base_internal {
27
+
28
+ class ScopedSetEnv {
29
+ public:
30
+ ScopedSetEnv(const char* var_name, const char* new_value);
31
+ ~ScopedSetEnv();
32
+
33
+ private:
34
+ std::string var_name_;
35
+ std::string old_value_;
36
+
37
+ // True if the environment variable was initially not set.
38
+ bool was_unset_;
39
+ };
40
+
41
+ } // namespace base_internal
42
+ ABSL_NAMESPACE_END
43
+ } // namespace absl
44
+
45
+ #endif // ABSL_BASE_INTERNAL_SCOPED_SET_ENV_H_
weight/_dep/abseil-cpp/absl/base/internal/scoped_set_env_test.cc ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2019 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #ifdef _WIN32
16
+ #include <windows.h>
17
+ #endif
18
+
19
+ #include "gtest/gtest.h"
20
+ #include "absl/base/internal/scoped_set_env.h"
21
+
22
+ namespace {
23
+
24
+ using absl::base_internal::ScopedSetEnv;
25
+
26
+ std::string GetEnvVar(const char* name) {
27
+ #ifdef _WIN32
28
+ char buf[1024];
29
+ auto get_res = GetEnvironmentVariableA(name, buf, sizeof(buf));
30
+ if (get_res >= sizeof(buf)) {
31
+ return "TOO_BIG";
32
+ }
33
+
34
+ if (get_res == 0) {
35
+ return "UNSET";
36
+ }
37
+
38
+ return std::string(buf, get_res);
39
+ #else
40
+ const char* val = ::getenv(name);
41
+ if (val == nullptr) {
42
+ return "UNSET";
43
+ }
44
+
45
+ return val;
46
+ #endif
47
+ }
48
+
49
+ TEST(ScopedSetEnvTest, SetNonExistingVarToString) {
50
+ EXPECT_EQ(GetEnvVar("SCOPED_SET_ENV_TEST_VAR"), "UNSET");
51
+
52
+ {
53
+ ScopedSetEnv scoped_set("SCOPED_SET_ENV_TEST_VAR", "value");
54
+
55
+ EXPECT_EQ(GetEnvVar("SCOPED_SET_ENV_TEST_VAR"), "value");
56
+ }
57
+
58
+ EXPECT_EQ(GetEnvVar("SCOPED_SET_ENV_TEST_VAR"), "UNSET");
59
+ }
60
+
61
+ TEST(ScopedSetEnvTest, SetNonExistingVarToNull) {
62
+ EXPECT_EQ(GetEnvVar("SCOPED_SET_ENV_TEST_VAR"), "UNSET");
63
+
64
+ {
65
+ ScopedSetEnv scoped_set("SCOPED_SET_ENV_TEST_VAR", nullptr);
66
+
67
+ EXPECT_EQ(GetEnvVar("SCOPED_SET_ENV_TEST_VAR"), "UNSET");
68
+ }
69
+
70
+ EXPECT_EQ(GetEnvVar("SCOPED_SET_ENV_TEST_VAR"), "UNSET");
71
+ }
72
+
73
+ TEST(ScopedSetEnvTest, SetExistingVarToString) {
74
+ ScopedSetEnv scoped_set("SCOPED_SET_ENV_TEST_VAR", "value");
75
+ EXPECT_EQ(GetEnvVar("SCOPED_SET_ENV_TEST_VAR"), "value");
76
+
77
+ {
78
+ ScopedSetEnv scoped_set("SCOPED_SET_ENV_TEST_VAR", "new_value");
79
+
80
+ EXPECT_EQ(GetEnvVar("SCOPED_SET_ENV_TEST_VAR"), "new_value");
81
+ }
82
+
83
+ EXPECT_EQ(GetEnvVar("SCOPED_SET_ENV_TEST_VAR"), "value");
84
+ }
85
+
86
+ TEST(ScopedSetEnvTest, SetExistingVarToNull) {
87
+ ScopedSetEnv scoped_set("SCOPED_SET_ENV_TEST_VAR", "value");
88
+ EXPECT_EQ(GetEnvVar("SCOPED_SET_ENV_TEST_VAR"), "value");
89
+
90
+ {
91
+ ScopedSetEnv scoped_set("SCOPED_SET_ENV_TEST_VAR", nullptr);
92
+
93
+ EXPECT_EQ(GetEnvVar("SCOPED_SET_ENV_TEST_VAR"), "UNSET");
94
+ }
95
+
96
+ EXPECT_EQ(GetEnvVar("SCOPED_SET_ENV_TEST_VAR"), "value");
97
+ }
98
+
99
+ } // namespace
weight/_dep/abseil-cpp/absl/base/internal/spinlock.cc ADDED
@@ -0,0 +1,232 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include "absl/base/internal/spinlock.h"
16
+
17
+ #include <algorithm>
18
+ #include <atomic>
19
+ #include <limits>
20
+
21
+ #include "absl/base/attributes.h"
22
+ #include "absl/base/config.h"
23
+ #include "absl/base/internal/atomic_hook.h"
24
+ #include "absl/base/internal/cycleclock.h"
25
+ #include "absl/base/internal/spinlock_wait.h"
26
+ #include "absl/base/internal/sysinfo.h" /* For NumCPUs() */
27
+ #include "absl/base/call_once.h"
28
+
29
+ // Description of lock-word:
30
+ // 31..00: [............................3][2][1][0]
31
+ //
32
+ // [0]: kSpinLockHeld
33
+ // [1]: kSpinLockCooperative
34
+ // [2]: kSpinLockDisabledScheduling
35
+ // [31..3]: ONLY kSpinLockSleeper OR
36
+ // Wait time in cycles >> PROFILE_TIMESTAMP_SHIFT
37
+ //
38
+ // Detailed descriptions:
39
+ //
40
+ // Bit [0]: The lock is considered held iff kSpinLockHeld is set.
41
+ //
42
+ // Bit [1]: Eligible waiters (e.g. Fibers) may co-operatively reschedule when
43
+ // contended iff kSpinLockCooperative is set.
44
+ //
45
+ // Bit [2]: This bit is exclusive from bit [1]. It is used only by a
46
+ // non-cooperative lock. When set, indicates that scheduling was
47
+ // successfully disabled when the lock was acquired. May be unset,
48
+ // even if non-cooperative, if a ThreadIdentity did not yet exist at
49
+ // time of acquisition.
50
+ //
51
+ // Bit [3]: If this is the only upper bit ([31..3]) set then this lock was
52
+ // acquired without contention, however, at least one waiter exists.
53
+ //
54
+ // Otherwise, bits [31..3] represent the time spent by the current lock
55
+ // holder to acquire the lock. There may be outstanding waiter(s).
56
+
57
+ namespace absl {
58
+ ABSL_NAMESPACE_BEGIN
59
+ namespace base_internal {
60
+
61
+ ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES static base_internal::AtomicHook<void (*)(
62
+ const void *lock, int64_t wait_cycles)>
63
+ submit_profile_data;
64
+
65
+ void RegisterSpinLockProfiler(void (*fn)(const void *contendedlock,
66
+ int64_t wait_cycles)) {
67
+ submit_profile_data.Store(fn);
68
+ }
69
+
70
+ #ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
71
+ // Static member variable definitions.
72
+ constexpr uint32_t SpinLock::kSpinLockHeld;
73
+ constexpr uint32_t SpinLock::kSpinLockCooperative;
74
+ constexpr uint32_t SpinLock::kSpinLockDisabledScheduling;
75
+ constexpr uint32_t SpinLock::kSpinLockSleeper;
76
+ constexpr uint32_t SpinLock::kWaitTimeMask;
77
+ #endif
78
+
79
+ // Uncommon constructors.
80
+ SpinLock::SpinLock(base_internal::SchedulingMode mode)
81
+ : lockword_(IsCooperative(mode) ? kSpinLockCooperative : 0) {
82
+ ABSL_TSAN_MUTEX_CREATE(this, __tsan_mutex_not_static);
83
+ }
84
+
85
+ // Monitor the lock to see if its value changes within some time period
86
+ // (adaptive_spin_count loop iterations). The last value read from the lock
87
+ // is returned from the method.
88
+ uint32_t SpinLock::SpinLoop() {
89
+ // We are already in the slow path of SpinLock, initialize the
90
+ // adaptive_spin_count here.
91
+ ABSL_CONST_INIT static absl::once_flag init_adaptive_spin_count;
92
+ ABSL_CONST_INIT static int adaptive_spin_count = 0;
93
+ base_internal::LowLevelCallOnce(&init_adaptive_spin_count, []() {
94
+ adaptive_spin_count = base_internal::NumCPUs() > 1 ? 1000 : 1;
95
+ });
96
+
97
+ int c = adaptive_spin_count;
98
+ uint32_t lock_value;
99
+ do {
100
+ lock_value = lockword_.load(std::memory_order_relaxed);
101
+ } while ((lock_value & kSpinLockHeld) != 0 && --c > 0);
102
+ return lock_value;
103
+ }
104
+
105
+ void SpinLock::SlowLock() {
106
+ uint32_t lock_value = SpinLoop();
107
+ lock_value = TryLockInternal(lock_value, 0);
108
+ if ((lock_value & kSpinLockHeld) == 0) {
109
+ return;
110
+ }
111
+
112
+ base_internal::SchedulingMode scheduling_mode;
113
+ if ((lock_value & kSpinLockCooperative) != 0) {
114
+ scheduling_mode = base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL;
115
+ } else {
116
+ scheduling_mode = base_internal::SCHEDULE_KERNEL_ONLY;
117
+ }
118
+
119
+ // The lock was not obtained initially, so this thread needs to wait for
120
+ // it. Record the current timestamp in the local variable wait_start_time
121
+ // so the total wait time can be stored in the lockword once this thread
122
+ // obtains the lock.
123
+ int64_t wait_start_time = CycleClock::Now();
124
+ uint32_t wait_cycles = 0;
125
+ int lock_wait_call_count = 0;
126
+ while ((lock_value & kSpinLockHeld) != 0) {
127
+ // If the lock is currently held, but not marked as having a sleeper, mark
128
+ // it as having a sleeper.
129
+ if ((lock_value & kWaitTimeMask) == 0) {
130
+ // Here, just "mark" that the thread is going to sleep. Don't store the
131
+ // lock wait time in the lock -- the lock word stores the amount of time
132
+ // that the current holder waited before acquiring the lock, not the wait
133
+ // time of any thread currently waiting to acquire it.
134
+ if (lockword_.compare_exchange_strong(
135
+ lock_value, lock_value | kSpinLockSleeper,
136
+ std::memory_order_relaxed, std::memory_order_relaxed)) {
137
+ // Successfully transitioned to kSpinLockSleeper. Pass
138
+ // kSpinLockSleeper to the SpinLockWait routine to properly indicate
139
+ // the last lock_value observed.
140
+ lock_value |= kSpinLockSleeper;
141
+ } else if ((lock_value & kSpinLockHeld) == 0) {
142
+ // Lock is free again, so try and acquire it before sleeping. The
143
+ // new lock state will be the number of cycles this thread waited if
144
+ // this thread obtains the lock.
145
+ lock_value = TryLockInternal(lock_value, wait_cycles);
146
+ continue; // Skip the delay at the end of the loop.
147
+ } else if ((lock_value & kWaitTimeMask) == 0) {
148
+ // The lock is still held, without a waiter being marked, but something
149
+ // else about the lock word changed, causing our CAS to fail. For
150
+ // example, a new lock holder may have acquired the lock with
151
+ // kSpinLockDisabledScheduling set, whereas the previous holder had not
152
+ // set that flag. In this case, attempt again to mark ourselves as a
153
+ // waiter.
154
+ continue;
155
+ }
156
+ }
157
+
158
+ // SpinLockDelay() calls into fiber scheduler, we need to see
159
+ // synchronization there to avoid false positives.
160
+ ABSL_TSAN_MUTEX_PRE_DIVERT(this, 0);
161
+ // Wait for an OS specific delay.
162
+ base_internal::SpinLockDelay(&lockword_, lock_value, ++lock_wait_call_count,
163
+ scheduling_mode);
164
+ ABSL_TSAN_MUTEX_POST_DIVERT(this, 0);
165
+ // Spin again after returning from the wait routine to give this thread
166
+ // some chance of obtaining the lock.
167
+ lock_value = SpinLoop();
168
+ wait_cycles = EncodeWaitCycles(wait_start_time, CycleClock::Now());
169
+ lock_value = TryLockInternal(lock_value, wait_cycles);
170
+ }
171
+ }
172
+
173
+ void SpinLock::SlowUnlock(uint32_t lock_value) {
174
+ base_internal::SpinLockWake(&lockword_,
175
+ false); // wake waiter if necessary
176
+
177
+ // If our acquisition was contended, collect contentionz profile info. We
178
+ // reserve a unitary wait time to represent that a waiter exists without our
179
+ // own acquisition having been contended.
180
+ if ((lock_value & kWaitTimeMask) != kSpinLockSleeper) {
181
+ const int64_t wait_cycles = DecodeWaitCycles(lock_value);
182
+ ABSL_TSAN_MUTEX_PRE_DIVERT(this, 0);
183
+ submit_profile_data(this, wait_cycles);
184
+ ABSL_TSAN_MUTEX_POST_DIVERT(this, 0);
185
+ }
186
+ }
187
+
188
+ // We use the upper 29 bits of the lock word to store the time spent waiting to
189
+ // acquire this lock. This is reported by contentionz profiling. Since the
190
+ // lower bits of the cycle counter wrap very quickly on high-frequency
191
+ // processors we divide to reduce the granularity to 2^kProfileTimestampShift
192
+ // sized units. On a 4Ghz machine this will lose track of wait times greater
193
+ // than (2^29/4 Ghz)*128 =~ 17.2 seconds. Such waits should be extremely rare.
194
+ static constexpr int kProfileTimestampShift = 7;
195
+
196
+ // We currently reserve the lower 3 bits.
197
+ static constexpr int kLockwordReservedShift = 3;
198
+
199
+ uint32_t SpinLock::EncodeWaitCycles(int64_t wait_start_time,
200
+ int64_t wait_end_time) {
201
+ static const int64_t kMaxWaitTime =
202
+ std::numeric_limits<uint32_t>::max() >> kLockwordReservedShift;
203
+ int64_t scaled_wait_time =
204
+ (wait_end_time - wait_start_time) >> kProfileTimestampShift;
205
+
206
+ // Return a representation of the time spent waiting that can be stored in
207
+ // the lock word's upper bits.
208
+ uint32_t clamped = static_cast<uint32_t>(
209
+ std::min(scaled_wait_time, kMaxWaitTime) << kLockwordReservedShift);
210
+
211
+ if (clamped == 0) {
212
+ return kSpinLockSleeper; // Just wake waiters, but don't record contention.
213
+ }
214
+ // Bump up value if necessary to avoid returning kSpinLockSleeper.
215
+ const uint32_t kMinWaitTime =
216
+ kSpinLockSleeper + (1 << kLockwordReservedShift);
217
+ if (clamped == kSpinLockSleeper) {
218
+ return kMinWaitTime;
219
+ }
220
+ return clamped;
221
+ }
222
+
223
+ int64_t SpinLock::DecodeWaitCycles(uint32_t lock_value) {
224
+ // Cast to uint32_t first to ensure bits [63:32] are cleared.
225
+ const int64_t scaled_wait_time =
226
+ static_cast<uint32_t>(lock_value & kWaitTimeMask);
227
+ return scaled_wait_time << (kProfileTimestampShift - kLockwordReservedShift);
228
+ }
229
+
230
+ } // namespace base_internal
231
+ ABSL_NAMESPACE_END
232
+ } // namespace absl
weight/_dep/abseil-cpp/absl/base/internal/spinlock.h ADDED
@@ -0,0 +1,265 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //
2
+ // Copyright 2017 The Abseil Authors.
3
+ //
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // you may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ //
8
+ // https://www.apache.org/licenses/LICENSE-2.0
9
+ //
10
+ // Unless required by applicable law or agreed to in writing, software
11
+ // distributed under the License is distributed on an "AS IS" BASIS,
12
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ // See the License for the specific language governing permissions and
14
+ // limitations under the License.
15
+ //
16
+
17
+ // Most users requiring mutual exclusion should use Mutex.
18
+ // SpinLock is provided for use in two situations:
19
+ // - for use by Abseil internal code that Mutex itself depends on
20
+ // - for async signal safety (see below)
21
+
22
+ // SpinLock with a base_internal::SchedulingMode::SCHEDULE_KERNEL_ONLY is async
23
+ // signal safe. If a spinlock is used within a signal handler, all code that
24
+ // acquires the lock must ensure that the signal cannot arrive while they are
25
+ // holding the lock. Typically, this is done by blocking the signal.
26
+ //
27
+ // Threads waiting on a SpinLock may be woken in an arbitrary order.
28
+
29
+ #ifndef ABSL_BASE_INTERNAL_SPINLOCK_H_
30
+ #define ABSL_BASE_INTERNAL_SPINLOCK_H_
31
+
32
+ #include <atomic>
33
+ #include <cstdint>
34
+
35
+ #include "absl/base/attributes.h"
36
+ #include "absl/base/const_init.h"
37
+ #include "absl/base/dynamic_annotations.h"
38
+ #include "absl/base/internal/low_level_scheduling.h"
39
+ #include "absl/base/internal/raw_logging.h"
40
+ #include "absl/base/internal/scheduling_mode.h"
41
+ #include "absl/base/internal/tsan_mutex_interface.h"
42
+ #include "absl/base/thread_annotations.h"
43
+
44
+ namespace tcmalloc {
45
+ namespace tcmalloc_internal {
46
+
47
+ class AllocationGuardSpinLockHolder;
48
+
49
+ } // namespace tcmalloc_internal
50
+ } // namespace tcmalloc
51
+
52
+ namespace absl {
53
+ ABSL_NAMESPACE_BEGIN
54
+ namespace base_internal {
55
+
56
+ class ABSL_LOCKABLE SpinLock {
57
+ public:
58
+ SpinLock() : lockword_(kSpinLockCooperative) {
59
+ ABSL_TSAN_MUTEX_CREATE(this, __tsan_mutex_not_static);
60
+ }
61
+
62
+ // Constructors that allow non-cooperative spinlocks to be created for use
63
+ // inside thread schedulers. Normal clients should not use these.
64
+ explicit SpinLock(base_internal::SchedulingMode mode);
65
+
66
+ // Constructor for global SpinLock instances. See absl/base/const_init.h.
67
+ constexpr SpinLock(absl::ConstInitType, base_internal::SchedulingMode mode)
68
+ : lockword_(IsCooperative(mode) ? kSpinLockCooperative : 0) {}
69
+
70
+ // For global SpinLock instances prefer trivial destructor when possible.
71
+ // Default but non-trivial destructor in some build configurations causes an
72
+ // extra static initializer.
73
+ #ifdef ABSL_INTERNAL_HAVE_TSAN_INTERFACE
74
+ ~SpinLock() { ABSL_TSAN_MUTEX_DESTROY(this, __tsan_mutex_not_static); }
75
+ #else
76
+ ~SpinLock() = default;
77
+ #endif
78
+
79
+ // Acquire this SpinLock.
80
+ inline void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION() {
81
+ ABSL_TSAN_MUTEX_PRE_LOCK(this, 0);
82
+ if (!TryLockImpl()) {
83
+ SlowLock();
84
+ }
85
+ ABSL_TSAN_MUTEX_POST_LOCK(this, 0, 0);
86
+ }
87
+
88
+ // Try to acquire this SpinLock without blocking and return true if the
89
+ // acquisition was successful. If the lock was not acquired, false is
90
+ // returned. If this SpinLock is free at the time of the call, TryLock
91
+ // will return true with high probability.
92
+ inline bool TryLock() ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true) {
93
+ ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_try_lock);
94
+ bool res = TryLockImpl();
95
+ ABSL_TSAN_MUTEX_POST_LOCK(
96
+ this, __tsan_mutex_try_lock | (res ? 0 : __tsan_mutex_try_lock_failed),
97
+ 0);
98
+ return res;
99
+ }
100
+
101
+ // Release this SpinLock, which must be held by the calling thread.
102
+ inline void Unlock() ABSL_UNLOCK_FUNCTION() {
103
+ ABSL_TSAN_MUTEX_PRE_UNLOCK(this, 0);
104
+ uint32_t lock_value = lockword_.load(std::memory_order_relaxed);
105
+ lock_value = lockword_.exchange(lock_value & kSpinLockCooperative,
106
+ std::memory_order_release);
107
+
108
+ if ((lock_value & kSpinLockDisabledScheduling) != 0) {
109
+ base_internal::SchedulingGuard::EnableRescheduling(true);
110
+ }
111
+ if ((lock_value & kWaitTimeMask) != 0) {
112
+ // Collect contentionz profile info, and speed the wakeup of any waiter.
113
+ // The wait_cycles value indicates how long this thread spent waiting
114
+ // for the lock.
115
+ SlowUnlock(lock_value);
116
+ }
117
+ ABSL_TSAN_MUTEX_POST_UNLOCK(this, 0);
118
+ }
119
+
120
+ // Determine if the lock is held. When the lock is held by the invoking
121
+ // thread, true will always be returned. Intended to be used as
122
+ // CHECK(lock.IsHeld()).
123
+ inline bool IsHeld() const {
124
+ return (lockword_.load(std::memory_order_relaxed) & kSpinLockHeld) != 0;
125
+ }
126
+
127
+ // Return immediately if this thread holds the SpinLock exclusively.
128
+ // Otherwise, report an error by crashing with a diagnostic.
129
+ inline void AssertHeld() const ABSL_ASSERT_EXCLUSIVE_LOCK() {
130
+ if (!IsHeld()) {
131
+ ABSL_RAW_LOG(FATAL, "thread should hold the lock on SpinLock");
132
+ }
133
+ }
134
+
135
+ protected:
136
+ // These should not be exported except for testing.
137
+
138
+ // Store number of cycles between wait_start_time and wait_end_time in a
139
+ // lock value.
140
+ static uint32_t EncodeWaitCycles(int64_t wait_start_time,
141
+ int64_t wait_end_time);
142
+
143
+ // Extract number of wait cycles in a lock value.
144
+ static int64_t DecodeWaitCycles(uint32_t lock_value);
145
+
146
+ // Provide access to protected method above. Use for testing only.
147
+ friend struct SpinLockTest;
148
+ friend class tcmalloc::tcmalloc_internal::AllocationGuardSpinLockHolder;
149
+
150
+ private:
151
+ // lockword_ is used to store the following:
152
+ //
153
+ // bit[0] encodes whether a lock is being held.
154
+ // bit[1] encodes whether a lock uses cooperative scheduling.
155
+ // bit[2] encodes whether the current lock holder disabled scheduling when
156
+ // acquiring the lock. Only set when kSpinLockHeld is also set.
157
+ // bit[3:31] encodes time a lock spent on waiting as a 29-bit unsigned int.
158
+ // This is set by the lock holder to indicate how long it waited on
159
+ // the lock before eventually acquiring it. The number of cycles is
160
+ // encoded as a 29-bit unsigned int, or in the case that the current
161
+ // holder did not wait but another waiter is queued, the LSB
162
+ // (kSpinLockSleeper) is set. The implementation does not explicitly
163
+ // track the number of queued waiters beyond this. It must always be
164
+ // assumed that waiters may exist if the current holder was required to
165
+ // queue.
166
+ //
167
+ // Invariant: if the lock is not held, the value is either 0 or
168
+ // kSpinLockCooperative.
169
+ static constexpr uint32_t kSpinLockHeld = 1;
170
+ static constexpr uint32_t kSpinLockCooperative = 2;
171
+ static constexpr uint32_t kSpinLockDisabledScheduling = 4;
172
+ static constexpr uint32_t kSpinLockSleeper = 8;
173
+ // Includes kSpinLockSleeper.
174
+ static constexpr uint32_t kWaitTimeMask =
175
+ ~(kSpinLockHeld | kSpinLockCooperative | kSpinLockDisabledScheduling);
176
+
177
+ // Returns true if the provided scheduling mode is cooperative.
178
+ static constexpr bool IsCooperative(
179
+ base_internal::SchedulingMode scheduling_mode) {
180
+ return scheduling_mode == base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL;
181
+ }
182
+
183
+ bool IsCooperative() const {
184
+ return lockword_.load(std::memory_order_relaxed) & kSpinLockCooperative;
185
+ }
186
+
187
+ uint32_t TryLockInternal(uint32_t lock_value, uint32_t wait_cycles);
188
+ void SlowLock() ABSL_ATTRIBUTE_COLD;
189
+ void SlowUnlock(uint32_t lock_value) ABSL_ATTRIBUTE_COLD;
190
+ uint32_t SpinLoop();
191
+
192
+ inline bool TryLockImpl() {
193
+ uint32_t lock_value = lockword_.load(std::memory_order_relaxed);
194
+ return (TryLockInternal(lock_value, 0) & kSpinLockHeld) == 0;
195
+ }
196
+
197
+ std::atomic<uint32_t> lockword_;
198
+
199
+ SpinLock(const SpinLock&) = delete;
200
+ SpinLock& operator=(const SpinLock&) = delete;
201
+ };
202
+
203
+ // Corresponding locker object that arranges to acquire a spinlock for
204
+ // the duration of a C++ scope.
205
+ class ABSL_SCOPED_LOCKABLE SpinLockHolder {
206
+ public:
207
+ inline explicit SpinLockHolder(SpinLock* l) ABSL_EXCLUSIVE_LOCK_FUNCTION(l)
208
+ : lock_(l) {
209
+ l->Lock();
210
+ }
211
+ inline ~SpinLockHolder() ABSL_UNLOCK_FUNCTION() { lock_->Unlock(); }
212
+
213
+ SpinLockHolder(const SpinLockHolder&) = delete;
214
+ SpinLockHolder& operator=(const SpinLockHolder&) = delete;
215
+
216
+ private:
217
+ SpinLock* lock_;
218
+ };
219
+
220
+ // Register a hook for profiling support.
221
+ //
222
+ // The function pointer registered here will be called whenever a spinlock is
223
+ // contended. The callback is given an opaque handle to the contended spinlock
224
+ // and the number of wait cycles. This is thread-safe, but only a single
225
+ // profiler can be registered. It is an error to call this function multiple
226
+ // times with different arguments.
227
+ void RegisterSpinLockProfiler(void (*fn)(const void* lock,
228
+ int64_t wait_cycles));
229
+
230
+ //------------------------------------------------------------------------------
231
+ // Public interface ends here.
232
+ //------------------------------------------------------------------------------
233
+
234
+ // If (result & kSpinLockHeld) == 0, then *this was successfully locked.
235
+ // Otherwise, returns last observed value for lockword_.
236
+ inline uint32_t SpinLock::TryLockInternal(uint32_t lock_value,
237
+ uint32_t wait_cycles) {
238
+ if ((lock_value & kSpinLockHeld) != 0) {
239
+ return lock_value;
240
+ }
241
+
242
+ uint32_t sched_disabled_bit = 0;
243
+ if ((lock_value & kSpinLockCooperative) == 0) {
244
+ // For non-cooperative locks we must make sure we mark ourselves as
245
+ // non-reschedulable before we attempt to CompareAndSwap.
246
+ if (base_internal::SchedulingGuard::DisableRescheduling()) {
247
+ sched_disabled_bit = kSpinLockDisabledScheduling;
248
+ }
249
+ }
250
+
251
+ if (!lockword_.compare_exchange_strong(
252
+ lock_value,
253
+ kSpinLockHeld | lock_value | wait_cycles | sched_disabled_bit,
254
+ std::memory_order_acquire, std::memory_order_relaxed)) {
255
+ base_internal::SchedulingGuard::EnableRescheduling(sched_disabled_bit != 0);
256
+ }
257
+
258
+ return lock_value;
259
+ }
260
+
261
+ } // namespace base_internal
262
+ ABSL_NAMESPACE_END
263
+ } // namespace absl
264
+
265
+ #endif // ABSL_BASE_INTERNAL_SPINLOCK_H_
weight/_dep/abseil-cpp/absl/base/internal/spinlock_benchmark.cc ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2018 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ // See also //absl/synchronization:mutex_benchmark for a comparison of SpinLock
16
+ // and Mutex performance under varying levels of contention.
17
+
18
+ #include "absl/base/internal/raw_logging.h"
19
+ #include "absl/base/internal/scheduling_mode.h"
20
+ #include "absl/base/internal/spinlock.h"
21
+ #include "absl/base/no_destructor.h"
22
+ #include "absl/synchronization/internal/create_thread_identity.h"
23
+ #include "benchmark/benchmark.h"
24
+
25
+ namespace {
26
+
27
+ template <absl::base_internal::SchedulingMode scheduling_mode>
28
+ static void BM_TryLock(benchmark::State& state) {
29
+ // Ensure a ThreadIdentity is installed so that KERNEL_ONLY has an effect.
30
+ ABSL_INTERNAL_CHECK(
31
+ absl::synchronization_internal::GetOrCreateCurrentThreadIdentity() !=
32
+ nullptr,
33
+ "GetOrCreateCurrentThreadIdentity() failed");
34
+
35
+ static absl::NoDestructor<absl::base_internal::SpinLock> spinlock(
36
+ scheduling_mode);
37
+ for (auto _ : state) {
38
+ if (spinlock->TryLock()) spinlock->Unlock();
39
+ }
40
+ }
41
+
42
+ template <absl::base_internal::SchedulingMode scheduling_mode>
43
+ static void BM_SpinLock(benchmark::State& state) {
44
+ // Ensure a ThreadIdentity is installed so that KERNEL_ONLY has an effect.
45
+ ABSL_INTERNAL_CHECK(
46
+ absl::synchronization_internal::GetOrCreateCurrentThreadIdentity() !=
47
+ nullptr,
48
+ "GetOrCreateCurrentThreadIdentity() failed");
49
+
50
+ static absl::NoDestructor<absl::base_internal::SpinLock> spinlock(
51
+ scheduling_mode);
52
+ for (auto _ : state) {
53
+ absl::base_internal::SpinLockHolder holder(spinlock.get());
54
+ }
55
+ }
56
+
57
+ BENCHMARK_TEMPLATE(BM_SpinLock,
58
+ absl::base_internal::SCHEDULE_KERNEL_ONLY)
59
+ ->UseRealTime()
60
+ ->Threads(1)
61
+ ->ThreadPerCpu();
62
+
63
+ BENCHMARK_TEMPLATE(BM_SpinLock,
64
+ absl::base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL)
65
+ ->UseRealTime()
66
+ ->Threads(1)
67
+ ->ThreadPerCpu();
68
+
69
+ BENCHMARK_TEMPLATE(BM_TryLock, absl::base_internal::SCHEDULE_KERNEL_ONLY)
70
+ ->UseRealTime()
71
+ ->Threads(1)
72
+ ->ThreadPerCpu();
73
+
74
+ BENCHMARK_TEMPLATE(BM_TryLock,
75
+ absl::base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL)
76
+ ->UseRealTime()
77
+ ->Threads(1)
78
+ ->ThreadPerCpu();
79
+
80
+ } // namespace
weight/_dep/abseil-cpp/absl/base/internal/spinlock_linux.inc ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2018 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+ // This file is a Linux-specific part of spinlock_wait.cc
16
+
17
+ #include <linux/futex.h>
18
+ #include <sys/syscall.h>
19
+ #include <unistd.h>
20
+
21
+ #include <atomic>
22
+ #include <climits>
23
+ #include <cstdint>
24
+ #include <ctime>
25
+
26
+ #include "absl/base/attributes.h"
27
+ #include "absl/base/internal/errno_saver.h"
28
+
29
+ // The SpinLock lockword is `std::atomic<uint32_t>`. Here we assert that
30
+ // `std::atomic<uint32_t>` is bitwise equivalent of the `int` expected
31
+ // by SYS_futex. We also assume that reads/writes done to the lockword
32
+ // by SYS_futex have rational semantics with regard to the
33
+ // std::atomic<> API. C++ provides no guarantees of these assumptions,
34
+ // but they are believed to hold in practice.
35
+ static_assert(sizeof(std::atomic<uint32_t>) == sizeof(int),
36
+ "SpinLock lockword has the wrong size for a futex");
37
+
38
+ // Some Android headers are missing these definitions even though they
39
+ // support these futex operations.
40
+ #ifdef __BIONIC__
41
+ #ifndef SYS_futex
42
+ #define SYS_futex __NR_futex
43
+ #endif
44
+ #ifndef FUTEX_PRIVATE_FLAG
45
+ #define FUTEX_PRIVATE_FLAG 128
46
+ #endif
47
+ #endif
48
+
49
+ #if defined(__NR_futex_time64) && !defined(SYS_futex_time64)
50
+ #define SYS_futex_time64 __NR_futex_time64
51
+ #endif
52
+
53
+ #if defined(SYS_futex_time64) && !defined(SYS_futex)
54
+ #define SYS_futex SYS_futex_time64
55
+ #endif
56
+
57
+ extern "C" {
58
+
59
+ ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay)(
60
+ std::atomic<uint32_t> *w, uint32_t value, int,
61
+ absl::base_internal::SchedulingMode) {
62
+ absl::base_internal::ErrnoSaver errno_saver;
63
+ syscall(SYS_futex, w, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, value, nullptr);
64
+ }
65
+
66
+ ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockWake)(
67
+ std::atomic<uint32_t> *w, bool all) {
68
+ syscall(SYS_futex, w, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, all ? INT_MAX : 1, 0);
69
+ }
70
+
71
+ } // extern "C"
weight/_dep/abseil-cpp/absl/base/internal/spinlock_posix.inc ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+ // This file is a Posix-specific part of spinlock_wait.cc
16
+
17
+ #include <sched.h>
18
+
19
+ #include <atomic>
20
+ #include <ctime>
21
+
22
+ #include "absl/base/internal/errno_saver.h"
23
+ #include "absl/base/internal/scheduling_mode.h"
24
+ #include "absl/base/port.h"
25
+
26
+ extern "C" {
27
+
28
+ ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay)(
29
+ std::atomic<uint32_t>* /* lock_word */, uint32_t /* value */, int loop,
30
+ absl::base_internal::SchedulingMode /* mode */) {
31
+ absl::base_internal::ErrnoSaver errno_saver;
32
+ if (loop == 0) {
33
+ } else if (loop == 1) {
34
+ sched_yield();
35
+ } else {
36
+ struct timespec tm;
37
+ tm.tv_sec = 0;
38
+ tm.tv_nsec = absl::base_internal::SpinLockSuggestedDelayNS(loop);
39
+ nanosleep(&tm, nullptr);
40
+ }
41
+ }
42
+
43
+ ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockWake)(
44
+ std::atomic<uint32_t>* /* lock_word */, bool /* all */) {}
45
+
46
+ } // extern "C"
weight/_dep/abseil-cpp/absl/base/internal/spinlock_wait.cc ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ // The OS-specific header included below must provide two calls:
16
+ // AbslInternalSpinLockDelay() and AbslInternalSpinLockWake().
17
+ // See spinlock_wait.h for the specs.
18
+
19
+ #include <atomic>
20
+ #include <cstdint>
21
+
22
+ #include "absl/base/internal/spinlock_wait.h"
23
+
24
+ #if defined(_WIN32)
25
+ #include "absl/base/internal/spinlock_win32.inc"
26
+ #elif defined(__linux__)
27
+ #include "absl/base/internal/spinlock_linux.inc"
28
+ #elif defined(__akaros__)
29
+ #include "absl/base/internal/spinlock_akaros.inc"
30
+ #else
31
+ #include "absl/base/internal/spinlock_posix.inc"
32
+ #endif
33
+
34
+ namespace absl {
35
+ ABSL_NAMESPACE_BEGIN
36
+ namespace base_internal {
37
+
38
+ // See spinlock_wait.h for spec.
39
+ uint32_t SpinLockWait(std::atomic<uint32_t> *w, int n,
40
+ const SpinLockWaitTransition trans[],
41
+ base_internal::SchedulingMode scheduling_mode) {
42
+ int loop = 0;
43
+ for (;;) {
44
+ uint32_t v = w->load(std::memory_order_acquire);
45
+ int i;
46
+ for (i = 0; i != n && v != trans[i].from; i++) {
47
+ }
48
+ if (i == n) {
49
+ SpinLockDelay(w, v, ++loop, scheduling_mode); // no matching transition
50
+ } else if (trans[i].to == v || // null transition
51
+ w->compare_exchange_strong(v, trans[i].to,
52
+ std::memory_order_acquire,
53
+ std::memory_order_relaxed)) {
54
+ if (trans[i].done) return v;
55
+ }
56
+ }
57
+ }
58
+
59
+ static std::atomic<uint64_t> delay_rand;
60
+
61
+ // Return a suggested delay in nanoseconds for iteration number "loop"
62
+ int SpinLockSuggestedDelayNS(int loop) {
63
+ // Weak pseudo-random number generator to get some spread between threads
64
+ // when many are spinning.
65
+ uint64_t r = delay_rand.load(std::memory_order_relaxed);
66
+ r = 0x5deece66dLL * r + 0xb; // numbers from nrand48()
67
+ delay_rand.store(r, std::memory_order_relaxed);
68
+
69
+ if (loop < 0 || loop > 32) { // limit loop to 0..32
70
+ loop = 32;
71
+ }
72
+ const int kMinDelay = 128 << 10; // 128us
73
+ // Double delay every 8 iterations, up to 16x (2ms).
74
+ int delay = kMinDelay << (loop / 8);
75
+ // Randomize in delay..2*delay range, for resulting 128us..4ms range.
76
+ return delay | ((delay - 1) & static_cast<int>(r));
77
+ }
78
+
79
+ } // namespace base_internal
80
+ ABSL_NAMESPACE_END
81
+ } // namespace absl
weight/_dep/abseil-cpp/absl/base/internal/spinlock_wait.h ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #ifndef ABSL_BASE_INTERNAL_SPINLOCK_WAIT_H_
16
+ #define ABSL_BASE_INTERNAL_SPINLOCK_WAIT_H_
17
+
18
+ // Operations to make atomic transitions on a word, and to allow
19
+ // waiting for those transitions to become possible.
20
+
21
+ #include <stdint.h>
22
+ #include <atomic>
23
+
24
+ #include "absl/base/internal/scheduling_mode.h"
25
+
26
+ namespace absl {
27
+ ABSL_NAMESPACE_BEGIN
28
+ namespace base_internal {
29
+
30
+ // SpinLockWait() waits until it can perform one of several transitions from
31
+ // "from" to "to". It returns when it performs a transition where done==true.
32
+ struct SpinLockWaitTransition {
33
+ uint32_t from;
34
+ uint32_t to;
35
+ bool done;
36
+ };
37
+
38
+ // Wait until *w can transition from trans[i].from to trans[i].to for some i
39
+ // satisfying 0<=i<n && trans[i].done, atomically make the transition,
40
+ // then return the old value of *w. Make any other atomic transitions
41
+ // where !trans[i].done, but continue waiting.
42
+ //
43
+ // Wakeups for threads blocked on SpinLockWait do not respect priorities.
44
+ uint32_t SpinLockWait(std::atomic<uint32_t> *w, int n,
45
+ const SpinLockWaitTransition trans[],
46
+ SchedulingMode scheduling_mode);
47
+
48
+ // If possible, wake some thread that has called SpinLockDelay(w, ...). If `all`
49
+ // is true, wake all such threads. On some systems, this may be a no-op; on
50
+ // those systems, threads calling SpinLockDelay() will always wake eventually
51
+ // even if SpinLockWake() is never called.
52
+ void SpinLockWake(std::atomic<uint32_t> *w, bool all);
53
+
54
+ // Wait for an appropriate spin delay on iteration "loop" of a
55
+ // spin loop on location *w, whose previously observed value was "value".
56
+ // SpinLockDelay() may do nothing, may yield the CPU, may sleep a clock tick,
57
+ // or may wait for a call to SpinLockWake(w).
58
+ void SpinLockDelay(std::atomic<uint32_t> *w, uint32_t value, int loop,
59
+ base_internal::SchedulingMode scheduling_mode);
60
+
61
+ // Helper used by AbslInternalSpinLockDelay.
62
+ // Returns a suggested delay in nanoseconds for iteration number "loop".
63
+ int SpinLockSuggestedDelayNS(int loop);
64
+
65
+ } // namespace base_internal
66
+ ABSL_NAMESPACE_END
67
+ } // namespace absl
68
+
69
+ // In some build configurations we pass --detect-odr-violations to the
70
+ // gold linker. This causes it to flag weak symbol overrides as ODR
71
+ // violations. Because ODR only applies to C++ and not C,
72
+ // --detect-odr-violations ignores symbols not mangled with C++ names.
73
+ // By changing our extension points to be extern "C", we dodge this
74
+ // check.
75
+ extern "C" {
76
+ void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockWake)(std::atomic<uint32_t> *w,
77
+ bool all);
78
+ void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay)(
79
+ std::atomic<uint32_t> *w, uint32_t value, int loop,
80
+ absl::base_internal::SchedulingMode scheduling_mode);
81
+ }
82
+
83
+ inline void absl::base_internal::SpinLockWake(std::atomic<uint32_t> *w,
84
+ bool all) {
85
+ ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockWake)(w, all);
86
+ }
87
+
88
+ inline void absl::base_internal::SpinLockDelay(
89
+ std::atomic<uint32_t> *w, uint32_t value, int loop,
90
+ absl::base_internal::SchedulingMode scheduling_mode) {
91
+ ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay)
92
+ (w, value, loop, scheduling_mode);
93
+ }
94
+
95
+ #endif // ABSL_BASE_INTERNAL_SPINLOCK_WAIT_H_
weight/_dep/abseil-cpp/absl/base/internal/spinlock_win32.inc ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+ // This file is a Win32-specific part of spinlock_wait.cc
16
+
17
+ #include <windows.h>
18
+ #include <atomic>
19
+ #include "absl/base/internal/scheduling_mode.h"
20
+
21
+ extern "C" {
22
+
23
+ void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay)(
24
+ std::atomic<uint32_t>* /* lock_word */, uint32_t /* value */, int loop,
25
+ absl::base_internal::SchedulingMode /* mode */) {
26
+ if (loop == 0) {
27
+ } else if (loop == 1) {
28
+ Sleep(0);
29
+ } else {
30
+ // SpinLockSuggestedDelayNS() always returns a positive integer, so this
31
+ // static_cast is safe.
32
+ Sleep(static_cast<DWORD>(
33
+ absl::base_internal::SpinLockSuggestedDelayNS(loop) / 1000000));
34
+ }
35
+ }
36
+
37
+ void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockWake)(
38
+ std::atomic<uint32_t>* /* lock_word */, bool /* all */) {}
39
+
40
+ } // extern "C"
weight/_dep/abseil-cpp/absl/base/internal/strerror.cc ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2020 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include "absl/base/internal/strerror.h"
16
+
17
+ #include <array>
18
+ #include <cerrno>
19
+ #include <cstddef>
20
+ #include <cstdio>
21
+ #include <cstring>
22
+ #include <string>
23
+ #include <type_traits>
24
+
25
+ #include "absl/base/internal/errno_saver.h"
26
+
27
+ namespace absl {
28
+ ABSL_NAMESPACE_BEGIN
29
+ namespace base_internal {
30
+ namespace {
31
+
32
+ const char* StrErrorAdaptor(int errnum, char* buf, size_t buflen) {
33
+ #if defined(_WIN32)
34
+ int rc = strerror_s(buf, buflen, errnum);
35
+ buf[buflen - 1] = '\0'; // guarantee NUL termination
36
+ if (rc == 0 && strncmp(buf, "Unknown error", buflen) == 0) *buf = '\0';
37
+ return buf;
38
+ #else
39
+ // The type of `ret` is platform-specific; both of these branches must compile
40
+ // either way but only one will execute on any given platform:
41
+ auto ret = strerror_r(errnum, buf, buflen);
42
+ if (std::is_same<decltype(ret), int>::value) {
43
+ // XSI `strerror_r`; `ret` is `int`:
44
+ if (ret) *buf = '\0';
45
+ return buf;
46
+ } else {
47
+ // GNU `strerror_r`; `ret` is `char *`:
48
+ return reinterpret_cast<const char*>(ret);
49
+ }
50
+ #endif
51
+ }
52
+
53
+ std::string StrErrorInternal(int errnum) {
54
+ char buf[100];
55
+ const char* str = StrErrorAdaptor(errnum, buf, sizeof buf);
56
+ if (*str == '\0') {
57
+ snprintf(buf, sizeof buf, "Unknown error %d", errnum);
58
+ str = buf;
59
+ }
60
+ return str;
61
+ }
62
+
63
+ // kSysNerr is the number of errors from a recent glibc. `StrError()` falls back
64
+ // to `StrErrorAdaptor()` if the value is larger than this.
65
+ constexpr int kSysNerr = 135;
66
+
67
+ std::array<std::string, kSysNerr>* NewStrErrorTable() {
68
+ auto* table = new std::array<std::string, kSysNerr>;
69
+ for (size_t i = 0; i < table->size(); ++i) {
70
+ (*table)[i] = StrErrorInternal(static_cast<int>(i));
71
+ }
72
+ return table;
73
+ }
74
+
75
+ } // namespace
76
+
77
+ std::string StrError(int errnum) {
78
+ absl::base_internal::ErrnoSaver errno_saver;
79
+ static const auto* table = NewStrErrorTable();
80
+ if (errnum >= 0 && static_cast<size_t>(errnum) < table->size()) {
81
+ return (*table)[static_cast<size_t>(errnum)];
82
+ }
83
+ return StrErrorInternal(errnum);
84
+ }
85
+
86
+ } // namespace base_internal
87
+ ABSL_NAMESPACE_END
88
+ } // namespace absl
weight/_dep/abseil-cpp/absl/base/internal/strerror.h ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2020 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #ifndef ABSL_BASE_INTERNAL_STRERROR_H_
16
+ #define ABSL_BASE_INTERNAL_STRERROR_H_
17
+
18
+ #include <string>
19
+
20
+ #include "absl/base/config.h"
21
+
22
+ namespace absl {
23
+ ABSL_NAMESPACE_BEGIN
24
+ namespace base_internal {
25
+
26
+ // A portable and thread-safe alternative to C89's `strerror`.
27
+ //
28
+ // The C89 specification of `strerror` is not suitable for use in a
29
+ // multi-threaded application as the returned string may be changed by calls to
30
+ // `strerror` from another thread. The many non-stdlib alternatives differ
31
+ // enough in their names, availability, and semantics to justify this wrapper
32
+ // around them. `errno` will not be modified by a call to `absl::StrError`.
33
+ std::string StrError(int errnum);
34
+
35
+ } // namespace base_internal
36
+ ABSL_NAMESPACE_END
37
+ } // namespace absl
38
+
39
+ #endif // ABSL_BASE_INTERNAL_STRERROR_H_
weight/_dep/abseil-cpp/absl/base/internal/strerror_benchmark.cc ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2020 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include <cerrno>
16
+ #include <cstdio>
17
+ #include <string>
18
+
19
+ #include "absl/base/internal/strerror.h"
20
+ #include "benchmark/benchmark.h"
21
+
22
+ namespace {
23
+ void BM_AbslStrError(benchmark::State& state) {
24
+ for (auto _ : state) {
25
+ benchmark::DoNotOptimize(absl::base_internal::StrError(ERANGE));
26
+ }
27
+ }
28
+ BENCHMARK(BM_AbslStrError);
29
+ } // namespace
weight/_dep/abseil-cpp/absl/base/internal/strerror_test.cc ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2020 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include "absl/base/internal/strerror.h"
16
+
17
+ #include <atomic>
18
+ #include <cerrno>
19
+ #include <cstdio>
20
+ #include <cstring>
21
+ #include <string>
22
+ #include <thread> // NOLINT(build/c++11)
23
+ #include <vector>
24
+
25
+ #include "gmock/gmock.h"
26
+ #include "gtest/gtest.h"
27
+ #include "absl/strings/match.h"
28
+
29
+ namespace {
30
+ using ::testing::AnyOf;
31
+ using ::testing::Eq;
32
+
33
+ TEST(StrErrorTest, ValidErrorCode) {
34
+ errno = ERANGE;
35
+ EXPECT_THAT(absl::base_internal::StrError(EDOM), Eq(strerror(EDOM)));
36
+ EXPECT_THAT(errno, Eq(ERANGE));
37
+ }
38
+
39
+ TEST(StrErrorTest, InvalidErrorCode) {
40
+ errno = ERANGE;
41
+ EXPECT_THAT(absl::base_internal::StrError(-1),
42
+ AnyOf(Eq("No error information"), Eq("Unknown error -1")));
43
+ EXPECT_THAT(errno, Eq(ERANGE));
44
+ }
45
+
46
+ TEST(StrErrorTest, MultipleThreads) {
47
+ // In this test, we will start up 2 threads and have each one call
48
+ // StrError 1000 times, each time with a different errnum. We
49
+ // expect that StrError(errnum) will return a string equal to the
50
+ // one returned by strerror(errnum), if the code is known. Since
51
+ // strerror is known to be thread-hostile, collect all the expected
52
+ // strings up front.
53
+ const int kNumCodes = 1000;
54
+ std::vector<std::string> expected_strings(kNumCodes);
55
+ for (int i = 0; i < kNumCodes; ++i) {
56
+ expected_strings[i] = strerror(i);
57
+ }
58
+
59
+ std::atomic_int counter(0);
60
+ auto thread_fun = [&]() {
61
+ for (int i = 0; i < kNumCodes; ++i) {
62
+ ++counter;
63
+ errno = ERANGE;
64
+ const std::string value = absl::base_internal::StrError(i);
65
+ // EXPECT_* could change errno. Stash it first.
66
+ int check_err = errno;
67
+ EXPECT_THAT(check_err, Eq(ERANGE));
68
+ // Only the GNU implementation is guaranteed to provide the
69
+ // string "Unknown error nnn". POSIX doesn't say anything.
70
+ if (!absl::StartsWith(value, "Unknown error ")) {
71
+ EXPECT_THAT(value, Eq(expected_strings[i]));
72
+ }
73
+ }
74
+ };
75
+
76
+ const int kNumThreads = 100;
77
+ std::vector<std::thread> threads;
78
+ for (int i = 0; i < kNumThreads; ++i) {
79
+ threads.push_back(std::thread(thread_fun));
80
+ }
81
+ for (auto& thread : threads) {
82
+ thread.join();
83
+ }
84
+
85
+ EXPECT_THAT(counter, Eq(kNumThreads * kNumCodes));
86
+ }
87
+
88
+ } // namespace
weight/_dep/abseil-cpp/absl/base/internal/sysinfo.cc ADDED
@@ -0,0 +1,489 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include "absl/base/internal/sysinfo.h"
16
+
17
+ #include "absl/base/attributes.h"
18
+
19
+ #ifdef _WIN32
20
+ #include <windows.h>
21
+ #else
22
+ #include <fcntl.h>
23
+ #include <pthread.h>
24
+ #include <sys/stat.h>
25
+ #include <sys/types.h>
26
+ #include <unistd.h>
27
+ #endif
28
+
29
+ #ifdef __linux__
30
+ #include <sys/syscall.h>
31
+ #endif
32
+
33
+ #if defined(__APPLE__) || defined(__FreeBSD__)
34
+ #include <sys/sysctl.h>
35
+ #endif
36
+
37
+ #ifdef __FreeBSD__
38
+ #include <pthread_np.h>
39
+ #endif
40
+
41
+ #ifdef __NetBSD__
42
+ #include <lwp.h>
43
+ #endif
44
+
45
+ #if defined(__myriad2__)
46
+ #include <rtems.h>
47
+ #endif
48
+
49
+ #include <string.h>
50
+
51
+ #include <cassert>
52
+ #include <cerrno>
53
+ #include <cstdint>
54
+ #include <cstdio>
55
+ #include <cstdlib>
56
+ #include <ctime>
57
+ #include <limits>
58
+ #include <thread> // NOLINT(build/c++11)
59
+ #include <utility>
60
+ #include <vector>
61
+
62
+ #include "absl/base/call_once.h"
63
+ #include "absl/base/config.h"
64
+ #include "absl/base/internal/raw_logging.h"
65
+ #include "absl/base/internal/spinlock.h"
66
+ #include "absl/base/internal/unscaledcycleclock.h"
67
+ #include "absl/base/thread_annotations.h"
68
+
69
+ namespace absl {
70
+ ABSL_NAMESPACE_BEGIN
71
+ namespace base_internal {
72
+
73
+ namespace {
74
+
75
+ #if defined(_WIN32)
76
+
77
+ // Returns number of bits set in `bitMask`
78
+ DWORD Win32CountSetBits(ULONG_PTR bitMask) {
79
+ for (DWORD bitSetCount = 0; ; ++bitSetCount) {
80
+ if (bitMask == 0) return bitSetCount;
81
+ bitMask &= bitMask - 1;
82
+ }
83
+ }
84
+
85
+ // Returns the number of logical CPUs using GetLogicalProcessorInformation(), or
86
+ // 0 if the number of processors is not available or can not be computed.
87
+ // https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getlogicalprocessorinformation
88
+ int Win32NumCPUs() {
89
+ #pragma comment(lib, "kernel32.lib")
90
+ using Info = SYSTEM_LOGICAL_PROCESSOR_INFORMATION;
91
+
92
+ DWORD info_size = sizeof(Info);
93
+ Info* info(static_cast<Info*>(malloc(info_size)));
94
+ if (info == nullptr) return 0;
95
+
96
+ bool success = GetLogicalProcessorInformation(info, &info_size);
97
+ if (!success && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
98
+ free(info);
99
+ info = static_cast<Info*>(malloc(info_size));
100
+ if (info == nullptr) return 0;
101
+ success = GetLogicalProcessorInformation(info, &info_size);
102
+ }
103
+
104
+ DWORD logicalProcessorCount = 0;
105
+ if (success) {
106
+ Info* ptr = info;
107
+ DWORD byteOffset = 0;
108
+ while (byteOffset + sizeof(Info) <= info_size) {
109
+ switch (ptr->Relationship) {
110
+ case RelationProcessorCore:
111
+ logicalProcessorCount += Win32CountSetBits(ptr->ProcessorMask);
112
+ break;
113
+
114
+ case RelationNumaNode:
115
+ case RelationCache:
116
+ case RelationProcessorPackage:
117
+ // Ignore other entries
118
+ break;
119
+
120
+ default:
121
+ // Ignore unknown entries
122
+ break;
123
+ }
124
+ byteOffset += sizeof(Info);
125
+ ptr++;
126
+ }
127
+ }
128
+ free(info);
129
+ return static_cast<int>(logicalProcessorCount);
130
+ }
131
+
132
+ #endif
133
+
134
+ } // namespace
135
+
136
+ static int GetNumCPUs() {
137
+ #if defined(__myriad2__)
138
+ return 1;
139
+ #elif defined(_WIN32)
140
+ const int hardware_concurrency = Win32NumCPUs();
141
+ return hardware_concurrency ? hardware_concurrency : 1;
142
+ #elif defined(_AIX)
143
+ return sysconf(_SC_NPROCESSORS_ONLN);
144
+ #else
145
+ // Other possibilities:
146
+ // - Read /sys/devices/system/cpu/online and use cpumask_parse()
147
+ // - sysconf(_SC_NPROCESSORS_ONLN)
148
+ return static_cast<int>(std::thread::hardware_concurrency());
149
+ #endif
150
+ }
151
+
152
+ #if defined(_WIN32)
153
+
154
+ static double GetNominalCPUFrequency() {
155
+ #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \
156
+ !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
157
+ // UWP apps don't have access to the registry and currently don't provide an
158
+ // API informing about CPU nominal frequency.
159
+ return 1.0;
160
+ #else
161
+ #pragma comment(lib, "advapi32.lib") // For Reg* functions.
162
+ HKEY key;
163
+ // Use the Reg* functions rather than the SH functions because shlwapi.dll
164
+ // pulls in gdi32.dll which makes process destruction much more costly.
165
+ if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,
166
+ "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0,
167
+ KEY_READ, &key) == ERROR_SUCCESS) {
168
+ DWORD type = 0;
169
+ DWORD data = 0;
170
+ DWORD data_size = sizeof(data);
171
+ auto result = RegQueryValueExA(key, "~MHz", nullptr, &type,
172
+ reinterpret_cast<LPBYTE>(&data), &data_size);
173
+ RegCloseKey(key);
174
+ if (result == ERROR_SUCCESS && type == REG_DWORD &&
175
+ data_size == sizeof(data)) {
176
+ return data * 1e6; // Value is MHz.
177
+ }
178
+ }
179
+ return 1.0;
180
+ #endif // WINAPI_PARTITION_APP && !WINAPI_PARTITION_DESKTOP
181
+ }
182
+
183
+ #elif defined(CTL_HW) && defined(HW_CPU_FREQ)
184
+
185
+ static double GetNominalCPUFrequency() {
186
+ unsigned freq;
187
+ size_t size = sizeof(freq);
188
+ int mib[2] = {CTL_HW, HW_CPU_FREQ};
189
+ if (sysctl(mib, 2, &freq, &size, nullptr, 0) == 0) {
190
+ return static_cast<double>(freq);
191
+ }
192
+ return 1.0;
193
+ }
194
+
195
+ #else
196
+
197
+ // Helper function for reading a long from a file. Returns true if successful
198
+ // and the memory location pointed to by value is set to the value read.
199
+ static bool ReadLongFromFile(const char *file, long *value) {
200
+ bool ret = false;
201
+ #if defined(_POSIX_C_SOURCE)
202
+ const int file_mode = (O_RDONLY | O_CLOEXEC);
203
+ #else
204
+ const int file_mode = O_RDONLY;
205
+ #endif
206
+
207
+ int fd = open(file, file_mode);
208
+ if (fd != -1) {
209
+ char line[1024];
210
+ char *err;
211
+ memset(line, '\0', sizeof(line));
212
+ ssize_t len;
213
+ do {
214
+ len = read(fd, line, sizeof(line) - 1);
215
+ } while (len < 0 && errno == EINTR);
216
+ if (len <= 0) {
217
+ ret = false;
218
+ } else {
219
+ const long temp_value = strtol(line, &err, 10);
220
+ if (line[0] != '\0' && (*err == '\n' || *err == '\0')) {
221
+ *value = temp_value;
222
+ ret = true;
223
+ }
224
+ }
225
+ close(fd);
226
+ }
227
+ return ret;
228
+ }
229
+
230
+ #if defined(ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY)
231
+
232
+ // Reads a monotonic time source and returns a value in
233
+ // nanoseconds. The returned value uses an arbitrary epoch, not the
234
+ // Unix epoch.
235
+ static int64_t ReadMonotonicClockNanos() {
236
+ struct timespec t;
237
+ #ifdef CLOCK_MONOTONIC_RAW
238
+ int rc = clock_gettime(CLOCK_MONOTONIC_RAW, &t);
239
+ #else
240
+ int rc = clock_gettime(CLOCK_MONOTONIC, &t);
241
+ #endif
242
+ if (rc != 0) {
243
+ ABSL_INTERNAL_LOG(
244
+ FATAL, "clock_gettime() failed: (" + std::to_string(errno) + ")");
245
+ }
246
+ return int64_t{t.tv_sec} * 1000000000 + t.tv_nsec;
247
+ }
248
+
249
+ class UnscaledCycleClockWrapperForInitializeFrequency {
250
+ public:
251
+ static int64_t Now() { return base_internal::UnscaledCycleClock::Now(); }
252
+ };
253
+
254
+ struct TimeTscPair {
255
+ int64_t time; // From ReadMonotonicClockNanos().
256
+ int64_t tsc; // From UnscaledCycleClock::Now().
257
+ };
258
+
259
+ // Returns a pair of values (monotonic kernel time, TSC ticks) that
260
+ // approximately correspond to each other. This is accomplished by
261
+ // doing several reads and picking the reading with the lowest
262
+ // latency. This approach is used to minimize the probability that
263
+ // our thread was preempted between clock reads.
264
+ static TimeTscPair GetTimeTscPair() {
265
+ int64_t best_latency = std::numeric_limits<int64_t>::max();
266
+ TimeTscPair best;
267
+ for (int i = 0; i < 10; ++i) {
268
+ int64_t t0 = ReadMonotonicClockNanos();
269
+ int64_t tsc = UnscaledCycleClockWrapperForInitializeFrequency::Now();
270
+ int64_t t1 = ReadMonotonicClockNanos();
271
+ int64_t latency = t1 - t0;
272
+ if (latency < best_latency) {
273
+ best_latency = latency;
274
+ best.time = t0;
275
+ best.tsc = tsc;
276
+ }
277
+ }
278
+ return best;
279
+ }
280
+
281
+ // Measures and returns the TSC frequency by taking a pair of
282
+ // measurements approximately `sleep_nanoseconds` apart.
283
+ static double MeasureTscFrequencyWithSleep(int sleep_nanoseconds) {
284
+ auto t0 = GetTimeTscPair();
285
+ struct timespec ts;
286
+ ts.tv_sec = 0;
287
+ ts.tv_nsec = sleep_nanoseconds;
288
+ while (nanosleep(&ts, &ts) != 0 && errno == EINTR) {}
289
+ auto t1 = GetTimeTscPair();
290
+ double elapsed_ticks = t1.tsc - t0.tsc;
291
+ double elapsed_time = (t1.time - t0.time) * 1e-9;
292
+ return elapsed_ticks / elapsed_time;
293
+ }
294
+
295
+ // Measures and returns the TSC frequency by calling
296
+ // MeasureTscFrequencyWithSleep(), doubling the sleep interval until the
297
+ // frequency measurement stabilizes.
298
+ static double MeasureTscFrequency() {
299
+ double last_measurement = -1.0;
300
+ int sleep_nanoseconds = 1000000; // 1 millisecond.
301
+ for (int i = 0; i < 8; ++i) {
302
+ double measurement = MeasureTscFrequencyWithSleep(sleep_nanoseconds);
303
+ if (measurement * 0.99 < last_measurement &&
304
+ last_measurement < measurement * 1.01) {
305
+ // Use the current measurement if it is within 1% of the
306
+ // previous measurement.
307
+ return measurement;
308
+ }
309
+ last_measurement = measurement;
310
+ sleep_nanoseconds *= 2;
311
+ }
312
+ return last_measurement;
313
+ }
314
+
315
+ #endif // ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY
316
+
317
+ static double GetNominalCPUFrequency() {
318
+ long freq = 0;
319
+
320
+ // Google's production kernel has a patch to export the TSC
321
+ // frequency through sysfs. If the kernel is exporting the TSC
322
+ // frequency use that. There are issues where cpuinfo_max_freq
323
+ // cannot be relied on because the BIOS may be exporting an invalid
324
+ // p-state (on x86) or p-states may be used to put the processor in
325
+ // a new mode (turbo mode). Essentially, those frequencies cannot
326
+ // always be relied upon. The same reasons apply to /proc/cpuinfo as
327
+ // well.
328
+ if (ReadLongFromFile("/sys/devices/system/cpu/cpu0/tsc_freq_khz", &freq)) {
329
+ return freq * 1e3; // Value is kHz.
330
+ }
331
+
332
+ #if defined(ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY)
333
+ // On these platforms, the TSC frequency is the nominal CPU
334
+ // frequency. But without having the kernel export it directly
335
+ // though /sys/devices/system/cpu/cpu0/tsc_freq_khz, there is no
336
+ // other way to reliably get the TSC frequency, so we have to
337
+ // measure it ourselves. Some CPUs abuse cpuinfo_max_freq by
338
+ // exporting "fake" frequencies for implementing new features. For
339
+ // example, Intel's turbo mode is enabled by exposing a p-state
340
+ // value with a higher frequency than that of the real TSC
341
+ // rate. Because of this, we prefer to measure the TSC rate
342
+ // ourselves on i386 and x86-64.
343
+ return MeasureTscFrequency();
344
+ #else
345
+
346
+ // If CPU scaling is in effect, we want to use the *maximum*
347
+ // frequency, not whatever CPU speed some random processor happens
348
+ // to be using now.
349
+ if (ReadLongFromFile("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq",
350
+ &freq)) {
351
+ return freq * 1e3; // Value is kHz.
352
+ }
353
+
354
+ return 1.0;
355
+ #endif // !ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY
356
+ }
357
+
358
+ #endif
359
+
360
+ ABSL_CONST_INIT static once_flag init_num_cpus_once;
361
+ ABSL_CONST_INIT static int num_cpus = 0;
362
+
363
+ // NumCPUs() may be called before main() and before malloc is properly
364
+ // initialized, therefore this must not allocate memory.
365
+ int NumCPUs() {
366
+ base_internal::LowLevelCallOnce(
367
+ &init_num_cpus_once, []() { num_cpus = GetNumCPUs(); });
368
+ return num_cpus;
369
+ }
370
+
371
+ // A default frequency of 0.0 might be dangerous if it is used in division.
372
+ ABSL_CONST_INIT static once_flag init_nominal_cpu_frequency_once;
373
+ ABSL_CONST_INIT static double nominal_cpu_frequency = 1.0;
374
+
375
+ // NominalCPUFrequency() may be called before main() and before malloc is
376
+ // properly initialized, therefore this must not allocate memory.
377
+ double NominalCPUFrequency() {
378
+ base_internal::LowLevelCallOnce(
379
+ &init_nominal_cpu_frequency_once,
380
+ []() { nominal_cpu_frequency = GetNominalCPUFrequency(); });
381
+ return nominal_cpu_frequency;
382
+ }
383
+
384
+ #if defined(_WIN32)
385
+
386
+ pid_t GetTID() {
387
+ return pid_t{GetCurrentThreadId()};
388
+ }
389
+
390
+ #elif defined(__linux__)
391
+
392
+ #ifndef SYS_gettid
393
+ #define SYS_gettid __NR_gettid
394
+ #endif
395
+
396
+ pid_t GetTID() {
397
+ return static_cast<pid_t>(syscall(SYS_gettid));
398
+ }
399
+
400
+ #elif defined(__akaros__)
401
+
402
+ pid_t GetTID() {
403
+ // Akaros has a concept of "vcore context", which is the state the program
404
+ // is forced into when we need to make a user-level scheduling decision, or
405
+ // run a signal handler. This is analogous to the interrupt context that a
406
+ // CPU might enter if it encounters some kind of exception.
407
+ //
408
+ // There is no current thread context in vcore context, but we need to give
409
+ // a reasonable answer if asked for a thread ID (e.g., in a signal handler).
410
+ // Thread 0 always exists, so if we are in vcore context, we return that.
411
+ //
412
+ // Otherwise, we know (since we are using pthreads) that the uthread struct
413
+ // current_uthread is pointing to is the first element of a
414
+ // struct pthread_tcb, so we extract and return the thread ID from that.
415
+ //
416
+ // TODO(dcross): Akaros anticipates moving the thread ID to the uthread
417
+ // structure at some point. We should modify this code to remove the cast
418
+ // when that happens.
419
+ if (in_vcore_context())
420
+ return 0;
421
+ return reinterpret_cast<struct pthread_tcb *>(current_uthread)->id;
422
+ }
423
+
424
+ #elif defined(__myriad2__)
425
+
426
+ pid_t GetTID() {
427
+ uint32_t tid;
428
+ rtems_task_ident(RTEMS_SELF, 0, &tid);
429
+ return tid;
430
+ }
431
+
432
+ #elif defined(__APPLE__)
433
+
434
+ pid_t GetTID() {
435
+ uint64_t tid;
436
+ // `nullptr` here implies this thread. This only fails if the specified
437
+ // thread is invalid or the pointer-to-tid is null, so we needn't worry about
438
+ // it.
439
+ pthread_threadid_np(nullptr, &tid);
440
+ return static_cast<pid_t>(tid);
441
+ }
442
+
443
+ #elif defined(__FreeBSD__)
444
+
445
+ pid_t GetTID() { return static_cast<pid_t>(pthread_getthreadid_np()); }
446
+
447
+ #elif defined(__OpenBSD__)
448
+
449
+ pid_t GetTID() { return getthrid(); }
450
+
451
+ #elif defined(__NetBSD__)
452
+
453
+ pid_t GetTID() { return static_cast<pid_t>(_lwp_self()); }
454
+
455
+ #elif defined(__native_client__)
456
+
457
+ pid_t GetTID() {
458
+ auto* thread = pthread_self();
459
+ static_assert(sizeof(pid_t) == sizeof(thread),
460
+ "In NaCL int expected to be the same size as a pointer");
461
+ return reinterpret_cast<pid_t>(thread);
462
+ }
463
+
464
+ #else
465
+
466
+ // Fallback implementation of `GetTID` using `pthread_self`.
467
+ pid_t GetTID() {
468
+ // `pthread_t` need not be arithmetic per POSIX; platforms where it isn't
469
+ // should be handled above.
470
+ return static_cast<pid_t>(pthread_self());
471
+ }
472
+
473
+ #endif
474
+
475
+ // GetCachedTID() caches the thread ID in thread-local storage (which is a
476
+ // userspace construct) to avoid unnecessary system calls. Without this caching,
477
+ // it can take roughly 98ns, while it takes roughly 1ns with this caching.
478
+ pid_t GetCachedTID() {
479
+ #ifdef ABSL_HAVE_THREAD_LOCAL
480
+ static thread_local pid_t thread_id = GetTID();
481
+ return thread_id;
482
+ #else
483
+ return GetTID();
484
+ #endif // ABSL_HAVE_THREAD_LOCAL
485
+ }
486
+
487
+ } // namespace base_internal
488
+ ABSL_NAMESPACE_END
489
+ } // namespace absl
weight/_dep/abseil-cpp/absl/base/internal/sysinfo.h ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+ // This file includes routines to find out characteristics
16
+ // of the machine a program is running on. It is undoubtedly
17
+ // system-dependent.
18
+
19
+ // Functions listed here that accept a pid_t as an argument act on the
20
+ // current process if the pid_t argument is 0
21
+ // All functions here are thread-hostile due to file caching unless
22
+ // commented otherwise.
23
+
24
+ #ifndef ABSL_BASE_INTERNAL_SYSINFO_H_
25
+ #define ABSL_BASE_INTERNAL_SYSINFO_H_
26
+
27
+ #ifndef _WIN32
28
+ #include <sys/types.h>
29
+ #endif
30
+
31
+ #include <cstdint>
32
+
33
+ #include "absl/base/config.h"
34
+ #include "absl/base/port.h"
35
+
36
+ namespace absl {
37
+ ABSL_NAMESPACE_BEGIN
38
+ namespace base_internal {
39
+
40
+ // Nominal core processor cycles per second of each processor. This is _not_
41
+ // necessarily the frequency of the CycleClock counter (see cycleclock.h)
42
+ // Thread-safe.
43
+ double NominalCPUFrequency();
44
+
45
+ // Number of logical processors (hyperthreads) in system. Thread-safe.
46
+ int NumCPUs();
47
+
48
+ // Return the thread id of the current thread, as told by the system.
49
+ // No two currently-live threads implemented by the OS shall have the same ID.
50
+ // Thread ids of exited threads may be reused. Multiple user-level threads
51
+ // may have the same thread ID if multiplexed on the same OS thread.
52
+ //
53
+ // On Linux, you may send a signal to the resulting ID with kill(). However,
54
+ // it is recommended for portability that you use pthread_kill() instead.
55
+ #ifdef _WIN32
56
+ // On Windows, process id and thread id are of the same type according to the
57
+ // return types of GetProcessId() and GetThreadId() are both DWORD, an unsigned
58
+ // 32-bit type.
59
+ using pid_t = uint32_t;
60
+ #endif
61
+ pid_t GetTID();
62
+
63
+ // Like GetTID(), but caches the result in thread-local storage in order
64
+ // to avoid unnecessary system calls. Note that there are some cases where
65
+ // one must call through to GetTID directly, which is why this exists as a
66
+ // separate function. For example, GetCachedTID() is not safe to call in
67
+ // an asynchronous signal-handling context nor right after a call to fork().
68
+ pid_t GetCachedTID();
69
+
70
+ } // namespace base_internal
71
+ ABSL_NAMESPACE_END
72
+ } // namespace absl
73
+
74
+ #endif // ABSL_BASE_INTERNAL_SYSINFO_H_
weight/_dep/abseil-cpp/absl/base/internal/sysinfo_test.cc ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include "absl/base/internal/sysinfo.h"
16
+
17
+ #ifndef _WIN32
18
+ #include <sys/types.h>
19
+ #include <unistd.h>
20
+ #endif
21
+
22
+ #include <thread> // NOLINT(build/c++11)
23
+ #include <unordered_set>
24
+ #include <vector>
25
+
26
+ #include "gtest/gtest.h"
27
+ #include "absl/synchronization/barrier.h"
28
+ #include "absl/synchronization/mutex.h"
29
+
30
+ namespace absl {
31
+ ABSL_NAMESPACE_BEGIN
32
+ namespace base_internal {
33
+ namespace {
34
+
35
+ TEST(SysinfoTest, NumCPUs) {
36
+ EXPECT_NE(NumCPUs(), 0)
37
+ << "NumCPUs() should not have the default value of 0";
38
+ }
39
+
40
+ TEST(SysinfoTest, GetTID) {
41
+ EXPECT_EQ(GetTID(), GetTID()); // Basic compile and equality test.
42
+ #ifdef __native_client__
43
+ // Native Client has a race condition bug that leads to memory
44
+ // exaustion when repeatedly creating and joining threads.
45
+ // https://bugs.chromium.org/p/nativeclient/issues/detail?id=1027
46
+ return;
47
+ #endif
48
+ // Test that TIDs are unique to each thread.
49
+ // Uses a few loops to exercise implementations that reallocate IDs.
50
+ for (int i = 0; i < 10; ++i) {
51
+ constexpr int kNumThreads = 10;
52
+ Barrier all_threads_done(kNumThreads);
53
+ std::vector<std::thread> threads;
54
+
55
+ Mutex mutex;
56
+ std::unordered_set<pid_t> tids;
57
+
58
+ for (int j = 0; j < kNumThreads; ++j) {
59
+ threads.push_back(std::thread([&]() {
60
+ pid_t id = GetTID();
61
+ {
62
+ MutexLock lock(&mutex);
63
+ ASSERT_TRUE(tids.find(id) == tids.end());
64
+ tids.insert(id);
65
+ }
66
+ // We can't simply join the threads here. The threads need to
67
+ // be alive otherwise the TID might have been reallocated to
68
+ // another live thread.
69
+ all_threads_done.Block();
70
+ }));
71
+ }
72
+ for (auto& thread : threads) {
73
+ thread.join();
74
+ }
75
+ }
76
+ }
77
+
78
+ #ifdef __linux__
79
+ TEST(SysinfoTest, LinuxGetTID) {
80
+ // On Linux, for the main thread, GetTID()==getpid() is guaranteed by the API.
81
+ EXPECT_EQ(GetTID(), getpid());
82
+ }
83
+ #endif
84
+
85
+ } // namespace
86
+ } // namespace base_internal
87
+ ABSL_NAMESPACE_END
88
+ } // namespace absl
weight/_dep/abseil-cpp/absl/base/internal/thread_identity.cc ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include "absl/base/internal/thread_identity.h"
16
+
17
+ #if !defined(_WIN32) || defined(__MINGW32__)
18
+ #include <pthread.h>
19
+ #ifndef __wasi__
20
+ // WASI does not provide this header, either way we disable use
21
+ // of signals with it below.
22
+ #include <signal.h>
23
+ #endif
24
+ #endif
25
+
26
+ #include <atomic>
27
+ #include <cassert>
28
+ #include <memory>
29
+
30
+ #include "absl/base/attributes.h"
31
+ #include "absl/base/call_once.h"
32
+ #include "absl/base/internal/raw_logging.h"
33
+ #include "absl/base/internal/spinlock.h"
34
+
35
+ namespace absl {
36
+ ABSL_NAMESPACE_BEGIN
37
+ namespace base_internal {
38
+
39
+ #if ABSL_THREAD_IDENTITY_MODE != ABSL_THREAD_IDENTITY_MODE_USE_CPP11
40
+ namespace {
41
+ // Used to co-ordinate one-time creation of our pthread_key
42
+ absl::once_flag init_thread_identity_key_once;
43
+ pthread_key_t thread_identity_pthread_key;
44
+ std::atomic<bool> pthread_key_initialized(false);
45
+
46
+ void AllocateThreadIdentityKey(ThreadIdentityReclaimerFunction reclaimer) {
47
+ pthread_key_create(&thread_identity_pthread_key, reclaimer);
48
+ pthread_key_initialized.store(true, std::memory_order_release);
49
+ }
50
+ } // namespace
51
+ #endif
52
+
53
+ #if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \
54
+ ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11
55
+ // The actual TLS storage for a thread's currently associated ThreadIdentity.
56
+ // This is referenced by inline accessors in the header.
57
+ // "protected" visibility ensures that if multiple instances of Abseil code
58
+ // exist within a process (via dlopen() or similar), references to
59
+ // thread_identity_ptr from each instance of the code will refer to
60
+ // *different* instances of this ptr.
61
+ // Apple platforms have the visibility attribute, but issue a compile warning
62
+ // that protected visibility is unsupported.
63
+ ABSL_CONST_INIT // Must come before __attribute__((visibility("protected")))
64
+ #if ABSL_HAVE_ATTRIBUTE(visibility) && !defined(__APPLE__)
65
+ __attribute__((visibility("protected")))
66
+ #endif // ABSL_HAVE_ATTRIBUTE(visibility) && !defined(__APPLE__)
67
+ #if ABSL_PER_THREAD_TLS
68
+ // Prefer __thread to thread_local as benchmarks indicate it is a bit
69
+ // faster.
70
+ ABSL_PER_THREAD_TLS_KEYWORD ThreadIdentity* thread_identity_ptr = nullptr;
71
+ #elif defined(ABSL_HAVE_THREAD_LOCAL)
72
+ thread_local ThreadIdentity* thread_identity_ptr = nullptr;
73
+ #endif // ABSL_PER_THREAD_TLS
74
+ #endif // TLS or CPP11
75
+
76
+ void SetCurrentThreadIdentity(ThreadIdentity* identity,
77
+ ThreadIdentityReclaimerFunction reclaimer) {
78
+ assert(CurrentThreadIdentityIfPresent() == nullptr);
79
+ // Associate our destructor.
80
+ // NOTE: This call to pthread_setspecific is currently the only immovable
81
+ // barrier to CurrentThreadIdentity() always being async signal safe.
82
+ #if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC
83
+ // NOTE: Not async-safe. But can be open-coded.
84
+ absl::call_once(init_thread_identity_key_once, AllocateThreadIdentityKey,
85
+ reclaimer);
86
+
87
+ #if defined(__wasi__) || defined(__EMSCRIPTEN__) || defined(__MINGW32__) || \
88
+ defined(__hexagon__)
89
+ // Emscripten, WASI and MinGW pthread implementations does not support
90
+ // signals. See
91
+ // https://kripken.github.io/emscripten-site/docs/porting/pthreads.html for
92
+ // more information.
93
+ pthread_setspecific(thread_identity_pthread_key,
94
+ reinterpret_cast<void*>(identity));
95
+ #else
96
+ // We must mask signals around the call to setspecific as with current glibc,
97
+ // a concurrent getspecific (needed for GetCurrentThreadIdentityIfPresent())
98
+ // may zero our value.
99
+ //
100
+ // While not officially async-signal safe, getspecific within a signal handler
101
+ // is otherwise OK.
102
+ sigset_t all_signals;
103
+ sigset_t curr_signals;
104
+ sigfillset(&all_signals);
105
+ pthread_sigmask(SIG_SETMASK, &all_signals, &curr_signals);
106
+ pthread_setspecific(thread_identity_pthread_key,
107
+ reinterpret_cast<void*>(identity));
108
+ pthread_sigmask(SIG_SETMASK, &curr_signals, nullptr);
109
+ #endif // !__EMSCRIPTEN__ && !__MINGW32__
110
+
111
+ #elif ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS
112
+ // NOTE: Not async-safe. But can be open-coded.
113
+ absl::call_once(init_thread_identity_key_once, AllocateThreadIdentityKey,
114
+ reclaimer);
115
+ pthread_setspecific(thread_identity_pthread_key,
116
+ reinterpret_cast<void*>(identity));
117
+ thread_identity_ptr = identity;
118
+ #elif ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11
119
+ thread_local std::unique_ptr<ThreadIdentity, ThreadIdentityReclaimerFunction>
120
+ holder(identity, reclaimer);
121
+ thread_identity_ptr = identity;
122
+ #else
123
+ #error Unimplemented ABSL_THREAD_IDENTITY_MODE
124
+ #endif
125
+ }
126
+
127
+ #if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \
128
+ ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11
129
+
130
+ // Please see the comment on `CurrentThreadIdentityIfPresent` in
131
+ // thread_identity.h. When we cannot expose thread_local variables in
132
+ // headers, we opt for the correct-but-slower option of not inlining this
133
+ // function.
134
+ #ifndef ABSL_INTERNAL_INLINE_CURRENT_THREAD_IDENTITY_IF_PRESENT
135
+ ThreadIdentity* CurrentThreadIdentityIfPresent() { return thread_identity_ptr; }
136
+ #endif
137
+ #endif
138
+
139
+ void ClearCurrentThreadIdentity() {
140
+ #if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \
141
+ ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11
142
+ thread_identity_ptr = nullptr;
143
+ #elif ABSL_THREAD_IDENTITY_MODE == \
144
+ ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC
145
+ // pthread_setspecific expected to clear value on destruction
146
+ assert(CurrentThreadIdentityIfPresent() == nullptr);
147
+ #endif
148
+ }
149
+
150
+ #if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC
151
+ ThreadIdentity* CurrentThreadIdentityIfPresent() {
152
+ bool initialized = pthread_key_initialized.load(std::memory_order_acquire);
153
+ if (!initialized) {
154
+ return nullptr;
155
+ }
156
+ return reinterpret_cast<ThreadIdentity*>(
157
+ pthread_getspecific(thread_identity_pthread_key));
158
+ }
159
+ #endif
160
+
161
+ } // namespace base_internal
162
+ ABSL_NAMESPACE_END
163
+ } // namespace absl
weight/_dep/abseil-cpp/absl/base/internal/thread_identity.h ADDED
@@ -0,0 +1,269 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+ // Each active thread has an ThreadIdentity that may represent the thread in
16
+ // various level interfaces. ThreadIdentity objects are never deallocated.
17
+ // When a thread terminates, its ThreadIdentity object may be reused for a
18
+ // thread created later.
19
+
20
+ #ifndef ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_
21
+ #define ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_
22
+
23
+ #ifndef _WIN32
24
+ #include <pthread.h>
25
+ // Defines __GOOGLE_GRTE_VERSION__ (via glibc-specific features.h) when
26
+ // supported.
27
+ #include <unistd.h>
28
+ #endif
29
+
30
+ #include <atomic>
31
+ #include <cstdint>
32
+
33
+ #include "absl/base/config.h"
34
+ #include "absl/base/internal/per_thread_tls.h"
35
+ #include "absl/base/optimization.h"
36
+
37
+ namespace absl {
38
+ ABSL_NAMESPACE_BEGIN
39
+
40
+ struct SynchLocksHeld;
41
+ struct SynchWaitParams;
42
+
43
+ namespace base_internal {
44
+
45
+ class SpinLock;
46
+ struct ThreadIdentity;
47
+
48
+ // Used by the implementation of absl::Mutex and absl::CondVar.
49
+ struct PerThreadSynch {
50
+ // The internal representation of absl::Mutex and absl::CondVar rely
51
+ // on the alignment of PerThreadSynch. Both store the address of the
52
+ // PerThreadSynch in the high-order bits of their internal state,
53
+ // which means the low kLowZeroBits of the address of PerThreadSynch
54
+ // must be zero.
55
+ static constexpr int kLowZeroBits = 8;
56
+ static constexpr int kAlignment = 1 << kLowZeroBits;
57
+
58
+ // Returns the associated ThreadIdentity.
59
+ // This can be implemented as a cast because we guarantee
60
+ // PerThreadSynch is the first element of ThreadIdentity.
61
+ ThreadIdentity* thread_identity() {
62
+ return reinterpret_cast<ThreadIdentity*>(this);
63
+ }
64
+
65
+ PerThreadSynch* next; // Circular waiter queue; initialized to 0.
66
+ PerThreadSynch* skip; // If non-zero, all entries in Mutex queue
67
+ // up to and including "skip" have same
68
+ // condition as this, and will be woken later
69
+ bool may_skip; // if false while on mutex queue, a mutex unlocker
70
+ // is using this PerThreadSynch as a terminator. Its
71
+ // skip field must not be filled in because the loop
72
+ // might then skip over the terminator.
73
+ bool wake; // This thread is to be woken from a Mutex.
74
+ // If "x" is on a waiter list for a mutex, "x->cond_waiter" is true iff the
75
+ // waiter is waiting on the mutex as part of a CV Wait or Mutex Await.
76
+ //
77
+ // The value of "x->cond_waiter" is meaningless if "x" is not on a
78
+ // Mutex waiter list.
79
+ bool cond_waiter;
80
+ bool maybe_unlocking; // Valid at head of Mutex waiter queue;
81
+ // true if UnlockSlow could be searching
82
+ // for a waiter to wake. Used for an optimization
83
+ // in Enqueue(). true is always a valid value.
84
+ // Can be reset to false when the unlocker or any
85
+ // writer releases the lock, or a reader fully
86
+ // releases the lock. It may not be set to false
87
+ // by a reader that decrements the count to
88
+ // non-zero. protected by mutex spinlock
89
+ bool suppress_fatal_errors; // If true, try to proceed even in the face
90
+ // of broken invariants. This is used within
91
+ // fatal signal handlers to improve the
92
+ // chances of debug logging information being
93
+ // output successfully.
94
+ int priority; // Priority of thread (updated every so often).
95
+
96
+ // State values:
97
+ // kAvailable: This PerThreadSynch is available.
98
+ // kQueued: This PerThreadSynch is unavailable, it's currently queued on a
99
+ // Mutex or CondVar waistlist.
100
+ //
101
+ // Transitions from kQueued to kAvailable require a release
102
+ // barrier. This is needed as a waiter may use "state" to
103
+ // independently observe that it's no longer queued.
104
+ //
105
+ // Transitions from kAvailable to kQueued require no barrier, they
106
+ // are externally ordered by the Mutex.
107
+ enum State { kAvailable, kQueued };
108
+ std::atomic<State> state;
109
+
110
+ // The wait parameters of the current wait. waitp is null if the
111
+ // thread is not waiting. Transitions from null to non-null must
112
+ // occur before the enqueue commit point (state = kQueued in
113
+ // Enqueue() and CondVarEnqueue()). Transitions from non-null to
114
+ // null must occur after the wait is finished (state = kAvailable in
115
+ // Mutex::Block() and CondVar::WaitCommon()). This field may be
116
+ // changed only by the thread that describes this PerThreadSynch. A
117
+ // special case is Fer(), which calls Enqueue() on another thread,
118
+ // but with an identical SynchWaitParams pointer, thus leaving the
119
+ // pointer unchanged.
120
+ SynchWaitParams* waitp;
121
+
122
+ intptr_t readers; // Number of readers in mutex.
123
+
124
+ // When priority will next be read (cycles).
125
+ int64_t next_priority_read_cycles;
126
+
127
+ // Locks held; used during deadlock detection.
128
+ // Allocated in Synch_GetAllLocks() and freed in ReclaimThreadIdentity().
129
+ SynchLocksHeld* all_locks;
130
+ };
131
+
132
+ // The instances of this class are allocated in NewThreadIdentity() with an
133
+ // alignment of PerThreadSynch::kAlignment.
134
+ //
135
+ // NOTE: The layout of fields in this structure is critical, please do not
136
+ // add, remove, or modify the field placements without fully auditing the
137
+ // layout.
138
+ struct ThreadIdentity {
139
+ // Must be the first member. The Mutex implementation requires that
140
+ // the PerThreadSynch object associated with each thread is
141
+ // PerThreadSynch::kAlignment aligned. We provide this alignment on
142
+ // ThreadIdentity itself.
143
+ PerThreadSynch per_thread_synch;
144
+
145
+ // Private: Reserved for absl::synchronization_internal::Waiter.
146
+ struct WaiterState {
147
+ alignas(void*) char data[256];
148
+ } waiter_state;
149
+
150
+ // Used by PerThreadSem::{Get,Set}ThreadBlockedCounter().
151
+ std::atomic<int>* blocked_count_ptr;
152
+
153
+ // The following variables are mostly read/written just by the
154
+ // thread itself. The only exception is that these are read by
155
+ // a ticker thread as a hint.
156
+ std::atomic<int> ticker; // Tick counter, incremented once per second.
157
+ std::atomic<int> wait_start; // Ticker value when thread started waiting.
158
+ std::atomic<bool> is_idle; // Has thread become idle yet?
159
+
160
+ ThreadIdentity* next;
161
+ };
162
+
163
+ // Returns the ThreadIdentity object representing the calling thread; guaranteed
164
+ // to be unique for its lifetime. The returned object will remain valid for the
165
+ // program's lifetime; although it may be re-assigned to a subsequent thread.
166
+ // If one does not exist, return nullptr instead.
167
+ //
168
+ // Does not malloc(*), and is async-signal safe.
169
+ // [*] Technically pthread_setspecific() does malloc on first use; however this
170
+ // is handled internally within tcmalloc's initialization already. Note that
171
+ // darwin does *not* use tcmalloc, so this can catch you if using MallocHooks
172
+ // on Apple platforms. Whatever function is calling your MallocHooks will need
173
+ // to watch for recursion on Apple platforms.
174
+ //
175
+ // New ThreadIdentity objects can be constructed and associated with a thread
176
+ // by calling GetOrCreateCurrentThreadIdentity() in per-thread-sem.h.
177
+ ThreadIdentity* CurrentThreadIdentityIfPresent();
178
+
179
+ using ThreadIdentityReclaimerFunction = void (*)(void*);
180
+
181
+ // Sets the current thread identity to the given value. 'reclaimer' is a
182
+ // pointer to the global function for cleaning up instances on thread
183
+ // destruction.
184
+ void SetCurrentThreadIdentity(ThreadIdentity* identity,
185
+ ThreadIdentityReclaimerFunction reclaimer);
186
+
187
+ // Removes the currently associated ThreadIdentity from the running thread.
188
+ // This must be called from inside the ThreadIdentityReclaimerFunction, and only
189
+ // from that function.
190
+ void ClearCurrentThreadIdentity();
191
+
192
+ // May be chosen at compile time via: -DABSL_FORCE_THREAD_IDENTITY_MODE=<mode
193
+ // index>
194
+ #ifdef ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC
195
+ #error ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC cannot be directly set
196
+ #else
197
+ #define ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC 0
198
+ #endif
199
+
200
+ #ifdef ABSL_THREAD_IDENTITY_MODE_USE_TLS
201
+ #error ABSL_THREAD_IDENTITY_MODE_USE_TLS cannot be directly set
202
+ #else
203
+ #define ABSL_THREAD_IDENTITY_MODE_USE_TLS 1
204
+ #endif
205
+
206
+ #ifdef ABSL_THREAD_IDENTITY_MODE_USE_CPP11
207
+ #error ABSL_THREAD_IDENTITY_MODE_USE_CPP11 cannot be directly set
208
+ #else
209
+ #define ABSL_THREAD_IDENTITY_MODE_USE_CPP11 2
210
+ #endif
211
+
212
+ #ifdef ABSL_THREAD_IDENTITY_MODE
213
+ #error ABSL_THREAD_IDENTITY_MODE cannot be directly set
214
+ #elif defined(ABSL_FORCE_THREAD_IDENTITY_MODE)
215
+ #define ABSL_THREAD_IDENTITY_MODE ABSL_FORCE_THREAD_IDENTITY_MODE
216
+ #elif defined(_WIN32) && !defined(__MINGW32__)
217
+ #define ABSL_THREAD_IDENTITY_MODE ABSL_THREAD_IDENTITY_MODE_USE_CPP11
218
+ #elif defined(__APPLE__) && defined(ABSL_HAVE_THREAD_LOCAL)
219
+ #define ABSL_THREAD_IDENTITY_MODE ABSL_THREAD_IDENTITY_MODE_USE_CPP11
220
+ #elif ABSL_PER_THREAD_TLS && defined(__GOOGLE_GRTE_VERSION__) && \
221
+ (__GOOGLE_GRTE_VERSION__ >= 20140228L)
222
+ // Support for async-safe TLS was specifically added in GRTEv4. It's not
223
+ // present in the upstream eglibc.
224
+ // Note: Current default for production systems.
225
+ #define ABSL_THREAD_IDENTITY_MODE ABSL_THREAD_IDENTITY_MODE_USE_TLS
226
+ #else
227
+ #define ABSL_THREAD_IDENTITY_MODE \
228
+ ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC
229
+ #endif
230
+
231
+ #if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \
232
+ ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11
233
+
234
+ #if ABSL_PER_THREAD_TLS
235
+ ABSL_CONST_INIT extern ABSL_PER_THREAD_TLS_KEYWORD ThreadIdentity*
236
+ thread_identity_ptr;
237
+ #elif defined(ABSL_HAVE_THREAD_LOCAL)
238
+ ABSL_CONST_INIT extern thread_local ThreadIdentity* thread_identity_ptr;
239
+ #else
240
+ #error Thread-local storage not detected on this platform
241
+ #endif
242
+
243
+ // thread_local variables cannot be in headers exposed by DLLs or in certain
244
+ // build configurations on Apple platforms. However, it is important for
245
+ // performance reasons in general that `CurrentThreadIdentityIfPresent` be
246
+ // inlined. In the other cases we opt to have the function not be inlined. Note
247
+ // that `CurrentThreadIdentityIfPresent` is declared above so we can exclude
248
+ // this entire inline definition.
249
+ #if !defined(__APPLE__) && !defined(ABSL_BUILD_DLL) && \
250
+ !defined(ABSL_CONSUME_DLL)
251
+ #define ABSL_INTERNAL_INLINE_CURRENT_THREAD_IDENTITY_IF_PRESENT 1
252
+ #endif
253
+
254
+ #ifdef ABSL_INTERNAL_INLINE_CURRENT_THREAD_IDENTITY_IF_PRESENT
255
+ inline ThreadIdentity* CurrentThreadIdentityIfPresent() {
256
+ return thread_identity_ptr;
257
+ }
258
+ #endif
259
+
260
+ #elif ABSL_THREAD_IDENTITY_MODE != \
261
+ ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC
262
+ #error Unknown ABSL_THREAD_IDENTITY_MODE
263
+ #endif
264
+
265
+ } // namespace base_internal
266
+ ABSL_NAMESPACE_END
267
+ } // namespace absl
268
+
269
+ #endif // ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_
weight/_dep/abseil-cpp/absl/base/internal/thread_identity_benchmark.cc ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include "benchmark/benchmark.h"
16
+ #include "absl/base/internal/thread_identity.h"
17
+ #include "absl/synchronization/internal/create_thread_identity.h"
18
+ #include "absl/synchronization/internal/per_thread_sem.h"
19
+
20
+ namespace {
21
+
22
+ void BM_SafeCurrentThreadIdentity(benchmark::State& state) {
23
+ for (auto _ : state) {
24
+ benchmark::DoNotOptimize(
25
+ absl::synchronization_internal::GetOrCreateCurrentThreadIdentity());
26
+ }
27
+ }
28
+ BENCHMARK(BM_SafeCurrentThreadIdentity);
29
+
30
+ void BM_UnsafeCurrentThreadIdentity(benchmark::State& state) {
31
+ for (auto _ : state) {
32
+ benchmark::DoNotOptimize(
33
+ absl::base_internal::CurrentThreadIdentityIfPresent());
34
+ }
35
+ }
36
+ BENCHMARK(BM_UnsafeCurrentThreadIdentity);
37
+
38
+ } // namespace
weight/_dep/abseil-cpp/absl/base/internal/thread_identity_test.cc ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include "absl/base/internal/thread_identity.h"
16
+
17
+ #include <thread> // NOLINT(build/c++11)
18
+ #include <vector>
19
+
20
+ #include "gtest/gtest.h"
21
+ #include "absl/base/attributes.h"
22
+ #include "absl/base/internal/spinlock.h"
23
+ #include "absl/base/macros.h"
24
+ #include "absl/base/thread_annotations.h"
25
+ #include "absl/synchronization/internal/per_thread_sem.h"
26
+ #include "absl/synchronization/mutex.h"
27
+
28
+ namespace absl {
29
+ ABSL_NAMESPACE_BEGIN
30
+ namespace base_internal {
31
+ namespace {
32
+
33
+ ABSL_CONST_INIT static absl::base_internal::SpinLock map_lock(
34
+ absl::kConstInit, base_internal::SCHEDULE_KERNEL_ONLY);
35
+ ABSL_CONST_INIT static int num_identities_reused ABSL_GUARDED_BY(map_lock);
36
+
37
+ static const void* const kCheckNoIdentity = reinterpret_cast<void*>(1);
38
+
39
+ static void TestThreadIdentityCurrent(const void* assert_no_identity) {
40
+ ThreadIdentity* identity;
41
+
42
+ // We have to test this conditionally, because if the test framework relies
43
+ // on Abseil, then some previous action may have already allocated an
44
+ // identity.
45
+ if (assert_no_identity == kCheckNoIdentity) {
46
+ identity = CurrentThreadIdentityIfPresent();
47
+ EXPECT_TRUE(identity == nullptr);
48
+ }
49
+
50
+ identity = synchronization_internal::GetOrCreateCurrentThreadIdentity();
51
+ EXPECT_TRUE(identity != nullptr);
52
+ ThreadIdentity* identity_no_init;
53
+ identity_no_init = CurrentThreadIdentityIfPresent();
54
+ EXPECT_TRUE(identity == identity_no_init);
55
+
56
+ // Check that per_thread_synch is correctly aligned.
57
+ EXPECT_EQ(0, reinterpret_cast<intptr_t>(&identity->per_thread_synch) %
58
+ PerThreadSynch::kAlignment);
59
+ EXPECT_EQ(identity, identity->per_thread_synch.thread_identity());
60
+
61
+ absl::base_internal::SpinLockHolder l(&map_lock);
62
+ num_identities_reused++;
63
+ }
64
+
65
+ TEST(ThreadIdentityTest, BasicIdentityWorks) {
66
+ // This tests for the main() thread.
67
+ TestThreadIdentityCurrent(nullptr);
68
+ }
69
+
70
+ TEST(ThreadIdentityTest, BasicIdentityWorksThreaded) {
71
+ // Now try the same basic test with multiple threads being created and
72
+ // destroyed. This makes sure that:
73
+ // - New threads are created without a ThreadIdentity.
74
+ // - We re-allocate ThreadIdentity objects from the free-list.
75
+ // - If a thread implementation chooses to recycle threads, that
76
+ // correct re-initialization occurs.
77
+ static const int kNumLoops = 3;
78
+ static const int kNumThreads = 32;
79
+ for (int iter = 0; iter < kNumLoops; iter++) {
80
+ std::vector<std::thread> threads;
81
+ for (int i = 0; i < kNumThreads; ++i) {
82
+ threads.push_back(
83
+ std::thread(TestThreadIdentityCurrent, kCheckNoIdentity));
84
+ }
85
+ for (auto& thread : threads) {
86
+ thread.join();
87
+ }
88
+ }
89
+
90
+ // We should have recycled ThreadIdentity objects above; while (external)
91
+ // library threads allocating their own identities may preclude some
92
+ // reuse, we should have sufficient repetitions to exclude this.
93
+ absl::base_internal::SpinLockHolder l(&map_lock);
94
+ EXPECT_LT(kNumThreads, num_identities_reused);
95
+ }
96
+
97
+ TEST(ThreadIdentityTest, ReusedThreadIdentityMutexTest) {
98
+ // This test repeatedly creates and joins a series of threads, each of
99
+ // which acquires and releases shared Mutex locks. This verifies
100
+ // Mutex operations work correctly under a reused
101
+ // ThreadIdentity. Note that the most likely failure mode of this
102
+ // test is a crash or deadlock.
103
+ static const int kNumLoops = 10;
104
+ static const int kNumThreads = 12;
105
+ static const int kNumMutexes = 3;
106
+ static const int kNumLockLoops = 5;
107
+
108
+ Mutex mutexes[kNumMutexes];
109
+ for (int iter = 0; iter < kNumLoops; ++iter) {
110
+ std::vector<std::thread> threads;
111
+ for (int thread = 0; thread < kNumThreads; ++thread) {
112
+ threads.push_back(std::thread([&]() {
113
+ for (int l = 0; l < kNumLockLoops; ++l) {
114
+ for (int m = 0; m < kNumMutexes; ++m) {
115
+ MutexLock lock(&mutexes[m]);
116
+ }
117
+ }
118
+ }));
119
+ }
120
+ for (auto& thread : threads) {
121
+ thread.join();
122
+ }
123
+ }
124
+ }
125
+
126
+ } // namespace
127
+ } // namespace base_internal
128
+ ABSL_NAMESPACE_END
129
+ } // namespace absl
weight/_dep/abseil-cpp/absl/base/internal/throw_delegate.cc ADDED
@@ -0,0 +1,203 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include "absl/base/internal/throw_delegate.h"
16
+
17
+ #include <cstdlib>
18
+ #include <functional>
19
+ #include <new>
20
+ #include <stdexcept>
21
+
22
+ #include "absl/base/config.h"
23
+ #include "absl/base/internal/raw_logging.h"
24
+
25
+ namespace absl {
26
+ ABSL_NAMESPACE_BEGIN
27
+ namespace base_internal {
28
+
29
+ // NOTE: The exception types, like `std::logic_error`, do not exist on all
30
+ // platforms. (For example, the Android NDK does not have them.)
31
+ // Therefore, their use must be guarded by `#ifdef` or equivalent.
32
+
33
+ void ThrowStdLogicError(const std::string& what_arg) {
34
+ #ifdef ABSL_HAVE_EXCEPTIONS
35
+ throw std::logic_error(what_arg);
36
+ #else
37
+ ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
38
+ std::abort();
39
+ #endif
40
+ }
41
+ void ThrowStdLogicError(const char* what_arg) {
42
+ #ifdef ABSL_HAVE_EXCEPTIONS
43
+ throw std::logic_error(what_arg);
44
+ #else
45
+ ABSL_RAW_LOG(FATAL, "%s", what_arg);
46
+ std::abort();
47
+ #endif
48
+ }
49
+ void ThrowStdInvalidArgument(const std::string& what_arg) {
50
+ #ifdef ABSL_HAVE_EXCEPTIONS
51
+ throw std::invalid_argument(what_arg);
52
+ #else
53
+ ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
54
+ std::abort();
55
+ #endif
56
+ }
57
+ void ThrowStdInvalidArgument(const char* what_arg) {
58
+ #ifdef ABSL_HAVE_EXCEPTIONS
59
+ throw std::invalid_argument(what_arg);
60
+ #else
61
+ ABSL_RAW_LOG(FATAL, "%s", what_arg);
62
+ std::abort();
63
+ #endif
64
+ }
65
+
66
+ void ThrowStdDomainError(const std::string& what_arg) {
67
+ #ifdef ABSL_HAVE_EXCEPTIONS
68
+ throw std::domain_error(what_arg);
69
+ #else
70
+ ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
71
+ std::abort();
72
+ #endif
73
+ }
74
+ void ThrowStdDomainError(const char* what_arg) {
75
+ #ifdef ABSL_HAVE_EXCEPTIONS
76
+ throw std::domain_error(what_arg);
77
+ #else
78
+ ABSL_RAW_LOG(FATAL, "%s", what_arg);
79
+ std::abort();
80
+ #endif
81
+ }
82
+
83
+ void ThrowStdLengthError(const std::string& what_arg) {
84
+ #ifdef ABSL_HAVE_EXCEPTIONS
85
+ throw std::length_error(what_arg);
86
+ #else
87
+ ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
88
+ std::abort();
89
+ #endif
90
+ }
91
+ void ThrowStdLengthError(const char* what_arg) {
92
+ #ifdef ABSL_HAVE_EXCEPTIONS
93
+ throw std::length_error(what_arg);
94
+ #else
95
+ ABSL_RAW_LOG(FATAL, "%s", what_arg);
96
+ std::abort();
97
+ #endif
98
+ }
99
+
100
+ void ThrowStdOutOfRange(const std::string& what_arg) {
101
+ #ifdef ABSL_HAVE_EXCEPTIONS
102
+ throw std::out_of_range(what_arg);
103
+ #else
104
+ ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
105
+ std::abort();
106
+ #endif
107
+ }
108
+ void ThrowStdOutOfRange(const char* what_arg) {
109
+ #ifdef ABSL_HAVE_EXCEPTIONS
110
+ throw std::out_of_range(what_arg);
111
+ #else
112
+ ABSL_RAW_LOG(FATAL, "%s", what_arg);
113
+ std::abort();
114
+ #endif
115
+ }
116
+
117
+ void ThrowStdRuntimeError(const std::string& what_arg) {
118
+ #ifdef ABSL_HAVE_EXCEPTIONS
119
+ throw std::runtime_error(what_arg);
120
+ #else
121
+ ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
122
+ std::abort();
123
+ #endif
124
+ }
125
+ void ThrowStdRuntimeError(const char* what_arg) {
126
+ #ifdef ABSL_HAVE_EXCEPTIONS
127
+ throw std::runtime_error(what_arg);
128
+ #else
129
+ ABSL_RAW_LOG(FATAL, "%s", what_arg);
130
+ std::abort();
131
+ #endif
132
+ }
133
+
134
+ void ThrowStdRangeError(const std::string& what_arg) {
135
+ #ifdef ABSL_HAVE_EXCEPTIONS
136
+ throw std::range_error(what_arg);
137
+ #else
138
+ ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
139
+ std::abort();
140
+ #endif
141
+ }
142
+ void ThrowStdRangeError(const char* what_arg) {
143
+ #ifdef ABSL_HAVE_EXCEPTIONS
144
+ throw std::range_error(what_arg);
145
+ #else
146
+ ABSL_RAW_LOG(FATAL, "%s", what_arg);
147
+ std::abort();
148
+ #endif
149
+ }
150
+
151
+ void ThrowStdOverflowError(const std::string& what_arg) {
152
+ #ifdef ABSL_HAVE_EXCEPTIONS
153
+ throw std::overflow_error(what_arg);
154
+ #else
155
+ ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
156
+ std::abort();
157
+ #endif
158
+ }
159
+ void ThrowStdOverflowError(const char* what_arg) {
160
+ #ifdef ABSL_HAVE_EXCEPTIONS
161
+ throw std::overflow_error(what_arg);
162
+ #else
163
+ ABSL_RAW_LOG(FATAL, "%s", what_arg);
164
+ std::abort();
165
+ #endif
166
+ }
167
+
168
+ void ThrowStdUnderflowError(const std::string& what_arg) {
169
+ #ifdef ABSL_HAVE_EXCEPTIONS
170
+ throw std::underflow_error(what_arg);
171
+ #else
172
+ ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
173
+ std::abort();
174
+ #endif
175
+ }
176
+ void ThrowStdUnderflowError(const char* what_arg) {
177
+ #ifdef ABSL_HAVE_EXCEPTIONS
178
+ throw std::underflow_error(what_arg);
179
+ #else
180
+ ABSL_RAW_LOG(FATAL, "%s", what_arg);
181
+ std::abort();
182
+ #endif
183
+ }
184
+
185
+ void ThrowStdBadFunctionCall() {
186
+ #ifdef ABSL_HAVE_EXCEPTIONS
187
+ throw std::bad_function_call();
188
+ #else
189
+ std::abort();
190
+ #endif
191
+ }
192
+
193
+ void ThrowStdBadAlloc() {
194
+ #ifdef ABSL_HAVE_EXCEPTIONS
195
+ throw std::bad_alloc();
196
+ #else
197
+ std::abort();
198
+ #endif
199
+ }
200
+
201
+ } // namespace base_internal
202
+ ABSL_NAMESPACE_END
203
+ } // namespace absl
weight/_dep/abseil-cpp/absl/base/internal/throw_delegate.h ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //
2
+ // Copyright 2017 The Abseil Authors.
3
+ //
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // you may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ //
8
+ // https://www.apache.org/licenses/LICENSE-2.0
9
+ //
10
+ // Unless required by applicable law or agreed to in writing, software
11
+ // distributed under the License is distributed on an "AS IS" BASIS,
12
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ // See the License for the specific language governing permissions and
14
+ // limitations under the License.
15
+ //
16
+
17
+ #ifndef ABSL_BASE_INTERNAL_THROW_DELEGATE_H_
18
+ #define ABSL_BASE_INTERNAL_THROW_DELEGATE_H_
19
+
20
+ #include <string>
21
+
22
+ #include "absl/base/config.h"
23
+
24
+ namespace absl {
25
+ ABSL_NAMESPACE_BEGIN
26
+ namespace base_internal {
27
+
28
+ // Helper functions that allow throwing exceptions consistently from anywhere.
29
+ // The main use case is for header-based libraries (eg templates), as they will
30
+ // be built by many different targets with their own compiler options.
31
+ // In particular, this will allow a safe way to throw exceptions even if the
32
+ // caller is compiled with -fno-exceptions. This is intended for implementing
33
+ // things like map<>::at(), which the standard documents as throwing an
34
+ // exception on error.
35
+ //
36
+ // Using other techniques like #if tricks could lead to ODR violations.
37
+ //
38
+ // You shouldn't use it unless you're writing code that you know will be built
39
+ // both with and without exceptions and you need to conform to an interface
40
+ // that uses exceptions.
41
+
42
+ [[noreturn]] void ThrowStdLogicError(const std::string& what_arg);
43
+ [[noreturn]] void ThrowStdLogicError(const char* what_arg);
44
+ [[noreturn]] void ThrowStdInvalidArgument(const std::string& what_arg);
45
+ [[noreturn]] void ThrowStdInvalidArgument(const char* what_arg);
46
+ [[noreturn]] void ThrowStdDomainError(const std::string& what_arg);
47
+ [[noreturn]] void ThrowStdDomainError(const char* what_arg);
48
+ [[noreturn]] void ThrowStdLengthError(const std::string& what_arg);
49
+ [[noreturn]] void ThrowStdLengthError(const char* what_arg);
50
+ [[noreturn]] void ThrowStdOutOfRange(const std::string& what_arg);
51
+ [[noreturn]] void ThrowStdOutOfRange(const char* what_arg);
52
+ [[noreturn]] void ThrowStdRuntimeError(const std::string& what_arg);
53
+ [[noreturn]] void ThrowStdRuntimeError(const char* what_arg);
54
+ [[noreturn]] void ThrowStdRangeError(const std::string& what_arg);
55
+ [[noreturn]] void ThrowStdRangeError(const char* what_arg);
56
+ [[noreturn]] void ThrowStdOverflowError(const std::string& what_arg);
57
+ [[noreturn]] void ThrowStdOverflowError(const char* what_arg);
58
+ [[noreturn]] void ThrowStdUnderflowError(const std::string& what_arg);
59
+ [[noreturn]] void ThrowStdUnderflowError(const char* what_arg);
60
+
61
+ [[noreturn]] void ThrowStdBadFunctionCall();
62
+ [[noreturn]] void ThrowStdBadAlloc();
63
+
64
+ // ThrowStdBadArrayNewLength() cannot be consistently supported because
65
+ // std::bad_array_new_length is missing in libstdc++ until 4.9.0.
66
+ // https://gcc.gnu.org/onlinedocs/gcc-4.8.3/libstdc++/api/a01379_source.html
67
+ // https://gcc.gnu.org/onlinedocs/gcc-4.9.0/libstdc++/api/a01327_source.html
68
+ // libcxx (as of 3.2) and msvc (as of 2015) both have it.
69
+ // [[noreturn]] void ThrowStdBadArrayNewLength();
70
+
71
+ } // namespace base_internal
72
+ ABSL_NAMESPACE_END
73
+ } // namespace absl
74
+
75
+ #endif // ABSL_BASE_INTERNAL_THROW_DELEGATE_H_
weight/_dep/abseil-cpp/absl/base/internal/tsan_mutex_interface.h ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+ // This file is intended solely for spinlock.h.
16
+ // It provides ThreadSanitizer annotations for custom mutexes.
17
+ // See <sanitizer/tsan_interface.h> for meaning of these annotations.
18
+
19
+ #ifndef ABSL_BASE_INTERNAL_TSAN_MUTEX_INTERFACE_H_
20
+ #define ABSL_BASE_INTERNAL_TSAN_MUTEX_INTERFACE_H_
21
+
22
+ #include "absl/base/config.h"
23
+
24
+ // ABSL_INTERNAL_HAVE_TSAN_INTERFACE
25
+ // Macro intended only for internal use.
26
+ //
27
+ // Checks whether LLVM Thread Sanitizer interfaces are available.
28
+ // First made available in LLVM 5.0 (Sep 2017).
29
+ #ifdef ABSL_INTERNAL_HAVE_TSAN_INTERFACE
30
+ #error "ABSL_INTERNAL_HAVE_TSAN_INTERFACE cannot be directly set."
31
+ #endif
32
+
33
+ #if defined(ABSL_HAVE_THREAD_SANITIZER) && defined(__has_include)
34
+ #if __has_include(<sanitizer/tsan_interface.h>)
35
+ #define ABSL_INTERNAL_HAVE_TSAN_INTERFACE 1
36
+ #endif
37
+ #endif
38
+
39
+ #ifdef ABSL_INTERNAL_HAVE_TSAN_INTERFACE
40
+ #include <sanitizer/tsan_interface.h>
41
+
42
+ #define ABSL_TSAN_MUTEX_CREATE __tsan_mutex_create
43
+ #define ABSL_TSAN_MUTEX_DESTROY __tsan_mutex_destroy
44
+ #define ABSL_TSAN_MUTEX_PRE_LOCK __tsan_mutex_pre_lock
45
+ #define ABSL_TSAN_MUTEX_POST_LOCK __tsan_mutex_post_lock
46
+ #define ABSL_TSAN_MUTEX_PRE_UNLOCK __tsan_mutex_pre_unlock
47
+ #define ABSL_TSAN_MUTEX_POST_UNLOCK __tsan_mutex_post_unlock
48
+ #define ABSL_TSAN_MUTEX_PRE_SIGNAL __tsan_mutex_pre_signal
49
+ #define ABSL_TSAN_MUTEX_POST_SIGNAL __tsan_mutex_post_signal
50
+ #define ABSL_TSAN_MUTEX_PRE_DIVERT __tsan_mutex_pre_divert
51
+ #define ABSL_TSAN_MUTEX_POST_DIVERT __tsan_mutex_post_divert
52
+
53
+ #else
54
+
55
+ #define ABSL_TSAN_MUTEX_CREATE(...)
56
+ #define ABSL_TSAN_MUTEX_DESTROY(...)
57
+ #define ABSL_TSAN_MUTEX_PRE_LOCK(...)
58
+ #define ABSL_TSAN_MUTEX_POST_LOCK(...)
59
+ #define ABSL_TSAN_MUTEX_PRE_UNLOCK(...)
60
+ #define ABSL_TSAN_MUTEX_POST_UNLOCK(...)
61
+ #define ABSL_TSAN_MUTEX_PRE_SIGNAL(...)
62
+ #define ABSL_TSAN_MUTEX_POST_SIGNAL(...)
63
+ #define ABSL_TSAN_MUTEX_PRE_DIVERT(...)
64
+ #define ABSL_TSAN_MUTEX_POST_DIVERT(...)
65
+
66
+ #endif
67
+
68
+ #endif // ABSL_BASE_INTERNAL_TSAN_MUTEX_INTERFACE_H_
weight/_dep/abseil-cpp/absl/base/internal/unaligned_access.h ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //
2
+ // Copyright 2017 The Abseil Authors.
3
+ //
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // you may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ //
8
+ // https://www.apache.org/licenses/LICENSE-2.0
9
+ //
10
+ // Unless required by applicable law or agreed to in writing, software
11
+ // distributed under the License is distributed on an "AS IS" BASIS,
12
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ // See the License for the specific language governing permissions and
14
+ // limitations under the License.
15
+ //
16
+
17
+ #ifndef ABSL_BASE_INTERNAL_UNALIGNED_ACCESS_H_
18
+ #define ABSL_BASE_INTERNAL_UNALIGNED_ACCESS_H_
19
+
20
+ #include <string.h>
21
+
22
+ #include <cstdint>
23
+
24
+ #include "absl/base/attributes.h"
25
+ #include "absl/base/config.h"
26
+ #include "absl/base/nullability.h"
27
+
28
+ // unaligned APIs
29
+
30
+ // Portable handling of unaligned loads, stores, and copies.
31
+
32
+ // The unaligned API is C++ only. The declarations use C++ features
33
+ // (namespaces, inline) which are absent or incompatible in C.
34
+ #if defined(__cplusplus)
35
+ namespace absl {
36
+ ABSL_NAMESPACE_BEGIN
37
+ namespace base_internal {
38
+
39
+ inline uint16_t UnalignedLoad16(absl::Nonnull<const void *> p) {
40
+ uint16_t t;
41
+ memcpy(&t, p, sizeof t);
42
+ return t;
43
+ }
44
+
45
+ inline uint32_t UnalignedLoad32(absl::Nonnull<const void *> p) {
46
+ uint32_t t;
47
+ memcpy(&t, p, sizeof t);
48
+ return t;
49
+ }
50
+
51
+ inline uint64_t UnalignedLoad64(absl::Nonnull<const void *> p) {
52
+ uint64_t t;
53
+ memcpy(&t, p, sizeof t);
54
+ return t;
55
+ }
56
+
57
+ inline void UnalignedStore16(absl::Nonnull<void *> p, uint16_t v) {
58
+ memcpy(p, &v, sizeof v);
59
+ }
60
+
61
+ inline void UnalignedStore32(absl::Nonnull<void *> p, uint32_t v) {
62
+ memcpy(p, &v, sizeof v);
63
+ }
64
+
65
+ inline void UnalignedStore64(absl::Nonnull<void *> p, uint64_t v) {
66
+ memcpy(p, &v, sizeof v);
67
+ }
68
+
69
+ } // namespace base_internal
70
+ ABSL_NAMESPACE_END
71
+ } // namespace absl
72
+
73
+ #define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \
74
+ (absl::base_internal::UnalignedLoad16(_p))
75
+ #define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \
76
+ (absl::base_internal::UnalignedLoad32(_p))
77
+ #define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) \
78
+ (absl::base_internal::UnalignedLoad64(_p))
79
+
80
+ #define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \
81
+ (absl::base_internal::UnalignedStore16(_p, _val))
82
+ #define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \
83
+ (absl::base_internal::UnalignedStore32(_p, _val))
84
+ #define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \
85
+ (absl::base_internal::UnalignedStore64(_p, _val))
86
+
87
+ #endif // defined(__cplusplus), end of unaligned API
88
+
89
+ #endif // ABSL_BASE_INTERNAL_UNALIGNED_ACCESS_H_
weight/_dep/abseil-cpp/absl/base/internal/unique_small_name_test.cc ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2020 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include "gtest/gtest.h"
16
+ #include "absl/base/optimization.h"
17
+ #include "absl/strings/string_view.h"
18
+
19
+ // This test by itself does not do anything fancy, but it serves as binary I can
20
+ // query in shell test.
21
+
22
+ namespace {
23
+
24
+ template <class T>
25
+ void DoNotOptimize(const T& var) {
26
+ #ifdef __GNUC__
27
+ asm volatile("" : "+m"(const_cast<T&>(var)));
28
+ #else
29
+ std::cout << (void*)&var;
30
+ #endif
31
+ }
32
+
33
+ int very_long_int_variable_name ABSL_INTERNAL_UNIQUE_SMALL_NAME() = 0;
34
+ char very_long_str_variable_name[] ABSL_INTERNAL_UNIQUE_SMALL_NAME() = "abc";
35
+
36
+ TEST(UniqueSmallName, NonAutomaticVar) {
37
+ EXPECT_EQ(very_long_int_variable_name, 0);
38
+ EXPECT_EQ(absl::string_view(very_long_str_variable_name), "abc");
39
+ }
40
+
41
+ int VeryLongFreeFunctionName() ABSL_INTERNAL_UNIQUE_SMALL_NAME();
42
+
43
+ TEST(UniqueSmallName, FreeFunction) {
44
+ DoNotOptimize(&VeryLongFreeFunctionName);
45
+
46
+ EXPECT_EQ(VeryLongFreeFunctionName(), 456);
47
+ }
48
+
49
+ int VeryLongFreeFunctionName() { return 456; }
50
+
51
+ struct VeryLongStructName {
52
+ explicit VeryLongStructName(int i);
53
+
54
+ int VeryLongMethodName() ABSL_INTERNAL_UNIQUE_SMALL_NAME();
55
+
56
+ static int VeryLongStaticMethodName() ABSL_INTERNAL_UNIQUE_SMALL_NAME();
57
+
58
+ private:
59
+ int fld;
60
+ };
61
+
62
+ TEST(UniqueSmallName, Struct) {
63
+ VeryLongStructName var(10);
64
+
65
+ DoNotOptimize(var);
66
+ DoNotOptimize(&VeryLongStructName::VeryLongMethodName);
67
+ DoNotOptimize(&VeryLongStructName::VeryLongStaticMethodName);
68
+
69
+ EXPECT_EQ(var.VeryLongMethodName(), 10);
70
+ EXPECT_EQ(VeryLongStructName::VeryLongStaticMethodName(), 123);
71
+ }
72
+
73
+ VeryLongStructName::VeryLongStructName(int i) : fld(i) {}
74
+ int VeryLongStructName::VeryLongMethodName() { return fld; }
75
+ int VeryLongStructName::VeryLongStaticMethodName() { return 123; }
76
+
77
+ } // namespace
weight/_dep/abseil-cpp/absl/base/internal/unscaledcycleclock.cc ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include "absl/base/internal/unscaledcycleclock.h"
16
+
17
+ #if ABSL_USE_UNSCALED_CYCLECLOCK
18
+
19
+ #if defined(_WIN32)
20
+ #include <intrin.h>
21
+ #endif
22
+
23
+ #if defined(__powerpc__) || defined(__ppc__)
24
+ #ifdef __GLIBC__
25
+ #include <sys/platform/ppc.h>
26
+ #elif defined(__FreeBSD__)
27
+ // clang-format off
28
+ // This order does actually matter =(.
29
+ #include <sys/types.h>
30
+ #include <sys/sysctl.h>
31
+ // clang-format on
32
+
33
+ #include "absl/base/call_once.h"
34
+ #endif
35
+ #endif
36
+
37
+ #include "absl/base/internal/sysinfo.h"
38
+
39
+ namespace absl {
40
+ ABSL_NAMESPACE_BEGIN
41
+ namespace base_internal {
42
+
43
+ #if defined(__i386__)
44
+
45
+ int64_t UnscaledCycleClock::Now() {
46
+ int64_t ret;
47
+ __asm__ volatile("rdtsc" : "=A"(ret));
48
+ return ret;
49
+ }
50
+
51
+ double UnscaledCycleClock::Frequency() {
52
+ return base_internal::NominalCPUFrequency();
53
+ }
54
+
55
+ #elif defined(__x86_64__)
56
+
57
+ double UnscaledCycleClock::Frequency() {
58
+ return base_internal::NominalCPUFrequency();
59
+ }
60
+
61
+ #elif defined(__powerpc__) || defined(__ppc__)
62
+
63
+ int64_t UnscaledCycleClock::Now() {
64
+ #ifdef __GLIBC__
65
+ return __ppc_get_timebase();
66
+ #else
67
+ #ifdef __powerpc64__
68
+ int64_t tbr;
69
+ asm volatile("mfspr %0, 268" : "=r"(tbr));
70
+ return tbr;
71
+ #else
72
+ int32_t tbu, tbl, tmp;
73
+ asm volatile(
74
+ "mftbu %[hi32]\n"
75
+ "mftb %[lo32]\n"
76
+ "mftbu %[tmp]\n"
77
+ "cmpw %[tmp],%[hi32]\n"
78
+ "bne $-16\n" // Retry on failure.
79
+ : [hi32] "=r"(tbu), [lo32] "=r"(tbl), [tmp] "=r"(tmp));
80
+ return (static_cast<int64_t>(tbu) << 32) | tbl;
81
+ #endif
82
+ #endif
83
+ }
84
+
85
+ double UnscaledCycleClock::Frequency() {
86
+ #ifdef __GLIBC__
87
+ return __ppc_get_timebase_freq();
88
+ #elif defined(_AIX)
89
+ // This is the same constant value as returned by
90
+ // __ppc_get_timebase_freq().
91
+ return static_cast<double>(512000000);
92
+ #elif defined(__FreeBSD__)
93
+ static once_flag init_timebase_frequency_once;
94
+ static double timebase_frequency = 0.0;
95
+ base_internal::LowLevelCallOnce(&init_timebase_frequency_once, [&]() {
96
+ size_t length = sizeof(timebase_frequency);
97
+ sysctlbyname("kern.timecounter.tc.timebase.frequency", &timebase_frequency,
98
+ &length, nullptr, 0);
99
+ });
100
+ return timebase_frequency;
101
+ #else
102
+ #error Must implement UnscaledCycleClock::Frequency()
103
+ #endif
104
+ }
105
+
106
+ #elif defined(__aarch64__)
107
+
108
+ // System timer of ARMv8 runs at a different frequency than the CPU's.
109
+ // The frequency is fixed, typically in the range 1-50MHz. It can be
110
+ // read at CNTFRQ special register. We assume the OS has set up
111
+ // the virtual timer properly.
112
+ int64_t UnscaledCycleClock::Now() {
113
+ int64_t virtual_timer_value;
114
+ asm volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer_value));
115
+ return virtual_timer_value;
116
+ }
117
+
118
+ double UnscaledCycleClock::Frequency() {
119
+ uint64_t aarch64_timer_frequency;
120
+ asm volatile("mrs %0, cntfrq_el0" : "=r"(aarch64_timer_frequency));
121
+ return aarch64_timer_frequency;
122
+ }
123
+
124
+ #elif defined(__riscv)
125
+
126
+ int64_t UnscaledCycleClock::Now() {
127
+ int64_t virtual_timer_value;
128
+ asm volatile("rdcycle %0" : "=r"(virtual_timer_value));
129
+ return virtual_timer_value;
130
+ }
131
+
132
+ double UnscaledCycleClock::Frequency() {
133
+ return base_internal::NominalCPUFrequency();
134
+ }
135
+
136
+ #elif defined(_M_IX86) || defined(_M_X64)
137
+
138
+ #pragma intrinsic(__rdtsc)
139
+
140
+ int64_t UnscaledCycleClock::Now() { return __rdtsc(); }
141
+
142
+ double UnscaledCycleClock::Frequency() {
143
+ return base_internal::NominalCPUFrequency();
144
+ }
145
+
146
+ #endif
147
+
148
+ } // namespace base_internal
149
+ ABSL_NAMESPACE_END
150
+ } // namespace absl
151
+
152
+ #endif // ABSL_USE_UNSCALED_CYCLECLOCK
weight/_dep/abseil-cpp/absl/base/internal/unscaledcycleclock.h ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+ // UnscaledCycleClock
16
+ // An UnscaledCycleClock yields the value and frequency of a cycle counter
17
+ // that increments at a rate that is approximately constant.
18
+ // This class is for internal use only, you should consider using CycleClock
19
+ // instead.
20
+ //
21
+ // Notes:
22
+ // The cycle counter frequency is not necessarily the core clock frequency.
23
+ // That is, CycleCounter cycles are not necessarily "CPU cycles".
24
+ //
25
+ // An arbitrary offset may have been added to the counter at power on.
26
+ //
27
+ // On some platforms, the rate and offset of the counter may differ
28
+ // slightly when read from different CPUs of a multiprocessor. Usually,
29
+ // we try to ensure that the operating system adjusts values periodically
30
+ // so that values agree approximately. If you need stronger guarantees,
31
+ // consider using alternate interfaces.
32
+ //
33
+ // The CPU is not required to maintain the ordering of a cycle counter read
34
+ // with respect to surrounding instructions.
35
+
36
+ #ifndef ABSL_BASE_INTERNAL_UNSCALEDCYCLECLOCK_H_
37
+ #define ABSL_BASE_INTERNAL_UNSCALEDCYCLECLOCK_H_
38
+
39
+ #include <cstdint>
40
+
41
+ #if defined(__APPLE__)
42
+ #include <TargetConditionals.h>
43
+ #endif
44
+
45
+ #include "absl/base/config.h"
46
+ #include "absl/base/internal/unscaledcycleclock_config.h"
47
+
48
+ #if ABSL_USE_UNSCALED_CYCLECLOCK
49
+
50
+ namespace absl {
51
+ ABSL_NAMESPACE_BEGIN
52
+ namespace time_internal {
53
+ class UnscaledCycleClockWrapperForGetCurrentTime;
54
+ } // namespace time_internal
55
+
56
+ namespace base_internal {
57
+ class CycleClock;
58
+ class UnscaledCycleClockWrapperForInitializeFrequency;
59
+
60
+ class UnscaledCycleClock {
61
+ private:
62
+ UnscaledCycleClock() = delete;
63
+
64
+ // Return the value of a cycle counter that counts at a rate that is
65
+ // approximately constant.
66
+ static int64_t Now();
67
+
68
+ // Return the how much UnscaledCycleClock::Now() increases per second.
69
+ // This is not necessarily the core CPU clock frequency.
70
+ // It may be the nominal value report by the kernel, rather than a measured
71
+ // value.
72
+ static double Frequency();
73
+
74
+ // Allowed users
75
+ friend class base_internal::CycleClock;
76
+ friend class time_internal::UnscaledCycleClockWrapperForGetCurrentTime;
77
+ friend class base_internal::UnscaledCycleClockWrapperForInitializeFrequency;
78
+ };
79
+
80
+ #if defined(__x86_64__)
81
+
82
+ inline int64_t UnscaledCycleClock::Now() {
83
+ uint64_t low, high;
84
+ __asm__ volatile("rdtsc" : "=a"(low), "=d"(high));
85
+ return static_cast<int64_t>((high << 32) | low);
86
+ }
87
+
88
+ #endif
89
+
90
+ } // namespace base_internal
91
+ ABSL_NAMESPACE_END
92
+ } // namespace absl
93
+
94
+ #endif // ABSL_USE_UNSCALED_CYCLECLOCK
95
+
96
+ #endif // ABSL_BASE_INTERNAL_UNSCALEDCYCLECLOCK_H_
weight/_dep/abseil-cpp/absl/base/port.h ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+ // This files is a forwarding header for other headers containing various
16
+ // portability macros and functions.
17
+
18
+ #ifndef ABSL_BASE_PORT_H_
19
+ #define ABSL_BASE_PORT_H_
20
+
21
+ #include "absl/base/attributes.h"
22
+ #include "absl/base/config.h"
23
+ #include "absl/base/optimization.h"
24
+
25
+ #endif // ABSL_BASE_PORT_H_
weight/_dep/abseil-cpp/absl/base/prefetch.h ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2023 The Abseil Authors
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+ // -----------------------------------------------------------------------------
16
+ // File: prefetch.h
17
+ // -----------------------------------------------------------------------------
18
+ //
19
+ // This header file defines prefetch functions to prefetch memory contents
20
+ // into the first level cache (L1) for the current CPU. The prefetch logic
21
+ // offered in this header is limited to prefetching first level cachelines
22
+ // only, and is aimed at relatively 'simple' prefetching logic.
23
+ //
24
+ #ifndef ABSL_BASE_PREFETCH_H_
25
+ #define ABSL_BASE_PREFETCH_H_
26
+
27
+ #include "absl/base/attributes.h"
28
+ #include "absl/base/config.h"
29
+
30
+ #if defined(ABSL_INTERNAL_HAVE_SSE)
31
+ #include <xmmintrin.h>
32
+ #endif
33
+
34
+ #if defined(_MSC_VER)
35
+ #include <intrin.h>
36
+ #if defined(ABSL_INTERNAL_HAVE_SSE)
37
+ #pragma intrinsic(_mm_prefetch)
38
+ #endif
39
+ #endif
40
+
41
+ namespace absl {
42
+ ABSL_NAMESPACE_BEGIN
43
+
44
+ // Moves data into the L1 cache before it is read, or "prefetches" it.
45
+ //
46
+ // The value of `addr` is the address of the memory to prefetch. If
47
+ // the target and compiler support it, data prefetch instructions are
48
+ // generated. If the prefetch is done some time before the memory is
49
+ // read, it may be in the cache by the time the read occurs.
50
+ //
51
+ // This method prefetches data with the highest degree of temporal locality;
52
+ // data is prefetched where possible into all levels of the cache.
53
+ //
54
+ // Incorrect or gratuitous use of this function can degrade performance.
55
+ // Use this function only when representative benchmarks show an improvement.
56
+ //
57
+ // Example:
58
+ //
59
+ // // Computes incremental checksum for `data`.
60
+ // int ComputeChecksum(int sum, absl::string_view data);
61
+ //
62
+ // // Computes cumulative checksum for all values in `data`
63
+ // int ComputeChecksum(absl::Span<const std::string> data) {
64
+ // int sum = 0;
65
+ // auto it = data.begin();
66
+ // auto pit = data.begin();
67
+ // auto end = data.end();
68
+ // for (int dist = 8; dist > 0 && pit != data.end(); --dist, ++pit) {
69
+ // absl::PrefetchToLocalCache(pit->data());
70
+ // }
71
+ // for (; pit != end; ++pit, ++it) {
72
+ // sum = ComputeChecksum(sum, *it);
73
+ // absl::PrefetchToLocalCache(pit->data());
74
+ // }
75
+ // for (; it != end; ++it) {
76
+ // sum = ComputeChecksum(sum, *it);
77
+ // }
78
+ // return sum;
79
+ // }
80
+ //
81
+ void PrefetchToLocalCache(const void* addr);
82
+
83
+ // Moves data into the L1 cache before it is read, or "prefetches" it.
84
+ //
85
+ // This function is identical to `PrefetchToLocalCache()` except that it has
86
+ // non-temporal locality: the fetched data should not be left in any of the
87
+ // cache tiers. This is useful for cases where the data is used only once /
88
+ // short term, for example, invoking a destructor on an object.
89
+ //
90
+ // Incorrect or gratuitous use of this function can degrade performance.
91
+ // Use this function only when representative benchmarks show an improvement.
92
+ //
93
+ // Example:
94
+ //
95
+ // template <typename Iterator>
96
+ // void DestroyPointers(Iterator begin, Iterator end) {
97
+ // size_t distance = std::min(8U, bars.size());
98
+ //
99
+ // int dist = 8;
100
+ // auto prefetch_it = begin;
101
+ // while (prefetch_it != end && --dist;) {
102
+ // absl::PrefetchToLocalCacheNta(*prefetch_it++);
103
+ // }
104
+ // while (prefetch_it != end) {
105
+ // delete *begin++;
106
+ // absl::PrefetchToLocalCacheNta(*prefetch_it++);
107
+ // }
108
+ // while (begin != end) {
109
+ // delete *begin++;
110
+ // }
111
+ // }
112
+ //
113
+ void PrefetchToLocalCacheNta(const void* addr);
114
+
115
+ // Moves data into the L1 cache with the intent to modify it.
116
+ //
117
+ // This function is similar to `PrefetchToLocalCache()` except that it
118
+ // prefetches cachelines with an 'intent to modify' This typically includes
119
+ // invalidating cache entries for this address in all other cache tiers, and an
120
+ // exclusive access intent.
121
+ //
122
+ // Incorrect or gratuitous use of this function can degrade performance. As this
123
+ // function can invalidate cached cachelines on other caches and computer cores,
124
+ // incorrect usage of this function can have an even greater negative impact
125
+ // than incorrect regular prefetches.
126
+ // Use this function only when representative benchmarks show an improvement.
127
+ //
128
+ // Example:
129
+ //
130
+ // void* Arena::Allocate(size_t size) {
131
+ // void* ptr = AllocateBlock(size);
132
+ // absl::PrefetchToLocalCacheForWrite(p);
133
+ // return ptr;
134
+ // }
135
+ //
136
+ void PrefetchToLocalCacheForWrite(const void* addr);
137
+
138
+ #if ABSL_HAVE_BUILTIN(__builtin_prefetch) || defined(__GNUC__)
139
+
140
+ #define ABSL_HAVE_PREFETCH 1
141
+
142
+ // See __builtin_prefetch:
143
+ // https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html.
144
+ //
145
+ ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCache(
146
+ const void* addr) {
147
+ __builtin_prefetch(addr, 0, 3);
148
+ }
149
+
150
+ ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCacheNta(
151
+ const void* addr) {
152
+ __builtin_prefetch(addr, 0, 0);
153
+ }
154
+
155
+ ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCacheForWrite(
156
+ const void* addr) {
157
+ // [x86] gcc/clang don't generate PREFETCHW for __builtin_prefetch(.., 1)
158
+ // unless -march=broadwell or newer; this is not generally the default, so we
159
+ // manually emit prefetchw. PREFETCHW is recognized as a no-op on older Intel
160
+ // processors and has been present on AMD processors since the K6-2.
161
+ #if defined(__x86_64__) && !defined(__PRFCHW__)
162
+ asm("prefetchw %0" : : "m"(*reinterpret_cast<const char*>(addr)));
163
+ #else
164
+ __builtin_prefetch(addr, 1, 3);
165
+ #endif
166
+ }
167
+
168
+ #elif defined(ABSL_INTERNAL_HAVE_SSE)
169
+
170
+ #define ABSL_HAVE_PREFETCH 1
171
+
172
+ ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCache(
173
+ const void* addr) {
174
+ _mm_prefetch(reinterpret_cast<const char*>(addr), _MM_HINT_T0);
175
+ }
176
+
177
+ ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCacheNta(
178
+ const void* addr) {
179
+ _mm_prefetch(reinterpret_cast<const char*>(addr), _MM_HINT_NTA);
180
+ }
181
+
182
+ ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCacheForWrite(
183
+ const void* addr) {
184
+ #if defined(_MM_HINT_ET0)
185
+ _mm_prefetch(reinterpret_cast<const char*>(addr), _MM_HINT_ET0);
186
+ #elif !defined(_MSC_VER) && defined(__x86_64__)
187
+ // _MM_HINT_ET0 is not universally supported. As we commented further
188
+ // up, PREFETCHW is recognized as a no-op on older Intel processors
189
+ // and has been present on AMD processors since the K6-2. We have this
190
+ // disabled for MSVC compilers as this miscompiles on older MSVC compilers.
191
+ asm("prefetchw %0" : : "m"(*reinterpret_cast<const char*>(addr)));
192
+ #endif
193
+ }
194
+
195
+ #else
196
+
197
+ ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCache(
198
+ const void* addr) {}
199
+ ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCacheNta(
200
+ const void* addr) {}
201
+ ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCacheForWrite(
202
+ const void* addr) {}
203
+
204
+ #endif
205
+
206
+ ABSL_NAMESPACE_END
207
+ } // namespace absl
208
+
209
+ #endif // ABSL_BASE_PREFETCH_H_
weight/_dep/abseil-cpp/absl/container/CMakeLists.txt ADDED
@@ -0,0 +1,989 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #
2
+ # Copyright 2017 The Abseil Authors.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # https://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ absl_cc_library(
18
+ NAME
19
+ btree
20
+ HDRS
21
+ "btree_map.h"
22
+ "btree_set.h"
23
+ "internal/btree.h"
24
+ "internal/btree_container.h"
25
+ COPTS
26
+ ${ABSL_DEFAULT_COPTS}
27
+ LINKOPTS
28
+ ${ABSL_DEFAULT_LINKOPTS}
29
+ DEPS
30
+ absl::container_common
31
+ absl::common_policy_traits
32
+ absl::compare
33
+ absl::compressed_tuple
34
+ absl::container_memory
35
+ absl::cord
36
+ absl::core_headers
37
+ absl::layout
38
+ absl::memory
39
+ absl::raw_logging_internal
40
+ absl::strings
41
+ absl::throw_delegate
42
+ absl::type_traits
43
+ absl::utility
44
+ )
45
+
46
+ # Internal-only target, do not depend on directly.
47
+ absl_cc_library(
48
+ NAME
49
+ btree_test_common
50
+ hdrs
51
+ "btree_test.h"
52
+ COPTS
53
+ ${ABSL_TEST_COPTS}
54
+ LINKOPTS
55
+ ${ABSL_DEFAULT_LINKOPTS}
56
+ DEPS
57
+ absl::btree
58
+ absl::cord
59
+ absl::flat_hash_set
60
+ absl::strings
61
+ absl::time
62
+ TESTONLY
63
+ )
64
+
65
+ absl_cc_test(
66
+ NAME
67
+ btree_test
68
+ SRCS
69
+ "btree_test.cc"
70
+ COPTS
71
+ ${ABSL_TEST_COPTS}
72
+ LINKOPTS
73
+ ${ABSL_DEFAULT_LINKOPTS}
74
+ DEPS
75
+ absl::algorithm_container
76
+ absl::btree
77
+ absl::btree_test_common
78
+ absl::compare
79
+ absl::core_headers
80
+ absl::flags
81
+ absl::hash_testing
82
+ absl::optional
83
+ absl::random_random
84
+ absl::raw_logging_internal
85
+ absl::strings
86
+ absl::test_allocator
87
+ absl::test_instance_tracker
88
+ GTest::gmock_main
89
+ )
90
+
91
+ # Internal-only target, do not depend on directly.
92
+ absl_cc_library(
93
+ NAME
94
+ compressed_tuple
95
+ HDRS
96
+ "internal/compressed_tuple.h"
97
+ COPTS
98
+ ${ABSL_DEFAULT_COPTS}
99
+ DEPS
100
+ absl::utility
101
+ PUBLIC
102
+ )
103
+
104
+ absl_cc_test(
105
+ NAME
106
+ compressed_tuple_test
107
+ SRCS
108
+ "internal/compressed_tuple_test.cc"
109
+ COPTS
110
+ ${ABSL_TEST_COPTS}
111
+ DEPS
112
+ absl::any
113
+ absl::compressed_tuple
114
+ absl::memory
115
+ absl::optional
116
+ absl::test_instance_tracker
117
+ absl::utility
118
+ GTest::gmock_main
119
+ )
120
+
121
+ absl_cc_library(
122
+ NAME
123
+ fixed_array
124
+ HDRS
125
+ "fixed_array.h"
126
+ COPTS
127
+ ${ABSL_DEFAULT_COPTS}
128
+ DEPS
129
+ absl::compressed_tuple
130
+ absl::algorithm
131
+ absl::config
132
+ absl::core_headers
133
+ absl::dynamic_annotations
134
+ absl::throw_delegate
135
+ absl::memory
136
+ PUBLIC
137
+ )
138
+
139
+ absl_cc_test(
140
+ NAME
141
+ fixed_array_test
142
+ SRCS
143
+ "fixed_array_test.cc"
144
+ COPTS
145
+ ${ABSL_TEST_COPTS}
146
+ DEPS
147
+ absl::fixed_array
148
+ absl::config
149
+ absl::exception_testing
150
+ absl::hash_testing
151
+ absl::memory
152
+ absl::test_allocator
153
+ GTest::gmock_main
154
+ )
155
+
156
+ absl_cc_test(
157
+ NAME
158
+ fixed_array_exception_safety_test
159
+ SRCS
160
+ "fixed_array_exception_safety_test.cc"
161
+ COPTS
162
+ ${ABSL_TEST_COPTS}
163
+ DEPS
164
+ absl::fixed_array
165
+ absl::config
166
+ absl::exception_safety_testing
167
+ GTest::gmock_main
168
+ )
169
+
170
+ # Internal-only target, do not depend on directly.
171
+ absl_cc_library(
172
+ NAME
173
+ inlined_vector_internal
174
+ HDRS
175
+ "internal/inlined_vector.h"
176
+ COPTS
177
+ ${ABSL_DEFAULT_COPTS}
178
+ DEPS
179
+ absl::compressed_tuple
180
+ absl::config
181
+ absl::core_headers
182
+ absl::memory
183
+ absl::span
184
+ absl::type_traits
185
+ PUBLIC
186
+ )
187
+
188
+ absl_cc_library(
189
+ NAME
190
+ inlined_vector
191
+ HDRS
192
+ "inlined_vector.h"
193
+ COPTS
194
+ ${ABSL_DEFAULT_COPTS}
195
+ DEPS
196
+ absl::algorithm
197
+ absl::core_headers
198
+ absl::inlined_vector_internal
199
+ absl::throw_delegate
200
+ absl::memory
201
+ absl::type_traits
202
+ PUBLIC
203
+ )
204
+
205
+ # Internal-only target, do not depend on directly.
206
+ absl_cc_library(
207
+ NAME
208
+ test_allocator
209
+ HDRS
210
+ "internal/test_allocator.h"
211
+ COPTS
212
+ ${ABSL_DEFAULT_COPTS}
213
+ DEPS
214
+ absl::config
215
+ GTest::gmock
216
+ )
217
+
218
+ absl_cc_test(
219
+ NAME
220
+ inlined_vector_test
221
+ SRCS
222
+ "inlined_vector_test.cc"
223
+ COPTS
224
+ ${ABSL_TEST_COPTS}
225
+ DEPS
226
+ absl::check
227
+ absl::config
228
+ absl::core_headers
229
+ absl::exception_testing
230
+ absl::hash_testing
231
+ absl::inlined_vector
232
+ absl::memory
233
+ absl::strings
234
+ absl::test_allocator
235
+ absl::test_instance_tracker
236
+ GTest::gmock_main
237
+ )
238
+
239
+ absl_cc_test(
240
+ NAME
241
+ inlined_vector_exception_safety_test
242
+ SRCS
243
+ "inlined_vector_exception_safety_test.cc"
244
+ COPTS
245
+ ${ABSL_TEST_COPTS}
246
+ DEPS
247
+ absl::inlined_vector
248
+ absl::config
249
+ absl::exception_safety_testing
250
+ GTest::gmock_main
251
+ )
252
+
253
+ # Internal-only target, do not depend on directly.
254
+ absl_cc_library(
255
+ NAME
256
+ test_instance_tracker
257
+ HDRS
258
+ "internal/test_instance_tracker.h"
259
+ SRCS
260
+ "internal/test_instance_tracker.cc"
261
+ COPTS
262
+ ${ABSL_DEFAULT_COPTS}
263
+ DEPS
264
+ absl::compare
265
+ TESTONLY
266
+ )
267
+
268
+ absl_cc_test(
269
+ NAME
270
+ test_instance_tracker_test
271
+ SRCS
272
+ "internal/test_instance_tracker_test.cc"
273
+ COPTS
274
+ ${ABSL_TEST_COPTS}
275
+ DEPS
276
+ absl::test_instance_tracker
277
+ GTest::gmock_main
278
+ )
279
+
280
+ absl_cc_library(
281
+ NAME
282
+ flat_hash_map
283
+ HDRS
284
+ "flat_hash_map.h"
285
+ COPTS
286
+ ${ABSL_DEFAULT_COPTS}
287
+ DEPS
288
+ absl::container_memory
289
+ absl::core_headers
290
+ absl::hash_function_defaults
291
+ absl::raw_hash_map
292
+ absl::algorithm_container
293
+ absl::memory
294
+ PUBLIC
295
+ )
296
+
297
+ absl_cc_test(
298
+ NAME
299
+ flat_hash_map_test
300
+ SRCS
301
+ "flat_hash_map_test.cc"
302
+ COPTS
303
+ ${ABSL_TEST_COPTS}
304
+ DEPS
305
+ absl::any
306
+ absl::check
307
+ absl::flat_hash_map
308
+ absl::hash_generator_testing
309
+ absl::type_traits
310
+ absl::unordered_map_constructor_test
311
+ absl::unordered_map_lookup_test
312
+ absl::unordered_map_members_test
313
+ absl::unordered_map_modifiers_test
314
+ GTest::gmock_main
315
+ )
316
+
317
+ absl_cc_library(
318
+ NAME
319
+ flat_hash_set
320
+ HDRS
321
+ "flat_hash_set.h"
322
+ COPTS
323
+ ${ABSL_DEFAULT_COPTS}
324
+ DEPS
325
+ absl::container_memory
326
+ absl::hash_function_defaults
327
+ absl::raw_hash_set
328
+ absl::algorithm_container
329
+ absl::core_headers
330
+ absl::memory
331
+ PUBLIC
332
+ )
333
+
334
+ absl_cc_test(
335
+ NAME
336
+ flat_hash_set_test
337
+ SRCS
338
+ "flat_hash_set_test.cc"
339
+ COPTS
340
+ ${ABSL_TEST_COPTS}
341
+ "-DUNORDERED_SET_CXX17"
342
+ DEPS
343
+ absl::check
344
+ absl::config
345
+ absl::container_memory
346
+ absl::flat_hash_set
347
+ absl::hash_generator_testing
348
+ absl::memory
349
+ absl::strings
350
+ absl::unordered_set_constructor_test
351
+ absl::unordered_set_lookup_test
352
+ absl::unordered_set_members_test
353
+ absl::unordered_set_modifiers_test
354
+ GTest::gmock_main
355
+ )
356
+
357
+ absl_cc_library(
358
+ NAME
359
+ node_hash_map
360
+ HDRS
361
+ "node_hash_map.h"
362
+ COPTS
363
+ ${ABSL_DEFAULT_COPTS}
364
+ DEPS
365
+ absl::container_memory
366
+ absl::core_headers
367
+ absl::hash_function_defaults
368
+ absl::node_slot_policy
369
+ absl::raw_hash_map
370
+ absl::algorithm_container
371
+ absl::memory
372
+ PUBLIC
373
+ )
374
+
375
+ absl_cc_test(
376
+ NAME
377
+ node_hash_map_test
378
+ SRCS
379
+ "node_hash_map_test.cc"
380
+ COPTS
381
+ ${ABSL_TEST_COPTS}
382
+ DEPS
383
+ absl::hash_generator_testing
384
+ absl::node_hash_map
385
+ absl::tracked
386
+ absl::unordered_map_constructor_test
387
+ absl::unordered_map_lookup_test
388
+ absl::unordered_map_members_test
389
+ absl::unordered_map_modifiers_test
390
+ GTest::gmock_main
391
+ )
392
+
393
+ absl_cc_library(
394
+ NAME
395
+ node_hash_set
396
+ HDRS
397
+ "node_hash_set.h"
398
+ COPTS
399
+ ${ABSL_DEFAULT_COPTS}
400
+ DEPS
401
+ absl::core_headers
402
+ absl::hash_function_defaults
403
+ absl::node_slot_policy
404
+ absl::raw_hash_set
405
+ absl::algorithm_container
406
+ absl::memory
407
+ PUBLIC
408
+ )
409
+
410
+ absl_cc_test(
411
+ NAME
412
+ node_hash_set_test
413
+ SRCS
414
+ "node_hash_set_test.cc"
415
+ COPTS
416
+ ${ABSL_TEST_COPTS}
417
+ "-DUNORDERED_SET_CXX17"
418
+ DEPS
419
+ absl::hash_generator_testing
420
+ absl::node_hash_set
421
+ absl::unordered_set_constructor_test
422
+ absl::unordered_set_lookup_test
423
+ absl::unordered_set_members_test
424
+ absl::unordered_set_modifiers_test
425
+ GTest::gmock_main
426
+ )
427
+
428
+ # Internal-only target, do not depend on directly.
429
+ absl_cc_library(
430
+ NAME
431
+ container_memory
432
+ HDRS
433
+ "internal/container_memory.h"
434
+ COPTS
435
+ ${ABSL_DEFAULT_COPTS}
436
+ DEPS
437
+ absl::config
438
+ absl::memory
439
+ absl::type_traits
440
+ absl::utility
441
+ PUBLIC
442
+ )
443
+
444
+ absl_cc_test(
445
+ NAME
446
+ container_memory_test
447
+ SRCS
448
+ "internal/container_memory_test.cc"
449
+ COPTS
450
+ ${ABSL_TEST_COPTS}
451
+ DEPS
452
+ absl::container_memory
453
+ absl::no_destructor
454
+ absl::strings
455
+ absl::test_instance_tracker
456
+ absl::type_traits
457
+ GTest::gmock_main
458
+ )
459
+
460
+ # Internal-only target, do not depend on directly.
461
+ absl_cc_library(
462
+ NAME
463
+ hash_function_defaults
464
+ HDRS
465
+ "internal/hash_function_defaults.h"
466
+ COPTS
467
+ ${ABSL_DEFAULT_COPTS}
468
+ DEPS
469
+ absl::config
470
+ absl::cord
471
+ absl::hash
472
+ absl::strings
473
+ PUBLIC
474
+ )
475
+
476
+ absl_cc_test(
477
+ NAME
478
+ hash_function_defaults_test
479
+ SRCS
480
+ "internal/hash_function_defaults_test.cc"
481
+ COPTS
482
+ ${ABSL_TEST_COPTS}
483
+ DEPS
484
+ absl::cord
485
+ absl::cord_test_helpers
486
+ absl::hash_function_defaults
487
+ absl::hash
488
+ absl::random_random
489
+ absl::strings
490
+ GTest::gmock_main
491
+ )
492
+
493
+ # Internal-only target, do not depend on directly.
494
+ absl_cc_library(
495
+ NAME
496
+ hash_generator_testing
497
+ HDRS
498
+ "internal/hash_generator_testing.h"
499
+ SRCS
500
+ "internal/hash_generator_testing.cc"
501
+ COPTS
502
+ ${ABSL_TEST_COPTS}
503
+ DEPS
504
+ absl::hash_policy_testing
505
+ absl::memory
506
+ absl::meta
507
+ absl::no_destructor
508
+ absl::strings
509
+ TESTONLY
510
+ )
511
+
512
+ # Internal-only target, do not depend on directly.
513
+ absl_cc_library(
514
+ NAME
515
+ hash_policy_testing
516
+ HDRS
517
+ "internal/hash_policy_testing.h"
518
+ COPTS
519
+ ${ABSL_TEST_COPTS}
520
+ DEPS
521
+ absl::hash
522
+ absl::strings
523
+ TESTONLY
524
+ )
525
+
526
+ absl_cc_test(
527
+ NAME
528
+ hash_policy_testing_test
529
+ SRCS
530
+ "internal/hash_policy_testing_test.cc"
531
+ COPTS
532
+ ${ABSL_TEST_COPTS}
533
+ DEPS
534
+ absl::hash_policy_testing
535
+ GTest::gmock_main
536
+ )
537
+
538
+ # Internal-only target, do not depend on directly.
539
+ absl_cc_library(
540
+ NAME
541
+ hash_policy_traits
542
+ HDRS
543
+ "internal/hash_policy_traits.h"
544
+ COPTS
545
+ ${ABSL_DEFAULT_COPTS}
546
+ DEPS
547
+ absl::common_policy_traits
548
+ absl::meta
549
+ PUBLIC
550
+ )
551
+
552
+ absl_cc_test(
553
+ NAME
554
+ hash_policy_traits_test
555
+ SRCS
556
+ "internal/hash_policy_traits_test.cc"
557
+ COPTS
558
+ ${ABSL_TEST_COPTS}
559
+ DEPS
560
+ absl::hash_policy_traits
561
+ GTest::gmock_main
562
+ )
563
+
564
+ # Internal-only target, do not depend on directly.
565
+ absl_cc_library(
566
+ NAME
567
+ common_policy_traits
568
+ HDRS
569
+ "internal/common_policy_traits.h"
570
+ COPTS
571
+ ${ABSL_DEFAULT_COPTS}
572
+ DEPS
573
+ absl::meta
574
+ PUBLIC
575
+ )
576
+
577
+ absl_cc_test(
578
+ NAME
579
+ common_policy_traits_test
580
+ SRCS
581
+ "internal/common_policy_traits_test.cc"
582
+ COPTS
583
+ ${ABSL_TEST_COPTS}
584
+ DEPS
585
+ absl::common_policy_traits
586
+ absl::config
587
+ GTest::gmock_main
588
+ )
589
+
590
+ # Internal-only target, do not depend on directly.
591
+ absl_cc_library(
592
+ NAME
593
+ hashtablez_sampler
594
+ HDRS
595
+ "internal/hashtablez_sampler.h"
596
+ SRCS
597
+ "internal/hashtablez_sampler.cc"
598
+ "internal/hashtablez_sampler_force_weak_definition.cc"
599
+ COPTS
600
+ ${ABSL_DEFAULT_COPTS}
601
+ DEPS
602
+ absl::base
603
+ absl::config
604
+ absl::exponential_biased
605
+ absl::raw_logging_internal
606
+ absl::sample_recorder
607
+ absl::synchronization
608
+ absl::time
609
+ )
610
+
611
+ absl_cc_test(
612
+ NAME
613
+ hashtablez_sampler_test
614
+ SRCS
615
+ "internal/hashtablez_sampler_test.cc"
616
+ COPTS
617
+ ${ABSL_TEST_COPTS}
618
+ DEPS
619
+ absl::config
620
+ absl::hashtablez_sampler
621
+ GTest::gmock_main
622
+ )
623
+
624
+ # Internal-only target, do not depend on directly.
625
+ absl_cc_library(
626
+ NAME
627
+ hashtable_debug
628
+ HDRS
629
+ "internal/hashtable_debug.h"
630
+ COPTS
631
+ ${ABSL_DEFAULT_COPTS}
632
+ DEPS
633
+ absl::hashtable_debug_hooks
634
+ )
635
+
636
+ # Internal-only target, do not depend on directly.
637
+ absl_cc_library(
638
+ NAME
639
+ hashtable_debug_hooks
640
+ HDRS
641
+ "internal/hashtable_debug_hooks.h"
642
+ COPTS
643
+ ${ABSL_DEFAULT_COPTS}
644
+ DEPS
645
+ absl::config
646
+ PUBLIC
647
+ )
648
+
649
+ # Internal-only target, do not depend on directly.
650
+ absl_cc_library(
651
+ NAME
652
+ node_slot_policy
653
+ HDRS
654
+ "internal/node_slot_policy.h"
655
+ COPTS
656
+ ${ABSL_DEFAULT_COPTS}
657
+ DEPS
658
+ absl::config
659
+ PUBLIC
660
+ )
661
+
662
+ absl_cc_test(
663
+ NAME
664
+ node_slot_policy_test
665
+ SRCS
666
+ "internal/node_slot_policy_test.cc"
667
+ COPTS
668
+ ${ABSL_TEST_COPTS}
669
+ DEPS
670
+ absl::config
671
+ absl::hash_policy_traits
672
+ absl::node_slot_policy
673
+ GTest::gmock_main
674
+ )
675
+
676
+ # Internal-only target, do not depend on directly.
677
+ absl_cc_library(
678
+ NAME
679
+ raw_hash_map
680
+ HDRS
681
+ "internal/raw_hash_map.h"
682
+ COPTS
683
+ ${ABSL_DEFAULT_COPTS}
684
+ DEPS
685
+ absl::config
686
+ absl::container_memory
687
+ absl::core_headers
688
+ absl::raw_hash_set
689
+ absl::throw_delegate
690
+ PUBLIC
691
+ )
692
+
693
+ # Internal-only target, do not depend on directly.
694
+ absl_cc_library(
695
+ NAME
696
+ container_common
697
+ HDRS
698
+ "internal/common.h"
699
+ COPTS
700
+ ${ABSL_DEFAULT_COPTS}
701
+ DEPS
702
+ absl::type_traits
703
+ )
704
+
705
+ # Internal-only target, do not depend on directly.
706
+ absl_cc_library(
707
+ NAME
708
+ raw_hash_set
709
+ HDRS
710
+ "internal/raw_hash_set.h"
711
+ SRCS
712
+ "internal/raw_hash_set.cc"
713
+ COPTS
714
+ ${ABSL_DEFAULT_COPTS}
715
+ DEPS
716
+ absl::bits
717
+ absl::compressed_tuple
718
+ absl::config
719
+ absl::container_common
720
+ absl::container_memory
721
+ absl::core_headers
722
+ absl::dynamic_annotations
723
+ absl::endian
724
+ absl::hash
725
+ absl::hash_policy_traits
726
+ absl::hashtable_debug_hooks
727
+ absl::hashtablez_sampler
728
+ absl::memory
729
+ absl::meta
730
+ absl::optional
731
+ absl::prefetch
732
+ absl::raw_logging_internal
733
+ absl::utility
734
+ PUBLIC
735
+ )
736
+
737
+ absl_cc_test(
738
+ NAME
739
+ raw_hash_set_test
740
+ SRCS
741
+ "internal/raw_hash_set_test.cc"
742
+ COPTS
743
+ ${ABSL_TEST_COPTS}
744
+ DEPS
745
+ absl::base
746
+ absl::config
747
+ absl::container_memory
748
+ absl::core_headers
749
+ absl::flat_hash_map
750
+ absl::flat_hash_set
751
+ absl::hash
752
+ absl::hash_function_defaults
753
+ absl::hash_policy_testing
754
+ absl::hashtable_debug
755
+ absl::hashtablez_sampler
756
+ absl::log
757
+ absl::memory
758
+ absl::prefetch
759
+ absl::raw_hash_set
760
+ absl::strings
761
+ absl::test_allocator
762
+ absl::type_traits
763
+ GTest::gmock_main
764
+ )
765
+
766
+ absl_cc_test(
767
+ NAME
768
+ raw_hash_set_allocator_test
769
+ SRCS
770
+ "internal/raw_hash_set_allocator_test.cc"
771
+ COPTS
772
+ ${ABSL_TEST_COPTS}
773
+ DEPS
774
+ absl::config
775
+ absl::raw_hash_set
776
+ absl::tracked
777
+ GTest::gmock_main
778
+ )
779
+
780
+ # Internal-only target, do not depend on directly.
781
+ absl_cc_library(
782
+ NAME
783
+ layout
784
+ HDRS
785
+ "internal/layout.h"
786
+ COPTS
787
+ ${ABSL_DEFAULT_COPTS}
788
+ DEPS
789
+ absl::config
790
+ absl::core_headers
791
+ absl::debugging_internal
792
+ absl::meta
793
+ absl::strings
794
+ absl::span
795
+ absl::utility
796
+ PUBLIC
797
+ )
798
+
799
+ absl_cc_test(
800
+ NAME
801
+ layout_test
802
+ SRCS
803
+ "internal/layout_test.cc"
804
+ COPTS
805
+ ${ABSL_TEST_COPTS}
806
+ DEPS
807
+ absl::layout
808
+ absl::check
809
+ absl::config
810
+ absl::span
811
+ absl::utility
812
+ GTest::gmock_main
813
+ )
814
+
815
+ # Internal-only target, do not depend on directly.
816
+ absl_cc_library(
817
+ NAME
818
+ tracked
819
+ HDRS
820
+ "internal/tracked.h"
821
+ COPTS
822
+ ${ABSL_TEST_COPTS}
823
+ DEPS
824
+ absl::config
825
+ TESTONLY
826
+ )
827
+
828
+ # Internal-only target, do not depend on directly.
829
+ absl_cc_library(
830
+ NAME
831
+ unordered_map_constructor_test
832
+ HDRS
833
+ "internal/unordered_map_constructor_test.h"
834
+ COPTS
835
+ ${ABSL_TEST_COPTS}
836
+ DEPS
837
+ absl::hash_generator_testing
838
+ absl::hash_policy_testing
839
+ GTest::gmock
840
+ TESTONLY
841
+ )
842
+
843
+ # Internal-only target, do not depend on directly.
844
+ absl_cc_library(
845
+ NAME
846
+ unordered_map_lookup_test
847
+ HDRS
848
+ "internal/unordered_map_lookup_test.h"
849
+ COPTS
850
+ ${ABSL_TEST_COPTS}
851
+ DEPS
852
+ absl::hash_generator_testing
853
+ absl::hash_policy_testing
854
+ GTest::gmock
855
+ TESTONLY
856
+ )
857
+
858
+ # Internal-only target, do not depend on directly.
859
+ absl_cc_library(
860
+ NAME
861
+ unordered_map_members_test
862
+ HDRS
863
+ "internal/unordered_map_members_test.h"
864
+ COPTS
865
+ ${ABSL_TEST_COPTS}
866
+ DEPS
867
+ absl::type_traits
868
+ GTest::gmock
869
+ TESTONLY
870
+ )
871
+
872
+ # Internal-only target, do not depend on directly.
873
+ absl_cc_library(
874
+ NAME
875
+ unordered_map_modifiers_test
876
+ HDRS
877
+ "internal/unordered_map_modifiers_test.h"
878
+ COPTS
879
+ ${ABSL_TEST_COPTS}
880
+ DEPS
881
+ absl::hash_generator_testing
882
+ absl::hash_policy_testing
883
+ GTest::gmock
884
+ TESTONLY
885
+ )
886
+
887
+ # Internal-only target, do not depend on directly.
888
+ absl_cc_library(
889
+ NAME
890
+ unordered_set_constructor_test
891
+ HDRS
892
+ "internal/unordered_set_constructor_test.h"
893
+ COPTS
894
+ ${ABSL_TEST_COPTS}
895
+ DEPS
896
+ absl::hash_generator_testing
897
+ absl::hash_policy_testing
898
+ GTest::gmock
899
+ TESTONLY
900
+ )
901
+
902
+ # Internal-only target, do not depend on directly.
903
+ absl_cc_library(
904
+ NAME
905
+ unordered_set_lookup_test
906
+ HDRS
907
+ "internal/unordered_set_lookup_test.h"
908
+ COPTS
909
+ ${ABSL_TEST_COPTS}
910
+ DEPS
911
+ absl::hash_generator_testing
912
+ absl::hash_policy_testing
913
+ GTest::gmock
914
+ TESTONLY
915
+ )
916
+
917
+ # Internal-only target, do not depend on directly.
918
+ absl_cc_library(
919
+ NAME
920
+ unordered_set_members_test
921
+ HDRS
922
+ "internal/unordered_set_members_test.h"
923
+ COPTS
924
+ ${ABSL_TEST_COPTS}
925
+ DEPS
926
+ absl::type_traits
927
+ GTest::gmock
928
+ TESTONLY
929
+ )
930
+
931
+ # Internal-only target, do not depend on directly.
932
+ absl_cc_library(
933
+ NAME
934
+ unordered_set_modifiers_test
935
+ HDRS
936
+ "internal/unordered_set_modifiers_test.h"
937
+ COPTS
938
+ ${ABSL_TEST_COPTS}
939
+ DEPS
940
+ absl::hash_generator_testing
941
+ absl::hash_policy_testing
942
+ GTest::gmock
943
+ TESTONLY
944
+ )
945
+
946
+ absl_cc_test(
947
+ NAME
948
+ unordered_set_test
949
+ SRCS
950
+ "internal/unordered_set_test.cc"
951
+ COPTS
952
+ ${ABSL_TEST_COPTS}
953
+ DEPS
954
+ absl::unordered_set_constructor_test
955
+ absl::unordered_set_lookup_test
956
+ absl::unordered_set_members_test
957
+ absl::unordered_set_modifiers_test
958
+ GTest::gmock_main
959
+ )
960
+
961
+ absl_cc_test(
962
+ NAME
963
+ unordered_map_test
964
+ SRCS
965
+ "internal/unordered_map_test.cc"
966
+ COPTS
967
+ ${ABSL_TEST_COPTS}
968
+ DEPS
969
+ absl::unordered_map_constructor_test
970
+ absl::unordered_map_lookup_test
971
+ absl::unordered_map_members_test
972
+ absl::unordered_map_modifiers_test
973
+ GTest::gmock_main
974
+ )
975
+
976
+ absl_cc_test(
977
+ NAME
978
+ sample_element_size_test
979
+ SRCS
980
+ "sample_element_size_test.cc"
981
+ COPTS
982
+ ${ABSL_TEST_COPTS}
983
+ DEPS
984
+ absl::flat_hash_map
985
+ absl::flat_hash_set
986
+ absl::node_hash_map
987
+ absl::node_hash_set
988
+ GTest::gmock_main
989
+ )
weight/_dep/abseil-cpp/absl/container/fixed_array.h ADDED
@@ -0,0 +1,556 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2018 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+ // -----------------------------------------------------------------------------
16
+ // File: fixed_array.h
17
+ // -----------------------------------------------------------------------------
18
+ //
19
+ // A `FixedArray<T>` represents a non-resizable array of `T` where the length of
20
+ // the array can be determined at run-time. It is a good replacement for
21
+ // non-standard and deprecated uses of `alloca()` and variable length arrays
22
+ // within the GCC extension. (See
23
+ // https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html).
24
+ //
25
+ // `FixedArray` allocates small arrays inline, keeping performance fast by
26
+ // avoiding heap operations. It also helps reduce the chances of
27
+ // accidentally overflowing your stack if large input is passed to
28
+ // your function.
29
+
30
+ #ifndef ABSL_CONTAINER_FIXED_ARRAY_H_
31
+ #define ABSL_CONTAINER_FIXED_ARRAY_H_
32
+
33
+ #include <algorithm>
34
+ #include <cassert>
35
+ #include <cstddef>
36
+ #include <initializer_list>
37
+ #include <iterator>
38
+ #include <limits>
39
+ #include <memory>
40
+ #include <new>
41
+ #include <type_traits>
42
+
43
+ #include "absl/algorithm/algorithm.h"
44
+ #include "absl/base/config.h"
45
+ #include "absl/base/dynamic_annotations.h"
46
+ #include "absl/base/internal/throw_delegate.h"
47
+ #include "absl/base/macros.h"
48
+ #include "absl/base/optimization.h"
49
+ #include "absl/base/port.h"
50
+ #include "absl/container/internal/compressed_tuple.h"
51
+ #include "absl/memory/memory.h"
52
+
53
+ namespace absl {
54
+ ABSL_NAMESPACE_BEGIN
55
+
56
+ constexpr static auto kFixedArrayUseDefault = static_cast<size_t>(-1);
57
+
58
+ // -----------------------------------------------------------------------------
59
+ // FixedArray
60
+ // -----------------------------------------------------------------------------
61
+ //
62
+ // A `FixedArray` provides a run-time fixed-size array, allocating a small array
63
+ // inline for efficiency.
64
+ //
65
+ // Most users should not specify the `N` template parameter and let `FixedArray`
66
+ // automatically determine the number of elements to store inline based on
67
+ // `sizeof(T)`. If `N` is specified, the `FixedArray` implementation will use
68
+ // inline storage for arrays with a length <= `N`.
69
+ //
70
+ // Note that a `FixedArray` constructed with a `size_type` argument will
71
+ // default-initialize its values by leaving trivially constructible types
72
+ // uninitialized (e.g. int, int[4], double), and others default-constructed.
73
+ // This matches the behavior of c-style arrays and `std::array`, but not
74
+ // `std::vector`.
75
+ template <typename T, size_t N = kFixedArrayUseDefault,
76
+ typename A = std::allocator<T>>
77
+ class FixedArray {
78
+ static_assert(!std::is_array<T>::value || std::extent<T>::value > 0,
79
+ "Arrays with unknown bounds cannot be used with FixedArray.");
80
+
81
+ static constexpr size_t kInlineBytesDefault = 256;
82
+
83
+ using AllocatorTraits = std::allocator_traits<A>;
84
+ // std::iterator_traits isn't guaranteed to be SFINAE-friendly until C++17,
85
+ // but this seems to be mostly pedantic.
86
+ template <typename Iterator>
87
+ using EnableIfForwardIterator = absl::enable_if_t<std::is_convertible<
88
+ typename std::iterator_traits<Iterator>::iterator_category,
89
+ std::forward_iterator_tag>::value>;
90
+ static constexpr bool NoexceptCopyable() {
91
+ return std::is_nothrow_copy_constructible<StorageElement>::value &&
92
+ absl::allocator_is_nothrow<allocator_type>::value;
93
+ }
94
+ static constexpr bool NoexceptMovable() {
95
+ return std::is_nothrow_move_constructible<StorageElement>::value &&
96
+ absl::allocator_is_nothrow<allocator_type>::value;
97
+ }
98
+ static constexpr bool DefaultConstructorIsNonTrivial() {
99
+ return !absl::is_trivially_default_constructible<StorageElement>::value;
100
+ }
101
+
102
+ public:
103
+ using allocator_type = typename AllocatorTraits::allocator_type;
104
+ using value_type = typename AllocatorTraits::value_type;
105
+ using pointer = typename AllocatorTraits::pointer;
106
+ using const_pointer = typename AllocatorTraits::const_pointer;
107
+ using reference = value_type&;
108
+ using const_reference = const value_type&;
109
+ using size_type = typename AllocatorTraits::size_type;
110
+ using difference_type = typename AllocatorTraits::difference_type;
111
+ using iterator = pointer;
112
+ using const_iterator = const_pointer;
113
+ using reverse_iterator = std::reverse_iterator<iterator>;
114
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
115
+
116
+ static constexpr size_type inline_elements =
117
+ (N == kFixedArrayUseDefault ? kInlineBytesDefault / sizeof(value_type)
118
+ : static_cast<size_type>(N));
119
+
120
+ FixedArray(const FixedArray& other) noexcept(NoexceptCopyable())
121
+ : FixedArray(other,
122
+ AllocatorTraits::select_on_container_copy_construction(
123
+ other.storage_.alloc())) {}
124
+
125
+ FixedArray(const FixedArray& other,
126
+ const allocator_type& a) noexcept(NoexceptCopyable())
127
+ : FixedArray(other.begin(), other.end(), a) {}
128
+
129
+ FixedArray(FixedArray&& other) noexcept(NoexceptMovable())
130
+ : FixedArray(std::move(other), other.storage_.alloc()) {}
131
+
132
+ FixedArray(FixedArray&& other,
133
+ const allocator_type& a) noexcept(NoexceptMovable())
134
+ : FixedArray(std::make_move_iterator(other.begin()),
135
+ std::make_move_iterator(other.end()), a) {}
136
+
137
+ // Creates an array object that can store `n` elements.
138
+ // Note that trivially constructible elements will be uninitialized.
139
+ explicit FixedArray(size_type n, const allocator_type& a = allocator_type())
140
+ : storage_(n, a) {
141
+ if (DefaultConstructorIsNonTrivial()) {
142
+ memory_internal::ConstructRange(storage_.alloc(), storage_.begin(),
143
+ storage_.end());
144
+ }
145
+ }
146
+
147
+ // Creates an array initialized with `n` copies of `val`.
148
+ FixedArray(size_type n, const value_type& val,
149
+ const allocator_type& a = allocator_type())
150
+ : storage_(n, a) {
151
+ memory_internal::ConstructRange(storage_.alloc(), storage_.begin(),
152
+ storage_.end(), val);
153
+ }
154
+
155
+ // Creates an array initialized with the size and contents of `init_list`.
156
+ FixedArray(std::initializer_list<value_type> init_list,
157
+ const allocator_type& a = allocator_type())
158
+ : FixedArray(init_list.begin(), init_list.end(), a) {}
159
+
160
+ // Creates an array initialized with the elements from the input
161
+ // range. The array's size will always be `std::distance(first, last)`.
162
+ // REQUIRES: Iterator must be a forward_iterator or better.
163
+ template <typename Iterator, EnableIfForwardIterator<Iterator>* = nullptr>
164
+ FixedArray(Iterator first, Iterator last,
165
+ const allocator_type& a = allocator_type())
166
+ : storage_(std::distance(first, last), a) {
167
+ memory_internal::CopyRange(storage_.alloc(), storage_.begin(), first, last);
168
+ }
169
+
170
+ ~FixedArray() noexcept {
171
+ for (auto* cur = storage_.begin(); cur != storage_.end(); ++cur) {
172
+ AllocatorTraits::destroy(storage_.alloc(), cur);
173
+ }
174
+ }
175
+
176
+ // Assignments are deleted because they break the invariant that the size of a
177
+ // `FixedArray` never changes.
178
+ void operator=(FixedArray&&) = delete;
179
+ void operator=(const FixedArray&) = delete;
180
+
181
+ // FixedArray::size()
182
+ //
183
+ // Returns the length of the fixed array.
184
+ size_type size() const { return storage_.size(); }
185
+
186
+ // FixedArray::max_size()
187
+ //
188
+ // Returns the largest possible value of `std::distance(begin(), end())` for a
189
+ // `FixedArray<T>`. This is equivalent to the most possible addressable bytes
190
+ // over the number of bytes taken by T.
191
+ constexpr size_type max_size() const {
192
+ return (std::numeric_limits<difference_type>::max)() / sizeof(value_type);
193
+ }
194
+
195
+ // FixedArray::empty()
196
+ //
197
+ // Returns whether or not the fixed array is empty.
198
+ bool empty() const { return size() == 0; }
199
+
200
+ // FixedArray::memsize()
201
+ //
202
+ // Returns the memory size of the fixed array in bytes.
203
+ size_t memsize() const { return size() * sizeof(value_type); }
204
+
205
+ // FixedArray::data()
206
+ //
207
+ // Returns a const T* pointer to elements of the `FixedArray`. This pointer
208
+ // can be used to access (but not modify) the contained elements.
209
+ const_pointer data() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
210
+ return AsValueType(storage_.begin());
211
+ }
212
+
213
+ // Overload of FixedArray::data() to return a T* pointer to elements of the
214
+ // fixed array. This pointer can be used to access and modify the contained
215
+ // elements.
216
+ pointer data() ABSL_ATTRIBUTE_LIFETIME_BOUND {
217
+ return AsValueType(storage_.begin());
218
+ }
219
+
220
+ // FixedArray::operator[]
221
+ //
222
+ // Returns a reference the ith element of the fixed array.
223
+ // REQUIRES: 0 <= i < size()
224
+ reference operator[](size_type i) ABSL_ATTRIBUTE_LIFETIME_BOUND {
225
+ ABSL_HARDENING_ASSERT(i < size());
226
+ return data()[i];
227
+ }
228
+
229
+ // Overload of FixedArray::operator()[] to return a const reference to the
230
+ // ith element of the fixed array.
231
+ // REQUIRES: 0 <= i < size()
232
+ const_reference operator[](size_type i) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
233
+ ABSL_HARDENING_ASSERT(i < size());
234
+ return data()[i];
235
+ }
236
+
237
+ // FixedArray::at
238
+ //
239
+ // Bounds-checked access. Returns a reference to the ith element of the fixed
240
+ // array, or throws std::out_of_range
241
+ reference at(size_type i) ABSL_ATTRIBUTE_LIFETIME_BOUND {
242
+ if (ABSL_PREDICT_FALSE(i >= size())) {
243
+ base_internal::ThrowStdOutOfRange("FixedArray::at failed bounds check");
244
+ }
245
+ return data()[i];
246
+ }
247
+
248
+ // Overload of FixedArray::at() to return a const reference to the ith element
249
+ // of the fixed array.
250
+ const_reference at(size_type i) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
251
+ if (ABSL_PREDICT_FALSE(i >= size())) {
252
+ base_internal::ThrowStdOutOfRange("FixedArray::at failed bounds check");
253
+ }
254
+ return data()[i];
255
+ }
256
+
257
+ // FixedArray::front()
258
+ //
259
+ // Returns a reference to the first element of the fixed array.
260
+ reference front() ABSL_ATTRIBUTE_LIFETIME_BOUND {
261
+ ABSL_HARDENING_ASSERT(!empty());
262
+ return data()[0];
263
+ }
264
+
265
+ // Overload of FixedArray::front() to return a reference to the first element
266
+ // of a fixed array of const values.
267
+ const_reference front() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
268
+ ABSL_HARDENING_ASSERT(!empty());
269
+ return data()[0];
270
+ }
271
+
272
+ // FixedArray::back()
273
+ //
274
+ // Returns a reference to the last element of the fixed array.
275
+ reference back() ABSL_ATTRIBUTE_LIFETIME_BOUND {
276
+ ABSL_HARDENING_ASSERT(!empty());
277
+ return data()[size() - 1];
278
+ }
279
+
280
+ // Overload of FixedArray::back() to return a reference to the last element
281
+ // of a fixed array of const values.
282
+ const_reference back() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
283
+ ABSL_HARDENING_ASSERT(!empty());
284
+ return data()[size() - 1];
285
+ }
286
+
287
+ // FixedArray::begin()
288
+ //
289
+ // Returns an iterator to the beginning of the fixed array.
290
+ iterator begin() ABSL_ATTRIBUTE_LIFETIME_BOUND { return data(); }
291
+
292
+ // Overload of FixedArray::begin() to return a const iterator to the
293
+ // beginning of the fixed array.
294
+ const_iterator begin() const ABSL_ATTRIBUTE_LIFETIME_BOUND { return data(); }
295
+
296
+ // FixedArray::cbegin()
297
+ //
298
+ // Returns a const iterator to the beginning of the fixed array.
299
+ const_iterator cbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
300
+ return begin();
301
+ }
302
+
303
+ // FixedArray::end()
304
+ //
305
+ // Returns an iterator to the end of the fixed array.
306
+ iterator end() ABSL_ATTRIBUTE_LIFETIME_BOUND { return data() + size(); }
307
+
308
+ // Overload of FixedArray::end() to return a const iterator to the end of the
309
+ // fixed array.
310
+ const_iterator end() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
311
+ return data() + size();
312
+ }
313
+
314
+ // FixedArray::cend()
315
+ //
316
+ // Returns a const iterator to the end of the fixed array.
317
+ const_iterator cend() const ABSL_ATTRIBUTE_LIFETIME_BOUND { return end(); }
318
+
319
+ // FixedArray::rbegin()
320
+ //
321
+ // Returns a reverse iterator from the end of the fixed array.
322
+ reverse_iterator rbegin() ABSL_ATTRIBUTE_LIFETIME_BOUND {
323
+ return reverse_iterator(end());
324
+ }
325
+
326
+ // Overload of FixedArray::rbegin() to return a const reverse iterator from
327
+ // the end of the fixed array.
328
+ const_reverse_iterator rbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
329
+ return const_reverse_iterator(end());
330
+ }
331
+
332
+ // FixedArray::crbegin()
333
+ //
334
+ // Returns a const reverse iterator from the end of the fixed array.
335
+ const_reverse_iterator crbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
336
+ return rbegin();
337
+ }
338
+
339
+ // FixedArray::rend()
340
+ //
341
+ // Returns a reverse iterator from the beginning of the fixed array.
342
+ reverse_iterator rend() ABSL_ATTRIBUTE_LIFETIME_BOUND {
343
+ return reverse_iterator(begin());
344
+ }
345
+
346
+ // Overload of FixedArray::rend() for returning a const reverse iterator
347
+ // from the beginning of the fixed array.
348
+ const_reverse_iterator rend() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
349
+ return const_reverse_iterator(begin());
350
+ }
351
+
352
+ // FixedArray::crend()
353
+ //
354
+ // Returns a reverse iterator from the beginning of the fixed array.
355
+ const_reverse_iterator crend() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
356
+ return rend();
357
+ }
358
+
359
+ // FixedArray::fill()
360
+ //
361
+ // Assigns the given `value` to all elements in the fixed array.
362
+ void fill(const value_type& val) { std::fill(begin(), end(), val); }
363
+
364
+ // Relational operators. Equality operators are elementwise using
365
+ // `operator==`, while order operators order FixedArrays lexicographically.
366
+ friend bool operator==(const FixedArray& lhs, const FixedArray& rhs) {
367
+ return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
368
+ }
369
+
370
+ friend bool operator!=(const FixedArray& lhs, const FixedArray& rhs) {
371
+ return !(lhs == rhs);
372
+ }
373
+
374
+ friend bool operator<(const FixedArray& lhs, const FixedArray& rhs) {
375
+ return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(),
376
+ rhs.end());
377
+ }
378
+
379
+ friend bool operator>(const FixedArray& lhs, const FixedArray& rhs) {
380
+ return rhs < lhs;
381
+ }
382
+
383
+ friend bool operator<=(const FixedArray& lhs, const FixedArray& rhs) {
384
+ return !(rhs < lhs);
385
+ }
386
+
387
+ friend bool operator>=(const FixedArray& lhs, const FixedArray& rhs) {
388
+ return !(lhs < rhs);
389
+ }
390
+
391
+ template <typename H>
392
+ friend H AbslHashValue(H h, const FixedArray& v) {
393
+ return H::combine(H::combine_contiguous(std::move(h), v.data(), v.size()),
394
+ v.size());
395
+ }
396
+
397
+ private:
398
+ // StorageElement
399
+ //
400
+ // For FixedArrays with a C-style-array value_type, StorageElement is a POD
401
+ // wrapper struct called StorageElementWrapper that holds the value_type
402
+ // instance inside. This is needed for construction and destruction of the
403
+ // entire array regardless of how many dimensions it has. For all other cases,
404
+ // StorageElement is just an alias of value_type.
405
+ //
406
+ // Maintainer's Note: The simpler solution would be to simply wrap value_type
407
+ // in a struct whether it's an array or not. That causes some paranoid
408
+ // diagnostics to misfire, believing that 'data()' returns a pointer to a
409
+ // single element, rather than the packed array that it really is.
410
+ // e.g.:
411
+ //
412
+ // FixedArray<char> buf(1);
413
+ // sprintf(buf.data(), "foo");
414
+ //
415
+ // error: call to int __builtin___sprintf_chk(etc...)
416
+ // will always overflow destination buffer [-Werror]
417
+ //
418
+ template <typename OuterT, typename InnerT = absl::remove_extent_t<OuterT>,
419
+ size_t InnerN = std::extent<OuterT>::value>
420
+ struct StorageElementWrapper {
421
+ InnerT array[InnerN];
422
+ };
423
+
424
+ using StorageElement =
425
+ absl::conditional_t<std::is_array<value_type>::value,
426
+ StorageElementWrapper<value_type>, value_type>;
427
+
428
+ static pointer AsValueType(pointer ptr) { return ptr; }
429
+ static pointer AsValueType(StorageElementWrapper<value_type>* ptr) {
430
+ return std::addressof(ptr->array);
431
+ }
432
+
433
+ static_assert(sizeof(StorageElement) == sizeof(value_type), "");
434
+ static_assert(alignof(StorageElement) == alignof(value_type), "");
435
+
436
+ class NonEmptyInlinedStorage {
437
+ public:
438
+ StorageElement* data() { return reinterpret_cast<StorageElement*>(buff_); }
439
+ void AnnotateConstruct(size_type n);
440
+ void AnnotateDestruct(size_type n);
441
+
442
+ #ifdef ABSL_HAVE_ADDRESS_SANITIZER
443
+ void* RedzoneBegin() { return &redzone_begin_; }
444
+ void* RedzoneEnd() { return &redzone_end_ + 1; }
445
+ #endif // ABSL_HAVE_ADDRESS_SANITIZER
446
+
447
+ private:
448
+ ABSL_ADDRESS_SANITIZER_REDZONE(redzone_begin_);
449
+ alignas(StorageElement) char buff_[sizeof(StorageElement[inline_elements])];
450
+ ABSL_ADDRESS_SANITIZER_REDZONE(redzone_end_);
451
+ };
452
+
453
+ class EmptyInlinedStorage {
454
+ public:
455
+ StorageElement* data() { return nullptr; }
456
+ void AnnotateConstruct(size_type) {}
457
+ void AnnotateDestruct(size_type) {}
458
+ };
459
+
460
+ using InlinedStorage =
461
+ absl::conditional_t<inline_elements == 0, EmptyInlinedStorage,
462
+ NonEmptyInlinedStorage>;
463
+
464
+ // Storage
465
+ //
466
+ // An instance of Storage manages the inline and out-of-line memory for
467
+ // instances of FixedArray. This guarantees that even when construction of
468
+ // individual elements fails in the FixedArray constructor body, the
469
+ // destructor for Storage will still be called and out-of-line memory will be
470
+ // properly deallocated.
471
+ //
472
+ class Storage : public InlinedStorage {
473
+ public:
474
+ Storage(size_type n, const allocator_type& a)
475
+ : size_alloc_(n, a), data_(InitializeData()) {}
476
+
477
+ ~Storage() noexcept {
478
+ if (UsingInlinedStorage(size())) {
479
+ InlinedStorage::AnnotateDestruct(size());
480
+ } else {
481
+ AllocatorTraits::deallocate(alloc(), AsValueType(begin()), size());
482
+ }
483
+ }
484
+
485
+ size_type size() const { return size_alloc_.template get<0>(); }
486
+ StorageElement* begin() const { return data_; }
487
+ StorageElement* end() const { return begin() + size(); }
488
+ allocator_type& alloc() { return size_alloc_.template get<1>(); }
489
+ const allocator_type& alloc() const {
490
+ return size_alloc_.template get<1>();
491
+ }
492
+
493
+ private:
494
+ static bool UsingInlinedStorage(size_type n) {
495
+ return n <= inline_elements;
496
+ }
497
+
498
+ #ifdef ABSL_HAVE_ADDRESS_SANITIZER
499
+ ABSL_ATTRIBUTE_NOINLINE
500
+ #endif // ABSL_HAVE_ADDRESS_SANITIZER
501
+ StorageElement* InitializeData() {
502
+ if (UsingInlinedStorage(size())) {
503
+ InlinedStorage::AnnotateConstruct(size());
504
+ return InlinedStorage::data();
505
+ } else {
506
+ return reinterpret_cast<StorageElement*>(
507
+ AllocatorTraits::allocate(alloc(), size()));
508
+ }
509
+ }
510
+
511
+ // `CompressedTuple` takes advantage of EBCO for stateless `allocator_type`s
512
+ container_internal::CompressedTuple<size_type, allocator_type> size_alloc_;
513
+ StorageElement* data_;
514
+ };
515
+
516
+ Storage storage_;
517
+ };
518
+
519
+ #ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
520
+ template <typename T, size_t N, typename A>
521
+ constexpr size_t FixedArray<T, N, A>::kInlineBytesDefault;
522
+
523
+ template <typename T, size_t N, typename A>
524
+ constexpr typename FixedArray<T, N, A>::size_type
525
+ FixedArray<T, N, A>::inline_elements;
526
+ #endif
527
+
528
+ template <typename T, size_t N, typename A>
529
+ void FixedArray<T, N, A>::NonEmptyInlinedStorage::AnnotateConstruct(
530
+ typename FixedArray<T, N, A>::size_type n) {
531
+ #ifdef ABSL_HAVE_ADDRESS_SANITIZER
532
+ if (!n) return;
533
+ ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(data(), RedzoneEnd(), RedzoneEnd(),
534
+ data() + n);
535
+ ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(RedzoneBegin(), data(), data(),
536
+ RedzoneBegin());
537
+ #endif // ABSL_HAVE_ADDRESS_SANITIZER
538
+ static_cast<void>(n); // Mark used when not in asan mode
539
+ }
540
+
541
+ template <typename T, size_t N, typename A>
542
+ void FixedArray<T, N, A>::NonEmptyInlinedStorage::AnnotateDestruct(
543
+ typename FixedArray<T, N, A>::size_type n) {
544
+ #ifdef ABSL_HAVE_ADDRESS_SANITIZER
545
+ if (!n) return;
546
+ ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(data(), RedzoneEnd(), data() + n,
547
+ RedzoneEnd());
548
+ ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(RedzoneBegin(), data(), RedzoneBegin(),
549
+ data());
550
+ #endif // ABSL_HAVE_ADDRESS_SANITIZER
551
+ static_cast<void>(n); // Mark used when not in asan mode
552
+ }
553
+ ABSL_NAMESPACE_END
554
+ } // namespace absl
555
+
556
+ #endif // ABSL_CONTAINER_FIXED_ARRAY_H_
weight/_dep/abseil-cpp/absl/container/fixed_array_benchmark.cc ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2019 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include <stddef.h>
16
+
17
+ #include <string>
18
+
19
+ #include "absl/container/fixed_array.h"
20
+ #include "benchmark/benchmark.h"
21
+
22
+ namespace {
23
+
24
+ // For benchmarking -- simple class with constructor and destructor that
25
+ // set an int to a constant..
26
+ class SimpleClass {
27
+ public:
28
+ SimpleClass() : i(3) {}
29
+ ~SimpleClass() { i = 0; }
30
+
31
+ private:
32
+ int i;
33
+ };
34
+
35
+ template <typename C, size_t stack_size>
36
+ void BM_FixedArray(benchmark::State& state) {
37
+ const int size = state.range(0);
38
+ for (auto _ : state) {
39
+ absl::FixedArray<C, stack_size> fa(size);
40
+ benchmark::DoNotOptimize(fa.data());
41
+ }
42
+ }
43
+ BENCHMARK_TEMPLATE(BM_FixedArray, char, absl::kFixedArrayUseDefault)
44
+ ->Range(0, 1 << 16);
45
+ BENCHMARK_TEMPLATE(BM_FixedArray, char, 0)->Range(0, 1 << 16);
46
+ BENCHMARK_TEMPLATE(BM_FixedArray, char, 1)->Range(0, 1 << 16);
47
+ BENCHMARK_TEMPLATE(BM_FixedArray, char, 16)->Range(0, 1 << 16);
48
+ BENCHMARK_TEMPLATE(BM_FixedArray, char, 256)->Range(0, 1 << 16);
49
+ BENCHMARK_TEMPLATE(BM_FixedArray, char, 65536)->Range(0, 1 << 16);
50
+
51
+ BENCHMARK_TEMPLATE(BM_FixedArray, SimpleClass, absl::kFixedArrayUseDefault)
52
+ ->Range(0, 1 << 16);
53
+ BENCHMARK_TEMPLATE(BM_FixedArray, SimpleClass, 0)->Range(0, 1 << 16);
54
+ BENCHMARK_TEMPLATE(BM_FixedArray, SimpleClass, 1)->Range(0, 1 << 16);
55
+ BENCHMARK_TEMPLATE(BM_FixedArray, SimpleClass, 16)->Range(0, 1 << 16);
56
+ BENCHMARK_TEMPLATE(BM_FixedArray, SimpleClass, 256)->Range(0, 1 << 16);
57
+ BENCHMARK_TEMPLATE(BM_FixedArray, SimpleClass, 65536)->Range(0, 1 << 16);
58
+
59
+ BENCHMARK_TEMPLATE(BM_FixedArray, std::string, absl::kFixedArrayUseDefault)
60
+ ->Range(0, 1 << 16);
61
+ BENCHMARK_TEMPLATE(BM_FixedArray, std::string, 0)->Range(0, 1 << 16);
62
+ BENCHMARK_TEMPLATE(BM_FixedArray, std::string, 1)->Range(0, 1 << 16);
63
+ BENCHMARK_TEMPLATE(BM_FixedArray, std::string, 16)->Range(0, 1 << 16);
64
+ BENCHMARK_TEMPLATE(BM_FixedArray, std::string, 256)->Range(0, 1 << 16);
65
+ BENCHMARK_TEMPLATE(BM_FixedArray, std::string, 65536)->Range(0, 1 << 16);
66
+
67
+ } // namespace
weight/_dep/abseil-cpp/absl/container/fixed_array_exception_safety_test.cc ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2019 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include "absl/base/config.h"
16
+ #include "absl/container/fixed_array.h"
17
+
18
+ #ifdef ABSL_HAVE_EXCEPTIONS
19
+
20
+ #include <initializer_list>
21
+
22
+ #include "gtest/gtest.h"
23
+ #include "absl/base/internal/exception_safety_testing.h"
24
+
25
+ namespace absl {
26
+ ABSL_NAMESPACE_BEGIN
27
+
28
+ namespace {
29
+
30
+ constexpr size_t kInlined = 25;
31
+ constexpr size_t kSmallSize = kInlined / 2;
32
+ constexpr size_t kLargeSize = kInlined * 2;
33
+
34
+ constexpr int kInitialValue = 5;
35
+ constexpr int kUpdatedValue = 10;
36
+
37
+ using ::testing::TestThrowingCtor;
38
+
39
+ using Thrower = testing::ThrowingValue<testing::TypeSpec::kEverythingThrows>;
40
+ using ThrowAlloc =
41
+ testing::ThrowingAllocator<Thrower, testing::AllocSpec::kEverythingThrows>;
42
+ using MoveThrower = testing::ThrowingValue<testing::TypeSpec::kNoThrowMove>;
43
+ using MoveThrowAlloc =
44
+ testing::ThrowingAllocator<MoveThrower,
45
+ testing::AllocSpec::kEverythingThrows>;
46
+
47
+ using FixedArr = absl::FixedArray<Thrower, kInlined>;
48
+ using FixedArrWithAlloc = absl::FixedArray<Thrower, kInlined, ThrowAlloc>;
49
+
50
+ using MoveFixedArr = absl::FixedArray<MoveThrower, kInlined>;
51
+ using MoveFixedArrWithAlloc =
52
+ absl::FixedArray<MoveThrower, kInlined, MoveThrowAlloc>;
53
+
54
+ TEST(FixedArrayExceptionSafety, CopyConstructor) {
55
+ auto small = FixedArr(kSmallSize);
56
+ TestThrowingCtor<FixedArr>(small);
57
+
58
+ auto large = FixedArr(kLargeSize);
59
+ TestThrowingCtor<FixedArr>(large);
60
+ }
61
+
62
+ TEST(FixedArrayExceptionSafety, CopyConstructorWithAlloc) {
63
+ auto small = FixedArrWithAlloc(kSmallSize);
64
+ TestThrowingCtor<FixedArrWithAlloc>(small);
65
+
66
+ auto large = FixedArrWithAlloc(kLargeSize);
67
+ TestThrowingCtor<FixedArrWithAlloc>(large);
68
+ }
69
+
70
+ TEST(FixedArrayExceptionSafety, MoveConstructor) {
71
+ TestThrowingCtor<FixedArr>(FixedArr(kSmallSize));
72
+ TestThrowingCtor<FixedArr>(FixedArr(kLargeSize));
73
+
74
+ // TypeSpec::kNoThrowMove
75
+ TestThrowingCtor<MoveFixedArr>(MoveFixedArr(kSmallSize));
76
+ TestThrowingCtor<MoveFixedArr>(MoveFixedArr(kLargeSize));
77
+ }
78
+
79
+ TEST(FixedArrayExceptionSafety, MoveConstructorWithAlloc) {
80
+ TestThrowingCtor<FixedArrWithAlloc>(FixedArrWithAlloc(kSmallSize));
81
+ TestThrowingCtor<FixedArrWithAlloc>(FixedArrWithAlloc(kLargeSize));
82
+
83
+ // TypeSpec::kNoThrowMove
84
+ TestThrowingCtor<MoveFixedArrWithAlloc>(MoveFixedArrWithAlloc(kSmallSize));
85
+ TestThrowingCtor<MoveFixedArrWithAlloc>(MoveFixedArrWithAlloc(kLargeSize));
86
+ }
87
+
88
+ TEST(FixedArrayExceptionSafety, SizeConstructor) {
89
+ TestThrowingCtor<FixedArr>(kSmallSize);
90
+ TestThrowingCtor<FixedArr>(kLargeSize);
91
+ }
92
+
93
+ TEST(FixedArrayExceptionSafety, SizeConstructorWithAlloc) {
94
+ TestThrowingCtor<FixedArrWithAlloc>(kSmallSize);
95
+ TestThrowingCtor<FixedArrWithAlloc>(kLargeSize);
96
+ }
97
+
98
+ TEST(FixedArrayExceptionSafety, SizeValueConstructor) {
99
+ TestThrowingCtor<FixedArr>(kSmallSize, Thrower());
100
+ TestThrowingCtor<FixedArr>(kLargeSize, Thrower());
101
+ }
102
+
103
+ TEST(FixedArrayExceptionSafety, SizeValueConstructorWithAlloc) {
104
+ TestThrowingCtor<FixedArrWithAlloc>(kSmallSize, Thrower());
105
+ TestThrowingCtor<FixedArrWithAlloc>(kLargeSize, Thrower());
106
+ }
107
+
108
+ TEST(FixedArrayExceptionSafety, IteratorConstructor) {
109
+ auto small = FixedArr(kSmallSize);
110
+ TestThrowingCtor<FixedArr>(small.begin(), small.end());
111
+
112
+ auto large = FixedArr(kLargeSize);
113
+ TestThrowingCtor<FixedArr>(large.begin(), large.end());
114
+ }
115
+
116
+ TEST(FixedArrayExceptionSafety, IteratorConstructorWithAlloc) {
117
+ auto small = FixedArrWithAlloc(kSmallSize);
118
+ TestThrowingCtor<FixedArrWithAlloc>(small.begin(), small.end());
119
+
120
+ auto large = FixedArrWithAlloc(kLargeSize);
121
+ TestThrowingCtor<FixedArrWithAlloc>(large.begin(), large.end());
122
+ }
123
+
124
+ TEST(FixedArrayExceptionSafety, InitListConstructor) {
125
+ constexpr int small_inlined = 3;
126
+ using SmallFixedArr = absl::FixedArray<Thrower, small_inlined>;
127
+
128
+ TestThrowingCtor<SmallFixedArr>(std::initializer_list<Thrower>{});
129
+ // Test inlined allocation
130
+ TestThrowingCtor<SmallFixedArr>(
131
+ std::initializer_list<Thrower>{Thrower{}, Thrower{}});
132
+ // Test out of line allocation
133
+ TestThrowingCtor<SmallFixedArr>(std::initializer_list<Thrower>{
134
+ Thrower{}, Thrower{}, Thrower{}, Thrower{}, Thrower{}});
135
+ }
136
+
137
+ TEST(FixedArrayExceptionSafety, InitListConstructorWithAlloc) {
138
+ constexpr int small_inlined = 3;
139
+ using SmallFixedArrWithAlloc =
140
+ absl::FixedArray<Thrower, small_inlined, ThrowAlloc>;
141
+
142
+ TestThrowingCtor<SmallFixedArrWithAlloc>(std::initializer_list<Thrower>{});
143
+ // Test inlined allocation
144
+ TestThrowingCtor<SmallFixedArrWithAlloc>(
145
+ std::initializer_list<Thrower>{Thrower{}, Thrower{}});
146
+ // Test out of line allocation
147
+ TestThrowingCtor<SmallFixedArrWithAlloc>(std::initializer_list<Thrower>{
148
+ Thrower{}, Thrower{}, Thrower{}, Thrower{}, Thrower{}});
149
+ }
150
+
151
+ template <typename FixedArrT>
152
+ testing::AssertionResult ReadMemory(FixedArrT* fixed_arr) {
153
+ int sum = 0;
154
+ for (const auto& thrower : *fixed_arr) {
155
+ sum += thrower.Get();
156
+ }
157
+ return testing::AssertionSuccess() << "Values sum to [" << sum << "]";
158
+ }
159
+
160
+ TEST(FixedArrayExceptionSafety, Fill) {
161
+ auto test_fill = testing::MakeExceptionSafetyTester()
162
+ .WithContracts(ReadMemory<FixedArr>)
163
+ .WithOperation([&](FixedArr* fixed_arr_ptr) {
164
+ auto thrower =
165
+ Thrower(kUpdatedValue, testing::nothrow_ctor);
166
+ fixed_arr_ptr->fill(thrower);
167
+ });
168
+
169
+ EXPECT_TRUE(
170
+ test_fill.WithInitialValue(FixedArr(kSmallSize, Thrower(kInitialValue)))
171
+ .Test());
172
+ EXPECT_TRUE(
173
+ test_fill.WithInitialValue(FixedArr(kLargeSize, Thrower(kInitialValue)))
174
+ .Test());
175
+ }
176
+
177
+ TEST(FixedArrayExceptionSafety, FillWithAlloc) {
178
+ auto test_fill = testing::MakeExceptionSafetyTester()
179
+ .WithContracts(ReadMemory<FixedArrWithAlloc>)
180
+ .WithOperation([&](FixedArrWithAlloc* fixed_arr_ptr) {
181
+ auto thrower =
182
+ Thrower(kUpdatedValue, testing::nothrow_ctor);
183
+ fixed_arr_ptr->fill(thrower);
184
+ });
185
+
186
+ EXPECT_TRUE(test_fill
187
+ .WithInitialValue(
188
+ FixedArrWithAlloc(kSmallSize, Thrower(kInitialValue)))
189
+ .Test());
190
+ EXPECT_TRUE(test_fill
191
+ .WithInitialValue(
192
+ FixedArrWithAlloc(kLargeSize, Thrower(kInitialValue)))
193
+ .Test());
194
+ }
195
+
196
+ } // namespace
197
+
198
+ ABSL_NAMESPACE_END
199
+ } // namespace absl
200
+
201
+ #endif // ABSL_HAVE_EXCEPTIONS