1 // Windows/System.cpp
2
3 #include "StdAfx.h"
4
5 #ifndef _WIN32
6 #include <unistd.h>
7 #ifdef __APPLE__
8 #include <sys/sysctl.h>
9 #else
10 #include <sys/sysinfo.h>
11 #endif
12 #endif
13
14 #include "../Common/Defs.h"
15 // #include "../Common/MyWindows.h"
16
17 // #include "../../C/CpuArch.h"
18
19 #include "System.h"
20
21 namespace NWindows {
22 namespace NSystem {
23
24 #ifdef _WIN32
25
CountAffinity(DWORD_PTR mask)26 UInt32 CountAffinity(DWORD_PTR mask)
27 {
28 UInt32 num = 0;
29 for (unsigned i = 0; i < sizeof(mask) * 8; i++)
30 num += (UInt32)((mask >> i) & 1);
31 return num;
32 }
33
Get()34 BOOL CProcessAffinity::Get()
35 {
36 #ifndef UNDER_CE
37 return GetProcessAffinityMask(GetCurrentProcess(), &processAffinityMask, &systemAffinityMask);
38 #else
39 return FALSE;
40 #endif
41 }
42
43
GetNumberOfProcessors()44 UInt32 GetNumberOfProcessors()
45 {
46 // We need to know how many threads we can use.
47 // By default the process is assigned to one group.
48 // So we get the number of logical processors (threads)
49 // assigned to current process in the current group.
50 // Group size can be smaller than total number logical processors, for exammple, 2x36
51
52 CProcessAffinity pa;
53
54 if (pa.Get() && pa.processAffinityMask != 0)
55 return pa.GetNumProcessThreads();
56
57 SYSTEM_INFO systemInfo;
58 GetSystemInfo(&systemInfo);
59 // the number of logical processors in the current group
60 return (UInt32)systemInfo.dwNumberOfProcessors;
61 }
62
63 #else
64
65
66 BOOL CProcessAffinity::Get()
67 {
68 numSysThreads = GetNumberOfProcessors();
69
70 /*
71 numSysThreads = 8;
72 for (unsigned i = 0; i < numSysThreads; i++)
73 CpuSet_Set(&cpu_set, i);
74 return TRUE;
75 */
76
77 #ifdef _7ZIP_AFFINITY_SUPPORTED
78
79 // numSysThreads = sysconf(_SC_NPROCESSORS_ONLN); // The number of processors currently online
80 if (sched_getaffinity(0, sizeof(cpu_set), &cpu_set) != 0)
81 return FALSE;
82 return TRUE;
83
84 #else
85
86 // cpu_set = ((CCpuSet)1 << (numSysThreads)) - 1;
87 return TRUE;
88 // errno = ENOSYS;
89 // return FALSE;
90
91 #endif
92 }
93
94 UInt32 GetNumberOfProcessors()
95 {
96 #ifndef _7ZIP_ST
97 long n = sysconf(_SC_NPROCESSORS_CONF); // The number of processors configured
98 if (n < 1)
99 n = 1;
100 return (UInt32)n;
101 #else
102 return 1;
103 #endif
104 }
105
106 #endif
107
108
109 #ifdef _WIN32
110
111 #ifndef UNDER_CE
112
113 #if !defined(_WIN64) && defined(__GNUC__)
114
115 typedef struct _MY_MEMORYSTATUSEX {
116 DWORD dwLength;
117 DWORD dwMemoryLoad;
118 DWORDLONG ullTotalPhys;
119 DWORDLONG ullAvailPhys;
120 DWORDLONG ullTotalPageFile;
121 DWORDLONG ullAvailPageFile;
122 DWORDLONG ullTotalVirtual;
123 DWORDLONG ullAvailVirtual;
124 DWORDLONG ullAvailExtendedVirtual;
125 } MY_MEMORYSTATUSEX, *MY_LPMEMORYSTATUSEX;
126
127 #else
128
129 #define MY_MEMORYSTATUSEX MEMORYSTATUSEX
130 #define MY_LPMEMORYSTATUSEX LPMEMORYSTATUSEX
131
132 #endif
133
134 typedef BOOL (WINAPI *GlobalMemoryStatusExP)(MY_LPMEMORYSTATUSEX lpBuffer);
135
136 #endif // !UNDER_CE
137
138
GetRamSize(UInt64 & size)139 bool GetRamSize(UInt64 &size)
140 {
141 size = (UInt64)(sizeof(size_t)) << 29;
142
143 #ifndef UNDER_CE
144 MY_MEMORYSTATUSEX stat;
145 stat.dwLength = sizeof(stat);
146 #endif
147
148 #ifdef _WIN64
149
150 if (!::GlobalMemoryStatusEx(&stat))
151 return false;
152 size = MyMin(stat.ullTotalVirtual, stat.ullTotalPhys);
153 return true;
154
155 #else
156
157 #ifndef UNDER_CE
158 GlobalMemoryStatusExP globalMemoryStatusEx = (GlobalMemoryStatusExP)
159 (void *)::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "GlobalMemoryStatusEx");
160 if (globalMemoryStatusEx && globalMemoryStatusEx(&stat))
161 {
162 size = MyMin(stat.ullTotalVirtual, stat.ullTotalPhys);
163 return true;
164 }
165 #endif
166
167 {
168 MEMORYSTATUS stat2;
169 stat2.dwLength = sizeof(stat2);
170 ::GlobalMemoryStatus(&stat2);
171 size = MyMin(stat2.dwTotalVirtual, stat2.dwTotalPhys);
172 return true;
173 }
174 #endif
175 }
176
177 #else
178
179 // POSIX
180 // #include <stdio.h>
181
GetRamSize(UInt64 & size)182 bool GetRamSize(UInt64 &size)
183 {
184 size = (UInt64)(sizeof(size_t)) << 29;
185
186 #ifdef __APPLE__
187
188 #ifdef HW_MEMSIZE
189 uint64_t val = 0; // support 2Gb+ RAM
190 int mib[2] = { CTL_HW, HW_MEMSIZE };
191 #elif defined(HW_PHYSMEM64)
192 uint64_t val = 0; // support 2Gb+ RAM
193 int mib[2] = { CTL_HW, HW_PHYSMEM64 };
194 #else
195 unsigned int val = 0; // For old system
196 int mib[2] = { CTL_HW, HW_PHYSMEM };
197 #endif // HW_MEMSIZE
198 size_t size_sys = sizeof(val);
199
200 sysctl(mib, 2, &val, &size_sys, NULL, 0);
201 if (val)
202 size = val;
203
204 #elif defined(_AIX)
205 // fixme
206 #elif defined(__gnu_hurd__)
207 // fixme
208 #elif defined(__FreeBSD_kernel__) && defined(__GLIBC__)
209 // GNU/kFreeBSD Debian
210 // fixme
211 #else
212
213 struct sysinfo info;
214 if (::sysinfo(&info) != 0)
215 return false;
216 size = (UInt64)info.mem_unit * info.totalram;
217 const UInt64 kLimit = (UInt64)1 << (sizeof(size_t) * 8 - 1);
218 if (size > kLimit)
219 size = kLimit;
220
221 /*
222 printf("\n mem_unit = %lld", (UInt64)info.mem_unit);
223 printf("\n totalram = %lld", (UInt64)info.totalram);
224 printf("\n freeram = %lld", (UInt64)info.freeram);
225 */
226
227 #endif
228
229 return true;
230 }
231
232 #endif
233
234 }}
235