1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 Rubber Band Library
5 An audio time-stretching and pitch-shifting library.
6 Copyright 2007-2021 Particular Programs Ltd.
7
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of the
11 License, or (at your option) any later version. See the file
12 COPYING included with this distribution for more information.
13
14 Alternatively, if you have a valid commercial licence for the
15 Rubber Band Library obtained by agreement with the copyright
16 holders, you may redistribute and/or modify it under the terms
17 described in that licence.
18
19 If you wish to distribute code using the Rubber Band Library
20 under terms other than those of the GNU General Public License,
21 you must obtain a valid commercial licence before doing so.
22 */
23
24 #include "sysutils.h"
25
26 #ifdef _WIN32
27 #include <windows.h>
28 #include <fcntl.h>
29 #include <io.h>
30 #else /* !_WIN32 */
31 #include <signal.h>
32 #include <unistd.h>
33 #ifdef __APPLE__
34 #include <sys/sysctl.h>
35 #include <mach/mach.h>
36 #include <mach/mach_time.h>
37 #else /* !__APPLE__, !_WIN32 */
38 #include <stdio.h>
39 #include <string.h>
40 #endif /* !__APPLE__, !_WIN32 */
41 #endif /* !_WIN32 */
42
43 #ifdef __sun
44 #include <sys/processor.h>
45 #endif
46
47 #include <cstdlib>
48 #include <iostream>
49
50 #ifdef HAVE_IPP
51 #include <ippversion.h>
52 #include <ipp.h>
53 #endif
54
55 #ifdef HAVE_VDSP
56 #include <Accelerate/Accelerate.h>
57 #include <fenv.h>
58 #endif
59
60 #ifdef _WIN32
61 #include <fstream>
62 #endif
63
64
65 namespace RubberBand {
66
67 const char *
system_get_platform_tag()68 system_get_platform_tag()
69 {
70 #ifdef _WIN32
71 return "win32";
72 #else /* !_WIN32 */
73 #ifdef __APPLE__
74 return "osx";
75 #else /* !__APPLE__ */
76 #ifdef __LINUX__
77 if (sizeof(long) == 8) {
78 return "linux64";
79 } else {
80 return "linux";
81 }
82 #else /* !__LINUX__ */
83 return "posix";
84 #endif /* !__LINUX__ */
85 #endif /* !__APPLE__ */
86 #endif /* !_WIN32 */
87 }
88
89 bool
system_is_multiprocessor()90 system_is_multiprocessor()
91 {
92 static bool tested = false, mp = false;
93
94 if (tested) return mp;
95 int count = 0;
96
97 #ifdef _WIN32
98
99 SYSTEM_INFO sysinfo;
100 GetSystemInfo(&sysinfo);
101 count = sysinfo.dwNumberOfProcessors;
102
103 #else /* !_WIN32 */
104 #ifdef __APPLE__
105
106 size_t sz = sizeof(count);
107 if (sysctlbyname("hw.ncpu", &count, &sz, NULL, 0)) {
108 count = 0;
109 mp = false;
110 } else {
111 mp = (count > 1);
112 }
113
114 #else /* !__APPLE__, !_WIN32 */
115 #ifdef __sun
116
117 processorid_t i, n;
118 n = sysconf(_SC_CPUID_MAX);
119 for (i = 0; i <= n; ++i) {
120 int status = p_online(i, P_STATUS);
121 if (status == P_ONLINE) {
122 ++count;
123 }
124 if (count > 1) break;
125 }
126
127 #else /* !__sun, !__APPLE__, !_WIN32 */
128
129 //...
130
131 FILE *cpuinfo = fopen("/proc/cpuinfo", "r");
132 if (!cpuinfo) return false;
133
134 char buf[256];
135 while (!feof(cpuinfo)) {
136 if (!fgets(buf, 256, cpuinfo)) break;
137 if (!strncmp(buf, "processor", 9)) {
138 ++count;
139 }
140 if (count > 1) break;
141 }
142
143 fclose(cpuinfo);
144
145 #endif /* !__sun, !__APPLE__, !_WIN32 */
146 #endif /* !__APPLE__, !_WIN32 */
147 #endif /* !_WIN32 */
148
149 mp = (count > 1);
150 tested = true;
151 return mp;
152 }
153
154 #ifdef _WIN32
155
gettimeofday(struct timeval * tv,void * tz)156 void gettimeofday(struct timeval *tv, void *tz)
157 {
158 union {
159 long long ns100;
160 FILETIME ft;
161 } now;
162
163 ::GetSystemTimeAsFileTime(&now.ft);
164 tv->tv_usec = (long)((now.ns100 / 10LL) % 1000000LL);
165 tv->tv_sec = (long)((now.ns100 - 116444736000000000LL) / 10000000LL);
166 }
167
usleep(unsigned long usec)168 void usleep(unsigned long usec)
169 {
170 ::Sleep(usec == 0 ? 0 : usec < 1000 ? 1 : usec / 1000);
171 }
172
173 #endif
174
system_specific_initialise()175 void system_specific_initialise()
176 {
177 #if defined HAVE_IPP
178 #ifndef USE_IPP_DYNAMIC_LIBS
179 #if (IPP_VERSION_MAJOR < 9)
180 // This was removed in v9
181 ippStaticInit();
182 #endif
183 #endif
184 ippSetDenormAreZeros(1);
185 #elif defined HAVE_VDSP
186 #if defined __i386__ || defined __x86_64__
187 fesetenv(FE_DFL_DISABLE_SSE_DENORMS_ENV);
188 #elif defined __arm64__
189 fesetenv(FE_DFL_DISABLE_DENORMS_ENV);
190 #endif
191 #endif
192 #if defined __ARMEL__
193 // ARM32
194 static const unsigned int x = 0x04086060;
195 static const unsigned int y = 0x03000000;
196 int r;
197 asm volatile (
198 "fmrx %0, fpscr \n\t"
199 "and %0, %0, %1 \n\t"
200 "orr %0, %0, %2 \n\t"
201 "fmxr fpscr, %0 \n\t"
202 : "=r"(r)
203 : "r"(x), "r"(y)
204 );
205 #endif
206 }
207
system_specific_application_initialise()208 void system_specific_application_initialise()
209 {
210 }
211
212
213 ProcessStatus
system_get_process_status(int pid)214 system_get_process_status(int pid)
215 {
216 #ifdef _WIN32
217 HANDLE handle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
218 if (!handle) {
219 return ProcessNotRunning;
220 } else {
221 CloseHandle(handle);
222 return ProcessRunning;
223 }
224 #else
225 if (kill(getpid(), 0) == 0) {
226 if (kill(pid, 0) == 0) {
227 return ProcessRunning;
228 } else {
229 return ProcessNotRunning;
230 }
231 } else {
232 return UnknownProcessStatus;
233 }
234 #endif
235 }
236
237 #ifdef _WIN32
system_memorybarrier()238 void system_memorybarrier()
239 {
240 #ifdef _MSC_VER
241 MemoryBarrier();
242 #else /* (mingw) */
243 LONG Barrier = 0;
244 __asm__ __volatile__("xchgl %%eax,%0 "
245 : "=r" (Barrier));
246 #endif
247 }
248 #else /* !_WIN32 */
249 #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
250 // Not required
251 #else
252 #include <pthread.h>
system_memorybarrier()253 void system_memorybarrier()
254 {
255 pthread_mutex_t dummy = PTHREAD_MUTEX_INITIALIZER;
256 pthread_mutex_lock(&dummy);
257 pthread_mutex_unlock(&dummy);
258 }
259 #endif
260 #endif
261
262 }
263
264
265
266