1 /*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2020 - 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 #if defined(__FreeBSD__) || defined(__DragonFly__)
24 #include <sys/sysinfo.h>
25 #endif
26
27 #if JUCE_BELA
28 extern "C" int cobalt_thread_mode();
29 #endif
30
31 namespace juce
32 {
33
outputDebugString(const String & text)34 void Logger::outputDebugString (const String& text)
35 {
36 std::cerr << text << std::endl;
37 }
38
39 //==============================================================================
getOperatingSystemType()40 SystemStats::OperatingSystemType SystemStats::getOperatingSystemType()
41 {
42 return Linux;
43 }
44
getOperatingSystemName()45 String SystemStats::getOperatingSystemName()
46 {
47 return "Linux";
48 }
49
isOperatingSystem64Bit()50 bool SystemStats::isOperatingSystem64Bit()
51 {
52 #if JUCE_64BIT
53 return true;
54 #else
55 //xxx not sure how to find this out?..
56 return false;
57 #endif
58 }
59
60 //==============================================================================
getCpuInfo(const char * key)61 static String getCpuInfo (const char* key)
62 {
63 return readPosixConfigFileValue ("/proc/cpuinfo", key);
64 }
65
getDeviceDescription()66 String SystemStats::getDeviceDescription()
67 {
68 return getCpuInfo ("Hardware");
69 }
70
getDeviceManufacturer()71 String SystemStats::getDeviceManufacturer()
72 {
73 return {};
74 }
75
getCpuVendor()76 String SystemStats::getCpuVendor()
77 {
78 auto v = getCpuInfo ("vendor_id");
79
80 if (v.isEmpty())
81 v = getCpuInfo ("model name");
82
83 return v;
84 }
85
getCpuModel()86 String SystemStats::getCpuModel()
87 {
88 return getCpuInfo ("model name");
89 }
90
getCpuSpeedInMegahertz()91 int SystemStats::getCpuSpeedInMegahertz()
92 {
93 return roundToInt (getCpuInfo ("cpu MHz").getFloatValue());
94 }
95
getMemorySizeInMegabytes()96 int SystemStats::getMemorySizeInMegabytes()
97 {
98 struct sysinfo sysi;
99
100 if (sysinfo (&sysi) == 0)
101 return (int) (sysi.totalram * sysi.mem_unit / (1024 * 1024));
102
103 return 0;
104 }
105
getPageSize()106 int SystemStats::getPageSize()
107 {
108 return (int) sysconf (_SC_PAGESIZE);
109 }
110
111 //==============================================================================
getLogonName()112 String SystemStats::getLogonName()
113 {
114 if (auto user = getenv ("USER"))
115 return String::fromUTF8 (user);
116
117 if (auto pw = getpwuid (getuid()))
118 return String::fromUTF8 (pw->pw_name);
119
120 return {};
121 }
122
getFullUserName()123 String SystemStats::getFullUserName()
124 {
125 return getLogonName();
126 }
127
getComputerName()128 String SystemStats::getComputerName()
129 {
130 char name[256] = {};
131
132 if (gethostname (name, sizeof (name) - 1) == 0)
133 return name;
134
135 return {};
136 }
137
getLocaleValue(nl_item key)138 static String getLocaleValue (nl_item key)
139 {
140 auto oldLocale = ::setlocale (LC_ALL, "");
141 auto result = String::fromUTF8 (nl_langinfo (key));
142 ::setlocale (LC_ALL, oldLocale);
143 return result;
144 }
145
146 #if JUCE_BSD
getUserLanguage()147 String SystemStats::getUserLanguage() { return String(); }
getUserRegion()148 String SystemStats::getUserRegion() { return String(); }
149 #else
getUserLanguage()150 String SystemStats::getUserLanguage() { return getLocaleValue (_NL_IDENTIFICATION_LANGUAGE); }
getUserRegion()151 String SystemStats::getUserRegion() { return getLocaleValue (_NL_IDENTIFICATION_TERRITORY); }
152 #endif
getDisplayLanguage()153 String SystemStats::getDisplayLanguage() { return getUserLanguage() + "-" + getUserRegion(); }
154
155 //==============================================================================
initialise()156 void CPUInformation::initialise() noexcept
157 {
158 auto flags = getCpuInfo ("flags");
159
160 hasMMX = flags.contains ("mmx");
161 hasFMA3 = flags.contains ("fma");
162 hasFMA4 = flags.contains ("fma4");
163 hasSSE = flags.contains ("sse");
164 hasSSE2 = flags.contains ("sse2");
165 hasSSE3 = flags.contains ("sse3");
166 has3DNow = flags.contains ("3dnow");
167 hasSSSE3 = flags.contains ("ssse3");
168 hasSSE41 = flags.contains ("sse4_1");
169 hasSSE42 = flags.contains ("sse4_2");
170 hasAVX = flags.contains ("avx");
171 hasAVX2 = flags.contains ("avx2");
172 hasAVX512F = flags.contains ("avx512f");
173 hasAVX512BW = flags.contains ("avx512bw");
174 hasAVX512CD = flags.contains ("avx512cd");
175 hasAVX512DQ = flags.contains ("avx512dq");
176 hasAVX512ER = flags.contains ("avx512er");
177 hasAVX512IFMA = flags.contains ("avx512ifma");
178 hasAVX512PF = flags.contains ("avx512pf");
179 hasAVX512VBMI = flags.contains ("avx512vbmi");
180 hasAVX512VL = flags.contains ("avx512vl");
181 hasAVX512VPOPCNTDQ = flags.contains ("avx512_vpopcntdq");
182
183 numLogicalCPUs = getCpuInfo ("processor").getIntValue() + 1;
184
185 // Assume CPUs in all sockets have the same number of cores
186 numPhysicalCPUs = getCpuInfo ("cpu cores").getIntValue() * (getCpuInfo ("physical id").getIntValue() + 1);
187
188 if (numPhysicalCPUs <= 0)
189 numPhysicalCPUs = numLogicalCPUs;
190 }
191
192 //==============================================================================
juce_millisecondsSinceStartup()193 uint32 juce_millisecondsSinceStartup() noexcept
194 {
195 return (uint32) (Time::getHighResolutionTicks() / 1000);
196 }
197
getHighResolutionTicks()198 int64 Time::getHighResolutionTicks() noexcept
199 {
200 timespec t;
201
202 #if JUCE_BELA
203 if (cobalt_thread_mode() == 0x200 /*XNRELAX*/)
204 clock_gettime (CLOCK_MONOTONIC, &t);
205 else
206 __wrap_clock_gettime (CLOCK_MONOTONIC, &t);
207 #else
208 clock_gettime (CLOCK_MONOTONIC, &t);
209 #endif
210
211 return (t.tv_sec * (int64) 1000000) + (t.tv_nsec / 1000);
212 }
213
getHighResolutionTicksPerSecond()214 int64 Time::getHighResolutionTicksPerSecond() noexcept
215 {
216 return 1000000; // (microseconds)
217 }
218
getMillisecondCounterHiRes()219 double Time::getMillisecondCounterHiRes() noexcept
220 {
221 return (double) getHighResolutionTicks() * 0.001;
222 }
223
setSystemTimeToThisTime() const224 bool Time::setSystemTimeToThisTime() const
225 {
226 timeval t;
227 t.tv_sec = decltype (timeval::tv_sec) (millisSinceEpoch / 1000);
228 t.tv_usec = decltype (timeval::tv_usec) ((millisSinceEpoch - t.tv_sec * 1000) * 1000);
229
230 return settimeofday (&t, nullptr) == 0;
231 }
232
juce_isRunningUnderDebugger()233 JUCE_API bool JUCE_CALLTYPE juce_isRunningUnderDebugger() noexcept
234 {
235 #if JUCE_BSD
236 return false;
237 #else
238 return readPosixConfigFileValue ("/proc/self/status", "TracerPid").getIntValue() > 0;
239 #endif
240 }
241
242 } // namespace juce
243