react-native-windows 0.78.4 → 0.78.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Directory.Build.props +6 -4
- package/Folly/Folly.vcxproj +46 -6
- package/Folly/Folly.vcxproj.filters +16 -4
- package/Folly/TEMP_UntilFollyUpdate/ConstexprMath.h +26 -18
- package/Folly/TEMP_UntilFollyUpdate/Conv.cpp +1205 -0
- package/Folly/TEMP_UntilFollyUpdate/chrono/Hardware.h +155 -0
- package/Folly/TEMP_UntilFollyUpdate/concurrency/CacheLocality.cpp +633 -0
- package/Folly/TEMP_UntilFollyUpdate/{dynamic-inl.h → json/dynamic-inl.h} +3 -4
- package/Folly/TEMP_UntilFollyUpdate/{json.cpp → json/json.cpp} +14 -10
- package/Folly/TEMP_UntilFollyUpdate/lang/SafeAssert.h +7 -14
- package/Folly/TEMP_UntilFollyUpdate/lang/ToAscii.h +6 -6
- package/Folly/ThreadNameStub.cpp +10 -0
- package/Folly/cgmanifest.json +11 -1
- package/Libraries/Components/View/View.windows.js +107 -56
- package/Libraries/Components/View/ViewAccessibility.d.ts +60 -1
- package/Libraries/Image/Image.windows.js +42 -21
- package/Libraries/Modal/Modal.d.ts +7 -0
- package/Libraries/Modal/Modal.windows.js +7 -1
- package/Libraries/NativeComponent/BaseViewConfig.windows.js +3 -0
- package/Libraries/Text/Text.d.ts +18 -0
- package/Microsoft.ReactNative/AsynchronousEventBeat.cpp +4 -25
- package/Microsoft.ReactNative/AsynchronousEventBeat.h +0 -3
- package/Microsoft.ReactNative/Base/FollyIncludes.h +1 -0
- package/Microsoft.ReactNative/CallInvoker.cpp +42 -0
- package/Microsoft.ReactNative/CallInvoker.h +34 -0
- package/Microsoft.ReactNative/{JSDispatcherWriter.cpp → CallInvokerWriter.cpp} +35 -47
- package/Microsoft.ReactNative/CallInvokerWriter.h +74 -0
- package/Microsoft.ReactNative/CompositionComponentView.idl +0 -5
- package/Microsoft.ReactNative/CompositionSwitcher.idl +7 -0
- package/Microsoft.ReactNative/Fabric/AbiViewProps.cpp +8 -10
- package/Microsoft.ReactNative/Fabric/ComponentView.cpp +4 -1
- package/Microsoft.ReactNative/Fabric/Composition/ActivityIndicatorComponentView.cpp +12 -2
- package/Microsoft.ReactNative/Fabric/Composition/ActivityIndicatorComponentView.h +2 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionAnnotationProvider.cpp +100 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionAnnotationProvider.h +31 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionContextHelper.cpp +77 -11
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +43 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h +7 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +86 -56
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +5 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +0 -4
- package/Microsoft.ReactNative/Fabric/Composition/CompositionUIService.cpp +0 -2
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +118 -63
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +2 -0
- package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp +133 -8
- package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.h +16 -2
- package/Microsoft.ReactNative/Fabric/Composition/FocusManager.cpp +4 -2
- package/Microsoft.ReactNative/Fabric/Composition/FocusManager.h +9 -1
- package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp +34 -11
- package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.h +3 -0
- package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +133 -135
- package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp +9 -6
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +46 -49
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +6 -1
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +13 -8
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +5 -2
- package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +146 -25
- package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h +14 -0
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +160 -12
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +6 -0
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputEventEmitter.cpp +47 -0
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputEventEmitter.h +15 -1
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputProps.cpp +6 -2
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputProps.h +4 -1
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.cpp +7 -9
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.h +4 -1
- package/Microsoft.ReactNative/Fabric/Composition/Theme.cpp +5 -0
- package/Microsoft.ReactNative/Fabric/Composition/TooltipService.cpp +40 -36
- package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +68 -0
- package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h +11 -0
- package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +70 -13
- package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.h +10 -2
- package/Microsoft.ReactNative/Fabric/ImageManager.cpp +5 -5
- package/Microsoft.ReactNative/Fabric/ImageRequestParams.cpp +26 -0
- package/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp +47 -8
- package/Microsoft.ReactNative/Fabric/WindowsImageManager.h +10 -1
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/CompositionAccessibilityProps.h +67 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewEventEmitter.cpp +22 -4
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewEventEmitter.h +15 -2
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.cpp +20 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.h +5 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/MouseEvent.h +20 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/HostPlatformColor.h +5 -8
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/PlatformColorParser.h +1 -2
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/TextLayoutManager.cpp +247 -45
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/TextLayoutManager.h +15 -0
- package/Microsoft.ReactNative/Fabric/platform/react/threading/MessageQueueThreadImpl.cpp +39 -0
- package/Microsoft.ReactNative/Fabric/platform/react/threading/MessageQueueThreadImpl.h +54 -0
- package/Microsoft.ReactNative/Fabric/platform/react/threading/TaskDispatchThread.cpp +126 -0
- package/Microsoft.ReactNative/Fabric/platform/react/threading/TaskDispatchThread.h +73 -0
- package/Microsoft.ReactNative/IReactContext.cpp +17 -0
- package/Microsoft.ReactNative/IReactContext.h +1 -0
- package/Microsoft.ReactNative/IReactContext.idl +18 -1
- package/Microsoft.ReactNative/IReactDispatcher.idl +1 -0
- package/Microsoft.ReactNative/IReactModuleBuilder.cpp +12 -0
- package/Microsoft.ReactNative/IReactModuleBuilder.h +2 -0
- package/Microsoft.ReactNative/IReactModuleBuilder.idl +8 -0
- package/Microsoft.ReactNative/JsiApi.cpp +10 -2
- package/Microsoft.ReactNative/JsiApi.h +1 -0
- package/Microsoft.ReactNative/JsiApi.idl +1 -0
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +0 -3
- package/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp +2 -3
- package/Microsoft.ReactNative/Modules/AlertModule.cpp +7 -12
- package/Microsoft.ReactNative/Modules/Animated/AnimationDriver.cpp +2 -1
- package/Microsoft.ReactNative/Modules/Animated/NativeAnimatedModule.cpp +4 -8
- package/Microsoft.ReactNative/Modules/AppStateModule.cpp +2 -2
- package/Microsoft.ReactNative/Modules/ClipboardModule.cpp +6 -8
- package/Microsoft.ReactNative/Modules/ClipboardModule.h +1 -1
- package/Microsoft.ReactNative/Modules/ImageViewManagerModule.cpp +6 -15
- package/Microsoft.ReactNative/Modules/NativeUIManager.cpp +13 -24
- package/Microsoft.ReactNative/QuirkSettings.cpp +0 -16
- package/Microsoft.ReactNative/QuirkSettings.h +0 -3
- package/Microsoft.ReactNative/ReactHost/ReactHost.cpp +11 -1
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +78 -68
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +1 -2
- package/Microsoft.ReactNative/ReactInstanceSettings.cpp +12 -0
- package/Microsoft.ReactNative/ReactInstanceSettings.h +2 -0
- package/Microsoft.ReactNative/ReactInstanceSettings.idl +6 -0
- package/Microsoft.ReactNative/ReactNativeIsland.idl +3 -0
- package/Microsoft.ReactNative/ReactSupport.cpp +44 -11
- package/Microsoft.ReactNative/RedBox.cpp +30 -1
- package/Microsoft.ReactNative/SchedulerSettings.cpp +4 -4
- package/Microsoft.ReactNative/SchedulerSettings.h +1 -1
- package/Microsoft.ReactNative/TurboModulesProvider.cpp +30 -12
- package/Microsoft.ReactNative/Utils/ImageUtils.h +1 -0
- package/Microsoft.ReactNative/Utils/LocalBundleReader.cpp +37 -31
- package/Microsoft.ReactNative.Cxx/ApiLoaders/JSRuntimeApi.cpp +1 -0
- package/Microsoft.ReactNative.Cxx/ApiLoaders/JSRuntimeApi.inc +2 -0
- package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi_posix.cpp +1 -1
- package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.cpp +94 -27
- package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.h +27 -6
- package/Microsoft.ReactNative.Cxx/JSI/JsiApiContext.cpp +45 -11
- package/Microsoft.ReactNative.Cxx/JSI/JsiApiContext.h +6 -0
- package/Microsoft.ReactNative.Cxx/JSI/decorator.h +220 -0
- package/Microsoft.ReactNative.Cxx/JSI/instrumentation.h +28 -0
- package/Microsoft.ReactNative.Cxx/JSI/jsi-inl.h +6 -0
- package/Microsoft.ReactNative.Cxx/JSI/jsi.cpp +241 -4
- package/Microsoft.ReactNative.Cxx/JSI/jsi.h +207 -19
- package/Microsoft.ReactNative.Cxx/JSValue.cpp +19 -3
- package/Microsoft.ReactNative.Cxx/JSValue.h +15 -7
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +2 -2
- package/Microsoft.ReactNative.Cxx/NativeModules.h +60 -2
- package/Microsoft.ReactNative.Cxx/NodeApiJsiRuntime.cpp +1267 -614
- package/Microsoft.ReactNative.Cxx/NodeApiJsiRuntime.h +4 -2
- package/Microsoft.ReactNative.Cxx/ReactContext.h +7 -0
- package/Microsoft.ReactNative.Cxx/TurboModuleProvider.cpp +11 -13
- package/Microsoft.ReactNative.Cxx/TurboModuleProvider.h +2 -3
- package/Microsoft.ReactNative.Cxx/node-api/js_native_api.h +81 -20
- package/Microsoft.ReactNative.Cxx/node-api/js_native_api_types.h +47 -2
- package/Microsoft.ReactNative.Cxx/node-api/js_runtime_api.h +13 -0
- package/Microsoft.ReactNative.Cxx/stubs/glog/logging.h +1 -1
- package/Microsoft.ReactNative.Managed/ReactContext.cs +3 -1
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/PropertySheets/JSEngine.props +1 -1
- package/PropertySheets/React.Cpp.props +2 -1
- package/PropertySheets/WebView2.props +1 -1
- package/PropertySheets/WinUI.props +2 -2
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jserrorhandler/JsErrorHandler.cpp +429 -0
- package/ReactCommon/cgmanifest.json +1 -1
- package/Shared/HermesRuntimeHolder.cpp +6 -0
- package/Shared/JSI/ChakraRuntime.cpp +4 -0
- package/Shared/JSI/ChakraRuntime.h +2 -0
- package/Shared/Modules/BlobModule.cpp +14 -16
- package/Shared/Modules/BlobModule.h +3 -1
- package/Shared/Networking/WinRTWebSocketResource.cpp +82 -101
- package/Shared/Networking/WinRTWebSocketResource.h +91 -7
- package/Shared/Shared.vcxitems +11 -7
- package/Shared/Shared.vcxitems.filters +6 -1
- package/Shared/TurboModuleManager.cpp +0 -15
- package/codegen/react/components/rnwcore/ActivityIndicatorView.g.h +6 -6
- package/codegen/react/components/rnwcore/AndroidDrawerLayout.g.h +6 -6
- package/codegen/react/components/rnwcore/AndroidHorizontalScrollContentView.g.h +6 -6
- package/codegen/react/components/rnwcore/AndroidProgressBar.g.h +6 -6
- package/codegen/react/components/rnwcore/AndroidSwipeRefreshLayout.g.h +6 -6
- package/codegen/react/components/rnwcore/AndroidSwitch.g.h +6 -6
- package/codegen/react/components/rnwcore/DebuggingOverlay.g.h +6 -6
- package/codegen/react/components/rnwcore/InputAccessory.g.h +6 -6
- package/codegen/react/components/rnwcore/ModalHostView.g.h +11 -7
- package/codegen/react/components/rnwcore/Props.cpp +2 -1
- package/codegen/react/components/rnwcore/Props.h +1 -0
- package/codegen/react/components/rnwcore/PullToRefreshView.g.h +6 -6
- package/codegen/react/components/rnwcore/SafeAreaView.g.h +6 -6
- package/codegen/react/components/rnwcore/Switch.g.h +6 -6
- package/codegen/react/components/rnwcore/UnimplementedNativeView.g.h +6 -6
- package/index.windows.js +4 -2
- package/package.json +3 -4
- package/src/private/specs/components/RCTModalHostViewNativeComponent.js +8 -0
- package/stubs/glog/logging.h +1 -1
- package/Microsoft.ReactNative/JSDispatcherWriter.h +0 -47
- package/Microsoft.ReactNative/SynchronousEventBeat.cpp +0 -51
- package/Microsoft.ReactNative/SynchronousEventBeat.h +0 -31
|
@@ -0,0 +1,633 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
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
|
+
* http://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
|
+
#include <folly/concurrency/CacheLocality.h>
|
|
18
|
+
|
|
19
|
+
#ifndef _MSC_VER
|
|
20
|
+
#define _GNU_SOURCE 1 // for RTLD_NOLOAD
|
|
21
|
+
#include <dlfcn.h>
|
|
22
|
+
#endif
|
|
23
|
+
#include <fstream>
|
|
24
|
+
#include <mutex>
|
|
25
|
+
#include <numeric>
|
|
26
|
+
#include <optional>
|
|
27
|
+
|
|
28
|
+
#include <fmt/core.h>
|
|
29
|
+
#include <glog/logging.h>
|
|
30
|
+
#include <folly/Indestructible.h>
|
|
31
|
+
#include <folly/Memory.h>
|
|
32
|
+
#include <folly/ScopeGuard.h>
|
|
33
|
+
#include <folly/detail/StaticSingletonManager.h>
|
|
34
|
+
#include <folly/hash/Hash.h>
|
|
35
|
+
#include <folly/lang/Exception.h>
|
|
36
|
+
#include <folly/portability/Unistd.h>
|
|
37
|
+
#include <folly/system/ThreadId.h>
|
|
38
|
+
|
|
39
|
+
namespace folly {
|
|
40
|
+
|
|
41
|
+
///////////// CacheLocality
|
|
42
|
+
|
|
43
|
+
/// Returns the CacheLocality information best for this machine
|
|
44
|
+
static CacheLocality getSystemLocalityInfo() {
|
|
45
|
+
if (kIsLinux) {
|
|
46
|
+
// First try to parse /proc/cpuinfo.
|
|
47
|
+
// If that fails, then try to parse /sys/devices/.
|
|
48
|
+
// The latter is slower but more accurate.
|
|
49
|
+
try {
|
|
50
|
+
return CacheLocality::readFromProcCpuinfo();
|
|
51
|
+
} catch (...) {
|
|
52
|
+
// /proc/cpuinfo might be non-standard
|
|
53
|
+
// lets try with sysfs /sys/devices/cpu
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
return CacheLocality::readFromSysfs();
|
|
58
|
+
} catch (...) {
|
|
59
|
+
// keep trying
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
long numCpus = sysconf(_SC_NPROCESSORS_CONF);
|
|
64
|
+
if (numCpus <= 0) {
|
|
65
|
+
// This shouldn't happen, but if it does we should try to keep
|
|
66
|
+
// going. We are probably not going to be able to parse /sys on
|
|
67
|
+
// this box either (although we will try), which means we are going
|
|
68
|
+
// to fall back to the SequentialThreadId splitter. On my 16 core
|
|
69
|
+
// (x hyperthreading) dev box 16 stripes is enough to get pretty good
|
|
70
|
+
// contention avoidance with SequentialThreadId, and there is little
|
|
71
|
+
// improvement from going from 32 to 64. This default gives us some
|
|
72
|
+
// wiggle room
|
|
73
|
+
numCpus = 32;
|
|
74
|
+
}
|
|
75
|
+
return CacheLocality::uniform(size_t(numCpus));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
template <>
|
|
79
|
+
const CacheLocality& CacheLocality::system<std::atomic>() {
|
|
80
|
+
static std::atomic<const CacheLocality*> cache;
|
|
81
|
+
auto value = cache.load(std::memory_order_acquire);
|
|
82
|
+
if (value != nullptr) {
|
|
83
|
+
return *value;
|
|
84
|
+
}
|
|
85
|
+
auto next = new CacheLocality(getSystemLocalityInfo());
|
|
86
|
+
if (cache.compare_exchange_strong(value, next, std::memory_order_acq_rel)) {
|
|
87
|
+
return *next;
|
|
88
|
+
}
|
|
89
|
+
delete next;
|
|
90
|
+
return *value;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
CacheLocality::CacheLocality(std::vector<std::vector<size_t>> equivClasses) {
|
|
94
|
+
numCpus = equivClasses.size();
|
|
95
|
+
|
|
96
|
+
for (size_t cpu = 0; cpu < numCpus; ++cpu) {
|
|
97
|
+
for (size_t level = 0; level < equivClasses[cpu].size(); ++level) {
|
|
98
|
+
if (equivClasses[cpu][level] == cpu) {
|
|
99
|
+
// we only want to count the equiv classes once, so we do it when we
|
|
100
|
+
// are processing their representative.
|
|
101
|
+
while (numCachesByLevel.size() <= level) {
|
|
102
|
+
numCachesByLevel.push_back(0);
|
|
103
|
+
}
|
|
104
|
+
numCachesByLevel[level]++;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
std::vector<size_t> cpus(numCpus);
|
|
110
|
+
std::iota(cpus.begin(), cpus.end(), 0);
|
|
111
|
+
|
|
112
|
+
std::sort(cpus.begin(), cpus.end(), [&](size_t lhs, size_t rhs) -> bool {
|
|
113
|
+
auto& lhsEquiv = equivClasses[lhs];
|
|
114
|
+
auto& rhsEquiv = equivClasses[rhs];
|
|
115
|
+
|
|
116
|
+
// If different cpus have different numbers of caches group first by number
|
|
117
|
+
// of caches to guarantee strict weak ordering, even though the resulting
|
|
118
|
+
// order may be sub-optimal.
|
|
119
|
+
if (lhsEquiv.size() != rhsEquiv.size()) {
|
|
120
|
+
return lhsEquiv.size() < rhsEquiv.size();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Order by equiv class of cache with highest index, direction doesn't
|
|
124
|
+
// matter.
|
|
125
|
+
for (size_t i = lhsEquiv.size(); i > 0; --i) {
|
|
126
|
+
auto idx = i - 1;
|
|
127
|
+
if (lhsEquiv[idx] != rhsEquiv[idx]) {
|
|
128
|
+
return lhsEquiv[idx] < rhsEquiv[idx];
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Break ties deterministically by cpu.
|
|
133
|
+
return lhs < rhs;
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// The cpus are now sorted by locality, with neighboring entries closer
|
|
137
|
+
// to each other than entries that are far away. For striping we want
|
|
138
|
+
// the inverse map, since we are starting with the cpu.
|
|
139
|
+
localityIndexByCpu.resize(numCpus);
|
|
140
|
+
for (size_t i = 0; i < cpus.size(); ++i) {
|
|
141
|
+
localityIndexByCpu[cpus[i]] = i;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
equivClassesByCpu = std::move(equivClasses);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Each level of cache has sharing sets, which are the set of cpus that share a
|
|
148
|
+
// common cache at that level. These are available in a hex bitset form
|
|
149
|
+
// (/sys/devices/system/cpu/cpu0/cache/index0/shared_cpu_map, for example).
|
|
150
|
+
// They are also available in human-readable form in the shared_cpu_list file in
|
|
151
|
+
// the same directory. The list is a comma-separated list of numbers and
|
|
152
|
+
// ranges, where the ranges are pairs of decimal numbers separated by a '-'.
|
|
153
|
+
//
|
|
154
|
+
// To sort the cpus for optimum locality we don't really need to parse the
|
|
155
|
+
// sharing sets, we just need a unique representative from the equivalence
|
|
156
|
+
// class. The smallest value works fine, and happens to be the first decimal
|
|
157
|
+
// number in the file. We load all of the equivalence class information from
|
|
158
|
+
// all of the cpu*/index* directories, order the cpus first by increasing
|
|
159
|
+
// last-level cache equivalence class, then by the smaller caches. Finally, we
|
|
160
|
+
// break ties with the cpu number itself.
|
|
161
|
+
|
|
162
|
+
/// Returns the first decimal number in the line, or throws an exception if the
|
|
163
|
+
/// line does not start with a number terminated by ',', '-', '\n', or EOS.
|
|
164
|
+
static size_t parseLeadingNumber(const std::string& line) {
|
|
165
|
+
auto raw = line.c_str();
|
|
166
|
+
char* end;
|
|
167
|
+
unsigned long val = strtoul(raw, &end, 10);
|
|
168
|
+
if (end == raw || (*end != ',' && *end != '-' && *end != '\n' && *end != 0)) {
|
|
169
|
+
throw std::runtime_error(fmt::format("error parsing list '{}'", line));
|
|
170
|
+
}
|
|
171
|
+
return val;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
CacheLocality CacheLocality::readFromSysfsTree(
|
|
175
|
+
const std::function<std::string(std::string const&)>& mapping) {
|
|
176
|
+
// the list of cache equivalence classes, where equivalence classes
|
|
177
|
+
// are named by the smallest cpu in the class
|
|
178
|
+
std::vector<std::vector<size_t>> equivClassesByCpu;
|
|
179
|
+
|
|
180
|
+
for (size_t cpu = 0;; ++cpu) {
|
|
181
|
+
std::vector<size_t> levels;
|
|
182
|
+
for (size_t index = 0;; ++index) {
|
|
183
|
+
auto dir = fmt::format(
|
|
184
|
+
"/sys/devices/system/cpu/cpu{}/cache/index{}/", cpu, index);
|
|
185
|
+
auto cacheType = mapping(dir + "type");
|
|
186
|
+
auto equivStr = mapping(dir + "shared_cpu_list");
|
|
187
|
+
if (cacheType.empty() || equivStr.empty()) {
|
|
188
|
+
// no more caches
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
if (cacheType[0] == 'I') {
|
|
192
|
+
// cacheType in { "Data", "Instruction", "Unified" }. skip icache
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
auto equiv = parseLeadingNumber(equivStr);
|
|
196
|
+
levels.push_back(equiv);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (levels.empty()) {
|
|
200
|
+
// no levels at all for this cpu, we must be done
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
equivClassesByCpu.emplace_back(std::move(levels));
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (equivClassesByCpu.empty()) {
|
|
207
|
+
throw std::runtime_error("unable to load cache sharing info");
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return CacheLocality{std::move(equivClassesByCpu)};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
CacheLocality CacheLocality::readFromSysfs() {
|
|
214
|
+
return readFromSysfsTree([](std::string const& name) {
|
|
215
|
+
std::ifstream xi(name.c_str());
|
|
216
|
+
std::string rv;
|
|
217
|
+
std::getline(xi, rv);
|
|
218
|
+
return rv;
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
namespace {
|
|
223
|
+
|
|
224
|
+
static bool procCpuinfoLineRelevant(std::string const& line) {
|
|
225
|
+
return line.size() > 4 && (line[0] == 'p' || line[0] == 'c');
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
std::vector<std::tuple<size_t, size_t, size_t>> parseProcCpuinfoLines(
|
|
229
|
+
std::vector<std::string> const& lines) {
|
|
230
|
+
std::vector<std::tuple<size_t, size_t, size_t>> cpus;
|
|
231
|
+
size_t physicalId = 0;
|
|
232
|
+
size_t coreId = 0;
|
|
233
|
+
size_t maxCpu = 0;
|
|
234
|
+
size_t numberOfPhysicalIds = 0;
|
|
235
|
+
size_t numberOfCoreIds = 0;
|
|
236
|
+
for (auto iter = lines.rbegin(); iter != lines.rend(); ++iter) {
|
|
237
|
+
auto& line = *iter;
|
|
238
|
+
if (!procCpuinfoLineRelevant(line)) {
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
auto sepIndex = line.find(':');
|
|
243
|
+
if (sepIndex == std::string::npos || sepIndex + 2 > line.size()) {
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
auto arg = line.substr(sepIndex + 2);
|
|
247
|
+
|
|
248
|
+
// "physical id" is socket, which is the most important locality
|
|
249
|
+
// context. "core id" is a real core, so two "processor" entries with
|
|
250
|
+
// the same physical id and core id are hyperthreads of each other.
|
|
251
|
+
// "processor" is the top line of each record, so when we hit it in
|
|
252
|
+
// the reverse order then we can emit a record.
|
|
253
|
+
if (line.find("physical id") == 0) {
|
|
254
|
+
physicalId = parseLeadingNumber(arg);
|
|
255
|
+
++numberOfPhysicalIds;
|
|
256
|
+
} else if (line.find("core id") == 0) {
|
|
257
|
+
coreId = parseLeadingNumber(arg);
|
|
258
|
+
++numberOfCoreIds;
|
|
259
|
+
} else if (line.find("processor") == 0) {
|
|
260
|
+
auto cpu = parseLeadingNumber(arg);
|
|
261
|
+
maxCpu = std::max(cpu, maxCpu);
|
|
262
|
+
cpus.emplace_back(physicalId, coreId, cpu);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (cpus.empty()) {
|
|
267
|
+
throw std::runtime_error("no CPUs parsed from /proc/cpuinfo");
|
|
268
|
+
}
|
|
269
|
+
if (maxCpu != cpus.size() - 1) {
|
|
270
|
+
throw std::runtime_error(
|
|
271
|
+
"offline CPUs not supported for /proc/cpuinfo cache locality source");
|
|
272
|
+
}
|
|
273
|
+
if (numberOfPhysicalIds == 0) {
|
|
274
|
+
throw std::runtime_error("no physical ids found");
|
|
275
|
+
}
|
|
276
|
+
if (numberOfCoreIds == 0) {
|
|
277
|
+
throw std::runtime_error("no core ids found");
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
return cpus;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
} // namespace
|
|
284
|
+
|
|
285
|
+
CacheLocality CacheLocality::readFromProcCpuinfoLines(
|
|
286
|
+
std::vector<std::string> const& lines) {
|
|
287
|
+
// (physicalId, coreId, cpu)
|
|
288
|
+
std::vector<std::tuple<size_t, size_t, size_t>> cpus =
|
|
289
|
+
parseProcCpuinfoLines(lines);
|
|
290
|
+
// Sort to make equivalence classes contiguous.
|
|
291
|
+
std::sort(cpus.begin(), cpus.end());
|
|
292
|
+
|
|
293
|
+
// We can't tell the real cache hierarchy from /proc/cpuinfo, but it works
|
|
294
|
+
// well enough to assume there are 3 levels, L1 and L2 per-core and L3 per
|
|
295
|
+
// socket.
|
|
296
|
+
std::vector<std::vector<size_t>> equivClassesByCpu(cpus.size());
|
|
297
|
+
size_t l1Equiv = 0;
|
|
298
|
+
size_t l3Equiv = 0;
|
|
299
|
+
for (size_t i = 0; i < cpus.size(); ++i) {
|
|
300
|
+
auto [physicalId, coreId, cpu] = cpus[i];
|
|
301
|
+
// The representative for each L1 and L3 equivalence class is the first cpu
|
|
302
|
+
// in the class.
|
|
303
|
+
if (i == 0 || physicalId != std::get<0>(cpus[i - 1]) ||
|
|
304
|
+
coreId != std::get<1>(cpus[i - 1])) {
|
|
305
|
+
l1Equiv = cpu;
|
|
306
|
+
}
|
|
307
|
+
if (i == 0 || physicalId != std::get<0>(cpus[i - 1])) {
|
|
308
|
+
l3Equiv = cpu;
|
|
309
|
+
}
|
|
310
|
+
equivClassesByCpu[cpu] = {l1Equiv, l1Equiv, l3Equiv};
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
return CacheLocality{std::move(equivClassesByCpu)};
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
CacheLocality CacheLocality::readFromProcCpuinfo() {
|
|
317
|
+
std::vector<std::string> lines;
|
|
318
|
+
{
|
|
319
|
+
std::ifstream xi("/proc/cpuinfo");
|
|
320
|
+
if (xi.fail()) {
|
|
321
|
+
throw std::runtime_error("unable to open /proc/cpuinfo");
|
|
322
|
+
}
|
|
323
|
+
char buf[8192];
|
|
324
|
+
while (xi.good() && lines.size() < 20000) {
|
|
325
|
+
xi.getline(buf, sizeof(buf));
|
|
326
|
+
std::string str(buf);
|
|
327
|
+
if (procCpuinfoLineRelevant(str)) {
|
|
328
|
+
lines.emplace_back(std::move(str));
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
return readFromProcCpuinfoLines(lines);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
CacheLocality CacheLocality::uniform(size_t numCpus) {
|
|
336
|
+
// One cache shared by all cpus.
|
|
337
|
+
std::vector<std::vector<size_t>> equivClassesByCpu(numCpus, {0});
|
|
338
|
+
return CacheLocality{std::move(equivClassesByCpu)};
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
////////////// Getcpu
|
|
342
|
+
|
|
343
|
+
Getcpu::Func Getcpu::resolveVdsoFunc() {
|
|
344
|
+
#if !defined(FOLLY_HAVE_LINUX_VDSO) || defined(FOLLY_SANITIZE_MEMORY)
|
|
345
|
+
return nullptr;
|
|
346
|
+
#else
|
|
347
|
+
void* h = dlopen("linux-vdso.so.1", RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
|
|
348
|
+
if (h == nullptr) {
|
|
349
|
+
return nullptr;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
auto func = Getcpu::Func(dlsym(h, "__vdso_getcpu"));
|
|
353
|
+
if (func == nullptr) {
|
|
354
|
+
// technically a null result could either be a failure or a successful
|
|
355
|
+
// lookup of a symbol with the null value, but the second can't actually
|
|
356
|
+
// happen for this symbol. No point holding the handle forever if
|
|
357
|
+
// we don't need the code
|
|
358
|
+
dlclose(h);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
return func;
|
|
362
|
+
#endif
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/////////////// SequentialThreadId
|
|
366
|
+
unsigned SequentialThreadId::get() {
|
|
367
|
+
static std::atomic<unsigned> global{0};
|
|
368
|
+
static thread_local unsigned local{0};
|
|
369
|
+
return FOLLY_LIKELY(local) ? local : (local = ++global);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/////////////// HashingThreadId
|
|
373
|
+
unsigned HashingThreadId::get() {
|
|
374
|
+
return hash::twang_32from64(getCurrentThreadID());
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
namespace detail {
|
|
378
|
+
|
|
379
|
+
int AccessSpreaderBase::degenerateGetcpu(unsigned* cpu, unsigned* node, void*) {
|
|
380
|
+
if (cpu != nullptr) {
|
|
381
|
+
*cpu = 0;
|
|
382
|
+
}
|
|
383
|
+
if (node != nullptr) {
|
|
384
|
+
*node = 0;
|
|
385
|
+
}
|
|
386
|
+
return 0;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
struct AccessSpreaderStaticInit {
|
|
390
|
+
static AccessSpreaderStaticInit instance;
|
|
391
|
+
AccessSpreaderStaticInit() { (void)AccessSpreader<>::current(~size_t(0)); }
|
|
392
|
+
};
|
|
393
|
+
AccessSpreaderStaticInit AccessSpreaderStaticInit::instance;
|
|
394
|
+
|
|
395
|
+
bool AccessSpreaderBase::initialize(
|
|
396
|
+
GlobalState& state,
|
|
397
|
+
Getcpu::Func (&pickGetcpuFunc)(),
|
|
398
|
+
const CacheLocality& (&system)()) {
|
|
399
|
+
(void)AccessSpreaderStaticInit::instance; // ODR-use it so it is not dropped
|
|
400
|
+
constexpr auto relaxed = std::memory_order_relaxed;
|
|
401
|
+
auto& cacheLocality = system();
|
|
402
|
+
auto n = cacheLocality.numCpus;
|
|
403
|
+
for (size_t width = 0; width <= kMaxCpus; ++width) {
|
|
404
|
+
auto& row = state.table[width];
|
|
405
|
+
auto numStripes = std::max(size_t{1}, width);
|
|
406
|
+
for (size_t cpu = 0; cpu < kMaxCpus && cpu < n; ++cpu) {
|
|
407
|
+
auto index = cacheLocality.localityIndexByCpu[cpu];
|
|
408
|
+
assert(index < n);
|
|
409
|
+
// as index goes from 0..n, post-transform value goes from
|
|
410
|
+
// 0..numStripes
|
|
411
|
+
make_atomic_ref(row[cpu]).store(
|
|
412
|
+
static_cast<CompactStripe>((index * numStripes) / n), relaxed);
|
|
413
|
+
assert(make_atomic_ref(row[cpu]).load(relaxed) < numStripes);
|
|
414
|
+
}
|
|
415
|
+
size_t filled = n;
|
|
416
|
+
while (filled < kMaxCpus) {
|
|
417
|
+
size_t len = std::min(filled, kMaxCpus - filled);
|
|
418
|
+
for (size_t i = 0; i < len; ++i) {
|
|
419
|
+
make_atomic_ref(row[filled + i])
|
|
420
|
+
.store(make_atomic_ref(row[i]).load(relaxed), relaxed);
|
|
421
|
+
}
|
|
422
|
+
filled += len;
|
|
423
|
+
}
|
|
424
|
+
for (size_t cpu = n; cpu < kMaxCpus; ++cpu) {
|
|
425
|
+
assert(
|
|
426
|
+
make_atomic_ref(row[cpu]).load(relaxed) ==
|
|
427
|
+
make_atomic_ref(row[cpu - n]).load(relaxed));
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
state.getcpu.exchange(pickGetcpuFunc(), std::memory_order_acq_rel);
|
|
431
|
+
return true;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
} // namespace detail
|
|
435
|
+
|
|
436
|
+
namespace {
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* A simple freelist allocator. Allocates things of size sz, from slabs of size
|
|
440
|
+
* kAllocSize. Takes a lock on each allocation/deallocation.
|
|
441
|
+
*/
|
|
442
|
+
class SimpleAllocator {
|
|
443
|
+
public:
|
|
444
|
+
// To support array aggregate initialization without an implicit constructor.
|
|
445
|
+
struct Ctor {};
|
|
446
|
+
|
|
447
|
+
SimpleAllocator(Ctor, size_t sz) : sz_(sz) {}
|
|
448
|
+
~SimpleAllocator() {
|
|
449
|
+
std::lock_guard<std::mutex> g(m_);
|
|
450
|
+
for (auto& block : blocks_) {
|
|
451
|
+
folly::aligned_free(block);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
void* allocate() {
|
|
456
|
+
std::lock_guard<std::mutex> g(m_);
|
|
457
|
+
// Freelist allocation.
|
|
458
|
+
if (freelist_) {
|
|
459
|
+
auto mem = freelist_;
|
|
460
|
+
freelist_ = *static_cast<void**>(freelist_);
|
|
461
|
+
return mem;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
if (mem_) {
|
|
465
|
+
// Bump-ptr allocation.
|
|
466
|
+
if (intptr_t(mem_) % kMallocAlign == 0) {
|
|
467
|
+
// Avoid allocating pointers that may look like malloc
|
|
468
|
+
// pointers.
|
|
469
|
+
mem_ += std::min(sz_, max_align_v);
|
|
470
|
+
}
|
|
471
|
+
if (mem_ + sz_ <= end_) {
|
|
472
|
+
auto mem = mem_;
|
|
473
|
+
mem_ += sz_;
|
|
474
|
+
|
|
475
|
+
assert(intptr_t(mem) % kMallocAlign != 0);
|
|
476
|
+
return mem;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
return allocateHard();
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
static void deallocate(void* ptr) {
|
|
484
|
+
assert(intptr_t(ptr) % kMallocAlign != 0);
|
|
485
|
+
// Find the allocator instance.
|
|
486
|
+
auto addr =
|
|
487
|
+
reinterpret_cast<void*>(intptr_t(ptr) & ~intptr_t(kAllocSize - 1));
|
|
488
|
+
auto allocator = *static_cast<SimpleAllocator**>(addr);
|
|
489
|
+
|
|
490
|
+
std::lock_guard<std::mutex> g(allocator->m_);
|
|
491
|
+
*static_cast<void**>(ptr) = allocator->freelist_;
|
|
492
|
+
if constexpr (kIsSanitizeAddress) {
|
|
493
|
+
// If running under ASAN, scrub the memory on deallocation, so we don't
|
|
494
|
+
// leave pointers that could hide leaks at shutdown, since the backing
|
|
495
|
+
// slabs may not be deallocated if the instance is a leaky singleton.
|
|
496
|
+
auto* base = static_cast<char*>(ptr);
|
|
497
|
+
std::fill(
|
|
498
|
+
base + sizeof(void*), base + allocator->sz_, static_cast<char>(0));
|
|
499
|
+
}
|
|
500
|
+
allocator->freelist_ = ptr;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
constexpr static size_t kMallocAlign = 128;
|
|
504
|
+
static_assert(
|
|
505
|
+
kMallocAlign % hardware_destructive_interference_size == 0,
|
|
506
|
+
"Large allocations should be cacheline-aligned");
|
|
507
|
+
|
|
508
|
+
private:
|
|
509
|
+
constexpr static size_t kAllocSize = 4096;
|
|
510
|
+
|
|
511
|
+
void* allocateHard() {
|
|
512
|
+
// Allocate a new slab.
|
|
513
|
+
mem_ = static_cast<uint8_t*>(folly::aligned_malloc(kAllocSize, kAllocSize));
|
|
514
|
+
if (!mem_) {
|
|
515
|
+
throw_exception<std::bad_alloc>();
|
|
516
|
+
}
|
|
517
|
+
end_ = mem_ + kAllocSize;
|
|
518
|
+
blocks_.push_back(mem_);
|
|
519
|
+
|
|
520
|
+
// Install a pointer to ourselves as the allocator.
|
|
521
|
+
*reinterpret_cast<SimpleAllocator**>(mem_) = this;
|
|
522
|
+
static_assert(
|
|
523
|
+
max_align_v >= sizeof(SimpleAllocator*), "alignment too small");
|
|
524
|
+
mem_ += std::min(sz_, max_align_v);
|
|
525
|
+
|
|
526
|
+
// New allocation.
|
|
527
|
+
auto mem = mem_;
|
|
528
|
+
mem_ += sz_;
|
|
529
|
+
assert(intptr_t(mem) % kMallocAlign != 0);
|
|
530
|
+
return mem;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
std::mutex m_;
|
|
534
|
+
uint8_t* mem_{nullptr};
|
|
535
|
+
uint8_t* end_{nullptr};
|
|
536
|
+
void* freelist_{nullptr};
|
|
537
|
+
size_t sz_;
|
|
538
|
+
std::vector<void*> blocks_;
|
|
539
|
+
};
|
|
540
|
+
|
|
541
|
+
class Allocator {
|
|
542
|
+
public:
|
|
543
|
+
void* allocate(size_t size) {
|
|
544
|
+
if (auto cl = sizeClass(size)) {
|
|
545
|
+
return allocators_[*cl].allocate();
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
// Fall back to malloc, returning a kMallocAlign-aligned allocation so it
|
|
549
|
+
// can be distinguished from SimpleAllocator allocations.
|
|
550
|
+
size = size + (SimpleAllocator::kMallocAlign - 1);
|
|
551
|
+
size &= ~size_t(SimpleAllocator::kMallocAlign - 1);
|
|
552
|
+
void* mem = aligned_malloc(size, SimpleAllocator::kMallocAlign);
|
|
553
|
+
if (!mem) {
|
|
554
|
+
throw_exception<std::bad_alloc>();
|
|
555
|
+
}
|
|
556
|
+
return mem;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
static void deallocate(void* ptr) {
|
|
560
|
+
if (!ptr) {
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// See if it came from SimpleAllocator or malloc.
|
|
565
|
+
if (intptr_t(ptr) % SimpleAllocator::kMallocAlign != 0) {
|
|
566
|
+
SimpleAllocator::deallocate(ptr);
|
|
567
|
+
} else {
|
|
568
|
+
aligned_free(ptr);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
private:
|
|
573
|
+
std::optional<uint8_t> sizeClass(size_t size) {
|
|
574
|
+
if (size <= 8) {
|
|
575
|
+
return static_cast<uint8_t>(0); // [Windows]
|
|
576
|
+
} else if (size <= 16) {
|
|
577
|
+
return static_cast<uint8_t>(1); // [Windows]
|
|
578
|
+
} else if (size <= 32) {
|
|
579
|
+
return static_cast<uint8_t>(2); // [Windows]
|
|
580
|
+
} else if (size <= 64) {
|
|
581
|
+
return static_cast<uint8_t>(3); // [Windows]
|
|
582
|
+
} else {
|
|
583
|
+
return std::nullopt;
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
std::array<SimpleAllocator, 4> allocators_{
|
|
588
|
+
{{SimpleAllocator::Ctor{}, 8},
|
|
589
|
+
{SimpleAllocator::Ctor{}, 16},
|
|
590
|
+
{SimpleAllocator::Ctor{}, 32},
|
|
591
|
+
{SimpleAllocator::Ctor{}, 64}}};
|
|
592
|
+
};
|
|
593
|
+
|
|
594
|
+
} // namespace
|
|
595
|
+
|
|
596
|
+
void* coreMalloc(size_t size, size_t numStripes, size_t stripe) {
|
|
597
|
+
static folly::Indestructible<Allocator>
|
|
598
|
+
allocators[AccessSpreader<>::maxLocalityIndexValue()];
|
|
599
|
+
auto index = AccessSpreader<>::localityIndexForStripe(numStripes, stripe);
|
|
600
|
+
return allocators[index]->allocate(size);
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
void coreFree(void* ptr) {
|
|
604
|
+
Allocator::deallocate(ptr);
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
namespace {
|
|
608
|
+
thread_local CoreAllocatorGuard* gCoreAllocatorGuard = nullptr;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
CoreAllocatorGuard::CoreAllocatorGuard(size_t numStripes, size_t stripe)
|
|
612
|
+
: numStripes_(numStripes), stripe_(stripe) {
|
|
613
|
+
CHECK(gCoreAllocatorGuard == nullptr)
|
|
614
|
+
<< "CoreAllocator::Guard cannot be used recursively";
|
|
615
|
+
gCoreAllocatorGuard = this;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
CoreAllocatorGuard::~CoreAllocatorGuard() {
|
|
619
|
+
gCoreAllocatorGuard = nullptr;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
namespace detail {
|
|
623
|
+
|
|
624
|
+
void* coreMallocFromGuard(size_t size) {
|
|
625
|
+
CHECK(gCoreAllocatorGuard != nullptr)
|
|
626
|
+
<< "CoreAllocator::allocator called without an active Guard";
|
|
627
|
+
return coreMalloc(
|
|
628
|
+
size, gCoreAllocatorGuard->numStripes_, gCoreAllocatorGuard->stripe_);
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
} // namespace detail
|
|
632
|
+
|
|
633
|
+
} // namespace folly
|
|
@@ -268,8 +268,6 @@ struct dynamic::const_item_iterator
|
|
|
268
268
|
const_item_iterator() = default;
|
|
269
269
|
/* implicit */ const_item_iterator(dynamic::ObjectImpl::const_iterator b)
|
|
270
270
|
: Super(b) {}
|
|
271
|
-
/* implicit */ const_item_iterator(const_item_iterator const& i)
|
|
272
|
-
: Super(i.base()) {}
|
|
273
271
|
/* implicit */ const_item_iterator(item_iterator i) : Super(i.base()) {}
|
|
274
272
|
|
|
275
273
|
using object_type = dynamic::ObjectImpl const;
|
|
@@ -389,7 +387,8 @@ dynamic::dynamic(T t) {
|
|
|
389
387
|
}
|
|
390
388
|
|
|
391
389
|
template <class Iterator>
|
|
392
|
-
dynamic::dynamic(Iterator first, Iterator last)
|
|
390
|
+
dynamic::dynamic(array_range_construct_t, Iterator first, Iterator last)
|
|
391
|
+
: type_(ARRAY) {
|
|
393
392
|
new (&u_.array) Array(first, last);
|
|
394
393
|
}
|
|
395
394
|
|
|
@@ -1436,4 +1435,4 @@ class FormatValue<detail::DefaultValueWrapper<dynamic, V>> {
|
|
|
1436
1435
|
|
|
1437
1436
|
} // namespace folly
|
|
1438
1437
|
|
|
1439
|
-
#undef FB_DYNAMIC_APPLY
|
|
1438
|
+
#undef FB_DYNAMIC_APPLY
|