Blender V4.3
system.c
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <limits.h>
10#include <stdio.h>
11#include <stdlib.h>
12
13#include "BLI_math_base.h"
14#include "BLI_string.h"
15#include "BLI_system.h"
16
17/* for backtrace and gethostname/GetComputerName */
18#if defined(WIN32)
19# include <intrin.h>
20
21# include "BLI_winstuff.h"
22#else
23# if defined(HAVE_EXECINFO_H)
24# include <execinfo.h>
25# endif
26# include <unistd.h>
27#endif
28
30{
31#if defined(__x86_64__) || defined(_M_X64)
32 /* x86_64 always has SSE2 instructions */
33 return 1;
34#elif defined(__GNUC__) && defined(i386)
35 /* for GCC x86 we check cpuid */
36 uint d;
37 __asm__(
38 "pushl %%ebx\n\t"
39 "cpuid\n\t"
40 "popl %%ebx\n\t"
41 : "=d"(d)
42 : "a"(1));
43 return (d & 0x04000000) != 0;
44#elif (defined(_MSC_VER) && defined(_M_IX86))
45 /* also check cpuid for MSVC x86 */
46 uint d;
47 __asm {
48 xor eax, eax
49 inc eax
50 push ebx
51 cpuid
52 pop ebx
53 mov d, edx
54 }
55 return (d & 0x04000000) != 0;
56#else
57 return 0;
58#endif
59}
60
61/* Windows stack-walk lives in system_win32.c */
62#if !defined(_MSC_VER)
64{
65 /* ----------------------- */
66 /* If system as execinfo.h */
67# if defined(HAVE_EXECINFO_H)
68
69# define SIZE 100
70 void *buffer[SIZE];
71 int nptrs;
72 char **strings;
73 int i;
74
75 /* Include a back-trace for good measure.
76 *
77 * NOTE: often values printed are addresses (no line numbers of function names),
78 * this information can be expanded using `addr2line`, a utility is included to
79 * conveniently run addr2line on the output generated here:
80 *
81 * `./tools/utils/addr2line_backtrace.py --exe=/path/to/blender trace.txt`
82 */
83 nptrs = backtrace(buffer, SIZE);
84 strings = backtrace_symbols(buffer, nptrs);
85 for (i = 0; i < nptrs; i++) {
86 fputs(strings[i], fp);
87 fputc('\n', fp);
88 }
89
90 free(strings);
91# undef SIZE
92
93# else
94 /* --------------------- */
95 /* Non MSVC/Apple/Linux. */
96 (void)fp;
97# endif
98}
99#endif
100/* end BLI_system_backtrace */
101
102/* NOTE: The code for CPU brand string is adopted from Cycles. */
103
104#if !defined(_WIN32) || defined(FREE_WINDOWS)
105static void __cpuid(
106 /* Cannot be const, because it is modified below.
107 * NOLINTNEXTLINE: readability-non-const-parameter. */
108 int data[4],
109 int selector)
110{
111# if defined(__x86_64__)
112 asm("cpuid" : "=a"(data[0]), "=b"(data[1]), "=c"(data[2]), "=d"(data[3]) : "a"(selector));
113# elif defined(__i386__)
114 asm("pushl %%ebx \n\t"
115 "cpuid \n\t"
116 "movl %%ebx, %1 \n\t"
117 "popl %%ebx \n\t"
118 : "=a"(data[0]), "=r"(data[1]), "=c"(data[2]), "=d"(data[3])
119 : "a"(selector)
120 : "ebx");
121# else
122 (void)selector;
123 data[0] = data[1] = data[2] = data[3] = 0;
124# endif
125}
126#endif
127
129{
130#if !defined(_M_ARM64)
131 char buf[49] = {0};
132 int result[4] = {0};
133 __cpuid(result, 0x80000000);
134 if (result[0] >= (int)0x80000004) {
135 __cpuid((int *)(buf + 0), 0x80000002);
136 __cpuid((int *)(buf + 16), 0x80000003);
137 __cpuid((int *)(buf + 32), 0x80000004);
138 char *brand = BLI_strdup(buf);
139 /* TODO(sergey): Make it a bit more presentable by removing trademark. */
140 return brand;
141 }
142#else
143 /* No CPUID on ARM64, so we pull from the registry (on Windows) instead. */
144 DWORD processorNameStringLength = 255;
145 char processorNameString[255];
146 if (RegGetValueA(HKEY_LOCAL_MACHINE,
147 "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
148 "ProcessorNameString",
149 RRF_RT_REG_SZ,
150 NULL,
151 &processorNameString,
152 &processorNameStringLength) == ERROR_SUCCESS)
153 {
154 return BLI_strdup(processorNameString);
155 }
156#endif
157 return NULL;
158}
159
161{
162#if !defined(_M_ARM64)
163 int result[4], num;
164 __cpuid(result, 0);
165 num = result[0];
166
167 if (num >= 1) {
168 __cpuid(result, 0x00000001);
169 return (result[2] & ((int)1 << 20)) != 0;
170 }
171#endif
172 return 0;
173}
174
175void BLI_hostname_get(char *buffer, size_t bufsize)
176{
177#ifndef WIN32
178 if (gethostname(buffer, bufsize - 1) < 0) {
179 BLI_strncpy(buffer, "-unknown-", bufsize);
180 }
181 /* When `gethostname()` truncates, it doesn't guarantee the trailing `\0`. */
182 buffer[bufsize - 1] = '\0';
183#else
184 DWORD bufsize_inout = bufsize;
185 if (!GetComputerName(buffer, &bufsize_inout)) {
186 BLI_strncpy(buffer, "-unknown-", bufsize);
187 }
188#endif
189}
190
192{
193 /* Maximum addressable bytes on this platform.
194 *
195 * NOTE: Due to the shift arithmetic this is a half of the memory. */
196 const size_t limit_bytes_half = (((size_t)1) << (sizeof(size_t[8]) - 1));
197 /* Convert it to megabytes and return. */
198 return (limit_bytes_half >> 20) * 2;
199}
200
202{
203 const size_t limit_megabytes = BLI_system_memory_max_in_megabytes();
204 /* NOTE: The result will fit into integer. */
205 return (int)min_zz(limit_megabytes, (size_t)INT_MAX);
206}
#define SIZE
void BLI_kdtree_nd_ free(KDTree *tree)
MINLINE size_t min_zz(size_t a, size_t b)
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
Definition string.c:40
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
unsigned int uint
Compatibility-like things for windows.
#define NULL
int BLI_cpu_support_sse42(void)
Definition system.c:160
void BLI_hostname_get(char *buffer, size_t bufsize)
Definition system.c:175
char * BLI_cpu_brand_string(void)
Definition system.c:128
int BLI_cpu_support_sse2(void)
Definition system.c:29
void BLI_system_backtrace(FILE *fp)
Definition system.c:63
static void __cpuid(int data[4], int selector)
Definition system.c:105
size_t BLI_system_memory_max_in_megabytes(void)
Definition system.c:191
int BLI_system_memory_max_in_megabytes_int(void)
Definition system.c:201