OpenShot Audio Library | OpenShotAudio 0.4.0

Loading...
Searching...
No Matches
juce_SystemStats.cpp
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23 namespace juce
24{
25
26 String SystemStats::getJUCEVersion()
27{
28 // Some basic tests, to keep an eye on things and make sure these types work ok
29 // on all platforms. Let me know if any of these assertions fail on your system!
30 static_assert (sizeof (pointer_sized_int) == sizeof (void*), "Basic sanity test failed: please report!");
31 static_assert (sizeof (int8) == 1, "Basic sanity test failed: please report!");
32 static_assert (sizeof (uint8) == 1, "Basic sanity test failed: please report!");
33 static_assert (sizeof (int16) == 2, "Basic sanity test failed: please report!");
34 static_assert (sizeof (uint16) == 2, "Basic sanity test failed: please report!");
35 static_assert (sizeof (int32) == 4, "Basic sanity test failed: please report!");
36 static_assert (sizeof (uint32) == 4, "Basic sanity test failed: please report!");
37 static_assert (sizeof (int64) == 8, "Basic sanity test failed: please report!");
38 static_assert (sizeof (uint64) == 8, "Basic sanity test failed: please report!");
39
40 return "JUCE v" JUCE_STRINGIFY (JUCE_MAJOR_VERSION)
41 "." JUCE_STRINGIFY (JUCE_MINOR_VERSION)
42 "." JUCE_STRINGIFY (JUCE_BUILDNUMBER);
43}
44
45#if JUCE_ANDROID && ! defined (JUCE_DISABLE_JUCE_VERSION_PRINTING)
46 #define JUCE_DISABLE_JUCE_VERSION_PRINTING 1
47#endif
48
49#if JUCE_DEBUG && ! JUCE_DISABLE_JUCE_VERSION_PRINTING
50 struct JuceVersionPrinter
51 {
52 JuceVersionPrinter()
53 {
54 DBG (SystemStats::getJUCEVersion());
55 }
56 };
57
58 static JuceVersionPrinter juceVersionPrinter;
59#endif
60
61 StringArray SystemStats::getDeviceIdentifiers()
62{
63 for (const auto flag : { MachineIdFlags::fileSystemId, MachineIdFlags::macAddresses })
64 if (auto ids = getMachineIdentifiers (flag); ! ids.isEmpty())
65 return ids;
66
67 jassertfalse; // Failed to create any IDs!
68 return {};
69}
70
71 String getLegacyUniqueDeviceID();
72
73 StringArray SystemStats::getMachineIdentifiers (MachineIdFlags flags)
74{
75 auto macAddressProvider = [] (StringArray& arr)
76 {
77 for (const auto& mac : MACAddress::getAllAddresses())
78 arr.add (mac.toString());
79 };
80
81 auto fileSystemProvider = [] (StringArray& arr)
82 {
83 #if JUCE_WINDOWS
84 File f (File::getSpecialLocation (File::windowsSystemDirectory));
85 #else
86 File f ("~");
87 #endif
88 if (auto num = f.getFileIdentifier())
89 arr.add (String::toHexString ((int64) num));
90 };
91
92 auto legacyIdProvider = [] ([[maybe_unused]] StringArray& arr)
93 {
94 #if JUCE_WINDOWS
95 arr.add (getLegacyUniqueDeviceID());
96 #endif
97 };
98
99 auto uniqueIdProvider = [] (StringArray& arr)
100 {
101 arr.add (getUniqueDeviceID());
102 };
103
104 struct Provider { MachineIdFlags flag; void (*func) (StringArray&); };
105 static const Provider providers[] =
106 {
107 { MachineIdFlags::macAddresses, macAddressProvider },
108 { MachineIdFlags::fileSystemId, fileSystemProvider },
109 { MachineIdFlags::legacyUniqueId, legacyIdProvider },
110 { MachineIdFlags::uniqueId, uniqueIdProvider }
111 };
112
113 StringArray ids;
114
115 for (const auto& provider : providers)
116 {
117 if (hasBitValueSet (flags, provider.flag))
118 provider.func (ids);
119 }
120
121 return ids;
122}
123
124//==============================================================================
125 struct CPUInformation
126{
127 CPUInformation() noexcept { initialise(); }
128
129 void initialise() noexcept;
130
131 int numLogicalCPUs = 0, numPhysicalCPUs = 0;
132
133 bool hasMMX = false, hasSSE = false, hasSSE2 = false, hasSSE3 = false,
134 has3DNow = false, hasFMA3 = false, hasFMA4 = false, hasSSSE3 = false,
135 hasSSE41 = false, hasSSE42 = false, hasAVX = false, hasAVX2 = false,
136 hasAVX512F = false, hasAVX512BW = false, hasAVX512CD = false,
137 hasAVX512DQ = false, hasAVX512ER = false, hasAVX512IFMA = false,
138 hasAVX512PF = false, hasAVX512VBMI = false, hasAVX512VL = false,
139 hasAVX512VPOPCNTDQ = false,
140 hasNeon = false;
141};
142
143static const CPUInformation& getCPUInformation() noexcept
144{
145 static CPUInformation info;
146 return info;
147}
148
149 int SystemStats::getNumCpus() noexcept { return getCPUInformation().numLogicalCPUs; }
150 int SystemStats::getNumPhysicalCpus() noexcept { return getCPUInformation().numPhysicalCPUs; }
151 bool SystemStats::hasMMX() noexcept { return getCPUInformation().hasMMX; }
152 bool SystemStats::has3DNow() noexcept { return getCPUInformation().has3DNow; }
153 bool SystemStats::hasFMA3() noexcept { return getCPUInformation().hasFMA3; }
154 bool SystemStats::hasFMA4() noexcept { return getCPUInformation().hasFMA4; }
155 bool SystemStats::hasSSE() noexcept { return getCPUInformation().hasSSE; }
156 bool SystemStats::hasSSE2() noexcept { return getCPUInformation().hasSSE2; }
157 bool SystemStats::hasSSE3() noexcept { return getCPUInformation().hasSSE3; }
158 bool SystemStats::hasSSSE3() noexcept { return getCPUInformation().hasSSSE3; }
159 bool SystemStats::hasSSE41() noexcept { return getCPUInformation().hasSSE41; }
160 bool SystemStats::hasSSE42() noexcept { return getCPUInformation().hasSSE42; }
161 bool SystemStats::hasAVX() noexcept { return getCPUInformation().hasAVX; }
162 bool SystemStats::hasAVX2() noexcept { return getCPUInformation().hasAVX2; }
163 bool SystemStats::hasAVX512F() noexcept { return getCPUInformation().hasAVX512F; }
164 bool SystemStats::hasAVX512BW() noexcept { return getCPUInformation().hasAVX512BW; }
165 bool SystemStats::hasAVX512CD() noexcept { return getCPUInformation().hasAVX512CD; }
166 bool SystemStats::hasAVX512DQ() noexcept { return getCPUInformation().hasAVX512DQ; }
167 bool SystemStats::hasAVX512ER() noexcept { return getCPUInformation().hasAVX512ER; }
168 bool SystemStats::hasAVX512IFMA() noexcept { return getCPUInformation().hasAVX512IFMA; }
169 bool SystemStats::hasAVX512PF() noexcept { return getCPUInformation().hasAVX512PF; }
170 bool SystemStats::hasAVX512VBMI() noexcept { return getCPUInformation().hasAVX512VBMI; }
171 bool SystemStats::hasAVX512VL() noexcept { return getCPUInformation().hasAVX512VL; }
172 bool SystemStats::hasAVX512VPOPCNTDQ() noexcept { return getCPUInformation().hasAVX512VPOPCNTDQ; }
173 bool SystemStats::hasNeon() noexcept { return getCPUInformation().hasNeon; }
174
175
176//==============================================================================
177 String SystemStats::getStackBacktrace()
178{
179 String result;
180
181 #if JUCE_ANDROID || JUCE_MINGW || JUCE_WASM
182 jassertfalse; // sorry, not implemented yet!
183
184 #elif JUCE_WINDOWS
185 HANDLE process = GetCurrentProcess();
186 SymInitialize (process, nullptr, TRUE);
187
188 void* stack[128];
189 int frames = (int) CaptureStackBackTrace (0, numElementsInArray (stack), stack, nullptr);
190
191 HeapBlock<SYMBOL_INFO> symbol;
192 symbol.calloc (sizeof (SYMBOL_INFO) + 256, 1);
193 symbol->MaxNameLen = 255;
194 symbol->SizeOfStruct = sizeof (SYMBOL_INFO);
195
196 for (int i = 0; i < frames; ++i)
197 {
198 DWORD64 displacement = 0;
199
200 if (SymFromAddr (process, (DWORD64) stack[i], &displacement, symbol))
201 {
202 result << i << ": ";
203
204 IMAGEHLP_MODULE64 moduleInfo;
205 zerostruct (moduleInfo);
206 moduleInfo.SizeOfStruct = sizeof (moduleInfo);
207
208 if (::SymGetModuleInfo64 (process, symbol->ModBase, &moduleInfo))
209 result << moduleInfo.ModuleName << ": ";
210
211 result << symbol->Name << " + 0x" << String::toHexString ((int64) displacement) << newLine;
212 }
213 }
214
215 #else
216 void* stack[128];
217 auto frames = backtrace (stack, numElementsInArray (stack));
218 char** frameStrings = backtrace_symbols (stack, frames);
219
220 for (auto i = (decltype (frames)) 0; i < frames; ++i)
221 result << frameStrings[i] << newLine;
222
223 ::free (frameStrings);
224 #endif
225
226 return result;
227}
228
229//==============================================================================
230#if ! JUCE_WASM
231
232 static SystemStats::CrashHandlerFunction globalCrashHandler = nullptr;
233
234#if JUCE_WINDOWS
235 static LONG WINAPI handleCrash (LPEXCEPTION_POINTERS ep)
236{
237 globalCrashHandler (ep);
238 return EXCEPTION_EXECUTE_HANDLER;
239}
240#else
241 static void handleCrash (int signum)
242{
243 globalCrashHandler ((void*) (pointer_sized_int) signum);
244 ::kill (getpid(), SIGKILL);
245}
246
247 int juce_siginterrupt (int sig, int flag);
248#endif
249
250 void SystemStats::setApplicationCrashHandler (CrashHandlerFunction handler)
251{
252 jassert (handler != nullptr); // This must be a valid function.
253 globalCrashHandler = handler;
254
255 #if JUCE_WINDOWS
256 SetUnhandledExceptionFilter (handleCrash);
257 #else
258 const int signals[] = { SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGABRT, SIGSYS };
259
260 for (int i = 0; i < numElementsInArray (signals); ++i)
261 {
262 ::signal (signals[i], handleCrash);
263 juce_siginterrupt (signals[i], 1);
264 }
265 #endif
266}
267
268#endif
269
270 bool SystemStats::isRunningInAppExtensionSandbox() noexcept
271{
272 #if JUCE_MAC || JUCE_IOS
273 static bool isRunningInAppSandbox = [&]
274 {
275 File bundle = File::getSpecialLocation (File::invokedExecutableFile).getParentDirectory();
276
277 #if JUCE_MAC
278 bundle = bundle.getParentDirectory().getParentDirectory();
279 #endif
280
281 if (bundle.isDirectory())
282 return bundle.getFileExtension() == ".appex";
283
284 return false;
285 }();
286
287 return isRunningInAppSandbox;
288 #else
289 return false;
290 #endif
291}
292
293#if JUCE_UNIT_TESTS
294
295 class UniqueHardwareIDTest final : public UnitTest
296{
297 public:
298 //==============================================================================
299 UniqueHardwareIDTest() : UnitTest ("UniqueHardwareID", UnitTestCategories::analytics) {}
300
301 void runTest() override
302 {
303 beginTest ("getUniqueDeviceID returns usable data.");
304 {
305 expect (SystemStats::getUniqueDeviceID().isNotEmpty());
306 }
307 }
308};
309
310 static UniqueHardwareIDTest uniqueHardwareIDTest;
311
312#endif
313
314} // namespace juce
juce::File
Definition juce_File.h:45
juce::File::isDirectory
bool isDirectory() const
juce::File::getFileExtension
String getFileExtension() const
Definition juce_File.cpp:672
juce::File::getSpecialLocation
static File JUCE_CALLTYPE getSpecialLocation(const SpecialLocationType type)
juce::File::invokedExecutableFile
@ invokedExecutableFile
Definition juce_File.h:949
juce::File::getParentDirectory
File getParentDirectory() const
Definition juce_File.cpp:358
juce::File::getFileIdentifier
uint64 getFileIdentifier() const
juce::HeapBlock
Definition juce_HeapBlock.h:87
juce::HeapBlock::calloc
void calloc(SizeType newNumElements, const size_t elementSize=sizeof(ElementType))
Definition juce_HeapBlock.h:259
juce::MACAddress::getAllAddresses
static Array< MACAddress > getAllAddresses()
Definition juce_MACAddress.cpp:88
juce::StringArray
Definition juce_StringArray.h:35
juce::StringArray::isEmpty
bool isEmpty() const noexcept
Definition juce_StringArray.h:139
juce::String
Definition juce_String.h:53
juce::String::toHexString
static String toHexString(IntegerType number)
Definition juce_String.h:1097
juce::SystemStats::hasAVX512CD
static bool hasAVX512CD() noexcept
Definition juce_SystemStats.cpp:165
juce::SystemStats::getStackBacktrace
static String getStackBacktrace()
Definition juce_SystemStats.cpp:177
juce::SystemStats::hasMMX
static bool hasMMX() noexcept
Definition juce_SystemStats.cpp:151
juce::SystemStats::setApplicationCrashHandler
static void setApplicationCrashHandler(CrashHandlerFunction)
Definition juce_SystemStats.cpp:250
juce::SystemStats::getNumPhysicalCpus
static int getNumPhysicalCpus() noexcept
Definition juce_SystemStats.cpp:150
juce::SystemStats::hasAVX512ER
static bool hasAVX512ER() noexcept
Definition juce_SystemStats.cpp:167
juce::SystemStats::has3DNow
static bool has3DNow() noexcept
Definition juce_SystemStats.cpp:152
juce::SystemStats::hasAVX2
static bool hasAVX2() noexcept
Definition juce_SystemStats.cpp:162
juce::SystemStats::hasAVX512VPOPCNTDQ
static bool hasAVX512VPOPCNTDQ() noexcept
Definition juce_SystemStats.cpp:172
juce::SystemStats::hasSSE
static bool hasSSE() noexcept
Definition juce_SystemStats.cpp:155
juce::SystemStats::hasAVX512DQ
static bool hasAVX512DQ() noexcept
Definition juce_SystemStats.cpp:166
juce::SystemStats::isRunningInAppExtensionSandbox
static bool isRunningInAppExtensionSandbox() noexcept
Definition juce_SystemStats.cpp:270
juce::SystemStats::hasNeon
static bool hasNeon() noexcept
Definition juce_SystemStats.cpp:173
juce::SystemStats::hasAVX512F
static bool hasAVX512F() noexcept
Definition juce_SystemStats.cpp:163
juce::SystemStats::hasSSE3
static bool hasSSE3() noexcept
Definition juce_SystemStats.cpp:157
juce::SystemStats::hasSSE2
static bool hasSSE2() noexcept
Definition juce_SystemStats.cpp:156
juce::SystemStats::hasAVX
static bool hasAVX() noexcept
Definition juce_SystemStats.cpp:161
juce::SystemStats::CrashHandlerFunction
void(*)(void *) CrashHandlerFunction
Definition juce_SystemStats.h:263
juce::SystemStats::hasAVX512VBMI
static bool hasAVX512VBMI() noexcept
Definition juce_SystemStats.cpp:170
juce::SystemStats::getUniqueDeviceID
static String getUniqueDeviceID()
juce::SystemStats::MachineIdFlags
MachineIdFlags
Definition juce_SystemStats.h:169
juce::SystemStats::MachineIdFlags::legacyUniqueId
@ legacyUniqueId
Only implemented on Windows. A hash of the full smbios table, may be unstable on certain machines.
juce::SystemStats::MachineIdFlags::uniqueId
@ uniqueId
The most stable kind of machine identifier. A good default to use.
juce::SystemStats::MachineIdFlags::fileSystemId
@ fileSystemId
The filesystem id of the user's home directory (or system directory on Windows).
juce::SystemStats::MachineIdFlags::macAddresses
@ macAddresses
All Mac addresses of the machine.
juce::SystemStats::hasSSSE3
static bool hasSSSE3() noexcept
Definition juce_SystemStats.cpp:158
juce::SystemStats::hasAVX512VL
static bool hasAVX512VL() noexcept
Definition juce_SystemStats.cpp:171
juce::SystemStats::hasAVX512PF
static bool hasAVX512PF() noexcept
Definition juce_SystemStats.cpp:169
juce::SystemStats::hasSSE41
static bool hasSSE41() noexcept
Definition juce_SystemStats.cpp:159
juce::SystemStats::getDeviceIdentifiers
static StringArray getDeviceIdentifiers()
Definition juce_SystemStats.cpp:61
juce::SystemStats::hasFMA4
static bool hasFMA4() noexcept
Definition juce_SystemStats.cpp:154
juce::SystemStats::getJUCEVersion
static String getJUCEVersion()
Definition juce_SystemStats.cpp:26
juce::SystemStats::hasSSE42
static bool hasSSE42() noexcept
Definition juce_SystemStats.cpp:160
juce::SystemStats::getMachineIdentifiers
static StringArray getMachineIdentifiers(MachineIdFlags flags)
Definition juce_SystemStats.cpp:73
juce::SystemStats::hasFMA3
static bool hasFMA3() noexcept
Definition juce_SystemStats.cpp:153
juce::SystemStats::hasAVX512IFMA
static bool hasAVX512IFMA() noexcept
Definition juce_SystemStats.cpp:168
juce::SystemStats::hasAVX512BW
static bool hasAVX512BW() noexcept
Definition juce_SystemStats.cpp:164
juce::SystemStats::getNumCpus
static int getNumCpus() noexcept
Definition juce_SystemStats.cpp:149
juce::UnitTest
Definition juce_UnitTest.h:70