Loading...
Searching...
No Matches
juce_SystemStats.cpp
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
The code included in this file is provided under the terms of the ISC license
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
To use, copy, modify, and/or distribute this software for any purpose with or
without fee is hereby granted provided that the above copyright notice and
this permission notice appear in all copies.
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
String SystemStats::getJUCEVersion()
{
// Some basic tests, to keep an eye on things and make sure these types work ok
// on all platforms. Let me know if any of these assertions fail on your system!
static_assert (sizeof (pointer_sized_int) == sizeof (void*), "Basic sanity test failed: please report!");
static_assert (sizeof (int8) == 1, "Basic sanity test failed: please report!");
static_assert (sizeof (uint8) == 1, "Basic sanity test failed: please report!");
static_assert (sizeof (int16) == 2, "Basic sanity test failed: please report!");
static_assert (sizeof (uint16) == 2, "Basic sanity test failed: please report!");
static_assert (sizeof (int32) == 4, "Basic sanity test failed: please report!");
static_assert (sizeof (uint32) == 4, "Basic sanity test failed: please report!");
static_assert (sizeof (int64) == 8, "Basic sanity test failed: please report!");
static_assert (sizeof (uint64) == 8, "Basic sanity test failed: please report!");
return "JUCE v" JUCE_STRINGIFY (JUCE_MAJOR_VERSION)
"." JUCE_STRINGIFY (JUCE_MINOR_VERSION)
"." JUCE_STRINGIFY (JUCE_BUILDNUMBER);
}
#if JUCE_ANDROID && ! defined (JUCE_DISABLE_JUCE_VERSION_PRINTING)
#define JUCE_DISABLE_JUCE_VERSION_PRINTING 1
#endif
#if JUCE_DEBUG && ! JUCE_DISABLE_JUCE_VERSION_PRINTING
struct JuceVersionPrinter
{
JuceVersionPrinter()
{
DBG (SystemStats::getJUCEVersion());
}
};
static JuceVersionPrinter juceVersionPrinter;
#endif
StringArray SystemStats::getDeviceIdentifiers()
{
for (const auto flag : { MachineIdFlags::fileSystemId, MachineIdFlags::macAddresses })
if (auto ids = getMachineIdentifiers (flag); ! ids.isEmpty())
return ids;
jassertfalse; // Failed to create any IDs!
return {};
}
String getLegacyUniqueDeviceID();
StringArray SystemStats::getMachineIdentifiers (MachineIdFlags flags)
{
auto macAddressProvider = [] (StringArray& arr)
{
for (const auto& mac : MACAddress::getAllAddresses())
arr.add (mac.toString());
};
auto fileSystemProvider = [] (StringArray& arr)
{
#if JUCE_WINDOWS
File f (File::getSpecialLocation (File::windowsSystemDirectory));
#else
File f ("~");
#endif
if (auto num = f.getFileIdentifier())
arr.add (String::toHexString ((int64) num));
};
auto legacyIdProvider = [] ([[maybe_unused]] StringArray& arr)
{
#if JUCE_WINDOWS
arr.add (getLegacyUniqueDeviceID());
#endif
};
auto uniqueIdProvider = [] (StringArray& arr)
{
arr.add (getUniqueDeviceID());
};
struct Provider { MachineIdFlags flag; void (*func) (StringArray&); };
static const Provider providers[] =
{
{ MachineIdFlags::macAddresses, macAddressProvider },
{ MachineIdFlags::fileSystemId, fileSystemProvider },
{ MachineIdFlags::legacyUniqueId, legacyIdProvider },
{ MachineIdFlags::uniqueId, uniqueIdProvider }
};
StringArray ids;
for (const auto& provider : providers)
{
if (hasBitValueSet (flags, provider.flag))
provider.func (ids);
}
return ids;
}
//==============================================================================
struct CPUInformation
{
CPUInformation() noexcept { initialise(); }
void initialise() noexcept;
int numLogicalCPUs = 0, numPhysicalCPUs = 0;
bool hasMMX = false, hasSSE = false, hasSSE2 = false, hasSSE3 = false,
has3DNow = false, hasFMA3 = false, hasFMA4 = false, hasSSSE3 = false,
hasSSE41 = false, hasSSE42 = false, hasAVX = false, hasAVX2 = false,
hasAVX512F = false, hasAVX512BW = false, hasAVX512CD = false,
hasAVX512DQ = false, hasAVX512ER = false, hasAVX512IFMA = false,
hasAVX512PF = false, hasAVX512VBMI = false, hasAVX512VL = false,
hasAVX512VPOPCNTDQ = false,
hasNeon = false;
};
static const CPUInformation& getCPUInformation() noexcept
{
static CPUInformation info;
return info;
}
int SystemStats::getNumCpus() noexcept { return getCPUInformation().numLogicalCPUs; }
int SystemStats::getNumPhysicalCpus() noexcept { return getCPUInformation().numPhysicalCPUs; }
bool SystemStats::hasMMX() noexcept { return getCPUInformation().hasMMX; }
bool SystemStats::has3DNow() noexcept { return getCPUInformation().has3DNow; }
bool SystemStats::hasFMA3() noexcept { return getCPUInformation().hasFMA3; }
bool SystemStats::hasFMA4() noexcept { return getCPUInformation().hasFMA4; }
bool SystemStats::hasSSE() noexcept { return getCPUInformation().hasSSE; }
bool SystemStats::hasSSE2() noexcept { return getCPUInformation().hasSSE2; }
bool SystemStats::hasSSE3() noexcept { return getCPUInformation().hasSSE3; }
bool SystemStats::hasSSSE3() noexcept { return getCPUInformation().hasSSSE3; }
bool SystemStats::hasSSE41() noexcept { return getCPUInformation().hasSSE41; }
bool SystemStats::hasSSE42() noexcept { return getCPUInformation().hasSSE42; }
bool SystemStats::hasAVX() noexcept { return getCPUInformation().hasAVX; }
bool SystemStats::hasAVX2() noexcept { return getCPUInformation().hasAVX2; }
bool SystemStats::hasAVX512F() noexcept { return getCPUInformation().hasAVX512F; }
bool SystemStats::hasAVX512BW() noexcept { return getCPUInformation().hasAVX512BW; }
bool SystemStats::hasAVX512CD() noexcept { return getCPUInformation().hasAVX512CD; }
bool SystemStats::hasAVX512DQ() noexcept { return getCPUInformation().hasAVX512DQ; }
bool SystemStats::hasAVX512ER() noexcept { return getCPUInformation().hasAVX512ER; }
bool SystemStats::hasAVX512IFMA() noexcept { return getCPUInformation().hasAVX512IFMA; }
bool SystemStats::hasAVX512PF() noexcept { return getCPUInformation().hasAVX512PF; }
bool SystemStats::hasAVX512VBMI() noexcept { return getCPUInformation().hasAVX512VBMI; }
bool SystemStats::hasAVX512VL() noexcept { return getCPUInformation().hasAVX512VL; }
bool SystemStats::hasAVX512VPOPCNTDQ() noexcept { return getCPUInformation().hasAVX512VPOPCNTDQ; }
bool SystemStats::hasNeon() noexcept { return getCPUInformation().hasNeon; }
//==============================================================================
String SystemStats::getStackBacktrace()
{
String result;
#if JUCE_ANDROID || JUCE_MINGW || JUCE_WASM
jassertfalse; // sorry, not implemented yet!
#elif JUCE_WINDOWS
HANDLE process = GetCurrentProcess();
SymInitialize (process, nullptr, TRUE);
void* stack[128];
int frames = (int) CaptureStackBackTrace (0, numElementsInArray (stack), stack, nullptr);
HeapBlock<SYMBOL_INFO> symbol;
symbol.calloc (sizeof (SYMBOL_INFO) + 256, 1);
symbol->MaxNameLen = 255;
symbol->SizeOfStruct = sizeof (SYMBOL_INFO);
for (int i = 0; i < frames; ++i)
{
DWORD64 displacement = 0;
if (SymFromAddr (process, (DWORD64) stack[i], &displacement, symbol))
{
result << i << ": ";
IMAGEHLP_MODULE64 moduleInfo;
zerostruct (moduleInfo);
moduleInfo.SizeOfStruct = sizeof (moduleInfo);
if (::SymGetModuleInfo64 (process, symbol->ModBase, &moduleInfo))
result << moduleInfo.ModuleName << ": ";
result << symbol->Name << " + 0x" << String::toHexString ((int64) displacement) << newLine;
}
}
#else
void* stack[128];
auto frames = backtrace (stack, numElementsInArray (stack));
char** frameStrings = backtrace_symbols (stack, frames);
for (auto i = (decltype (frames)) 0; i < frames; ++i)
result << frameStrings[i] << newLine;
::free (frameStrings);
#endif
return result;
}
//==============================================================================
#if ! JUCE_WASM
static SystemStats::CrashHandlerFunction globalCrashHandler = nullptr;
#if JUCE_WINDOWS
static LONG WINAPI handleCrash (LPEXCEPTION_POINTERS ep)
{
globalCrashHandler (ep);
return EXCEPTION_EXECUTE_HANDLER;
}
#else
static void handleCrash (int signum)
{
globalCrashHandler ((void*) (pointer_sized_int) signum);
::kill (getpid(), SIGKILL);
}
int juce_siginterrupt (int sig, int flag);
#endif
void SystemStats::setApplicationCrashHandler (CrashHandlerFunction handler)
{
jassert (handler != nullptr); // This must be a valid function.
globalCrashHandler = handler;
#if JUCE_WINDOWS
SetUnhandledExceptionFilter (handleCrash);
#else
const int signals[] = { SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGABRT, SIGSYS };
for (int i = 0; i < numElementsInArray (signals); ++i)
{
::signal (signals[i], handleCrash);
juce_siginterrupt (signals[i], 1);
}
#endif
}
#endif
bool SystemStats::isRunningInAppExtensionSandbox() noexcept
{
#if JUCE_MAC || JUCE_IOS
static bool isRunningInAppSandbox = [&]
{
File bundle = File::getSpecialLocation (File::invokedExecutableFile).getParentDirectory();
#if JUCE_MAC
bundle = bundle.getParentDirectory().getParentDirectory();
#endif
if (bundle.isDirectory())
return bundle.getFileExtension() == ".appex";
return false;
}();
return isRunningInAppSandbox;
#else
return false;
#endif
}
#if JUCE_UNIT_TESTS
class UniqueHardwareIDTest final : public UnitTest
{
public:
//==============================================================================
UniqueHardwareIDTest() : UnitTest ("UniqueHardwareID", UnitTestCategories::analytics) {}
void runTest() override
{
beginTest ("getUniqueDeviceID returns usable data.");
{
expect (SystemStats::getUniqueDeviceID().isNotEmpty());
}
}
};
static UniqueHardwareIDTest uniqueHardwareIDTest;
#endif
} // 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::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.
Definition juce_SystemStats.h:172
juce::SystemStats::MachineIdFlags::uniqueId
@ uniqueId
The most stable kind of machine identifier. A good default to use.
Definition juce_SystemStats.h:173
juce::SystemStats::MachineIdFlags::fileSystemId
@ fileSystemId
The filesystem id of the user's home directory (or system directory on Windows).
Definition juce_SystemStats.h:171
juce::SystemStats::MachineIdFlags::macAddresses
@ macAddresses
All Mac addresses of the machine.
Definition juce_SystemStats.h:170
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