mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 06:05:58 -06:00
This might bring some incompatibilities in the code that expects wchar to be 16 bit, which escpecially involves dealing with Win32 (and to lesser extend MacOS) APIs, so if your application is doing that, please check all instances of WCHAR (UniChar on MacOS) or even wchar especially type casts. To support host APIs, char16 is introduced (but there is no 16-bit String varian). Use ToSystemCharsetW, FromSystemCharsetW to convert texts to Win32 API. - Support of drawing non-BMP characters in GUI - Vastly improved character font replacement code (when drawing characters missing with requested font, replacement font is used) - Last instances of Win32 ANSI calls (those ending with A) are removed - UTF handling routines are refactored and their's naming is unified - RTF is now being able to handle non-BMP characters (RTF is used as clipboard format for RichText) Other minor changes: - fixed TryRealloc issue - improved MemoryCheck - Removed MemoryAlloc48/MemoryFree48 - In theide Background parsing should less often cause delays in the main thread
209 lines
4.4 KiB
C++
209 lines
4.4 KiB
C++
#include "Core.h"
|
|
|
|
#if !(defined(CPU_X86) && defined(COMPILER_MSC))
|
|
#include <cpuid.h>
|
|
#endif
|
|
|
|
#ifdef PLATFORM_FREEBSD
|
|
#include <sys/vmmeter.h>
|
|
#endif
|
|
#ifdef PLATFORM_MACOS
|
|
#include <mach/mach.h>
|
|
#include <mach/vm_statistics.h>
|
|
#endif
|
|
|
|
namespace Upp {
|
|
|
|
#ifdef CPU_X86
|
|
|
|
static bool sHasMMX;
|
|
static bool sHasSSE;
|
|
static bool sHasSSE2;
|
|
static bool sHasSSE3;
|
|
static bool sHasAVX;
|
|
static bool sHypervisor;
|
|
|
|
static void sCheckCPU()
|
|
{
|
|
static bool done;
|
|
if(done) return;
|
|
done = true;
|
|
ONCELOCK {
|
|
unsigned int eax, ebx, ecx, edx;
|
|
#ifdef COMPILER_MSC
|
|
int cpuInfo[4];
|
|
__cpuid(cpuInfo, 1);
|
|
eax = cpuInfo[0];
|
|
ebx = cpuInfo[1];
|
|
ecx = cpuInfo[2];
|
|
edx = cpuInfo[3];
|
|
#else
|
|
if(__get_cpuid(1, &eax, &ebx, &ecx, &edx))
|
|
#endif
|
|
// https://en.wikipedia.org/wiki/CPUID#EAX.3D1:_Processor_Info_and_Feature_Bits
|
|
{
|
|
sHasMMX = edx & (1 << 23);
|
|
sHasSSE = edx & (1 << 25);
|
|
sHasSSE2 = edx & (1 << 26);
|
|
sHasSSE3 = ecx & 1;
|
|
sHasAVX = ecx & (1 << 28);
|
|
sHypervisor = ecx & (1 << 31);
|
|
}
|
|
}
|
|
}
|
|
|
|
INITBLOCK {
|
|
// sCheckCPU();
|
|
}
|
|
|
|
bool CpuMMX() { sCheckCPU(); return sHasMMX; }
|
|
bool CpuSSE() { sCheckCPU(); return sHasSSE; }
|
|
bool CpuSSE2() { sCheckCPU(); return sHasSSE2; }
|
|
bool CpuSSE3() { sCheckCPU(); return sHasSSE3; }
|
|
bool CpuAVX() { sCheckCPU(); return sHasAVX; }
|
|
bool CpuHypervisor() { sCheckCPU(); return sHypervisor; }
|
|
|
|
#ifdef PLATFORM_POSIX
|
|
#ifdef PLATFORM_BSD
|
|
#include <sys/param.h>
|
|
#include <sys/sysctl.h>
|
|
#else
|
|
#include <sys/sysinfo.h>
|
|
#endif
|
|
#endif
|
|
|
|
int CPU_Cores()
|
|
{
|
|
static int n;
|
|
ONCELOCK {
|
|
#ifdef PLATFORM_WIN32
|
|
#ifdef CPU_64
|
|
uint64 pa, sa;
|
|
GetProcessAffinityMask(GetCurrentProcess(), &pa, &sa);
|
|
for(int i = 0; i < 64; i++)
|
|
n += !!(sa & ((uint64)1 << i));
|
|
#else
|
|
DWORD pa, sa;
|
|
GetProcessAffinityMask(GetCurrentProcess(), &pa, &sa);
|
|
for(int i = 0; i < 32; i++)
|
|
n += !!(sa & (1 << i));
|
|
#endif
|
|
#elif defined(PLATFORM_POSIX)
|
|
#ifdef PLATFORM_BSD
|
|
int mib[2];
|
|
size_t len = sizeof(n);
|
|
mib[0] = CTL_HW;
|
|
mib[1] = HW_NCPU;
|
|
sysctl(mib, 2, &n, &len, NULL, 0);
|
|
n = minmax(n, 1, 256);
|
|
#elif defined(PLATFORM_SOLARIS)
|
|
n = minmax((int)sysconf(_SC_NPROCESSORS_ONLN), 1, 256);
|
|
#else
|
|
n = minmax(get_nprocs(), 1, 256);
|
|
#endif
|
|
#else
|
|
n = 1;
|
|
#endif
|
|
}
|
|
return n;
|
|
}
|
|
#else
|
|
|
|
#ifdef PLATFORM_LINUX
|
|
#ifdef PLATFORM_ANDROID
|
|
#include <cpu-features.h>
|
|
|
|
int CPU_Cores()
|
|
{
|
|
return android_getCpuCount();
|
|
}
|
|
|
|
#else
|
|
#include <sys/sysinfo.h>
|
|
|
|
int CPU_Cores()
|
|
{
|
|
return minmax(get_nprocs(), 1, 256);
|
|
}
|
|
#endif
|
|
#else
|
|
int CPU_Cores()
|
|
{
|
|
return 1;
|
|
}
|
|
#endif
|
|
|
|
#endif
|
|
|
|
void GetSystemMemoryStatus(uint64& total, uint64& available)
|
|
{
|
|
#ifdef PLATFORM_WIN32
|
|
MEMORYSTATUSEX m;
|
|
m.dwLength = sizeof(m);
|
|
if(GlobalMemoryStatusEx(&m)) {
|
|
total = m.ullTotalPhys;
|
|
available = m.ullAvailPhys;
|
|
return;
|
|
}
|
|
#endif
|
|
#ifdef PLATFORM_LINUX
|
|
int pgsz = getpagesize();
|
|
total = sysconf(_SC_PHYS_PAGES);
|
|
available = sysconf(_SC_AVPHYS_PAGES);
|
|
if(total >= 0 && available >= 0) {
|
|
total *= pgsz;
|
|
available *= pgsz;
|
|
return;
|
|
}
|
|
#endif
|
|
#ifdef PLATFORM_MACOS
|
|
mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
|
|
vm_statistics_data_t vmstat;
|
|
|
|
int mib[2];
|
|
int64 physical_memory;
|
|
size_t length;
|
|
|
|
// Get the Physical memory size
|
|
mib[0] = CTL_HW;
|
|
mib[1] = HW_MEMSIZE;
|
|
length = sizeof(int64);
|
|
|
|
if(host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmstat, &count) == KERN_SUCCESS &&
|
|
sysctl(mib, 2, &physical_memory, &length, NULL, 0) >= 0) {
|
|
int pgsz = getpagesize();
|
|
available = (vmstat.free_count + vmstat.inactive_count) * pgsz;
|
|
// available = physical_memory - (vmstat.wire_count + vmstat.inactive_count) * pgsz;
|
|
total = physical_memory;
|
|
return;
|
|
}
|
|
#endif
|
|
#ifdef PLATFORM_FREEBSD
|
|
u_int page_size;
|
|
struct vmtotal vmt;
|
|
size_t vmt_size, uint_size;
|
|
|
|
vmt_size = sizeof(vmt);
|
|
uint_size = sizeof(page_size);
|
|
|
|
if(sysctlbyname("vm.vmtotal", &vmt, &vmt_size, NULL, 0) >= 0 &&
|
|
sysctlbyname("vm.stats.vm.v_page_size", &page_size, &uint_size, NULL, 0) >= 0) {
|
|
available = vmt.t_free * (u_int64_t)page_size;
|
|
total = vmt.t_avm * (u_int64_t)page_size;
|
|
return;
|
|
}
|
|
#endif
|
|
total = 256*1024*1024;
|
|
available = 16*1024*1024;
|
|
}
|
|
|
|
#define ENDIAN_SWAP { while(count--) { EndianSwap(*v++); } }
|
|
|
|
void EndianSwap(word *v, size_t count) ENDIAN_SWAP
|
|
void EndianSwap(int16 *v, size_t count) ENDIAN_SWAP
|
|
void EndianSwap(dword *v, size_t count) ENDIAN_SWAP
|
|
void EndianSwap(int *v, size_t count) ENDIAN_SWAP
|
|
void EndianSwap(int64 *v, size_t count) ENDIAN_SWAP
|
|
void EndianSwap(uint64 *v, size_t count) ENDIAN_SWAP
|
|
|
|
}
|