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.
Files changed (191) hide show
  1. package/Directory.Build.props +6 -4
  2. package/Folly/Folly.vcxproj +46 -6
  3. package/Folly/Folly.vcxproj.filters +16 -4
  4. package/Folly/TEMP_UntilFollyUpdate/ConstexprMath.h +26 -18
  5. package/Folly/TEMP_UntilFollyUpdate/Conv.cpp +1205 -0
  6. package/Folly/TEMP_UntilFollyUpdate/chrono/Hardware.h +155 -0
  7. package/Folly/TEMP_UntilFollyUpdate/concurrency/CacheLocality.cpp +633 -0
  8. package/Folly/TEMP_UntilFollyUpdate/{dynamic-inl.h → json/dynamic-inl.h} +3 -4
  9. package/Folly/TEMP_UntilFollyUpdate/{json.cpp → json/json.cpp} +14 -10
  10. package/Folly/TEMP_UntilFollyUpdate/lang/SafeAssert.h +7 -14
  11. package/Folly/TEMP_UntilFollyUpdate/lang/ToAscii.h +6 -6
  12. package/Folly/ThreadNameStub.cpp +10 -0
  13. package/Folly/cgmanifest.json +11 -1
  14. package/Libraries/Components/View/View.windows.js +107 -56
  15. package/Libraries/Components/View/ViewAccessibility.d.ts +60 -1
  16. package/Libraries/Image/Image.windows.js +42 -21
  17. package/Libraries/Modal/Modal.d.ts +7 -0
  18. package/Libraries/Modal/Modal.windows.js +7 -1
  19. package/Libraries/NativeComponent/BaseViewConfig.windows.js +3 -0
  20. package/Libraries/Text/Text.d.ts +18 -0
  21. package/Microsoft.ReactNative/AsynchronousEventBeat.cpp +4 -25
  22. package/Microsoft.ReactNative/AsynchronousEventBeat.h +0 -3
  23. package/Microsoft.ReactNative/Base/FollyIncludes.h +1 -0
  24. package/Microsoft.ReactNative/CallInvoker.cpp +42 -0
  25. package/Microsoft.ReactNative/CallInvoker.h +34 -0
  26. package/Microsoft.ReactNative/{JSDispatcherWriter.cpp → CallInvokerWriter.cpp} +35 -47
  27. package/Microsoft.ReactNative/CallInvokerWriter.h +74 -0
  28. package/Microsoft.ReactNative/CompositionComponentView.idl +0 -5
  29. package/Microsoft.ReactNative/CompositionSwitcher.idl +7 -0
  30. package/Microsoft.ReactNative/Fabric/AbiViewProps.cpp +8 -10
  31. package/Microsoft.ReactNative/Fabric/ComponentView.cpp +4 -1
  32. package/Microsoft.ReactNative/Fabric/Composition/ActivityIndicatorComponentView.cpp +12 -2
  33. package/Microsoft.ReactNative/Fabric/Composition/ActivityIndicatorComponentView.h +2 -0
  34. package/Microsoft.ReactNative/Fabric/Composition/CompositionAnnotationProvider.cpp +100 -0
  35. package/Microsoft.ReactNative/Fabric/Composition/CompositionAnnotationProvider.h +31 -0
  36. package/Microsoft.ReactNative/Fabric/Composition/CompositionContextHelper.cpp +77 -11
  37. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +43 -1
  38. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h +7 -0
  39. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +86 -56
  40. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +5 -1
  41. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +0 -4
  42. package/Microsoft.ReactNative/Fabric/Composition/CompositionUIService.cpp +0 -2
  43. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +118 -63
  44. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +2 -0
  45. package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp +133 -8
  46. package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.h +16 -2
  47. package/Microsoft.ReactNative/Fabric/Composition/FocusManager.cpp +4 -2
  48. package/Microsoft.ReactNative/Fabric/Composition/FocusManager.h +9 -1
  49. package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp +34 -11
  50. package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.h +3 -0
  51. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +133 -135
  52. package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp +9 -6
  53. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +46 -49
  54. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +6 -1
  55. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +13 -8
  56. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +5 -2
  57. package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +146 -25
  58. package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h +14 -0
  59. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +160 -12
  60. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +6 -0
  61. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputEventEmitter.cpp +47 -0
  62. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputEventEmitter.h +15 -1
  63. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputProps.cpp +6 -2
  64. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputProps.h +4 -1
  65. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.cpp +7 -9
  66. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.h +4 -1
  67. package/Microsoft.ReactNative/Fabric/Composition/Theme.cpp +5 -0
  68. package/Microsoft.ReactNative/Fabric/Composition/TooltipService.cpp +40 -36
  69. package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +68 -0
  70. package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h +11 -0
  71. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +70 -13
  72. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.h +10 -2
  73. package/Microsoft.ReactNative/Fabric/ImageManager.cpp +5 -5
  74. package/Microsoft.ReactNative/Fabric/ImageRequestParams.cpp +26 -0
  75. package/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp +47 -8
  76. package/Microsoft.ReactNative/Fabric/WindowsImageManager.h +10 -1
  77. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/CompositionAccessibilityProps.h +67 -0
  78. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewEventEmitter.cpp +22 -4
  79. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewEventEmitter.h +15 -2
  80. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.cpp +20 -0
  81. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.h +5 -0
  82. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/MouseEvent.h +20 -0
  83. package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/HostPlatformColor.h +5 -8
  84. package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/PlatformColorParser.h +1 -2
  85. package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/TextLayoutManager.cpp +247 -45
  86. package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/TextLayoutManager.h +15 -0
  87. package/Microsoft.ReactNative/Fabric/platform/react/threading/MessageQueueThreadImpl.cpp +39 -0
  88. package/Microsoft.ReactNative/Fabric/platform/react/threading/MessageQueueThreadImpl.h +54 -0
  89. package/Microsoft.ReactNative/Fabric/platform/react/threading/TaskDispatchThread.cpp +126 -0
  90. package/Microsoft.ReactNative/Fabric/platform/react/threading/TaskDispatchThread.h +73 -0
  91. package/Microsoft.ReactNative/IReactContext.cpp +17 -0
  92. package/Microsoft.ReactNative/IReactContext.h +1 -0
  93. package/Microsoft.ReactNative/IReactContext.idl +18 -1
  94. package/Microsoft.ReactNative/IReactDispatcher.idl +1 -0
  95. package/Microsoft.ReactNative/IReactModuleBuilder.cpp +12 -0
  96. package/Microsoft.ReactNative/IReactModuleBuilder.h +2 -0
  97. package/Microsoft.ReactNative/IReactModuleBuilder.idl +8 -0
  98. package/Microsoft.ReactNative/JsiApi.cpp +10 -2
  99. package/Microsoft.ReactNative/JsiApi.h +1 -0
  100. package/Microsoft.ReactNative/JsiApi.idl +1 -0
  101. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +0 -3
  102. package/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp +2 -3
  103. package/Microsoft.ReactNative/Modules/AlertModule.cpp +7 -12
  104. package/Microsoft.ReactNative/Modules/Animated/AnimationDriver.cpp +2 -1
  105. package/Microsoft.ReactNative/Modules/Animated/NativeAnimatedModule.cpp +4 -8
  106. package/Microsoft.ReactNative/Modules/AppStateModule.cpp +2 -2
  107. package/Microsoft.ReactNative/Modules/ClipboardModule.cpp +6 -8
  108. package/Microsoft.ReactNative/Modules/ClipboardModule.h +1 -1
  109. package/Microsoft.ReactNative/Modules/ImageViewManagerModule.cpp +6 -15
  110. package/Microsoft.ReactNative/Modules/NativeUIManager.cpp +13 -24
  111. package/Microsoft.ReactNative/QuirkSettings.cpp +0 -16
  112. package/Microsoft.ReactNative/QuirkSettings.h +0 -3
  113. package/Microsoft.ReactNative/ReactHost/ReactHost.cpp +11 -1
  114. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +78 -68
  115. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +1 -2
  116. package/Microsoft.ReactNative/ReactInstanceSettings.cpp +12 -0
  117. package/Microsoft.ReactNative/ReactInstanceSettings.h +2 -0
  118. package/Microsoft.ReactNative/ReactInstanceSettings.idl +6 -0
  119. package/Microsoft.ReactNative/ReactNativeIsland.idl +3 -0
  120. package/Microsoft.ReactNative/ReactSupport.cpp +44 -11
  121. package/Microsoft.ReactNative/RedBox.cpp +30 -1
  122. package/Microsoft.ReactNative/SchedulerSettings.cpp +4 -4
  123. package/Microsoft.ReactNative/SchedulerSettings.h +1 -1
  124. package/Microsoft.ReactNative/TurboModulesProvider.cpp +30 -12
  125. package/Microsoft.ReactNative/Utils/ImageUtils.h +1 -0
  126. package/Microsoft.ReactNative/Utils/LocalBundleReader.cpp +37 -31
  127. package/Microsoft.ReactNative.Cxx/ApiLoaders/JSRuntimeApi.cpp +1 -0
  128. package/Microsoft.ReactNative.Cxx/ApiLoaders/JSRuntimeApi.inc +2 -0
  129. package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi_posix.cpp +1 -1
  130. package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.cpp +94 -27
  131. package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.h +27 -6
  132. package/Microsoft.ReactNative.Cxx/JSI/JsiApiContext.cpp +45 -11
  133. package/Microsoft.ReactNative.Cxx/JSI/JsiApiContext.h +6 -0
  134. package/Microsoft.ReactNative.Cxx/JSI/decorator.h +220 -0
  135. package/Microsoft.ReactNative.Cxx/JSI/instrumentation.h +28 -0
  136. package/Microsoft.ReactNative.Cxx/JSI/jsi-inl.h +6 -0
  137. package/Microsoft.ReactNative.Cxx/JSI/jsi.cpp +241 -4
  138. package/Microsoft.ReactNative.Cxx/JSI/jsi.h +207 -19
  139. package/Microsoft.ReactNative.Cxx/JSValue.cpp +19 -3
  140. package/Microsoft.ReactNative.Cxx/JSValue.h +15 -7
  141. package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +2 -2
  142. package/Microsoft.ReactNative.Cxx/NativeModules.h +60 -2
  143. package/Microsoft.ReactNative.Cxx/NodeApiJsiRuntime.cpp +1267 -614
  144. package/Microsoft.ReactNative.Cxx/NodeApiJsiRuntime.h +4 -2
  145. package/Microsoft.ReactNative.Cxx/ReactContext.h +7 -0
  146. package/Microsoft.ReactNative.Cxx/TurboModuleProvider.cpp +11 -13
  147. package/Microsoft.ReactNative.Cxx/TurboModuleProvider.h +2 -3
  148. package/Microsoft.ReactNative.Cxx/node-api/js_native_api.h +81 -20
  149. package/Microsoft.ReactNative.Cxx/node-api/js_native_api_types.h +47 -2
  150. package/Microsoft.ReactNative.Cxx/node-api/js_runtime_api.h +13 -0
  151. package/Microsoft.ReactNative.Cxx/stubs/glog/logging.h +1 -1
  152. package/Microsoft.ReactNative.Managed/ReactContext.cs +3 -1
  153. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  154. package/PropertySheets/JSEngine.props +1 -1
  155. package/PropertySheets/React.Cpp.props +2 -1
  156. package/PropertySheets/WebView2.props +1 -1
  157. package/PropertySheets/WinUI.props +2 -2
  158. package/ReactCommon/TEMP_UntilReactCommonUpdate/jserrorhandler/JsErrorHandler.cpp +429 -0
  159. package/ReactCommon/cgmanifest.json +1 -1
  160. package/Shared/HermesRuntimeHolder.cpp +6 -0
  161. package/Shared/JSI/ChakraRuntime.cpp +4 -0
  162. package/Shared/JSI/ChakraRuntime.h +2 -0
  163. package/Shared/Modules/BlobModule.cpp +14 -16
  164. package/Shared/Modules/BlobModule.h +3 -1
  165. package/Shared/Networking/WinRTWebSocketResource.cpp +82 -101
  166. package/Shared/Networking/WinRTWebSocketResource.h +91 -7
  167. package/Shared/Shared.vcxitems +11 -7
  168. package/Shared/Shared.vcxitems.filters +6 -1
  169. package/Shared/TurboModuleManager.cpp +0 -15
  170. package/codegen/react/components/rnwcore/ActivityIndicatorView.g.h +6 -6
  171. package/codegen/react/components/rnwcore/AndroidDrawerLayout.g.h +6 -6
  172. package/codegen/react/components/rnwcore/AndroidHorizontalScrollContentView.g.h +6 -6
  173. package/codegen/react/components/rnwcore/AndroidProgressBar.g.h +6 -6
  174. package/codegen/react/components/rnwcore/AndroidSwipeRefreshLayout.g.h +6 -6
  175. package/codegen/react/components/rnwcore/AndroidSwitch.g.h +6 -6
  176. package/codegen/react/components/rnwcore/DebuggingOverlay.g.h +6 -6
  177. package/codegen/react/components/rnwcore/InputAccessory.g.h +6 -6
  178. package/codegen/react/components/rnwcore/ModalHostView.g.h +11 -7
  179. package/codegen/react/components/rnwcore/Props.cpp +2 -1
  180. package/codegen/react/components/rnwcore/Props.h +1 -0
  181. package/codegen/react/components/rnwcore/PullToRefreshView.g.h +6 -6
  182. package/codegen/react/components/rnwcore/SafeAreaView.g.h +6 -6
  183. package/codegen/react/components/rnwcore/Switch.g.h +6 -6
  184. package/codegen/react/components/rnwcore/UnimplementedNativeView.g.h +6 -6
  185. package/index.windows.js +4 -2
  186. package/package.json +3 -4
  187. package/src/private/specs/components/RCTModalHostViewNativeComponent.js +8 -0
  188. package/stubs/glog/logging.h +1 -1
  189. package/Microsoft.ReactNative/JSDispatcherWriter.h +0 -47
  190. package/Microsoft.ReactNative/SynchronousEventBeat.cpp +0 -51
  191. 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) : type_(ARRAY) {
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