The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

216 lines
7.9KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2016 - ROLI Ltd.
  5. Permission is granted to use this software under the terms of the ISC license
  6. http://www.isc.org/downloads/software-support-policy/isc-license/
  7. Permission to use, copy, modify, and/or distribute this software for any
  8. purpose with or without fee is hereby granted, provided that the above
  9. copyright notice and this permission notice appear in all copies.
  10. THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD
  11. TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  12. FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
  13. OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  14. USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  15. TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  16. OF THIS SOFTWARE.
  17. -----------------------------------------------------------------------------
  18. To release a closed-source product which uses other parts of JUCE not
  19. licensed under the ISC terms, commercial licenses are available: visit
  20. www.juce.com for more information.
  21. ==============================================================================
  22. */
  23. String SystemStats::getJUCEVersion()
  24. {
  25. // Some basic tests, to keep an eye on things and make sure these types work ok
  26. // on all platforms. Let me know if any of these assertions fail on your system!
  27. static_assert (sizeof (pointer_sized_int) == sizeof (void*), "Basic sanity test failed: please report!");
  28. static_assert (sizeof (int8) == 1, "Basic sanity test failed: please report!");
  29. static_assert (sizeof (uint8) == 1, "Basic sanity test failed: please report!");
  30. static_assert (sizeof (int16) == 2, "Basic sanity test failed: please report!");
  31. static_assert (sizeof (uint16) == 2, "Basic sanity test failed: please report!");
  32. static_assert (sizeof (int32) == 4, "Basic sanity test failed: please report!");
  33. static_assert (sizeof (uint32) == 4, "Basic sanity test failed: please report!");
  34. static_assert (sizeof (int64) == 8, "Basic sanity test failed: please report!");
  35. static_assert (sizeof (uint64) == 8, "Basic sanity test failed: please report!");
  36. return "JUCE v" JUCE_STRINGIFY(JUCE_MAJOR_VERSION)
  37. "." JUCE_STRINGIFY(JUCE_MINOR_VERSION)
  38. "." JUCE_STRINGIFY(JUCE_BUILDNUMBER);
  39. }
  40. #if JUCE_ANDROID && ! defined (JUCE_DISABLE_JUCE_VERSION_PRINTING)
  41. #define JUCE_DISABLE_JUCE_VERSION_PRINTING 1
  42. #endif
  43. #if JUCE_DEBUG && ! JUCE_DISABLE_JUCE_VERSION_PRINTING
  44. struct JuceVersionPrinter
  45. {
  46. JuceVersionPrinter()
  47. {
  48. DBG (SystemStats::getJUCEVersion());
  49. }
  50. };
  51. static JuceVersionPrinter juceVersionPrinter;
  52. #endif
  53. //==============================================================================
  54. struct CPUInformation
  55. {
  56. CPUInformation() noexcept { initialise(); }
  57. void initialise() noexcept;
  58. int numLogicalCPUs = 0, numPhysicalCPUs = 0;
  59. bool hasMMX = false, hasSSE = false, hasSSE2 = false, hasSSE3 = false,
  60. has3DNow = false, hasSSSE3 = false, hasSSE41 = false,
  61. hasSSE42 = false, hasAVX = false, hasAVX2 = false;
  62. };
  63. static const CPUInformation& getCPUInformation() noexcept
  64. {
  65. static CPUInformation info;
  66. return info;
  67. }
  68. int SystemStats::getNumCpus() noexcept { return getCPUInformation().numLogicalCPUs; }
  69. int SystemStats::getNumPhysicalCpus() noexcept { return getCPUInformation().numPhysicalCPUs; }
  70. bool SystemStats::hasMMX() noexcept { return getCPUInformation().hasMMX; }
  71. bool SystemStats::has3DNow() noexcept { return getCPUInformation().has3DNow; }
  72. bool SystemStats::hasSSE() noexcept { return getCPUInformation().hasSSE; }
  73. bool SystemStats::hasSSE2() noexcept { return getCPUInformation().hasSSE2; }
  74. bool SystemStats::hasSSE3() noexcept { return getCPUInformation().hasSSE3; }
  75. bool SystemStats::hasSSSE3() noexcept { return getCPUInformation().hasSSSE3; }
  76. bool SystemStats::hasSSE41() noexcept { return getCPUInformation().hasSSE41; }
  77. bool SystemStats::hasSSE42() noexcept { return getCPUInformation().hasSSE42; }
  78. bool SystemStats::hasAVX() noexcept { return getCPUInformation().hasAVX; }
  79. bool SystemStats::hasAVX2() noexcept { return getCPUInformation().hasAVX2; }
  80. //==============================================================================
  81. String SystemStats::getStackBacktrace()
  82. {
  83. String result;
  84. #if JUCE_ANDROID || JUCE_MINGW
  85. jassertfalse; // sorry, not implemented yet!
  86. #elif JUCE_WINDOWS
  87. HANDLE process = GetCurrentProcess();
  88. SymInitialize (process, nullptr, TRUE);
  89. void* stack[128];
  90. int frames = (int) CaptureStackBackTrace (0, numElementsInArray (stack), stack, nullptr);
  91. HeapBlock<SYMBOL_INFO> symbol;
  92. symbol.calloc (sizeof (SYMBOL_INFO) + 256, 1);
  93. symbol->MaxNameLen = 255;
  94. symbol->SizeOfStruct = sizeof (SYMBOL_INFO);
  95. for (int i = 0; i < frames; ++i)
  96. {
  97. DWORD64 displacement = 0;
  98. if (SymFromAddr (process, (DWORD64) stack[i], &displacement, symbol))
  99. {
  100. result << i << ": ";
  101. IMAGEHLP_MODULE64 moduleInfo;
  102. zerostruct (moduleInfo);
  103. moduleInfo.SizeOfStruct = sizeof (moduleInfo);
  104. if (::SymGetModuleInfo64 (process, symbol->ModBase, &moduleInfo))
  105. result << moduleInfo.ModuleName << ": ";
  106. result << symbol->Name << " + 0x" << String::toHexString ((int64) displacement) << newLine;
  107. }
  108. }
  109. #else
  110. void* stack[128];
  111. int frames = backtrace (stack, numElementsInArray (stack));
  112. char** frameStrings = backtrace_symbols (stack, frames);
  113. for (int i = 0; i < frames; ++i)
  114. result << frameStrings[i] << newLine;
  115. ::free (frameStrings);
  116. #endif
  117. return result;
  118. }
  119. //==============================================================================
  120. static SystemStats::CrashHandlerFunction globalCrashHandler = nullptr;
  121. #if JUCE_WINDOWS
  122. static LONG WINAPI handleCrash (LPEXCEPTION_POINTERS ep)
  123. {
  124. globalCrashHandler (ep);
  125. return EXCEPTION_EXECUTE_HANDLER;
  126. }
  127. #else
  128. static void handleCrash (int signum)
  129. {
  130. globalCrashHandler ((void*) (pointer_sized_int) signum);
  131. kill (getpid(), SIGKILL);
  132. }
  133. int juce_siginterrupt (int sig, int flag);
  134. #endif
  135. void SystemStats::setApplicationCrashHandler (CrashHandlerFunction handler)
  136. {
  137. jassert (handler != nullptr); // This must be a valid function.
  138. globalCrashHandler = handler;
  139. #if JUCE_WINDOWS
  140. SetUnhandledExceptionFilter (handleCrash);
  141. #else
  142. const int signals[] = { SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGABRT, SIGSYS };
  143. for (int i = 0; i < numElementsInArray (signals); ++i)
  144. {
  145. ::signal (signals[i], handleCrash);
  146. juce_siginterrupt (signals[i], 1);
  147. }
  148. #endif
  149. }
  150. bool SystemStats::isRunningInAppExtensionSandbox() noexcept
  151. {
  152. #if JUCE_MAC || JUCE_IOS
  153. static bool firstQuery = true;
  154. static bool isRunningInAppSandbox = false;
  155. if (firstQuery)
  156. {
  157. firstQuery = false;
  158. File bundle = File::getSpecialLocation (File::invokedExecutableFile).getParentDirectory();
  159. #if JUCE_MAC
  160. bundle = bundle.getParentDirectory().getParentDirectory();
  161. #endif
  162. if (bundle.isDirectory())
  163. isRunningInAppSandbox = (bundle.getFileExtension() == ".appex");
  164. }
  165. return isRunningInAppSandbox;
  166. #else
  167. return false;
  168. #endif
  169. }