VST3: fetch midi mappings all at once, use it for note/sound-off
[carla.git] / source / modules / juce_core / system / juce_SystemStats.cpp
blob59707c9d102b45c4ebcdc366a579de518165f285
1 /*
2 ==============================================================================
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
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.
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.
20 ==============================================================================
23 namespace juce
26 String SystemStats::getJUCEVersion()
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!");
40 return "JUCE v" JUCE_STRINGIFY(JUCE_MAJOR_VERSION)
41 "." JUCE_STRINGIFY(JUCE_MINOR_VERSION)
42 "." JUCE_STRINGIFY(JUCE_BUILDNUMBER);
45 #if JUCE_ANDROID && ! defined (JUCE_DISABLE_JUCE_VERSION_PRINTING)
46 #define JUCE_DISABLE_JUCE_VERSION_PRINTING 1
47 #endif
49 #if JUCE_DEBUG && ! JUCE_DISABLE_JUCE_VERSION_PRINTING
50 struct JuceVersionPrinter
52 JuceVersionPrinter()
54 DBG (SystemStats::getJUCEVersion());
58 static JuceVersionPrinter juceVersionPrinter;
59 #endif
61 StringArray SystemStats::getDeviceIdentifiers()
63 StringArray ids;
65 #if JUCE_WINDOWS
66 File f (File::getSpecialLocation (File::windowsSystemDirectory));
67 #else
68 File f ("~");
69 #endif
70 if (auto num = f.getFileIdentifier())
72 ids.add (String::toHexString ((int64) num));
75 jassert (! ids.isEmpty()); // Failed to create any IDs!
76 return ids;
79 //==============================================================================
80 struct CPUInformation
82 CPUInformation() noexcept { initialise(); }
84 void initialise() noexcept;
86 int numLogicalCPUs = 0, numPhysicalCPUs = 0;
88 bool hasMMX = false, hasSSE = false, hasSSE2 = false, hasSSE3 = false,
89 has3DNow = false, hasFMA3 = false, hasFMA4 = false, hasSSSE3 = false,
90 hasSSE41 = false, hasSSE42 = false, hasAVX = false, hasAVX2 = false,
91 hasAVX512F = false, hasAVX512BW = false, hasAVX512CD = false,
92 hasAVX512DQ = false, hasAVX512ER = false, hasAVX512IFMA = false,
93 hasAVX512PF = false, hasAVX512VBMI = false, hasAVX512VL = false,
94 hasAVX512VPOPCNTDQ = false,
95 hasNeon = false;
98 static const CPUInformation& getCPUInformation() noexcept
100 static CPUInformation info;
101 return info;
104 int SystemStats::getNumCpus() noexcept { return getCPUInformation().numLogicalCPUs; }
105 int SystemStats::getNumPhysicalCpus() noexcept { return getCPUInformation().numPhysicalCPUs; }
106 bool SystemStats::hasMMX() noexcept { return getCPUInformation().hasMMX; }
107 bool SystemStats::has3DNow() noexcept { return getCPUInformation().has3DNow; }
108 bool SystemStats::hasFMA3() noexcept { return getCPUInformation().hasFMA3; }
109 bool SystemStats::hasFMA4() noexcept { return getCPUInformation().hasFMA4; }
110 bool SystemStats::hasSSE() noexcept { return getCPUInformation().hasSSE; }
111 bool SystemStats::hasSSE2() noexcept { return getCPUInformation().hasSSE2; }
112 bool SystemStats::hasSSE3() noexcept { return getCPUInformation().hasSSE3; }
113 bool SystemStats::hasSSSE3() noexcept { return getCPUInformation().hasSSSE3; }
114 bool SystemStats::hasSSE41() noexcept { return getCPUInformation().hasSSE41; }
115 bool SystemStats::hasSSE42() noexcept { return getCPUInformation().hasSSE42; }
116 bool SystemStats::hasAVX() noexcept { return getCPUInformation().hasAVX; }
117 bool SystemStats::hasAVX2() noexcept { return getCPUInformation().hasAVX2; }
118 bool SystemStats::hasAVX512F() noexcept { return getCPUInformation().hasAVX512F; }
119 bool SystemStats::hasAVX512BW() noexcept { return getCPUInformation().hasAVX512BW; }
120 bool SystemStats::hasAVX512CD() noexcept { return getCPUInformation().hasAVX512CD; }
121 bool SystemStats::hasAVX512DQ() noexcept { return getCPUInformation().hasAVX512DQ; }
122 bool SystemStats::hasAVX512ER() noexcept { return getCPUInformation().hasAVX512ER; }
123 bool SystemStats::hasAVX512IFMA() noexcept { return getCPUInformation().hasAVX512IFMA; }
124 bool SystemStats::hasAVX512PF() noexcept { return getCPUInformation().hasAVX512PF; }
125 bool SystemStats::hasAVX512VBMI() noexcept { return getCPUInformation().hasAVX512VBMI; }
126 bool SystemStats::hasAVX512VL() noexcept { return getCPUInformation().hasAVX512VL; }
127 bool SystemStats::hasAVX512VPOPCNTDQ() noexcept { return getCPUInformation().hasAVX512VPOPCNTDQ; }
128 bool SystemStats::hasNeon() noexcept { return getCPUInformation().hasNeon; }
131 //==============================================================================
132 String SystemStats::getStackBacktrace()
134 String result;
136 #if JUCE_ANDROID || JUCE_MINGW || JUCE_WASM
137 jassertfalse; // sorry, not implemented yet!
139 #elif JUCE_WINDOWS
140 HANDLE process = GetCurrentProcess();
141 SymInitialize (process, nullptr, TRUE);
143 void* stack[128];
144 int frames = (int) CaptureStackBackTrace (0, numElementsInArray (stack), stack, nullptr);
146 HeapBlock<SYMBOL_INFO> symbol;
147 symbol.calloc (sizeof (SYMBOL_INFO) + 256, 1);
148 symbol->MaxNameLen = 255;
149 symbol->SizeOfStruct = sizeof (SYMBOL_INFO);
151 for (int i = 0; i < frames; ++i)
153 DWORD64 displacement = 0;
155 if (SymFromAddr (process, (DWORD64) stack[i], &displacement, symbol))
157 result << i << ": ";
159 IMAGEHLP_MODULE64 moduleInfo;
160 zerostruct (moduleInfo);
161 moduleInfo.SizeOfStruct = sizeof (moduleInfo);
163 if (::SymGetModuleInfo64 (process, symbol->ModBase, &moduleInfo))
164 result << moduleInfo.ModuleName << ": ";
166 result << symbol->Name << " + 0x" << String::toHexString ((int64) displacement) << newLine;
170 #else
171 void* stack[128];
172 auto frames = backtrace (stack, numElementsInArray (stack));
173 char** frameStrings = backtrace_symbols (stack, frames);
175 for (int i = 0; i < frames; ++i)
176 result << frameStrings[i] << newLine;
178 ::free (frameStrings);
179 #endif
181 return result;
184 //==============================================================================
185 #if ! JUCE_WASM
187 static SystemStats::CrashHandlerFunction globalCrashHandler = nullptr;
189 #if JUCE_WINDOWS
190 static LONG WINAPI handleCrash (LPEXCEPTION_POINTERS ep)
192 globalCrashHandler (ep);
193 return EXCEPTION_EXECUTE_HANDLER;
195 #else
196 static void handleCrash (int signum)
198 globalCrashHandler ((void*) (pointer_sized_int) signum);
199 ::kill (getpid(), SIGKILL);
202 int juce_siginterrupt (int sig, int flag);
203 #endif
205 void SystemStats::setApplicationCrashHandler (CrashHandlerFunction handler)
207 jassert (handler != nullptr); // This must be a valid function.
208 globalCrashHandler = handler;
210 #if JUCE_WINDOWS
211 SetUnhandledExceptionFilter (handleCrash);
212 #else
213 const int signals[] = { SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGABRT, SIGSYS };
215 for (int i = 0; i < numElementsInArray (signals); ++i)
217 ::signal (signals[i], handleCrash);
218 juce_siginterrupt (signals[i], 1);
220 #endif
223 #endif
225 bool SystemStats::isRunningInAppExtensionSandbox() noexcept
227 #if JUCE_MAC || JUCE_IOS
228 static bool firstQuery = true;
229 static bool isRunningInAppSandbox = false;
231 if (firstQuery)
233 firstQuery = false;
235 File bundle = File::getSpecialLocation (File::invokedExecutableFile).getParentDirectory();
237 #if JUCE_MAC
238 bundle = bundle.getParentDirectory().getParentDirectory();
239 #endif
241 if (bundle.isDirectory())
242 isRunningInAppSandbox = (bundle.getFileExtension() == ".appex");
245 return isRunningInAppSandbox;
246 #else
247 return false;
248 #endif
251 } // namespace juce