forked from 0ad/0ad
janwas
0bb0df5b2c
- remove headers always included from PCH - nommgr.h is only included ifdef REDEFINED_NEW (allows leaving out the mmgr stuff) - in lib/*.cpp, moved the corresponding include file to right behind the PCH (catches headers that aren't compilable by themselves) - byte_order no longer depends on SDL - add debug_level (another means of filtering debug output; needed for thesis) - split posix stuff up into subdirs (lib/posix and sysdep/win/wposix). makes including only some of the modules (e.g. sockets, time) much easier. This was SVN commit r4728.
126 lines
3.4 KiB
C++
126 lines
3.4 KiB
C++
/**
|
|
* =========================================================================
|
|
* File : cpu.cpp
|
|
* Project : 0 A.D.
|
|
* Description : CPU and memory detection.
|
|
*
|
|
* @author Jan.Wassenberg@stud.uni-karlsruhe.de
|
|
* =========================================================================
|
|
*/
|
|
|
|
/*
|
|
* Copyright (c) 2003-2005 Jan Wassenberg
|
|
*
|
|
* Redistribution and/or modification are also permitted under the
|
|
* terms of the GNU General Public License as published by the
|
|
* Free Software Foundation (version 2 or later, at your option).
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
*/
|
|
|
|
#include "precompiled.h"
|
|
#include "cpu.h"
|
|
|
|
#include "lib/lib.h"
|
|
#if CPU_IA32
|
|
# include "lib/sysdep/ia32.h"
|
|
#endif
|
|
|
|
|
|
AT_STARTUP(\
|
|
error_setDescription(ERR::CPU_FEATURE_MISSING, "This CPU doesn't support a required feature");\
|
|
error_setDescription(ERR::CPU_UNKNOWN_OPCODE, "Disassembly failed");\
|
|
error_setDescription(ERR::CPU_RESTRICTED_AFFINITY, "Cannot set desired CPU affinity");\
|
|
)
|
|
|
|
|
|
char cpu_type[CPU_TYPE_LEN] = "";
|
|
double cpu_freq = 0.f;
|
|
|
|
// -1 if detect not yet called, or cannot be determined
|
|
int cpus = -1;
|
|
int cpu_ht_units = -1;
|
|
int cpu_cores = -1;
|
|
int cpu_speedstep = -1;
|
|
|
|
|
|
void cpu_init()
|
|
{
|
|
#if CPU_IA32
|
|
// must come before any uses of ia32.asm, e.g. by get_cpu_info
|
|
ia32_init();
|
|
|
|
// no longer set 24 bit (float) precision by default: for
|
|
// very long game uptimes (> 1 day; e.g. dedicated server),
|
|
// we need full precision when calculating the time.
|
|
// if there's a spot where we want to speed up divides|sqrts,
|
|
// we can temporarily change precision there.
|
|
//ia32_control87(IA32_PC_24, IA32_MCW_PC);
|
|
|
|
// to help catch bugs, enable as many floating-point exceptions as
|
|
// possible. that means only zero-divide, because the JS engine is
|
|
// triggering the rest.
|
|
// note: passing a flag *disables* that exception.
|
|
ia32_control87(IA32_EM_ZERODIVIDE|IA32_EM_INVALID|IA32_EM_DENORMAL|IA32_EM_OVERFLOW|IA32_EM_UNDERFLOW|IA32_EM_INEXACT, IA32_MCW_EM);
|
|
|
|
// no longer round toward zero (truncate). changing this setting
|
|
// resulted in much faster float->int casts, because the compiler
|
|
// could be told (via /QIfist) to use FISTP while still truncating
|
|
// the result as required by ANSI C. however, FPU calculation
|
|
// results were changed significantly, so it had to be disabled.
|
|
//ia32_control87(IA32_RC_CHOP, IA32_MCW_RC);
|
|
#endif
|
|
|
|
// detects CPU clock frequency and capabilities, which are prerequisites
|
|
// for using the TSC as a timer (desirable due to its high resolution).
|
|
// do this before lengthy init so we can time those accurately.
|
|
#if OS_WIN
|
|
extern LibError win_get_cpu_info();
|
|
win_get_cpu_info();
|
|
#elif OS_UNIX
|
|
extern LibError unix_get_cpu_info();
|
|
unix_get_cpu_info();
|
|
#endif
|
|
|
|
#if CPU_IA32
|
|
ia32_get_cpu_info();
|
|
#endif
|
|
}
|
|
|
|
|
|
//
|
|
// memory
|
|
//
|
|
|
|
size_t tot_mem = 0;
|
|
size_t avl_mem = 0;
|
|
|
|
size_t page_size = 0;
|
|
|
|
void get_mem_status()
|
|
{
|
|
#ifdef _SC_PAGESIZE
|
|
if(!page_size)
|
|
page_size = (size_t)sysconf(_SC_PAGESIZE);
|
|
#endif
|
|
|
|
// Sys V derived (GNU/Linux, Solaris)
|
|
#if defined(_SC_AVPHYS_PAGES)
|
|
|
|
tot_mem = sysconf(_SC_PHYS_PAGES ) * page_size;
|
|
avl_mem = sysconf(_SC_AVPHYS_PAGES) * page_size;
|
|
|
|
// BSD / Mac OS X
|
|
#elif defined(HW_PHYSMEM)
|
|
|
|
size_t len = sizeof(tot_mem);
|
|
int mib[2] = { CTL_HW, HW_PHYSMEM };
|
|
sysctl(mib, 2, &tot_mem, &len, 0, 0);
|
|
mib[1] = HW_USERMEM;
|
|
sysctl(mib, 2, &avl_mem, &len, 0, 0);
|
|
|
|
#endif
|
|
}
|