Cycles: svn merge -r41225:41232 ^/trunk/blender
[blender.git] / intern / cycles / util / util_system.cpp
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18
19 #include "util_system.h"
20 #include "util_types.h"
21
22 #ifdef _WIN32
23 #if(!defined(FREE_WINDOWS))
24 #include <intrin.h>
25 #endif
26 #include <windows.h>
27 #elif defined(__APPLE__)
28 #include <sys/sysctl.h>
29 #include <sys/types.h>
30 #else
31 #include <unistd.h>
32 #endif
33
34 CCL_NAMESPACE_BEGIN
35
36 int system_cpu_thread_count()
37 {
38         static uint count = 0;
39
40         if(count > 0)
41                 return count;
42
43 #ifdef _WIN32
44         SYSTEM_INFO info;
45         GetSystemInfo(&info);
46         count = (uint)info.dwNumberOfProcessors;
47 #elif defined(__APPLE__)
48         size_t len = sizeof(count);
49         int mib[2] = { CTL_HW, HW_NCPU };
50         
51         sysctl(mib, 2, &count, &len, NULL, 0);
52 #else
53         count = (uint)sysconf(_SC_NPROCESSORS_ONLN);
54 #endif
55
56         if(count < 1)
57                 count = 1;
58
59         return count;
60 }
61
62 #if !defined(_WIN32) || defined(FREE_WINDOWS)
63 static void __cpuid(int data[4], int selector)
64 {
65 #ifdef __x86_64__
66         asm("cpuid" : "=a" (data[0]), "=b" (data[1]), "=c" (data[2]), "=d" (data[3]) : "a"(selector));
67 #else
68 #ifdef __i386__
69         asm("pushl %%ebx    \n\t"
70                 "cpuid          \n\t"
71                 "movl %%ebx, %1 \n\t"
72                 "popl %%ebx     \n\t" : "=a" (data[0]), "=r" (data[1]), "=c" (data[2]), "=d" (data[3]) : "a"(selector));
73 #else
74         data[0] = data[1] = data[2] = data[3] = 0;
75 #endif
76 #endif
77 }
78 #endif
79
80 static void replace_string(string& haystack, const string& needle, const string& other)
81 {
82         size_t i;
83
84         while((i = haystack.find(needle)) != string::npos)
85                 haystack.replace(i, needle.length(), other);
86 }
87
88 string system_cpu_brand_string()
89 {
90         char buf[48];
91         int result[4];
92
93         __cpuid(result, 0x80000000);
94
95         if(result[0] >= (int)0x80000004) {
96                 __cpuid((int*)(buf+0), 0x80000002);
97                 __cpuid((int*)(buf+16), 0x80000003);
98                 __cpuid((int*)(buf+32), 0x80000004);
99
100                 string brand = buf;
101
102                 /* make it a bit more presentable */
103                 replace_string(brand, "(TM)", "");
104                 replace_string(brand, "(R)", "");
105
106                 size_t i;
107                 if((i = brand.find("  ")) != string::npos)
108                         brand = brand.substr(0, i);
109
110                 return brand;
111         }
112
113         return "Unknown CPU";
114 }
115
116 int system_cpu_bits()
117 {
118         return (sizeof(void*)*8);
119 }
120
121 CCL_NAMESPACE_END
122