mirror of
https://gitea.wildfiregames.com/0ad/0ad.git
synced 2026-06-21 01:29:50 +00:00
# SwEng / MacOSX compat
further cleanup to sysdep.h: avoid pulling in win and ia32; split header up into stl, compiler, and the actual sys_* API. (all but the latter are in PCH). timer: also avoid dragging in ia32 win: move snprintf fix to posix.h cpu: simplify reasoning about cores, now given as logicalPerCore (not package) vfs_optimizer: fix if archive building is partially disabled This was SVN commit r5008.
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "maths/MathUtil.h"
|
||||
#include "graphics/SColor.h"
|
||||
#include "lib/sysdep/ia32/ia32.h"
|
||||
|
||||
static u32 fallback_ConvertRGBColorTo4ub(const RGBColor& src)
|
||||
{
|
||||
|
||||
@@ -39,6 +39,7 @@ gee@pyro.nu
|
||||
#include "ps/Hotkey.h"
|
||||
#include "ps/Globals.h"
|
||||
#include "lib/timer.h"
|
||||
#include "lib/sysdep/sysdep.h"
|
||||
|
||||
// namespaces used
|
||||
using namespace std;
|
||||
|
||||
@@ -12,6 +12,7 @@ gee@pyro.nu
|
||||
#include "lib/ogl.h"
|
||||
|
||||
#include "lib/res/graphics/unifont.h"
|
||||
#include "lib/sysdep/sysdep.h"
|
||||
|
||||
#include "ps/Hotkey.h"
|
||||
#include "ps/CLogger.h"
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "app_hooks.h"
|
||||
|
||||
#include "lib/path_util.h"
|
||||
#include "lib/sysdep/sysdep.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -305,12 +305,6 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// snprintf, swprintf, etc.
|
||||
#define HAVE_NPRINTF 0
|
||||
#if HAVE_C99
|
||||
# undef HAVE_NPRINTF
|
||||
# define HAVE_NPRINTF 1
|
||||
#endif
|
||||
|
||||
// strdup, wcsdup
|
||||
#define HAVE_STRDUP 1
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "path_util.h"
|
||||
#include "debug_stl.h"
|
||||
#include "lib/sysdep/cpu.h" // CAS
|
||||
#include "lib/sysdep/sysdep.h"
|
||||
#include "lib/res/file/file.h" // FILE_ACCESS
|
||||
// some functions here are called from within mmgr; disable its hooks
|
||||
// so that our allocations don't cause infinite recursion.
|
||||
@@ -178,6 +179,7 @@ bool debug_filter_allows(const char* text)
|
||||
}
|
||||
|
||||
|
||||
#undef debug_printf // allowing #defining it out
|
||||
void debug_printf(const char* fmt, ...)
|
||||
{
|
||||
char buf[MAX_CHARS]; buf[ARRAY_SIZE(buf)-1] = '\0';
|
||||
@@ -191,6 +193,7 @@ void debug_printf(const char* fmt, ...)
|
||||
debug_puts(buf);
|
||||
}
|
||||
|
||||
#undef debug_wprintf // allowing #defining it out
|
||||
void debug_wprintf(const wchar_t* fmt, ...)
|
||||
{
|
||||
wchar_t wcs_buf[MAX_CHARS]; wcs_buf[ARRAY_SIZE(wcs_buf)-1] = '\0';
|
||||
@@ -698,7 +701,7 @@ ErrorReaction debug_display_error(const wchar_t* description,
|
||||
|
||||
ErrorMessageMem emm;
|
||||
emm.alloca_buf_size = 50000;
|
||||
emm.alloca_buf = alloca(emm.alloca_buf_size);
|
||||
emm.alloca_buf = sys_alloca(emm.alloca_buf_size);
|
||||
const wchar_t* text = debug_error_message_build(description,
|
||||
fn_only, line, func, skip, context, &emm);
|
||||
|
||||
|
||||
+3
-3
@@ -8,7 +8,7 @@
|
||||
* =========================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
/*b
|
||||
* Copyright (c) 2003-2005 Jan Wassenberg
|
||||
*
|
||||
* Redistribution and/or modification are also permitted under the
|
||||
@@ -261,7 +261,7 @@ checking, but does not cause any compiler warnings.
|
||||
// 1) final build: optimize assuming this location cannot be reached.
|
||||
// may crash if that turns out to be untrue, but removes checking overhead.
|
||||
#if CONFIG_FINAL
|
||||
# define UNREACHABLE SYS_UNREACHABLE
|
||||
# define UNREACHABLE ASSUME_UNREACHABLE
|
||||
// 2) normal build:
|
||||
#else
|
||||
// a) normal implementation: includes "abort", which is declared with
|
||||
@@ -275,7 +275,7 @@ checking, but does not cause any compiler warnings.
|
||||
)
|
||||
// b) VC only: don't generate any code; squelch the warning and optimize.
|
||||
# else
|
||||
# define UNREACHABLE SYS_UNREACHABLE
|
||||
# define UNREACHABLE ASSUME_UNREACHABLE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "lib/posix/posix_pthread.h"
|
||||
#include "lib.h"
|
||||
#include "lib/sysdep/cpu.h"
|
||||
#include "lib/sysdep/sysdep.h"
|
||||
#include "timer.h"
|
||||
|
||||
/*
|
||||
@@ -283,7 +284,7 @@ static void smr_release_unreferenced_nodes(TLS* tls)
|
||||
retry:
|
||||
const size_t max_hps = (active_threads+3) * NUM_HPS;
|
||||
// allow for creating a few additional threads during the loop
|
||||
void** hps = (void**)alloca(max_hps * sizeof(void*));
|
||||
void** hps = (void**)sys_alloca(max_hps * sizeof(void*));
|
||||
size_t num_hps = 0;
|
||||
// for each participating thread:
|
||||
for(TLS* t = tls_list; t; t = t->next)
|
||||
@@ -560,7 +561,7 @@ retry:
|
||||
// or 0 if not found in the list.
|
||||
void* lfl_find(LFList* list, uintptr_t key)
|
||||
{
|
||||
ListPos* pos = (ListPos*)alloca(sizeof(ListPos));
|
||||
ListPos* pos = (ListPos*)sys_alloca(sizeof(ListPos));
|
||||
if(!list_lookup(list, key, pos))
|
||||
return 0;
|
||||
return node_user_data(pos->cur);
|
||||
@@ -578,7 +579,7 @@ void* lfl_insert(LFList* list, uintptr_t key, size_t additional_bytes, int* was_
|
||||
// if this triggers, tls_alloc called from lfl_init failed due to
|
||||
// lack of memory and the caller didn't check its return value.
|
||||
|
||||
ListPos* pos = (ListPos*)alloca(sizeof(ListPos));
|
||||
ListPos* pos = (ListPos*)sys_alloca(sizeof(ListPos));
|
||||
|
||||
Node* node = 0;
|
||||
if(was_inserted)
|
||||
@@ -631,7 +632,7 @@ LibError lfl_erase(LFList* list, uintptr_t key)
|
||||
// if this triggers, tls_alloc called from lfl_init failed due to
|
||||
// lack of memory and the caller didn't check its return value.
|
||||
|
||||
ListPos* pos = (ListPos*)alloca(sizeof(ListPos));
|
||||
ListPos* pos = (ListPos*)sys_alloca(sizeof(ListPos));
|
||||
|
||||
retry:
|
||||
// not found in list - abort.
|
||||
|
||||
@@ -1,3 +1,64 @@
|
||||
#include "precompiled.h"
|
||||
#include "posix.h"
|
||||
|
||||
#if CPU_IA32
|
||||
# include "lib/sysdep/ia32/ia32.h"
|
||||
#endif
|
||||
|
||||
|
||||
#if !HAVE_C99_MATH
|
||||
|
||||
float rintf(float f)
|
||||
{
|
||||
#if CPU_IA32
|
||||
return ia32_asm_rintf(f);
|
||||
#else
|
||||
return (float)(int)f;
|
||||
#endif
|
||||
}
|
||||
|
||||
double rint(double d)
|
||||
{
|
||||
#if CPU_IA32
|
||||
return ia32_asm_rint(d);
|
||||
#else
|
||||
return (double)(int)d;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
float fminf(float a, float b)
|
||||
{
|
||||
#if CPU_IA32
|
||||
return ia32_asm_fminf(a, b);
|
||||
#else
|
||||
return (a < b)? a : b;
|
||||
#endif
|
||||
}
|
||||
|
||||
float fmaxf(float a, float b)
|
||||
{
|
||||
#if CPU_IA32
|
||||
return ia32_asm_fmaxf(a, b);
|
||||
#else
|
||||
return (a > b)? a : b;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
uint fpclassifyd(double d)
|
||||
{
|
||||
// really sucky stub implementation; doesn't attempt to cover all cases.
|
||||
|
||||
if(d != d)
|
||||
return FP_NAN;
|
||||
else
|
||||
return FP_NORMAL;
|
||||
}
|
||||
|
||||
uint fpclassifyf(float f)
|
||||
{
|
||||
return fpclassify((double)f);
|
||||
}
|
||||
|
||||
#endif // #if !HAVE_C99_MATH
|
||||
|
||||
@@ -56,6 +56,8 @@ need only be renamed (e.g. _open, _stat).
|
||||
#ifndef INCLUDED_POSIX
|
||||
#define INCLUDED_POSIX
|
||||
|
||||
#include <cmath> // see isfinite comment below
|
||||
|
||||
#if OS_WIN
|
||||
# include "lib/sysdep/win/wposix/wposix.h"
|
||||
# include "lib/sysdep/win/win.h"
|
||||
@@ -73,9 +75,60 @@ need only be renamed (e.g. _open, _stat).
|
||||
#include "posix_utsname.h"
|
||||
|
||||
|
||||
#if OS_MACOSX
|
||||
// provide C99 *snprintf functions if compiler doesn't already
|
||||
// (MinGW does, VC7.1 doesn't).
|
||||
#if MSC_VERSION
|
||||
# define snprintf _snprintf
|
||||
# define swprintf _snwprintf
|
||||
# define vsnprintf _vsnprintf
|
||||
# define vswprintf _vsnwprintf
|
||||
#endif
|
||||
|
||||
|
||||
#if !HAVE_STRDUP
|
||||
extern char* strdup(const char* str);
|
||||
extern wchar_t* wcsdup(const wchar_t* str);
|
||||
#endif // #if OS_MACOSX
|
||||
#endif // #if !HAVE_STRDUP
|
||||
|
||||
|
||||
#if !HAVE_C99_MATH
|
||||
// round float to nearest integral value, according to
|
||||
// current rounding mode.
|
||||
extern float rintf(float f);
|
||||
extern double rint(double d);
|
||||
// return minimum/maximum of two floats.
|
||||
extern float fminf(float a, float b);
|
||||
extern float fmaxf(float a, float b);
|
||||
|
||||
extern uint fpclassifyf(float f);
|
||||
extern uint fpclassifyd(double d);
|
||||
#define fpclassify(x) ( (sizeof(x) == sizeof(float))? fpclassifyf(x) : fpclassifyd(x) )
|
||||
|
||||
// these definitions "happen" to match IA32_FP_* and allow using
|
||||
// ia32_fp_classify without having to translate the return value.
|
||||
// we don't #define to IA32_FP_* to avoid dependency.
|
||||
# define FP_NAN 0x0100
|
||||
# define FP_NORMAL 0x0400
|
||||
# define FP_INFINITE (FP_NAN | FP_NORMAL)
|
||||
# define FP_ZERO 0x4000
|
||||
# define FP_SUBNORMAL (FP_NORMAL | FP_ZERO)
|
||||
|
||||
# define isnan(d) (fpclassify(d) == FP_NAN)
|
||||
# define isfinite(d) ((fpclassify(d) & (FP_NORMAL|FP_ZERO)) != 0)
|
||||
# define isinf(d) (fpclassify(d) == FP_NAN|FP_NORMAL)
|
||||
# define isnormal(d) (fpclassify(d) == FP_NORMAL)
|
||||
//# define signbit
|
||||
#else // HAVE_C99_MATH
|
||||
// Some systems have C99 support but in C++ they provide only std::isfinite
|
||||
// and not isfinite. C99 specifies that isfinite is a macro, so we can use
|
||||
// #ifndef and define it if it's not there already.
|
||||
// We've included <cmath> above to make sure it defines that macro.
|
||||
# ifndef isfinite
|
||||
# define isfinite std::isfinite
|
||||
# define isnan std::isnan
|
||||
# define isinf std::isinf
|
||||
# define isnormal std::isnormal
|
||||
# endif
|
||||
#endif // HAVE_C99_MATH
|
||||
|
||||
#endif // #ifndef INCLUDED_POSIX
|
||||
|
||||
@@ -58,8 +58,10 @@
|
||||
#include "lib/types.h"
|
||||
#include "lib/lib_errors.h"
|
||||
#include "lib/string_s.h" // CRT secure string
|
||||
#include "lib/sysdep/sysdep.h"
|
||||
#include "lib/debug.h" // (sysdep.h pulls in debug.h)
|
||||
#include "lib/debug.h"
|
||||
#include "lib/sysdep/compiler.h"
|
||||
#include "lib/sysdep/stl.h"
|
||||
#include "lib/posix/posix.h"
|
||||
|
||||
|
||||
//
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "lib/lib.h"
|
||||
#include "lib/adts.h"
|
||||
#include "lib/allocators.h"
|
||||
#include "lib/sysdep/sysdep.h"
|
||||
#include "file_internal.h"
|
||||
|
||||
|
||||
|
||||
@@ -664,6 +664,7 @@ static LibError build_mini_archive(const char* mini_archive_fn_fmt)
|
||||
if(!should_build_mini_archive(mini_archive_fn_fmt))
|
||||
return INFO::SKIPPED;
|
||||
|
||||
#if AB_COUNT_LOOSE_FILES
|
||||
Filenames V_fns = (Filenames)malloc((loose_files.size()+1) * sizeof(const char*));
|
||||
if(!V_fns)
|
||||
WARN_RETURN(ERR::NO_MEM);
|
||||
@@ -678,6 +679,9 @@ static LibError build_mini_archive(const char* mini_archive_fn_fmt)
|
||||
|
||||
RETURN_ERR(archive_build(mini_archive_fn, V_fns));
|
||||
return INFO::OK;
|
||||
#else
|
||||
return ERR::NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
#ifndef INCLUDED_COMPILER
|
||||
#define INCLUDED_COMPILER
|
||||
|
||||
|
||||
// pass "omit frame pointer" setting on to the compiler
|
||||
#if MSC_VERSION
|
||||
# if CONFIG_OMIT_FP
|
||||
# pragma optimize("y", on)
|
||||
# else
|
||||
# pragma optimize("y", off)
|
||||
# endif
|
||||
#elif GCC_VERSION
|
||||
// TODO
|
||||
#endif
|
||||
|
||||
|
||||
// try to define _W64, if not already done
|
||||
// (this is useful for catching pointer size bugs)
|
||||
#ifndef _W64
|
||||
# if MSC_VERSION
|
||||
# define _W64 __w64
|
||||
# elif GCC_VERSION
|
||||
# define _W64 __attribute__((mode (__pointer__)))
|
||||
# else
|
||||
# define _W64
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
// C99-like restrict (non-standard in C++, but widely supported in various forms).
|
||||
//
|
||||
// May be used on pointers. May also be used on member functions to indicate
|
||||
// that 'this' is unaliased (e.g. "void C::m() RESTRICT { ... }").
|
||||
// Must not be used on references - GCC supports that but VC doesn't.
|
||||
//
|
||||
// We call this "RESTRICT" to avoid conflicts with VC's __declspec(restrict),
|
||||
// and because it's not really the same as C99's restrict.
|
||||
//
|
||||
// To be safe and satisfy the compilers' stated requirements: an object accessed
|
||||
// by a restricted pointer must not be accessed by any other pointer within the
|
||||
// lifetime of the restricted pointer, if the object is modified.
|
||||
// To maximise the chance of optimisation, any pointers that could potentially
|
||||
// alias with the restricted one should be marked as restricted too.
|
||||
//
|
||||
// It would probably be a good idea to write test cases for any code that uses
|
||||
// this in an even very slightly unclear way, in case it causes obscure problems
|
||||
// in a rare compiler due to differing semantics.
|
||||
//
|
||||
// .. we made g++ claim to support C99 by defining __STDC_VERSION__ in the
|
||||
// makefiles, but that's wrong and it doesn't have the restrict keyword.
|
||||
// use the extension __restrict__ instead.
|
||||
#if GCC_VERSION
|
||||
# define RESTRICT __restrict__
|
||||
// .. already available in C99 as 'restrict'
|
||||
#elif HAVE_C99
|
||||
# define RESTRICT restrict
|
||||
// .. VC8 provides __restrict
|
||||
#elif MSC_VERSION >= 1400
|
||||
# define RESTRICT __restrict
|
||||
// .. ICC supports the keyword 'restrict' when run with the /Qrestrict option,
|
||||
// but it always also supports __restrict__ or __restrict to be compatible
|
||||
// with GCC/MSVC, so we'll use the underscored version. One of {GCC,MSC}_VERSION
|
||||
// should have been defined in addition to ICC_VERSION, so we should be using
|
||||
// one of the above cases (unless it's an old VS7.1-emulating ICC).
|
||||
#elif ICC_VERSION
|
||||
# error ICC_VERSION defined without either GCC_VERSION or an adequate MSC_VERSION
|
||||
// .. unsupported; remove it from code
|
||||
#else
|
||||
# define RESTRICT
|
||||
#endif
|
||||
|
||||
|
||||
// C99 __func__
|
||||
// .. already available; need do nothing
|
||||
#if HAVE_C99
|
||||
// .. VC supports something similar
|
||||
#elif MSC_VERSION
|
||||
# define __func__ __FUNCTION__
|
||||
// .. unsupported; remove it from code
|
||||
#else
|
||||
# define __func__ "(unknown)"
|
||||
#endif
|
||||
|
||||
|
||||
// tell the compiler that the code at/following this macro invocation is
|
||||
// unreachable. this can improve optimization and avoid warnings.
|
||||
//
|
||||
// this macro should not generate any fallback code; it is merely the
|
||||
// compiler-specific backend for lib.h's UNREACHABLE.
|
||||
// #define it to nothing if the compiler doesn't support such a hint.
|
||||
#if MSC_VERSION
|
||||
# define ASSUME_UNREACHABLE __assume(0)
|
||||
#else
|
||||
# define ASSUME_UNREACHABLE
|
||||
#endif
|
||||
|
||||
|
||||
#endif // #ifndef INCLUDED_COMPILER
|
||||
@@ -86,10 +86,10 @@ int cpu_coresPerPackage()
|
||||
#endif
|
||||
}
|
||||
|
||||
int cpu_logicalPerPackage()
|
||||
int cpu_logicalPerCore()
|
||||
{
|
||||
#if CPU_IA32
|
||||
return ia32_logicalPerPackage();
|
||||
return ia32_logicalPerCore();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ extern const char* cpu_identifierString();
|
||||
extern double cpu_clockFrequency();
|
||||
extern int cpu_numPackages(); // i.e. sockets
|
||||
extern int cpu_coresPerPackage();
|
||||
extern int cpu_logicalPerPackage();
|
||||
extern int cpu_logicalPerCore();
|
||||
extern bool cpu_isThrottlingPossible();
|
||||
|
||||
|
||||
|
||||
@@ -386,38 +386,69 @@ double ia32_clockFrequency()
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// detect processor types / topology
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// (these are uniform over all packages)
|
||||
|
||||
|
||||
static uint logicalPerPackage()
|
||||
{
|
||||
// not Hyperthreading capable
|
||||
if(!ia32_cap(IA32_CAP_HT))
|
||||
return 1;
|
||||
|
||||
u32 regs[4];
|
||||
if(!ia32_asm_cpuid(1, regs))
|
||||
DEBUG_WARN_ERR(ERR::CPU_FEATURE_MISSING);
|
||||
const uint logical_per_package = bits(regs[EBX], 16, 23);
|
||||
return logical_per_package;
|
||||
}
|
||||
// OSes report hyperthreading units and cores as "processors". we need to
|
||||
// drill down and find out the exact counts (for thread pool dimensioning
|
||||
// and cache sharing considerations).
|
||||
// note: Intel Appnote 485 (CPUID) assures uniformity of coresPerPackage and
|
||||
// logicalPerCore.
|
||||
|
||||
static uint coresPerPackage()
|
||||
{
|
||||
// single core
|
||||
u32 regs[4];
|
||||
if(!ia32_asm_cpuid(4, regs))
|
||||
return 1;
|
||||
static uint cores_per_package = 0;
|
||||
if(cores_per_package == 0)
|
||||
{
|
||||
u32 regs[4];
|
||||
if(ia32_asm_cpuid(4, regs))
|
||||
cores_per_package = bits(regs[EAX], 26, 31)+1;
|
||||
else
|
||||
cores_per_package = 1; // single-core
|
||||
}
|
||||
|
||||
const uint cores_per_package = bits(regs[EAX], 26, 31)+1;
|
||||
return cores_per_package;
|
||||
}
|
||||
|
||||
static uint logicalPerCore()
|
||||
{
|
||||
static uint logical_per_core = 0;
|
||||
if(logical_per_core == 0)
|
||||
{
|
||||
if(ia32_cap(IA32_CAP_HT))
|
||||
{
|
||||
u32 regs[4];
|
||||
if(!ia32_asm_cpuid(1, regs))
|
||||
DEBUG_WARN_ERR(ERR::CPU_FEATURE_MISSING);
|
||||
const uint logical_per_package = bits(regs[EBX], 16, 23);
|
||||
// cores ought to be uniform WRT # logical processors
|
||||
debug_assert(logical_per_package % coresPerPackage() == 0);
|
||||
logical_per_core = logical_per_package / coresPerPackage();
|
||||
}
|
||||
else
|
||||
logical_per_core = 1; // not Hyperthreading capable
|
||||
}
|
||||
|
||||
return logical_per_core;
|
||||
}
|
||||
|
||||
// the above two functions give the maximum number of cores/logical units.
|
||||
// however, some of them may actually be disabled by the BIOS!
|
||||
// what we can do is to analyze the APIC IDs. they are allocated sequentially
|
||||
// for all "processors". treating the IDs as variable-width bitfields
|
||||
// (according to the number of cores/logical units present) allows
|
||||
// determining the exact topology as well as number of packages.
|
||||
|
||||
// these are set by detectProcessorTopology, called from ia32_init.
|
||||
static uint num_packages = 0; // i.e. sockets; > 1 => true SMP system
|
||||
static uint enabled_cores_per_package = 0;
|
||||
static uint enabled_logical_per_core = 0; // hyperthreading units
|
||||
|
||||
typedef std::vector<u8> Ids;
|
||||
typedef std::set<u8> IdSet;
|
||||
|
||||
// add the currently running processor's APIC ID to a list of IDs.
|
||||
static void storeApicId(void* param)
|
||||
{
|
||||
u32 regs[4];
|
||||
@@ -429,9 +460,14 @@ static void storeApicId(void* param)
|
||||
apic_ids->push_back(apic_id);
|
||||
}
|
||||
|
||||
|
||||
// field := a range of bits sufficient to represent <num_values> integers.
|
||||
// for each id in apic_ids: extract the value of the field at offset bit_pos
|
||||
// and insert it into ids. afterwards, adjust bit_pos to the next field.
|
||||
// used to gather e.g. all core IDs from all APIC IDs.
|
||||
static void extractFieldsIntoSet(const Ids& apic_ids, uint& bit_pos, uint num_values, IdSet& ids)
|
||||
{
|
||||
const uint id_bits = log2(num_values);
|
||||
const uint id_bits = log2(num_values); // (rounded up)
|
||||
if(id_bits == 0)
|
||||
return;
|
||||
|
||||
@@ -447,65 +483,62 @@ static void extractFieldsIntoSet(const Ids& apic_ids, uint& bit_pos, uint num_va
|
||||
bit_pos += id_bits;
|
||||
}
|
||||
|
||||
static int num_packages = -1; // i.e. sockets; > 1 => true SMP system
|
||||
static int cores_per_package = -1;
|
||||
static int logical_per_package = -1; // hyperthreading units
|
||||
|
||||
// note: even though APIC IDs are assigned sequentially, we can't make any
|
||||
// assumptions about the values/ordering because we get them according to
|
||||
// the CPU affinity mask, which is unknown.
|
||||
|
||||
// HT and dual cores may be disabled, so see how many are actually enabled.
|
||||
// (examine each APIC ID to determine the kind of CPU)
|
||||
static void detectActualTopology()
|
||||
// determine how many coresPerPackage and logicalPerCore are
|
||||
// actually enabled and also count numPackages.
|
||||
// (scans the APIC IDs, which requires OS support for thread affinity)
|
||||
static void detectProcessorTopology()
|
||||
{
|
||||
Ids apic_ids;
|
||||
if(cpu_callByEachCPU(storeApicId, &apic_ids) != INFO::OK)
|
||||
return;
|
||||
// .. if they're not unique, cpu_callByEachCPU is broken.
|
||||
std::sort(apic_ids.begin(), apic_ids.end());
|
||||
debug_assert(std::unique(apic_ids.begin(), apic_ids.end()) == apic_ids.end());
|
||||
|
||||
const uint max_cores_per_package = coresPerPackage();
|
||||
const uint logical_per_core = logicalPerPackage() / max_cores_per_package;
|
||||
|
||||
// extract values from all 3 fields into separate sets
|
||||
// (we want to know how many logical CPUs per core, cores per package and packages exist)
|
||||
// extract values from all 3 ID bitfields into separate sets
|
||||
uint bit_pos = 0;
|
||||
IdSet logical_ids;
|
||||
extractFieldsIntoSet(apic_ids, bit_pos, logical_per_core, logical_ids);
|
||||
extractFieldsIntoSet(apic_ids, bit_pos, logicalPerCore(), logical_ids);
|
||||
IdSet core_ids;
|
||||
extractFieldsIntoSet(apic_ids, bit_pos, max_cores_per_package, core_ids);
|
||||
extractFieldsIntoSet(apic_ids, bit_pos, coresPerPackage(), core_ids);
|
||||
IdSet package_ids;
|
||||
extractFieldsIntoSet(apic_ids, bit_pos, 0xFF, core_ids);
|
||||
extractFieldsIntoSet(apic_ids, bit_pos, 0xFF, package_ids);
|
||||
|
||||
num_packages = std::max((int)package_ids.size(), 1);
|
||||
cores_per_package = std::max((int)core_ids.size(), 1);
|
||||
logical_per_package = std::max((int)logical_ids.size(), 1) * cores_per_package;
|
||||
// (the set cardinality is representative of all packages/cores since
|
||||
// they are uniform.)
|
||||
num_packages = std::max((uint)package_ids.size(), 1u);
|
||||
enabled_cores_per_package = std::max((uint)core_ids .size(), 1u);
|
||||
enabled_logical_per_core = std::max((uint)logical_ids.size(), 1u);
|
||||
|
||||
// note: even though APIC IDs are assigned sequentially, we can't make any
|
||||
// assumptions about the values/ordering because we get them according to
|
||||
// the CPU affinity mask, which is unknown.
|
||||
}
|
||||
|
||||
|
||||
uint ia32_logicalPerPackage()
|
||||
uint ia32_numPackages()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
debug_assert(logical_per_package != -1);
|
||||
debug_assert(num_packages != 0);
|
||||
#endif
|
||||
return (uint)logical_per_package;
|
||||
return (uint)num_packages;
|
||||
}
|
||||
|
||||
uint ia32_coresPerPackage()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
debug_assert(cores_per_package != -1);
|
||||
debug_assert(enabled_cores_per_package != 0);
|
||||
#endif
|
||||
return (uint)cores_per_package;
|
||||
return (uint)enabled_cores_per_package;
|
||||
}
|
||||
|
||||
uint ia32_numPackages()
|
||||
uint ia32_logicalPerCore()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
debug_assert(num_packages != -1);
|
||||
debug_assert(enabled_logical_per_core != 0);
|
||||
#endif
|
||||
return (uint)num_packages;
|
||||
return (uint)enabled_logical_per_core;
|
||||
}
|
||||
|
||||
|
||||
@@ -585,5 +618,5 @@ void ia32_init()
|
||||
|
||||
detectVendor();
|
||||
|
||||
detectActualTopology();
|
||||
detectProcessorTopology();
|
||||
}
|
||||
|
||||
@@ -130,8 +130,8 @@ extern const char* ia32_identifierString();
|
||||
extern int ia32_isThrottlingPossible();
|
||||
extern double ia32_clockFrequency();
|
||||
|
||||
extern uint ia32_logicalPerPackage();
|
||||
extern uint ia32_coresPerPackage();
|
||||
extern uint ia32_numPackages();
|
||||
extern uint ia32_coresPerPackage();
|
||||
extern uint ia32_logicalPerCore();
|
||||
|
||||
#endif // #ifndef IA32_H
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
#ifndef INCLUDED_IA32_MEMCPY
|
||||
#define INCLUDED_IA32_MEMCPY
|
||||
|
||||
#include "lib/sysdep/sysdep.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
extern void ia32_memcpy_init();
|
||||
|
||||
#define RESTRICT __restrict
|
||||
extern void* ia32_memcpy(void* RESTRICT dst, const void* RESTRICT src, size_t nbytes);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
#ifndef INCLUDED_STL
|
||||
#define INCLUDED_STL
|
||||
|
||||
// compiling without exceptions (usually for performance reasons);
|
||||
// tell STL not to generate any.
|
||||
#if CONFIG_DISABLE_EXCEPTIONS
|
||||
# if OS_WIN
|
||||
# define _HAS_EXCEPTIONS 0
|
||||
# else
|
||||
# define STL_NO_EXCEPTIONS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
// STL_HASH_MAP, STL_HASH_MULTIMAP, STL_HASH_SET
|
||||
// these containers are useful but not part of C++98. most STL vendors
|
||||
// provide them in some form; we hide their differences behind macros.
|
||||
|
||||
#if GCC_VERSION
|
||||
# include <ext/hash_map>
|
||||
# include <ext/hash_set>
|
||||
|
||||
# define STL_HASH_MAP __gnu_cxx::hash_map
|
||||
# define STL_HASH_MULTIMAP __gnu_cxx::hash_multimap
|
||||
# define STL_HASH_SET __gnu_cxx::hash_set
|
||||
# define STL_HASH_MULTISET __gnu_cxx::hash_multiset
|
||||
# define STL_SLIST __gnu_cxx::slist
|
||||
|
||||
template<typename T>
|
||||
size_t STL_HASH_VALUE(T v)
|
||||
{
|
||||
return __gnu_cxx::hash<T>()(v);
|
||||
}
|
||||
|
||||
// Hack: GCC Doesn't have a hash instance for std::string included (and it looks
|
||||
// like they won't add it - marked resolved/wontfix in the gcc bugzilla)
|
||||
namespace __gnu_cxx
|
||||
{
|
||||
template<> struct hash<std::string>
|
||||
{
|
||||
size_t operator()(const std::string& __x) const
|
||||
{
|
||||
return __stl_hash_string(__x.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct hash<const void*>
|
||||
{
|
||||
// Nemesi hash function (see: http://mail-index.netbsd.org/tech-kern/2001/11/30/0001.html)
|
||||
// treating the pointer as an array of bytes that is hashed.
|
||||
size_t operator()(const void* __x) const
|
||||
{
|
||||
union {
|
||||
const void* ptr;
|
||||
unsigned char bytes[sizeof(void*)];
|
||||
} val;
|
||||
size_t h = 5381;
|
||||
|
||||
val.ptr = __x;
|
||||
|
||||
for(uint i = 0; i < sizeof(val); ++i)
|
||||
h = 257*h + val.bytes[i];
|
||||
|
||||
return 257*h;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#else // !__GNUC__
|
||||
|
||||
# include <hash_map>
|
||||
# include <hash_set>
|
||||
// VC7 or above
|
||||
# if MSC_VERSION >= 1300
|
||||
# define STL_HASH_MAP stdext::hash_map
|
||||
# define STL_HASH_MULTIMAP stdext::hash_multimap
|
||||
# define STL_HASH_SET stdext::hash_set
|
||||
# define STL_HASH_MULTISET stdext::hash_multiset
|
||||
# define STL_HASH_VALUE stdext::hash_value
|
||||
// VC6 and anything else (most likely name)
|
||||
# else
|
||||
# define STL_HASH_MAP std::hash_map
|
||||
# define STL_HASH_MULTIMAP std::hash_multimap
|
||||
# define STL_HASH_SET std::hash_set
|
||||
# define STL_HASH_MULTISET std::hash_multiset
|
||||
# define STL_HASH_VALUE std::hash_value
|
||||
# endif // MSC_VERSION >= 1300
|
||||
|
||||
#endif // !__GNUC__
|
||||
|
||||
#endif // #ifndef INCLUDED_STL
|
||||
@@ -23,48 +23,3 @@
|
||||
#include "precompiled.h"
|
||||
#include "sysdep.h"
|
||||
|
||||
|
||||
// emulate C99 functionality
|
||||
#if !HAVE_C99_MATH
|
||||
|
||||
// fallback versions in case ia32 optimized versions are unavailable.
|
||||
#if !HAVE_MS_ASM
|
||||
|
||||
inline float rintf(float f)
|
||||
{
|
||||
return (float)(int)f;
|
||||
}
|
||||
|
||||
inline double rint(double d)
|
||||
{
|
||||
return (double)(int)d;
|
||||
}
|
||||
|
||||
float fminf(float a, float b)
|
||||
{
|
||||
return (a < b)? a : b;
|
||||
}
|
||||
|
||||
float fmaxf(float a, float b)
|
||||
{
|
||||
return (a > b)? a : b;
|
||||
}
|
||||
|
||||
uint fpclassify(double d)
|
||||
{
|
||||
// really sucky stub implementation; doesn't attempt to cover all cases.
|
||||
|
||||
if(d != d)
|
||||
return FP_NAN;
|
||||
else
|
||||
return FP_NORMAL;
|
||||
}
|
||||
|
||||
uint fpclassifyf(float f)
|
||||
{
|
||||
return fpclassify((double)f);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #if !HAVE_C99_MATH
|
||||
|
||||
+9
-258
@@ -9,7 +9,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003-2005 Jan Wassenberg
|
||||
* Copyright (c) 2003-2007 Jan Wassenberg
|
||||
*
|
||||
* Redistribution and/or modification are also permitted under the
|
||||
* terms of the GNU General Public License as published by the
|
||||
@@ -20,64 +20,14 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#ifndef SYSDEP_H_INCLUDED
|
||||
#define SYSDEP_H_INCLUDED
|
||||
#ifndef INCLUDED_SYSDEP
|
||||
#define INCLUDED_SYSDEP
|
||||
|
||||
#include "lib/config.h"
|
||||
#include "lib/debug.h" // ErrorReaction
|
||||
|
||||
#include <cmath> // see comments below about isfinite
|
||||
#include <cstdarg> // needed for vsnprintf2
|
||||
|
||||
// some functions among the sysdep API are implemented as macros
|
||||
// that redirect to the platform-dependent version. this is done where
|
||||
// the cost of a trampoline function would be too great; VC7 does not
|
||||
// always inline them.
|
||||
// we therefore need to include those headers.
|
||||
#if OS_WIN
|
||||
# include "lib/sysdep/win/win.h"
|
||||
#elif OS_UNIX
|
||||
# include "lib/sysdep/unix/unix.h"
|
||||
#endif
|
||||
#if CPU_IA32
|
||||
#include "ia32/ia32.h"
|
||||
#endif
|
||||
|
||||
|
||||
// pass "omit frame pointer" setting on to the compiler
|
||||
#if MSC_VERSION
|
||||
# if CONFIG_OMIT_FP
|
||||
# pragma optimize("y", on)
|
||||
# else
|
||||
# pragma optimize("y", off)
|
||||
# endif
|
||||
#elif GCC_VERSION
|
||||
// TODO
|
||||
#endif
|
||||
|
||||
// compiling without exceptions (usually for performance reasons);
|
||||
// tell STL not to generate any.
|
||||
#if CONFIG_DISABLE_EXCEPTIONS
|
||||
# if OS_WIN
|
||||
# define _HAS_EXCEPTIONS 0
|
||||
# else
|
||||
# define STL_NO_EXCEPTIONS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
// try to define _W64, if not already done
|
||||
// (this is useful for catching pointer size bugs)
|
||||
#ifndef _W64
|
||||
# if MSC_VERSION
|
||||
# define _W64 __w64
|
||||
# elif GCC_VERSION
|
||||
# define _W64 __attribute__((mode (__pointer__)))
|
||||
# else
|
||||
# define _W64
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// C99 / SUSv3 emulation where needed
|
||||
@@ -95,118 +45,6 @@ extern int vsnprintf2(char* buffer, size_t count, const char* format, va_list ar
|
||||
#define strnicmp strncasecmp
|
||||
#endif
|
||||
|
||||
// alloca: allocate on stack, automatically free, return 0 if out of mem.
|
||||
// already available on *nix, emulated on Win32.
|
||||
#if OS_WIN
|
||||
#undef alloca // from malloc.h
|
||||
extern void* alloca(size_t size);
|
||||
#endif
|
||||
|
||||
// emulate some C99 functions if not already available:
|
||||
// rint: round float to nearest integral value, according to
|
||||
// current rounding mode.
|
||||
// fminf/fmaxf: return minimum/maximum of two floats.
|
||||
#if !HAVE_C99_MATH
|
||||
// .. fast IA-32 versions
|
||||
# if CPU_IA32
|
||||
# define rintf ia32_asm_rintf
|
||||
# define rint ia32_asm_rint
|
||||
# define fminf ia32_asm_fminf
|
||||
# define fmaxf ia32_asm_fmaxf
|
||||
|
||||
# define FP_NAN IA32_FP_NAN
|
||||
# define FP_NORMAL IA32_FP_NORMAL
|
||||
# define FP_INFINITE (FP_NAN | FP_NORMAL)
|
||||
# define FP_ZERO IA32_FP_ZERO
|
||||
# define FP_SUBNORMAL (FP_NORMAL | FP_ZERO)
|
||||
# define fpclassify(x) ( (sizeof(x) == sizeof(float))? ia32_asm_fpclassifyf(x) : ia32_asm_fpclassify(x) )
|
||||
// .. portable C emulation
|
||||
# else
|
||||
extern float rintf(float f);
|
||||
extern double rint(double d);
|
||||
extern float fminf(float a, float b);
|
||||
extern float fmaxf(float a, float b);
|
||||
|
||||
# define FP_NAN 1
|
||||
# define FP_NORMAL 2
|
||||
# define FP_INFINITE (FP_NAN | FP_NORMAL)
|
||||
# define FP_ZERO 4
|
||||
# define FP_SUBNORMAL (FP_NORMAL | FP_ZERO)
|
||||
extern uint fpclassify(double d);
|
||||
# endif
|
||||
|
||||
# define isnan(d) (fpclassify(d) == FP_NAN)
|
||||
# define isfinite(d) ((fpclassify(d) & (FP_NORMAL|FP_ZERO)) != 0)
|
||||
# define isinf(d) (fpclassify(d) == FP_NAN|FP_NORMAL)
|
||||
# define isnormal(d) (fpclassify(d) == FP_NORMAL)
|
||||
//# define signbit
|
||||
#else // HAVE_C99_MATH
|
||||
// Some systems have C99 support but in C++ they provide only std::isfinite
|
||||
// and not isfinite. C99 specifies that isfinite is a macro, so we can use
|
||||
// #ifndef and define it if it's not there already.
|
||||
// We've included <cmath> above to make sure it defines that macro.
|
||||
# ifndef isfinite
|
||||
# define isfinite std::isfinite
|
||||
# define isnan std::isnan
|
||||
# define isinf std::isinf
|
||||
# define isnormal std::isnormal
|
||||
# endif
|
||||
#endif // HAVE_C99_MATH
|
||||
|
||||
|
||||
// C99-like restrict (non-standard in C++, but widely supported in various forms).
|
||||
//
|
||||
// May be used on pointers. May also be used on member functions to indicate
|
||||
// that 'this' is unaliased (e.g. "void C::m() RESTRICT { ... }").
|
||||
// Must not be used on references - GCC supports that but VC doesn't.
|
||||
//
|
||||
// We call this "RESTRICT" to avoid conflicts with VC's __declspec(restrict),
|
||||
// and because it's not really the same as C99's restrict.
|
||||
//
|
||||
// To be safe and satisfy the compilers' stated requirements: an object accessed
|
||||
// by a restricted pointer must not be accessed by any other pointer within the
|
||||
// lifetime of the restricted pointer, if the object is modified.
|
||||
// To maximise the chance of optimisation, any pointers that could potentially
|
||||
// alias with the restricted one should be marked as restricted too.
|
||||
//
|
||||
// It would probably be a good idea to write test cases for any code that uses
|
||||
// this in an even very slightly unclear way, in case it causes obscure problems
|
||||
// in a rare compiler due to differing semantics.
|
||||
//
|
||||
// .. we made g++ claim to support C99 by defining __STDC_VERSION__ in the
|
||||
// makefiles, but that's wrong and it doesn't have the restrict keyword.
|
||||
// use the extension __restrict__ instead.
|
||||
#if GCC_VERSION
|
||||
# define RESTRICT __restrict__
|
||||
// .. already available in C99 as 'restrict'
|
||||
#elif HAVE_C99
|
||||
# define RESTRICT restrict
|
||||
// .. VC8 provides __restrict
|
||||
#elif MSC_VERSION >= 1400
|
||||
# define RESTRICT __restrict
|
||||
// .. ICC supports the keyword 'restrict' when run with the /Qrestrict option,
|
||||
// but it always also supports __restrict__ or __restrict to be compatible
|
||||
// with GCC/MSVC, so we'll use the underscored version. One of {GCC,MSC}_VERSION
|
||||
// should have been defined in addition to ICC_VERSION, so we should be using
|
||||
// one of the above cases (unless it's an old VS7.1-emulating ICC).
|
||||
#elif ICC_VERSION
|
||||
# error ICC_VERSION defined without either GCC_VERSION or an adequate MSC_VERSION
|
||||
// .. unsupported; remove it from code
|
||||
#else
|
||||
# define RESTRICT
|
||||
#endif
|
||||
|
||||
|
||||
// C99 __func__
|
||||
// .. already available; need do nothing
|
||||
#if HAVE_C99
|
||||
// .. VC supports something similar
|
||||
#elif MSC_VERSION
|
||||
# define __func__ __FUNCTION__
|
||||
// .. unsupported; remove it from code
|
||||
#else
|
||||
# define __func__ "(unknown)"
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -282,6 +120,11 @@ extern LibError sys_cursor_free(void* cursor);
|
||||
// misc
|
||||
//
|
||||
|
||||
/**
|
||||
* allocate on stack, automatically free when current function returns.
|
||||
**/
|
||||
extern void* sys_alloca(size_t size);
|
||||
|
||||
// describe the current OS error state.
|
||||
//
|
||||
// err: if not 0, use that as the error code to translate; otherwise,
|
||||
@@ -337,96 +180,4 @@ extern size_t sys_max_sector_size();
|
||||
# define SYS_DIR_SEP '/'
|
||||
#endif
|
||||
|
||||
// tell the compiler that the code at/following this macro invocation is
|
||||
// unreachable. this can improve optimization and avoid warnings.
|
||||
//
|
||||
// this macro should not generate any fallback code; it is merely the
|
||||
// compiler-specific backend for lib.h's UNREACHABLE.
|
||||
// #define it to nothing if the compiler doesn't support such a hint.
|
||||
#if MSC_VERSION
|
||||
# define SYS_UNREACHABLE __assume(0)
|
||||
#else
|
||||
# define SYS_UNREACHABLE
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// STL_HASH_MAP, STL_HASH_MULTIMAP, STL_HASH_SET
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// these containers are useful but not part of C++98. most STL vendors
|
||||
// provide them in some form; we hide their differences behind macros.
|
||||
|
||||
#if GCC_VERSION
|
||||
# include <ext/hash_map>
|
||||
# include <ext/hash_set> // Probably?
|
||||
|
||||
# define STL_HASH_MAP __gnu_cxx::hash_map
|
||||
# define STL_HASH_MULTIMAP __gnu_cxx::hash_multimap
|
||||
# define STL_HASH_SET __gnu_cxx::hash_set
|
||||
# define STL_HASH_MULTISET __gnu_cxx::hash_multiset
|
||||
# define STL_SLIST __gnu_cxx::slist
|
||||
|
||||
template<typename T>
|
||||
size_t STL_HASH_VALUE(T v)
|
||||
{
|
||||
return __gnu_cxx::hash<T>()(v);
|
||||
}
|
||||
|
||||
// Hack: GCC Doesn't have a hash instance for std::string included (and it looks
|
||||
// like they won't add it - marked resolved/wontfix in the gcc bugzilla)
|
||||
namespace __gnu_cxx
|
||||
{
|
||||
template<> struct hash<std::string>
|
||||
{
|
||||
size_t operator()(const std::string& __x) const
|
||||
{
|
||||
return __stl_hash_string(__x.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct hash<const void*>
|
||||
{
|
||||
// Nemesi hash function (see: http://mail-index.netbsd.org/tech-kern/2001/11/30/0001.html)
|
||||
// treating the pointer as an array of bytes that is hashed.
|
||||
size_t operator()(const void* __x) const
|
||||
{
|
||||
union {
|
||||
const void* ptr;
|
||||
unsigned char bytes[sizeof(void*)];
|
||||
} val;
|
||||
size_t h = 5381;
|
||||
|
||||
val.ptr = __x;
|
||||
|
||||
for(uint i = 0; i < sizeof(val); ++i)
|
||||
h = 257*h + val.bytes[i];
|
||||
|
||||
return 257*h;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#else // !__GNUC__
|
||||
|
||||
# include <hash_map>
|
||||
# include <hash_set>
|
||||
// VC7 or above
|
||||
# if MSC_VERSION >= 1300
|
||||
# define STL_HASH_MAP stdext::hash_map
|
||||
# define STL_HASH_MULTIMAP stdext::hash_multimap
|
||||
# define STL_HASH_SET stdext::hash_set
|
||||
# define STL_HASH_MULTISET stdext::hash_multiset
|
||||
# define STL_HASH_VALUE stdext::hash_value
|
||||
// VC6 and anything else (most likely name)
|
||||
# else
|
||||
# define STL_HASH_MAP std::hash_map
|
||||
# define STL_HASH_MULTIMAP std::hash_multimap
|
||||
# define STL_HASH_SET std::hash_set
|
||||
# define STL_HASH_MULTISET std::hash_multiset
|
||||
# define STL_HASH_VALUE std::hash_value
|
||||
# endif // MSC_VERSION >= 1300
|
||||
|
||||
#endif // !__GNUC__
|
||||
|
||||
#endif // #ifndef SYSDEP_H_INCLUDED
|
||||
#endif // #ifndef INCLUDED_SYSDEP
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "lib/lib.h"
|
||||
#include "lib/self_test.h"
|
||||
|
||||
#include "lib/sysdep/sysdep.h"
|
||||
|
||||
class TestPrintf : public CxxTest::TestSuite
|
||||
{
|
||||
// Split some bits into separate functions, so we can get
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#ifndef WIN_H__
|
||||
#define WIN_H__
|
||||
#ifndef INCLUDED_WIN
|
||||
#define INCLUDED_WIN
|
||||
|
||||
#include "lib/config.h"
|
||||
|
||||
@@ -29,19 +29,6 @@
|
||||
#error "win.h: do not include if not compiling for Windows"
|
||||
#endif
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
// provide C99 *snprintf functions if compiler doesn't already
|
||||
// (MinGW does, VC7.1 doesn't).
|
||||
#if !HAVE_NPRINTF
|
||||
# define snprintf _snprintf
|
||||
# define swprintf _snwprintf
|
||||
# define vsnprintf _vsnprintf
|
||||
# define vswprintf _vsnwprintf
|
||||
#endif
|
||||
|
||||
#include <stddef.h> // wchar_t
|
||||
|
||||
// libpng.h -> zlib.h -> zconf.h includes <windows.h>, which causes conflicts.
|
||||
// prevent that, and define what they actually need from windows.h.
|
||||
// incidentally, this requires all dependents of windows.h to include
|
||||
@@ -75,4 +62,4 @@
|
||||
// remembering to call the init function, but it can't be helped.
|
||||
extern void win_pre_main_init();
|
||||
|
||||
#endif // #ifndef WIN_H__
|
||||
#endif // #ifndef INCLUDED_WIN
|
||||
|
||||
@@ -46,13 +46,7 @@ void sys_display_msgw(const wchar_t* caption, const wchar_t* msg)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// workaround: apparently PCH contents may be included after the headers.
|
||||
// malloc.h is defining alloca to _alloca and then VC complains about us
|
||||
// redefining an intrinsic. so, stomp on the macro here.
|
||||
#undef alloca
|
||||
|
||||
void* alloca(size_t size)
|
||||
void* sys_alloca(size_t size)
|
||||
{
|
||||
void* ret;
|
||||
__try
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#ifndef INCLUDED_WSYSDEP
|
||||
#define INCLUDED_WSYSDEP
|
||||
|
||||
#endif // #ifndef INCLUDED_WSYSDEP
|
||||
@@ -33,6 +33,10 @@
|
||||
#include "adts.h"
|
||||
#include "lib/sysdep/cpu.h"
|
||||
|
||||
#if TIMER_USE_RDTSC
|
||||
# include "lib/sysdep/ia32/ia32.h"
|
||||
#endif
|
||||
|
||||
// rationale for wrapping gettimeofday and clock_gettime, instead of emulating
|
||||
// them where not available: allows returning higher-resolution timer values
|
||||
// than their us / ns interface, via double [seconds]. they're also not
|
||||
@@ -328,3 +332,13 @@ void timer_display_client_totals()
|
||||
|
||||
debug_printf("-----------------------------------------------------\n");
|
||||
}
|
||||
|
||||
|
||||
#if TIMER_USE_RDTSC
|
||||
|
||||
TimerRdtsc::unit TimerRdtsc::get_timestamp() const
|
||||
{
|
||||
return ia32_rdtsc();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+1
-4
@@ -200,10 +200,7 @@ class TimerRdtsc
|
||||
{
|
||||
public:
|
||||
typedef i64 unit;
|
||||
unit get_timestamp() const
|
||||
{
|
||||
return ia32_rdtsc();
|
||||
}
|
||||
unit get_timestamp() const;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "lib/lib.h"
|
||||
#include "lib/path_util.h"
|
||||
#include "lib/res/file/file.h"
|
||||
#include "lib/sysdep/sysdep.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <ostream>
|
||||
|
||||
+1
-1
@@ -69,7 +69,7 @@ private:
|
||||
* Helper class for unit tests - captures all log output while it is in scope,
|
||||
* and returns it as a single string.
|
||||
*/
|
||||
class TestLogger
|
||||
class TestLogger : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
TestLogger();
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "lib/path_util.h"
|
||||
#include "lib/res/file/file.h"
|
||||
#include "lib/sysdep/sysdep.h"
|
||||
|
||||
DEFINE_ERROR(PS_OK, "OK");
|
||||
DEFINE_ERROR(PS_FAIL, "Fail");
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@ void WriteSystemInfo()
|
||||
fprintf(f, "OS : %s %s (%s)\n", un.sysname, un.release, un.version);
|
||||
|
||||
// .. CPU
|
||||
fprintf(f, "CPU : %s, %s (%dx%dx%d)", un.machine, cpu_identifierString(), cpu_numPackages(), cpu_coresPerPackage(), cpu_logicalPerPackage()/cpu_coresPerPackage());
|
||||
fprintf(f, "CPU : %s, %s (%dx%dx%d)", un.machine, cpu_identifierString(), cpu_numPackages(), cpu_coresPerPackage(), cpu_logicalPerCore());
|
||||
const double cpu_freq = cpu_clockFrequency();
|
||||
if(cpu_freq != 0.0f)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user