1
0
forked from 0ad/0ad

. split up lib.h/.cpp, include the remnants from PCH, remove (pretty much universal) include of it.

. timer, config: fix definition of ALLOW_RDTSC
. add movsx_be64 (for whirlpool), revise implementation, move to
byte_order, add test
. MAX -> std::max, remove those macros
. add timestamp to system_info as requested by philip

This was SVN commit r5050.
This commit is contained in:
janwas 2007-05-09 21:01:11 +00:00
parent 78d950e419
commit a34b759720
123 changed files with 1163 additions and 1033 deletions

View File

@ -3,6 +3,7 @@
#include "ColladaManager.h"
#include "graphics/ModelDef.h"
#include "lib/fnv_hash.h"
#include "lib/res/file/vfs.h"
#include "lib/res/handle.h"
#include "ps/CLogger.h"

View File

@ -16,7 +16,6 @@
#include "graphics/Unit.h"
#include "graphics/UnitManager.h"
#include "lib/input.h"
#include "lib/lib.h"
#include "lib/timer.h"
#include "maths/Bound.h"
#include "maths/MathUtil.h"

View File

@ -61,7 +61,7 @@ void CMapWriter::SaveMap(const char* filename, CTerrain* pTerrain,
// handle isn't in list
static u16 GetHandleIndex(const Handle handle, const std::vector<Handle>& handles)
{
const uint limit = MIN((uint)handles.size(), 0xFFFE); // paranoia
const uint limit = std::min((uint)handles.size(), 0xFFFEu); // paranoia
for (uint i=0;i<limit;i++) {
if (handles[i]==handle) {
return (u16)i;

View File

@ -8,8 +8,6 @@
#include "precompiled.h"
#include "lib/lib.h"
#include "Patch.h"
#include "MiniPatch.h"
#include "Terrain.h"
@ -38,3 +36,4 @@ void CMiniPatch::GetTileIndex(u32& x,u32& z)
}

View File

@ -30,6 +30,7 @@ CGUI
#include "ps/Pyrogenesis.h"
#include "lib/input.h"
#include "lib/bits.h"
// TODO Gee: Whatever include CRect/CPos/CSize
#include "ps/Overlay.h"
@ -708,7 +709,7 @@ SGUIText CGUI::GenerateText(const CGUIString &string,
// after the last image, like a stack downwards.
float _y;
if (Images[j].size() > 0)
_y = MAX(y, Images[j].back().m_YTo);
_y = std::max(y, Images[j].back().m_YTo);
else
_y = y;
@ -719,7 +720,7 @@ SGUIText CGUI::GenerateText(const CGUIString &string,
Image.SetupSpriteCall((j==CGUIString::SFeedback::Left), SpriteCall, Width, _y, size, icon.m_SpriteName, BufferZone, icon.m_CellID);
// Check if image is the lowest thing.
Text.m_Size.cy = MAX(Text.m_Size.cy, Image.m_YTo);
Text.m_Size.cy = std::max(Text.m_Size.cy, Image.m_YTo);
Images[j].push_back(Image);
Text.m_SpriteCalls.push_back(SpriteCall);
@ -727,10 +728,10 @@ SGUIText CGUI::GenerateText(const CGUIString &string,
}
}
pos_last_img = MAX(pos_last_img, i);
pos_last_img = std::max(pos_last_img, i);
x += Feedback.m_Size.cx;
prelim_line_height = MAX(prelim_line_height, Feedback.m_Size.cy);
prelim_line_height = std::max(prelim_line_height, Feedback.m_Size.cy);
// If Width is 0, then there's no word-wrapping, disable NewLine.
if ((WordWrapping && (x > Width-BufferZone || Feedback.m_NewLine)) || i == (int)string.m_Words.size()-2)
@ -766,16 +767,16 @@ SGUIText CGUI::GenerateText(const CGUIString &string,
// let's find the union of these two.
float union_from, union_to;
union_from = MAX(y, it->m_YFrom);
union_to = MIN(y+prelim_line_height, it->m_YTo);
union_from = std::max(y, it->m_YFrom);
union_to = std::min(y+prelim_line_height, it->m_YTo);
// The union is not empty
if (union_to > union_from)
{
if (j == From)
width_range[From] = MAX(width_range[From], it->m_Indentation);
width_range[From] = std::max(width_range[From], it->m_Indentation);
else
width_range[To] = MIN(width_range[To], Width - it->m_Indentation);
width_range[To] = std::min(width_range[To], Width - it->m_Indentation);
}
}
}
@ -811,7 +812,7 @@ SGUIText CGUI::GenerateText(const CGUIString &string,
break;
// Let line_height be the maximum m_Height we encounter.
line_height = MAX(line_height, Feedback2.m_Size.cy);
line_height = std::max(line_height, Feedback2.m_Size.cy);
if (WordWrapping && Feedback2.m_NewLine)
break;
@ -856,7 +857,7 @@ SGUIText CGUI::GenerateText(const CGUIString &string,
// Append X value.
x += Feedback2.m_Size.cx;
Text.m_Size.cx = MAX(Text.m_Size.cx, x+BufferZone);
Text.m_Size.cx = std::max(Text.m_Size.cx, x+BufferZone);
// The first word overrides the width limit, what we
// do, in those cases, are just drawing that word even
@ -898,7 +899,7 @@ SGUIText CGUI::GenerateText(const CGUIString &string,
x = 0.f;
// Update height of all
Text.m_Size.cy = MAX(Text.m_Size.cy, y+BufferZone);
Text.m_Size.cy = std::max(Text.m_Size.cy, y+BufferZone);
FirstLine = false;

View File

@ -257,7 +257,7 @@ public:
* Set content length
* @param range Maximum scrollable range
*/
void SetScrollRange(const float &range) { m_ScrollRange = MAX(range, 1.f); SetupBarSize(); UpdatePosBoundaries(); }
void SetScrollRange(const float &range) { m_ScrollRange = std::max(range, 1.f); SetupBarSize(); UpdatePosBoundaries(); }
/**
* Set space that is visible in the scrollable control.

View File

@ -13,6 +13,7 @@
#include "graphics/UnitManager.h"
#include "lib/ogl.h"
#include "lib/external_libraries/sdl.h"
#include "lib/bits.h"
#include "lib/timer.h"
#include "network/NetMessage.h"
#include "ps/Game.h"

View File

@ -11,6 +11,9 @@
#ifndef INCLUDED_ADTS
#define INCLUDED_ADTS
#include "lib/fnv_hash.h"
//-----------------------------------------------------------------------------
// dynamic (grow-able) hash table
//-----------------------------------------------------------------------------

View File

@ -15,6 +15,7 @@
#include "lib/posix/posix.h" // sysconf
#include "lib/sysdep/cpu.h" // CAS
#include "byte_order.h"
#include "bits.h"

40
source/lib/base32.cpp Normal file
View File

@ -0,0 +1,40 @@
/**
* =========================================================================
* File : base32.cpp
* Project : 0 A.D.
* Description : base32 conversion
* =========================================================================
*/
// license: GPL; see lib/license.txt
#include "precompiled.h"
// big endian!
void base32(const size_t in_len, const u8* in, u8* out)
{
u32 pool = 0; // of bits from buffer
uint pool_bits = 0; // # bits currently in buffer
static const u8 tbl[33] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
size_t in_bytes_left = in_len; // to avoid overrunning input buffer
const size_t out_chars = (in_len*8 + 4) / 5; // = ceil(# 5-bit blocks)
for(size_t i = 0; i < out_chars; i++)
{
if(pool_bits < 5 && in_bytes_left)
{
pool <<= 8;
pool |= *in++;
pool_bits += 8;
in_bytes_left--;
}
pool_bits -= 5;
const uint c = (pool >> pool_bits) & 31;
*out++ = tbl[c];
}
*out++ = '\0';
}

24
source/lib/base32.h Normal file
View File

@ -0,0 +1,24 @@
/**
* =========================================================================
* File : base32.h
* Project : 0 A.D.
* Description : base32 conversion
* =========================================================================
*/
// license: GPL; see lib/license.txt
#ifndef INCLUDED_BASE32
#define INCLUDED_BASE32
/**
* generate the base32 textual representation of a buffer.
*
* @param len size [bytes] of input
* @param big-endian input data (assumed to be integral number of bytes)
* @param output string; zero-terminated. must be big enough
* (i.e. at least ceil(len*CHAR_BIT/5) + 1 chars)
**/
extern void base32(const size_t len, const u8* in, u8* out);
#endif // #ifndef INCLUDED_BASE32

106
source/lib/bits.cpp Normal file
View File

@ -0,0 +1,106 @@
/**
* =========================================================================
* File : bits.cpp
* Project : 0 A.D.
* Description : bit-twiddling.
* =========================================================================
*/
// license: GPL; see lib/license.txt
#include "precompiled.h"
#if CPU_IA32
# include "lib/sysdep/ia32/ia32_asm.h" // ia32_asm_log2_of_pow2
#endif
bool is_pow2(uint n)
{
// 0 would pass the test below but isn't a POT.
if(n == 0)
return false;
return (n & (n-1ul)) == 0;
}
int log2_of_pow2(uint n)
{
int bit_index;
#if CPU_IA32
bit_index = ia32_asm_log2_of_pow2(n);
#else
if(!is_pow2(n))
bit_index = -1;
else
{
bit_index = 0;
// note: compare against n directly because it is known to be a POT.
for(uint bit_value = 1; bit_value != n; bit_value *= 2)
bit_index++;
}
#endif
debug_assert(-1 <= bit_index && bit_index < (int)sizeof(int)*CHAR_BIT);
debug_assert(bit_index == -1 || n == (1u << bit_index));
return bit_index;
}
uint ceil_log2(uint x)
{
uint bit = 1;
uint l = 0;
while(bit < x && bit != 0) // must detect overflow
{
l++;
bit += bit;
}
return l;
}
int floor_log2(const float x)
{
const u32 i = *(u32*)&x;
u32 biased_exp = (i >> 23) & 0xFF;
return (int)biased_exp - 127;
}
// round_up_to_pow2 implementation assumes 32-bit int.
// if 64, add "x |= (x >> 32);"
cassert(sizeof(int)*CHAR_BIT == 32);
uint round_up_to_pow2(uint x)
{
// fold upper bit into lower bits; leaves same MSB set but
// everything below it 1. adding 1 yields next POT.
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
return x+1;
}
// multiple must be a power of two.
uintptr_t round_up(const uintptr_t n, const uintptr_t multiple)
{
debug_assert(is_pow2((long)multiple));
const uintptr_t result = (n + multiple-1) & ~(multiple-1);
debug_assert(n <= result && result < n+multiple);
return result;
}
// multiple must be a power of two.
uintptr_t round_down(const uintptr_t n, const uintptr_t multiple)
{
debug_assert(is_pow2((long)multiple));
const uintptr_t result = n & ~(multiple-1);
debug_assert(result <= n && n < result+multiple);
return result;
}

103
source/lib/bits.h Normal file
View File

@ -0,0 +1,103 @@
/**
* =========================================================================
* File : bits.h
* Project : 0 A.D.
* Description : bit-twiddling.
* =========================================================================
*/
// license: GPL; see lib/license.txt
#ifndef INCLUDED_BITS
#define INCLUDED_BITS
/**
* value of bit number <n> as unsigned long.
*
* @param n bit index (0..CHAR_BIT*sizeof(int)-1)
**/
#define BIT(n) (1ul << (n))
/**
* value of bit number <n> as unsigned long long.
*
* @param n bit index (0..CHAR_BIT*sizeof(int)-1)
**/
#define BIT64(n) (1ull << (n))
// these are declared in the header and inlined to aid compiler optimizations
// (they can easily end up being time-critical).
// note: GCC can't inline extern functions, while VC's "Whole Program
// Optimization" can.
/**
* a mask that includes the lowest N bits
*
* @param num_bits number of bits in mask
**/
inline uint bit_mask(uint num_bits)
{
return (1u << num_bits)-1;
}
/**
* extract the value of bits hi_idx:lo_idx within num
*
* example: bits(0x69, 2, 5) == 0x0A
*
* @param num number whose bits are to be extracted
* @param lo_idx bit index of lowest bit to include
* @param hi_idx bit index of highest bit to include
* @return value of extracted bits.
**/
inline uint bits(uint num, uint lo_idx, uint hi_idx)
{
const uint count = (hi_idx - lo_idx)+1; // # bits to return
uint result = num >> lo_idx;
result &= bit_mask(count);
return result;
}
/**
* @return whether the given number is a power of two.
**/
extern bool is_pow2(uint n);
/**
* @return the (integral) base 2 logarithm, or -1 if the number
* is not a power-of-two.
**/
extern int log2_of_pow2(uint n);
/**
* ceil(log2(n))
*
* @param n (integer) input; MUST be > 0, else results are undefined.
* @return ceiling of the base-2 logarithm (i.e. rounded up).
**/
extern uint ceil_log2(uint x);
/**
* floor(log2(f))
* fast, uses the FPU normalization hardware.
*
* @param f (float) input; MUST be > 0, else results are undefined.
* @return floor of the base-2 logarithm (i.e. rounded down).
**/
extern int floor_log2(const float x);
/**
* round up to next larger power of two.
**/
extern uint round_up_to_pow2(uint x);
/**
* round number up/down to the next given multiple.
*
* @param multiple: must be a power of two.
**/
extern uintptr_t round_up (uintptr_t n, uintptr_t multiple);
extern uintptr_t round_down(uintptr_t n, uintptr_t multiple);
#endif // #ifndef INCLUDED_BITS

View File

@ -11,6 +11,7 @@
#include "precompiled.h"
#include "byte_order.h"
#include "bits.h"
#ifndef swap16
@ -161,3 +162,58 @@ void write_be64(void* p, u64 x)
{
*(u64*)p = to_be64(x);
}
u64 movzx_le64(const u8* p, size_t size_bytes)
{
u64 number = 0;
for(uint i = 0; i < std::min(size_bytes, 8u); i++)
number |= ((u64)p[i]) << (i*8);
return number;
}
u64 movzx_be64(const u8* p, size_t size_bytes)
{
u64 number = 0;
for(uint i = 0; i < std::min(size_bytes, 8u); i++)
{
number <<= 8;
number |= p[i];
}
return number;
}
static inline i64 SignExtend(u64 bits, size_t size_bytes)
{
// no point in sign-extending if >= 8 bytes were requested
if(size_bytes < 8)
{
const u64 sign_bit = BIT64((size_bytes*8)-1);
// number would be negative in the smaller type,
// so sign-extend, i.e. set all more significant bits.
if(bits & sign_bit)
{
const u64 valid_bit_mask = (sign_bit+sign_bit)-1;
bits |= ~valid_bit_mask;
}
}
const i64 number = static_cast<i64>(bits);
return number;
}
i64 movsx_le64(const u8* p, size_t size_bytes)
{
const u64 number = movzx_le64(p, size_bytes);
return SignExtend(number, size_bytes);
}
i64 movsx_be64(const u8* p, size_t size_bytes)
{
const u64 number = movzx_be64(p, size_bytes);
return SignExtend(number, size_bytes);
}

View File

@ -75,6 +75,20 @@ extern void write_be16(void* p, u16 x);
extern void write_be32(void* p, u32 x); /// see write_be16
extern void write_be64(void* p, u64 x); /// see write_be16
/**
* zero-extend <size> (truncated to 8) bytes of little-endian data to u64,
* starting at address <p> (need not be aligned).
**/
extern u64 movzx_le64(const u8* p, size_t size);
extern u64 movzx_be64(const u8* p, size_t size);
/**
* sign-extend <size> (truncated to 8) bytes of little-endian data to i64,
* starting at address <p> (need not be aligned).
**/
extern i64 movsx_le64(const u8* p, size_t size);
extern i64 movsx_be64(const u8* p, size_t size);
// Debug-mode ICC doesn't like the intrinsics, so only use them
// for MSVC and non-debug ICC.

View File

@ -147,7 +147,7 @@ public:
void notify_decreased(const Entry& entry)
{
min_credit_density = MIN(min_credit_density, entry.credit_density());
min_credit_density = std::min(min_credit_density, entry.credit_density());
}
void notify_impending_increase_or_remove(const Entry& entry)

View File

@ -0,0 +1,152 @@
/**
* =========================================================================
* File : code_annotation.h
* Project : 0 A.D.
* Description : macros for code annotation.
* =========================================================================
*/
// license: GPL; see lib/license.txt
#ifndef INCLUDED_CODE_ANNOTATION
#define INCLUDED_CODE_ANNOTATION
/**
* mark a function local variable or parameter as unused and avoid
* the corresponding compiler warning.
* use inside the function body, e.g. void f(int x) { UNUSED2(x); }
**/
#define UNUSED2(param) (void)param;
/**
* mark a function parameter as unused and avoid
* the corresponding compiler warning.
* wrap around the parameter name, e.g. void f(int UNUSED(x))
**/
#define UNUSED(param)
/**
"unreachable code" helpers
unreachable lines of code are often the source or symptom of subtle bugs.
they are flagged by compiler warnings; however, the opposite problem -
erroneously reaching certain spots (e.g. due to missing return statement)
is worse and not detected automatically.
to defend against this, the programmer can annotate their code to
indicate to humans that a particular spot should never be reached.
however, that isn't much help; better is a sentinel that raises an
error if if it is actually reached. hence, the UNREACHABLE macro.
ironically, if the code guarded by UNREACHABLE works as it should,
compilers may flag the macro's code as unreachable. this would
distract from genuine warnings, which is unacceptable.
even worse, compilers differ in their code checking: GCC only complains if
non-void functions end without returning a value (i.e. missing return
statement), while VC checks if lines are unreachable (e.g. if they are
preceded by a return on all paths).
our implementation of UNREACHABLE solves this dilemna as follows:
- on GCC: call abort(); since it has the noreturn attributes, the
"non-void" warning disappears.
- on VC: avoid generating any code. we allow the compiler to assume the
spot is actually unreachable, which incidentally helps optimization.
if reached after all, a crash usually results. in that case, compile with
CONFIG_PARANOIA, which will cause an error message to be displayed.
this approach still allows for the possiblity of automated
checking, but does not cause any compiler warnings.
**/
#define UNREACHABLE // actually defined below.. this is for
# undef UNREACHABLE // CppDoc's benefit only.
// 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 ASSUME_UNREACHABLE
// 2) normal build:
#else
// a) normal implementation: includes "abort", which is declared with
// noreturn attribute and therefore avoids GCC's "execution reaches
// end of non-void function" warning.
# if !MSC_VERSION || CONFIG_PARANOIA
# define UNREACHABLE\
STMT(\
debug_warn("hit supposedly unreachable code");\
abort();\
)
// b) VC only: don't generate any code; squelch the warning and optimize.
# else
# define UNREACHABLE ASSUME_UNREACHABLE
# endif
#endif
/**
convenient specialization of UNREACHABLE for switch statements whose
default can never be reached. example usage:
int x;
switch(x % 2)
{
case 0: break;
case 1: break;
NODEFAULT;
}
**/
#define NODEFAULT default: UNREACHABLE
/**
* equivalent to strcpy, but indicates that the programmer checked usage and
* promises it is safe.
*
* (this macro prevents actually-safe instances of the function from
* showing up in searches)
**/
#define SAFE_STRCPY str##cpy
#define SAFE_WCSCPY wcs##cpy
// generate a symbol containing the line number of the macro invocation.
// used to give a unique name (per file) to types made by cassert.
// we can't prepend __FILE__ to make it globally unique - the filename
// may be enclosed in quotes. PASTE3_HIDDEN__ is needed to make sure
// __LINE__ is expanded correctly.
#define PASTE3_HIDDEN__(a, b, c) a ## b ## c
#define PASTE3__(a, b, c) PASTE3_HIDDEN__(a, b, c)
#define UID__ PASTE3__(LINE_, __LINE__, _)
#define UID2__ PASTE3__(LINE_, __LINE__, _2)
/**
* compile-time debug_assert. causes a compile error if the expression
* evaluates to zero/false.
*
* no runtime overhead; may be used anywhere, including file scope.
* especially useful for testing sizeof types.
*
* this version has a more descriptive error message, but may cause a
* struct redefinition warning if used from the same line in different files.
*
* note: alternative method in C++: specialize a struct only for true;
* using it will raise 'incomplete type' errors if instantiated with false.
*
* @param expression that is expected to evaluate to non-zero at compile-time.
**/
#define cassert(expr) struct UID__ { int CASSERT_FAILURE: (expr); }
/**
* compile-time debug_assert. causes a compile error if the expression
* evaluates to zero/false.
*
* no runtime overhead; may be used anywhere, including file scope.
* especially useful for testing sizeof types.
*
* this version has a less helpful error message, but redefinition doesn't
* trigger warnings.
*
* @param expression that is expected to evaluate to non-zero at compile-time.
**/
#define cassert2(expr) extern char CASSERT_FAILURE[1][(expr)]
#endif // #ifndef INCLUDED_CODE_ANNOTATION

View File

@ -46,7 +46,11 @@
// allow use of RDTSC for raw tick counts (otherwise, the slower but
// more reliable on MP systems wall-clock will be used).
#ifndef CONFIG_TIMER_ALLOW_RDTSC
# if CPU_IA32
# define CONFIG_TIMER_ALLOW_RDTSC 1
# else
# define CONFIG_TIMER_ALLOW_RDTSC 0
# endif
#endif
// this enables/disables the actual checking done by OverrunProtector-s

View File

@ -14,11 +14,11 @@
#include <stdarg.h>
#include <string.h>
#include "lib.h"
#include "app_hooks.h"
#include "path_util.h"
#include "debug_stl.h"
#include "allocators.h"
#include "fnv_hash.h"
#include "lib/posix/posix_pthread.h"
#include "lib/sysdep/cpu.h" // CAS
#include "lib/sysdep/sysdep.h"

View File

@ -11,7 +11,6 @@
#ifndef INCLUDED_DEBUG
#define INCLUDED_DEBUG
#include "lib.h" // STMT
#if OS_WIN
# include "lib/sysdep/win/wdbg.h"
#else

View File

@ -16,7 +16,7 @@
#include <set>
#include <cassert>
#include "lib.h" // match_wildcard
#include "regex.h"
AT_STARTUP(\
@ -251,7 +251,7 @@ class Any_deque : public std::deque<int>
const u8* get_item(size_t i, size_t el_size) const
{
const u8** map = (const u8**)_Map;
const size_t el_per_bucket = MAX(16 / el_size, 1);
const size_t el_per_bucket = std::max(16u / el_size, 1u);
const size_t bucket_idx = i / el_per_bucket;
const size_t idx_in_bucket = i - bucket_idx * el_per_bucket;
const u8* bucket = map[bucket_idx];
@ -266,7 +266,7 @@ public:
#if STL_DINKUMWARE
if(!container_valid(_Map, _Mysize))
return false;
const size_t el_per_bucket = MAX(16 / el_size, 1); // see _DEQUESIZ
const size_t el_per_bucket = std::max(16u / el_size, 1u); // see _DEQUESIZ
// initial element is beyond end of first bucket
if(_Myoff >= el_per_bucket)
return false;

117
source/lib/fnv_hash.cpp Normal file
View File

@ -0,0 +1,117 @@
/**
* =========================================================================
* File : fnv_hash.h
* Project : 0 A.D.
* Description : Fowler/Noll/Vo string hash
* =========================================================================
*/
// license: GPL; see lib/license.txt
#include "precompiled.h"
// FNV1-A hash - good for strings.
// if len = 0 (default), treat buf as a C-string;
// otherwise, hash <len> bytes of buf.
u32 fnv_hash(const void* buf, size_t len)
{
u32 h = 0x811c9dc5u;
// give distinct values for different length 0 buffers.
// value taken from FNV; it has no special significance.
const u8* p = (const u8*)buf;
// expected case: string
if(!len)
{
while(*p)
{
h ^= *p++;
h *= 0x01000193u;
}
}
else
{
size_t bytes_left = len;
while(bytes_left != 0)
{
h ^= *p++;
h *= 0x01000193u;
bytes_left--;
}
}
return h;
}
// FNV1-A hash - good for strings.
// if len = 0 (default), treat buf as a C-string;
// otherwise, hash <len> bytes of buf.
u64 fnv_hash64(const void* buf, size_t len)
{
u64 h = 0xCBF29CE484222325ull;
// give distinct values for different length 0 buffers.
// value taken from FNV; it has no special significance.
const u8* p = (const u8*)buf;
// expected case: string
if(!len)
{
while(*p)
{
h ^= *p++;
h *= 0x100000001B3ull;
}
}
else
{
size_t bytes_left = len;
while(bytes_left != 0)
{
h ^= *p++;
h *= 0x100000001B3ull;
bytes_left--;
}
}
return h;
}
// special version for strings: first converts to lowercase
// (useful for comparing mixed-case filenames).
// note: still need <len>, e.g. to support non-0-terminated strings
u32 fnv_lc_hash(const char* str, size_t len)
{
u32 h = 0x811c9dc5u;
// give distinct values for different length 0 buffers.
// value taken from FNV; it has no special significance.
// expected case: string
if(!len)
{
while(*str)
{
h ^= tolower(*str++);
h *= 0x01000193u;
}
}
else
{
size_t bytes_left = len;
while(bytes_left != 0)
{
h ^= tolower(*str++);
h *= 0x01000193u;
bytes_left--;
}
}
return h;
}

39
source/lib/fnv_hash.h Normal file
View File

@ -0,0 +1,39 @@
/**
* =========================================================================
* File : fnv_hash.h
* Project : 0 A.D.
* Description : Fowler/Noll/Vo string hash
* =========================================================================
*/
// license: GPL; see lib/license.txt
#ifndef INCLUDED_FNV_HASH
#define INCLUDED_FNV_HASH
/**
* rationale: this algorithm was chosen because it delivers 'good' results
* for string data and is relatively simple. other good alternatives exist;
* see Ozan Yigit's hash roundup.
**/
/**
* calculate FNV1-A hash.
*
* @param buf input buffer.
* @param len if 0 (default), treat buf as a C-string; otherwise,
* indicates how many bytes of buffer to hash.
* @return hash result. note: results are distinct for buffers containing
* differing amounts of zero bytes because the hash value is seeded.
**/
extern u32 fnv_hash(const void* buf, size_t len = 0);
/// 64-bit version of fnv_hash.
extern u64 fnv_hash64(const void* buf, size_t len = 0);
/**
* special version of fnv_hash for strings: first converts to lowercase
* (useful for comparing mixed-case filenames)
**/
extern u32 fnv_lc_hash(const char* str, size_t len = 0);
#endif // #ifndef INCLUDED_FNV_HASH

View File

@ -15,7 +15,6 @@
#include <stdio.h>
#include <stdlib.h>
#include "lib.h"
#include "lib/external_libraries/sdl.h"
#include "lib/res/file/file.h"

View File

@ -15,7 +15,6 @@
#include <algorithm>
#include <limits.h>
#include "lib.h"
#include "posix.h"
#include "lib/sysdep/cpu.h"
#include "lockfree.h"
@ -296,7 +295,7 @@ static void* MallocFromActive(ProcHeap* heap)
new_anchor.state = FULL;
else
{
more_credits = MIN(old_anchor.count, MAX_CREDITS);
more_credits = std::min(old_anchor.count, MAX_CREDITS);
new_anchor.count -= more_credits;
}
}
@ -332,7 +331,7 @@ retry:
}
// old_anchor state must be PARTIAL
// old_anchor count must be > 0
more_credits = MIN(old_anchor.count-1, MAX_CREDITS);
more_credits = std::min(old_anchor.count-1, MAX_CREDITS);
new_anchor.count -= more_credits+1;
new_anchor.state = (more_credits > 0)? ACTIVE : FULL;
}
@ -370,7 +369,7 @@ static void* MallocFromNewSB(ProcHeap* heap)
desc->sz = heap->sc->sz;
desc->maxcount = (uint)(heap->sc->sb_size/desc->sz);
Active new_active = (Active)desc;
new_active.credits = MIN(desc->maxcount-1, MAX_CREDITS)-1;
new_active.credits = std::min(desc->maxcount-1, MAX_CREDITS)-1;
desc->anchor.count = (desc->maxcount-1)-(new_active.credits+1);
desc->anchor.state = ACTIVE;
cpu_MemoryFence();

View File

@ -18,131 +18,17 @@
#include "lib/app_hooks.h"
#include "lib/sysdep/sysdep.h"
//-----------------------------------------------------------------------------
// bit bashing
//-----------------------------------------------------------------------------
bool is_pow2(uint n)
{
// 0 would pass the test below but isn't a POT.
if(n == 0)
return false;
return (n & (n-1l)) == 0;
}
// return -1 if not an integral power of 2,
// otherwise the base2 logarithm
int ilog2(uint n)
{
int bit_index; // return value
#if CPU_IA32 && HAVE_MS_ASM
__asm
{
mov ecx, [n]
or eax, -1 // return value if not a POT
test ecx, ecx
jz not_pot
lea edx, [ecx-1]
test ecx, edx
jnz not_pot
bsf eax, ecx
not_pot:
mov [bit_index], eax
}
#else
if(!is_pow2(n))
return -1;
bit_index = 0;
// note: compare against n directly because it is known to be a POT.
for(uint bit_value = 1; bit_value != n; bit_value *= 2)
bit_index++;
#endif
debug_assert(-1 <= bit_index && bit_index < (int)sizeof(int)*CHAR_BIT);
debug_assert(bit_index == -1 || n == (1u << bit_index));
return bit_index;
}
// return log base 2, rounded up.
uint log2(uint x)
{
uint bit = 1;
uint l = 0;
while(bit < x && bit != 0) // must detect overflow
{
l++;
bit += bit;
}
return l;
}
int ilog2(const float x)
{
const u32 i = *(u32*)&x;
u32 biased_exp = (i >> 23) & 0xff;
return (int)biased_exp - 127;
}
// round_up_to_pow2 implementation assumes 32-bit int.
// if 64, add "x |= (x >> 32);"
cassert(sizeof(int)*CHAR_BIT == 32);
uint round_up_to_pow2(uint x)
{
// fold upper bit into lower bits; leaves same MSB set but
// everything below it 1. adding 1 yields next POT.
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
return x+1;
}
//-----------------------------------------------------------------------------
// misc arithmetic
// multiple must be a power of two.
uintptr_t round_up(const uintptr_t n, const uintptr_t multiple)
{
debug_assert(is_pow2((long)multiple));
const uintptr_t result = (n + multiple-1) & ~(multiple-1);
debug_assert(n <= result && result < n+multiple);
return result;
}
// multiple must be a power of two.
uintptr_t round_down(const uintptr_t n, const uintptr_t multiple)
{
debug_assert(is_pow2((long)multiple));
const uintptr_t result = n & ~(multiple-1);
debug_assert(result <= n && n < result+multiple);
return result;
}
u16 addusw(u16 x, u16 y)
{
u32 t = x;
return (u16)MIN(t+y, 0xffffu);
return (u16)std::min(t+y, 0xFFFFu);
}
u16 subusw(u16 x, u16 y)
{
long t = x;
return (u16)(MAX(t-y, 0));
return (u16)(std::max(t-y, 0l));
}
@ -245,49 +131,8 @@ u32 u32_from_u16(u16 hi, u16 lo)
}
// zero-extend <size> (truncated to 8) bytes of little-endian data to u64,
// starting at address <p> (need not be aligned).
u64 movzx_64le(const u8* p, size_t size)
{
size = MIN(size, 8);
u64 data = 0;
for(u64 i = 0; i < size; i++)
data |= ((u64)p[i]) << (i*8);
return data;
}
// sign-extend <size> (truncated to 8) bytes of little-endian data to i64,
// starting at address <p> (need not be aligned).
i64 movsx_64le(const u8* p, size_t size)
{
size = MIN(size, 8);
u64 data = movzx_64le(p, size);
// no point in sign-extending if >= 8 bytes were requested
if(size < 8)
{
u64 sign_bit = 1;
sign_bit <<= (size*8)-1;
// be sure that we don't shift more than variable's bit width
// number would be negative in the smaller type,
// so sign-extend, i.e. set all more significant bits.
if(data & sign_bit)
{
const u64 size_mask = (sign_bit+sign_bit)-1;
data |= ~size_mask;
}
}
return (i64)data;
}
// input in [0, 1); convert to u8 range
u8 fp_to_u8(double in)
u8 u8_from_double(double in)
{
if(!(0.0 <= in && in < 1.0))
{
@ -301,7 +146,7 @@ u8 fp_to_u8(double in)
}
// input in [0, 1); convert to u16 range
u16 fp_to_u16(double in)
u16 u16_from_double(double in)
{
if(!(0.0 <= in && in < 1.0))
{
@ -315,242 +160,6 @@ u16 fp_to_u16(double in)
}
//-----------------------------------------------------------------------------
// string processing
// big endian!
void base32(const size_t in_len, const u8* in, u8* out)
{
u32 pool = 0; // of bits from buffer
uint pool_bits = 0; // # bits currently in buffer
static const u8 tbl[33] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
size_t in_bytes_left = in_len; // to avoid overrunning input buffer
const size_t out_chars = (in_len*8 + 4) / 5; // = ceil(# 5-bit blocks)
for(size_t i = 0; i < out_chars; i++)
{
if(pool_bits < 5 && in_bytes_left)
{
pool <<= 8;
pool |= *in++;
pool_bits += 8;
in_bytes_left--;
}
pool_bits -= 5;
const uint c = (pool >> pool_bits) & 31;
*out++ = tbl[c];
}
*out++ = '\0';
}
int match_wildcard(const char* s, const char* w)
{
if(!w)
return 1;
// saved position in both strings, used to expand '*':
// s2 is advanced until match.
// initially 0 - we abort on mismatch before the first '*'.
const char* s2 = 0;
const char* w2 = 0;
while(*s)
{
const int wc = *w;
if(wc == '*')
{
// wildcard string ended with * => match.
if(*++w == '\0')
return 1;
w2 = w;
s2 = s+1;
}
// match one character
else if(toupper(wc) == toupper(*s) || wc == '?')
{
w++;
s++;
}
// mismatched character
else
{
// no '*' found yet => mismatch.
if(!s2)
return 0;
// resume at previous position+1
w = w2;
s = s2++;
}
}
// strip trailing * in wildcard string
while(*w == '*')
w++;
return (*w == '\0');
}
int match_wildcardw(const wchar_t* s, const wchar_t* w)
{
if(!w)
return 1;
// saved position in both strings, used to expand '*':
// s2 is advanced until match.
// initially 0 - we abort on mismatch before the first '*'.
const wchar_t* s2 = 0;
const wchar_t* w2 = 0;
while(*s)
{
const wchar_t wc = *w;
if(wc == '*')
{
// wildcard string ended with * => match.
if(*++w == '\0')
return 1;
w2 = w;
s2 = s+1;
}
// match one character
else if(towupper(wc) == towupper(*s) || wc == '?')
{
w++;
s++;
}
// mismatched character
else
{
// no '*' found yet => mismatch.
if(!s2)
return 0;
// resume at previous position+1
w = w2;
s = s2++;
}
}
// strip trailing * in wildcard string
while(*w == '*')
w++;
return (*w == '\0');
}
// FNV1-A hash - good for strings.
// if len = 0 (default), treat buf as a C-string;
// otherwise, hash <len> bytes of buf.
u32 fnv_hash(const void* buf, size_t len)
{
u32 h = 0x811c9dc5u;
// give distinct values for different length 0 buffers.
// value taken from FNV; it has no special significance.
const u8* p = (const u8*)buf;
// expected case: string
if(!len)
{
while(*p)
{
h ^= *p++;
h *= 0x01000193u;
}
}
else
{
size_t bytes_left = len;
while(bytes_left != 0)
{
h ^= *p++;
h *= 0x01000193u;
bytes_left--;
}
}
return h;
}
// FNV1-A hash - good for strings.
// if len = 0 (default), treat buf as a C-string;
// otherwise, hash <len> bytes of buf.
u64 fnv_hash64(const void* buf, size_t len)
{
u64 h = 0xCBF29CE484222325ull;
// give distinct values for different length 0 buffers.
// value taken from FNV; it has no special significance.
const u8* p = (const u8*)buf;
// expected case: string
if(!len)
{
while(*p)
{
h ^= *p++;
h *= 0x100000001B3ull;
}
}
else
{
size_t bytes_left = len;
while(bytes_left != 0)
{
h ^= *p++;
h *= 0x100000001B3ull;
bytes_left--;
}
}
return h;
}
// special version for strings: first converts to lowercase
// (useful for comparing mixed-case filenames).
// note: still need <len>, e.g. to support non-0-terminated strings
u32 fnv_lc_hash(const char* str, size_t len)
{
u32 h = 0x811c9dc5u;
// give distinct values for different length 0 buffers.
// value taken from FNV; it has no special significance.
// expected case: string
if(!len)
{
while(*str)
{
h ^= tolower(*str++);
h *= 0x01000193u;
}
}
else
{
size_t bytes_left = len;
while(bytes_left != 0)
{
h ^= tolower(*str++);
h *= 0x01000193u;
bytes_left--;
}
}
return h;
}
//-----------------------------------------------------------------------------
// helpers for module init

View File

@ -49,19 +49,14 @@ scope
#include "config.h"
const size_t KiB = 1ul << 10;
const size_t MiB = 1ul << 20;
const size_t GiB = 1ul << 30;
// generate a symbol containing the line number of the macro invocation.
// used to give a unique name (per file) to types made by cassert.
// we can't prepend __FILE__ to make it globally unique - the filename
// may be enclosed in quotes. PASTE3_HIDDEN__ is needed to make sure
// __LINE__ is expanded correctly.
#define PASTE3_HIDDEN__(a, b, c) a ## b ## c
#define PASTE3__(a, b, c) PASTE3_HIDDEN__(a, b, c)
#define UID__ PASTE3__(LINE_, __LINE__, _)
#define UID2__ PASTE3__(LINE_, __LINE__, _2)
/// number of array elements
#define ARRAY_SIZE(name) (sizeof(name) / sizeof(name[0]))
//-----------------------------------------------------------------------------
@ -85,9 +80,6 @@ const size_t GiB = 1ul << 30;
**/
#define STMT(STMT_code__) do { STMT_code__; } while(false)
// must come after definition of STMT
#include "lib/lib_errors.h"
/**
* execute the code passed as a parameter only the first time this is
* reached.
@ -184,225 +176,6 @@ STMT(\
//-----------------------------------------------------------------------------
// source code annotation
//-----------------------------------------------------------------------------
/**
* mark a function local variable or parameter as unused and avoid
* the corresponding compiler warning.
* use inside the function body, e.g. void f(int x) { UNUSED2(x); }
**/
#define UNUSED2(param) (void)param;
/**
* mark a function parameter as unused and avoid
* the corresponding compiler warning.
* wrap around the parameter name, e.g. void f(int UNUSED(x))
**/
#define UNUSED(param)
/**
"unreachable code" helpers
unreachable lines of code are often the source or symptom of subtle bugs.
they are flagged by compiler warnings; however, the opposite problem -
erroneously reaching certain spots (e.g. due to missing return statement)
is worse and not detected automatically.
to defend against this, the programmer can annotate their code to
indicate to humans that a particular spot should never be reached.
however, that isn't much help; better is a sentinel that raises an
error if if it is actually reached. hence, the UNREACHABLE macro.
ironically, if the code guarded by UNREACHABLE works as it should,
compilers may flag the macro's code as unreachable. this would
distract from genuine warnings, which is unacceptable.
even worse, compilers differ in their code checking: GCC only complains if
non-void functions end without returning a value (i.e. missing return
statement), while VC checks if lines are unreachable (e.g. if they are
preceded by a return on all paths).
our implementation of UNREACHABLE solves this dilemna as follows:
- on GCC: call abort(); since it has the noreturn attributes, the
"non-void" warning disappears.
- on VC: avoid generating any code. we allow the compiler to assume the
spot is actually unreachable, which incidentally helps optimization.
if reached after all, a crash usually results. in that case, compile with
CONFIG_PARANOIA, which will cause an error message to be displayed.
this approach still allows for the possiblity of automated
checking, but does not cause any compiler warnings.
**/
#define UNREACHABLE // actually defined below.. this is for
# undef UNREACHABLE // CppDoc's benefit only.
// 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 ASSUME_UNREACHABLE
// 2) normal build:
#else
// a) normal implementation: includes "abort", which is declared with
// noreturn attribute and therefore avoids GCC's "execution reaches
// end of non-void function" warning.
# if !MSC_VERSION || CONFIG_PARANOIA
# define UNREACHABLE\
STMT(\
debug_warn("hit supposedly unreachable code");\
abort();\
)
// b) VC only: don't generate any code; squelch the warning and optimize.
# else
# define UNREACHABLE ASSUME_UNREACHABLE
# endif
#endif
/**
convenient specialization of UNREACHABLE for switch statements whose
default can never be reached. example usage:
int x;
switch(x % 2)
{
case 0: break;
case 1: break;
NODEFAULT;
}
**/
#define NODEFAULT default: UNREACHABLE
//-----------------------------------------------------------------------------
// cassert
/**
* compile-time debug_assert. causes a compile error if the expression
* evaluates to zero/false.
*
* no runtime overhead; may be used anywhere, including file scope.
* especially useful for testing sizeof types.
*
* this version has a more descriptive error message, but may cause a
* struct redefinition warning if used from the same line in different files.
*
* note: alternative method in C++: specialize a struct only for true;
* using it will raise 'incomplete type' errors if instantiated with false.
*
* @param expression that is expected to evaluate to non-zero at compile-time.
**/
#define cassert(expr) struct UID__ { int CASSERT_FAILURE: (expr); }
/**
* compile-time debug_assert. causes a compile error if the expression
* evaluates to zero/false.
*
* no runtime overhead; may be used anywhere, including file scope.
* especially useful for testing sizeof types.
*
* this version has a less helpful error message, but redefinition doesn't
* trigger warnings.
*
* @param expression that is expected to evaluate to non-zero at compile-time.
**/
#define cassert2(expr) extern char CASSERT_FAILURE[1][(expr)]
//-----------------------------------------------------------------------------
// bit bashing
//-----------------------------------------------------------------------------
/**
* value of bit number <n>.
*
* @param n bit index (0..CHAR_BIT*sizeof(int)-1)
**/
#define BIT(n) (1ul << (n))
// these are declared in the header and inlined to aid compiler optimizations
// (they can easily end up being time-critical).
// note: GCC can't inline extern functions, while VC's "Whole Program
// Optimization" can.
/**
* a mask that includes the lowest N bits
*
* @param num_bits number of bits in mask
**/
inline uint bit_mask(uint num_bits)
{
return (1u << num_bits)-1;
}
/**
* extract the value of bits hi_idx:lo_idx within num
*
* example: bits(0x69, 2, 5) == 0x0A
*
* @param num number whose bits are to be extracted
* @param lo_idx bit index of lowest bit to include
* @param hi_idx bit index of highest bit to include
* @return value of extracted bits.
**/
inline uint bits(uint num, uint lo_idx, uint hi_idx)
{
const uint count = (hi_idx - lo_idx)+1; // # bits to return
uint result = num >> lo_idx;
result &= bit_mask(count);
return result;
}
/// is the given number a power of two?
extern bool is_pow2(uint n);
/**
* base-2 logarithm; return -1 for non-integral powers of 2.
**/
extern int ilog2(uint n);
/**
* base-2 logarithm, rounded up.
*
* @param n input; MUST be > 0, else results are undefined.
**/
extern uint log2(uint x);
/**
* base-2 logarithm (uses the FPU normalization hardware).
*
* @param n input; MUST be > 0, else results are undefined.
**/
extern int ilog2(const float x);
/**
* round up to next larger power of two.
**/
extern uint round_up_to_pow2(uint x);
//-----------------------------------------------------------------------------
// misc arithmetic
/// canonical minimum macro
#ifndef MIN
#define MIN(a, b) (((a) < (b))? (a) : (b))
#endif
/// canonical maximum macro
#ifndef MAX
#define MAX(a, b) (((a) > (b))? (a) : (b))
#endif
/// number of array elements
#define ARRAY_SIZE(name) (sizeof(name) / sizeof(name[0]))
/**
* round number up/down to the next given multiple.
*
* @param multiple: must be a power of two.
**/
extern uintptr_t round_up (uintptr_t n, uintptr_t multiple);
extern uintptr_t round_down(uintptr_t n, uintptr_t multiple);
/// 16-bit saturating (does not overflow) addition.
extern u16 addusw(u16 x, u16 y);
@ -457,87 +230,10 @@ extern u16 u32_lo(u32 x); /// return lower 16-bits
extern u64 u64_from_u32(u32 hi, u32 lo); /// assemble u64 from u32
extern u32 u32_from_u16(u16 hi, u16 lo); /// assemble u32 from u16
/**
* zero-extend <size> (truncated to 8) bytes of little-endian data to u64,
* starting at address <p> (need not be aligned).
**/
extern u64 movzx_64le(const u8* p, size_t size);
/**
* sign-extend <size> (truncated to 8) bytes of little-endian data to i64,
* starting at address <p> (need not be aligned).
**/
extern i64 movsx_64le(const u8* p, size_t size);
/// convert double to u8; verifies number is in range.
extern u8 fp_to_u8 (double in);
extern u8 u8_from_double(double in);
/// convert double to u16; verifies number is in range.
extern u16 fp_to_u16(double in);
//-----------------------------------------------------------------------------
// string processing
/**
* this is strcpy, but indicates that the programmer checked usage and
* promises it is safe.
*
* (this macro prevents actually-safe instances of the function from
* showing up in searches)
**/
#define SAFE_STRCPY str##cpy
#define SAFE_WCSCPY wcs##cpy
/**
* generate the base32 textual representation of a buffer.
*
* @param len size [bytes] of input
* @param big-endian input data (assumed to be integral number of bytes)
* @param output string; zero-terminated. must be big enough
* (i.e. at least ceil(len*CHAR_BIT/5) + 1 chars)
**/
extern void base32(const size_t len, const u8* in, u8* out);
/**
* partial regex implementation: see if string matches pattern.
*
* @param s input string
* @param w pseudo-regex to match against. case-insensitive;
* may contain '?' and/or '*' wildcards. if NULL, matches everything.
*
* @return 1 if they match, otherwise 0.
*
* algorithmfrom http://www.codeproject.com/string/wildcmp.asp.
**/
extern int match_wildcard(const char* s, const char* w);
/// unicode version of match_wildcard.
extern int match_wildcardw(const wchar_t* s, const wchar_t* w);
/**
* calculate FNV1-A hash.
*
* @param buf input buffer.
* @param len if 0 (default), treat buf as a C-string; otherwise,
* indicates how many bytes of buffer to hash.
* @return hash result. note: results are distinct for buffers containing
* differing amounts of zero bytes because the hash value is seeded.
*
* rationale: this algorithm was chosen because it delivers 'good' results
* for string data and is relatively simple. other good alternatives exist;
* see Ozan Yigit's hash roundup.
**/
extern u32 fnv_hash(const void* buf, size_t len = 0);
/// 64-bit version of fnv_hash.
extern u64 fnv_hash64(const void* buf, size_t len = 0);
/**
* special version of fnv_hash for strings: first converts to lowercase
* (useful for comparing mixed-case filenames)
**/
extern u32 fnv_lc_hash(const char* str, size_t len = 0);
extern u16 u16_from_double(double in);
//-----------------------------------------------------------------------------

View File

@ -15,7 +15,7 @@
#include <algorithm>
#include "lib/posix/posix_pthread.h"
#include "lib.h"
#include "lib/bits.h"
#include "lib/sysdep/cpu.h"
#include "lib/sysdep/sysdep.h"
#include "timer.h"

View File

@ -31,7 +31,6 @@ AT_STARTUP(\
#include <stdarg.h>
#include <new>
#include "lib.h"
#include "posix/posix.h"
#include "debug.h"
@ -507,9 +506,9 @@ static void stats_add(const Alloc* a)
stats.total_mem += size;
stats.total_allocs++;
stats.peak_user_mem = MAX(stats.peak_user_mem, stats.cur_user_mem);
stats.peak_mem = MAX(stats.peak_mem, stats.cur_mem);
stats.peak_allocs = MAX(stats.peak_allocs, stats.cur_allocs);
stats.peak_user_mem = std::max(stats.peak_user_mem, stats.cur_user_mem);
stats.peak_mem = std::max(stats.peak_mem, stats.cur_mem);
stats.peak_allocs = std::max(stats.peak_allocs, stats.cur_allocs);
}
static void stats_remove(const Alloc* a)
@ -1212,7 +1211,7 @@ void* realloc_dbg(const void* user_p, size_t user_size, AllocType type, const ch
// old_size should only be non-zero if the Alloc security checks all passed
// If the old buffer was actually zero bytes large, do nothing :P
if (old_size && ret)
cpu_memcpy(ret, user_p, MIN(old_size, user_size));
cpu_memcpy(ret, user_p, std::min(old_size, user_size));
if(user_p)
free_dbg(user_p, AT_FREE, file,line,func, stack_frames+1);

View File

@ -15,7 +15,6 @@
#include <string.h>
#include <stdarg.h>
#include "lib.h"
#include "lib/external_libraries/sdl.h"
#include "debug.h"
#include "lib/sysdep/gfx.h"

View File

@ -14,8 +14,6 @@
#include <string.h>
#include <errno.h>
#include "lib.h"
AT_STARTUP(\
error_setDescription(ERR::PATH_LENGTH, "Path exceeds PATH_MAX characters");\
@ -236,7 +234,7 @@ const char* path_name_only(const char* path)
return path;
// return name, i.e. component after the last portable or platform slash
return MAX(slash1, slash2)+1;
return std::max(slash1, slash2)+1;
}

View File

@ -44,9 +44,11 @@
//
#include "lib/types.h"
#include "lib/lib.h"
#include "lib/lib_errors.h"
#include "lib/string_s.h" // CRT secure string
#include "lib/debug.h"
#include "lib/code_annotation.h"
#include "lib/sysdep/compiler.h"
#include "lib/sysdep/stl.h"
#include "lib/posix/posix.h"

110
source/lib/regex.cpp Normal file
View File

@ -0,0 +1,110 @@
/**
* =========================================================================
* File : regex.cpp
* Project : 0 A.D.
* Description : minimal regex implementation
* =========================================================================
*/
// license: GPL; see lib/license.txt
#include "precompiled.h"
int match_wildcard(const char* s, const char* w)
{
if(!w)
return 1;
// saved position in both strings, used to expand '*':
// s2 is advanced until match.
// initially 0 - we abort on mismatch before the first '*'.
const char* s2 = 0;
const char* w2 = 0;
while(*s)
{
const int wc = *w;
if(wc == '*')
{
// wildcard string ended with * => match.
if(*++w == '\0')
return 1;
w2 = w;
s2 = s+1;
}
// match one character
else if(toupper(wc) == toupper(*s) || wc == '?')
{
w++;
s++;
}
// mismatched character
else
{
// no '*' found yet => mismatch.
if(!s2)
return 0;
// resume at previous position+1
w = w2;
s = s2++;
}
}
// strip trailing * in wildcard string
while(*w == '*')
w++;
return (*w == '\0');
}
int match_wildcardw(const wchar_t* s, const wchar_t* w)
{
if(!w)
return 1;
// saved position in both strings, used to expand '*':
// s2 is advanced until match.
// initially 0 - we abort on mismatch before the first '*'.
const wchar_t* s2 = 0;
const wchar_t* w2 = 0;
while(*s)
{
const wchar_t wc = *w;
if(wc == '*')
{
// wildcard string ended with * => match.
if(*++w == '\0')
return 1;
w2 = w;
s2 = s+1;
}
// match one character
else if(towupper(wc) == towupper(*s) || wc == '?')
{
w++;
s++;
}
// mismatched character
else
{
// no '*' found yet => mismatch.
if(!s2)
return 0;
// resume at previous position+1
w = w2;
s = s2++;
}
}
// strip trailing * in wildcard string
while(*w == '*')
w++;
return (*w == '\0');
}

29
source/lib/regex.h Normal file
View File

@ -0,0 +1,29 @@
/**
* =========================================================================
* File : regex.h
* Project : 0 A.D.
* Description : minimal regex implementation
* =========================================================================
*/
// license: GPL; see lib/license.txt
#ifndef INCLUDED_REGEX
#define INCLUDED_REGEX
/**
* see if string matches pattern.
*
* @param s input string
* @param w pseudo-regex to match against. case-insensitive;
* may contain '?' and/or '*' wildcards. if NULL, matches everything.
*
* @return 1 if they match, otherwise 0.
*
* algorithmfrom http://www.codeproject.com/string/wildcmp.asp.
**/
extern int match_wildcard(const char* s, const char* w);
/// unicode version of match_wildcard.
extern int match_wildcardw(const wchar_t* s, const wchar_t* w);
#endif // #ifndef INCLUDED_REGEX

View File

@ -432,7 +432,7 @@ LibError afile_io_issue(File* f, off_t user_ofs, size_t max_output_size, void* u
// less work for aio) or up to EOF.
const ssize_t left_in_chunk = CHUNK_SIZE - (cofs % CHUNK_SIZE);
const ssize_t left_in_file = af->csize - cofs;
const size_t csize = MIN(left_in_chunk, left_in_file);
const size_t csize = std::min(left_in_chunk, left_in_file);
void* cbuf = mem_alloc(csize, 4*KiB);
if(!cbuf)

View File

@ -11,7 +11,6 @@
#include "precompiled.h"
#include "archive_builder.h"
#include "lib/lib.h"
#include "lib/timer.h"
#include "file_internal.h"

View File

@ -19,7 +19,6 @@
#include "lib/posix/posix_filesystem.h"
#include "lib/posix/posix_aio.h"
#include "lib/posix/posix_mman.h"
#include "lib/lib.h"
#include "lib/adts.h"
#include "lib/sysdep/sysdep.h"
#include "lib/byte_order.h"

View File

@ -16,6 +16,7 @@
#include "lib/posix/posix_mman.h"
#include "lib/allocators.h"
#include "lib/bits.h"
#include "lib/byte_order.h"
#include "lib/cache_adt.h"
#include "file_internal.h"
@ -499,7 +500,7 @@ private:
// except for i=0, which corresponds to size=1.
static uint size_class_of(size_t size_pa)
{
return log2((uint)size_pa);
return ceil_log2((uint)size_pa);
}
// value of LSB 1-bit.

View File

@ -14,7 +14,7 @@
#include <deque>
#include "lib/posix/posix_aio.h"
#include "lib/lib.h"
#include "lib/bits.h"
#include "lib/allocators.h"
#include "lib/adts.h"
#include "file_internal.h"
@ -434,7 +434,7 @@ class IOManager
const off_t bytes_left = f->size - start_ofs;
if(bytes_left < 0)
WARN_RETURN(ERR::IO_EOF);
size = MIN(size, (size_t)bytes_left);
size = std::min(size, (size_t)bytes_left);
// and round back up to sector size.
// see rationale in file_io_issue.
@ -450,7 +450,7 @@ class IOManager
{
const off_t ofs = start_ofs+(off_t)total_issued;
// for both reads and writes, do not issue beyond end of file/data
const size_t issue_size = MIN(FILE_BLOCK_SIZE, size - total_issued);
const size_t issue_size = std::min(FILE_BLOCK_SIZE, size - total_issued);
// try to grab whole blocks (so we can put them in the cache).
// any excess data (can only be within first or last) is
// discarded in wait().

View File

@ -119,7 +119,7 @@ void stats_unique_name(size_t name_len)
void stats_open(const char* atom_fn, size_t file_size)
{
open_files_cur++;
open_files_max = MAX(open_files_max, open_files_cur);
open_files_max = std::max(open_files_max, open_files_cur);
PairIB ret = opened_files.insert(atom_fn);
// hadn't been opened yet
@ -141,7 +141,7 @@ void stats_close()
void stats_buf_alloc(size_t user_size, size_t padded_size)
{
extant_bufs_cur++;
extant_bufs_max = MAX(extant_bufs_max, extant_bufs_cur);
extant_bufs_max = std::max(extant_bufs_max, extant_bufs_cur);
extant_bufs_total++;
buf_user_size_total += user_size;

View File

@ -12,6 +12,7 @@
#include <queue>
#include "lib/regex.h"
#include "file_internal.h"
@ -285,7 +286,7 @@ void next_numbered_filename(const char* fn_fmt,
while(vfs_dir_next_ent(hd, &ent, 0) == INFO::OK)
{
if(!DIRENT_IS_DIR(&ent) && sscanf(ent.name, name_fmt, &num) == 1)
max_num = MAX(num, max_num);
max_num = std::max(num, max_num);
}
(void)vfs_dir_close(hd);
}
@ -297,7 +298,7 @@ void next_numbered_filename(const char* fn_fmt,
{
while(dir_next_ent(&it, &ent) == INFO::OK)
if(!DIRENT_IS_DIR(&ent) && sscanf(ent.name, name_fmt, &num) == 1)
max_num = MAX(num, max_num);
max_num = std::max(num, max_num);
(void)dir_close(&it);
}
}

View File

@ -14,7 +14,6 @@
#include <string.h>
#include "lib/posix/posix_filesystem.h"
#include "lib/lib.h"
#include "lib/adts.h"
#include "lib/allocators.h"
#include "lib/sysdep/sysdep.h"

View File

@ -11,8 +11,6 @@
#ifndef INCLUDED_PATH
#define INCLUDED_PATH
#include "lib/lib.h"
namespace ERR
{

View File

@ -1,5 +1,6 @@
#include "lib/self_test.h"
#include "lib/base32.h"
#include "lib/res/file/path.h"
#include "lib/res/file/file.h"
#include "lib/res/file/file_cache.h"

View File

@ -1,6 +1,5 @@
#include "lib/self_test.h"
#include "lib/lib.h"
#include "lib/self_test.h"
#include "lib/res/file/compression.h"

View File

@ -1,6 +1,5 @@
#include "lib/self_test.h"
#include "lib/lib.h"
#include "lib/res/file/file_cache.h"
class TestFileCache : public CxxTest::TestSuite

View File

@ -1,6 +1,5 @@
#include "lib/self_test.h"
#include "lib/lib.h"
#include "lib/self_test.h"
#include "lib/res/file/path.h"
#include "lib/res/file/file.h"

View File

@ -2,7 +2,6 @@
#include <time.h>
#include "lib/lib.h"
#include "lib/res/file/zip.h"
class TestZip : public CxxTest::TestSuite

View File

@ -21,7 +21,6 @@
#include <string>
#include <algorithm>
#include "lib/lib.h"
#include "lib/adts.h"
#include "lib/timer.h"
#include "lib/res/res.h"

View File

@ -498,7 +498,7 @@ static bool should_rebuild_main_archive(const char* trace_filename,
// note: a loop is more convenient than std::for_each, which would
// require referencing the returned functor (since param is a copy).
for(DirEnts::const_iterator it = existing_archives.begin(); it != existing_archives.end(); ++it)
most_recent_archive_mtime = MAX(it->mtime, most_recent_archive_mtime);
most_recent_archive_mtime = std::max(it->mtime, most_recent_archive_mtime);
// .. no archive yet OR 'lots' of them: rebuild so that they'll be
// merged into one archive and the rest deleted.
if(existing_archives.empty() || existing_archives.size() >= 4)

View File

@ -56,7 +56,7 @@ static void* node_alloc();
static time_t most_recent_mtime;
static void set_most_recent_if_newer(time_t mtime)
{
most_recent_mtime = MAX(most_recent_mtime, mtime);
most_recent_mtime = std::max(most_recent_mtime, mtime);
}
time_t tree_most_recent_mtime()
{
@ -316,7 +316,7 @@ static Pool node_pool;
static inline void node_init()
{
const size_t el_size = MAX(sizeof(TDir), sizeof(TFile));
const size_t el_size = std::max(sizeof(TDir), sizeof(TFile));
(void)pool_create(&node_pool, VFS_MAX_FILES*el_size, el_size);
}

View File

@ -14,7 +14,7 @@
#include <time.h>
#include <limits>
#include "lib/lib.h"
#include "lib/bits.h"
#include "lib/byte_order.h"
#include "lib/allocators.h"
#include "lib/timer.h"
@ -361,7 +361,7 @@ static LibError za_find_ecdr(File* f, size_t max_scan_amount, ECDR* dst_ecdr_le)
{
// don't scan more than the entire file
const size_t file_size = f->size;
const size_t scan_amount = MIN(max_scan_amount, file_size);
const size_t scan_amount = std::min(max_scan_amount, file_size);
// read desired chunk of file into memory
const off_t ofs = (off_t)(file_size - scan_amount);

View File

@ -9,7 +9,6 @@
#include "precompiled.h"
#include "ogl_shader.h"
#include "lib/lib.h"
#include "lib/res/res.h"
#include "lib/ogl.h"

View File

@ -12,9 +12,9 @@
#include "precompiled.h"
#include "ogl_tex.h"
#include "lib/lib.h"
#include "lib/app_hooks.h"
#include "lib/ogl.h"
#include "lib/bits.h"
#include "lib/sysdep/gfx.h"
#include "lib/res/res.h"
#include "tex.h"
@ -741,7 +741,7 @@ static LibError get_mipmaps(Tex* t, GLint filter, uint q_flags, int* plevels_to_
// require uploading unused levels, which is wasteful.
// .. can be expanded to reduce to 1/4, 1/8 by encoding factor in q_flags.
const uint reduce = (q_flags & OGL_TEX_HALF_RES)? 2 : 1;
*plevels_to_skip = log2(reduce);
*plevels_to_skip = ceil_log2(reduce);
}
return INFO::OK;

View File

@ -15,8 +15,8 @@
#include <stdlib.h>
#include <algorithm>
#include "lib/lib.h"
#include "lib/timer.h"
#include "lib/bits.h"
#include "lib/res/res.h"
#include "tex_codec.h"
@ -192,7 +192,7 @@ static void create_level(uint level, uint level_w, uint level_h,
// image is either a horizontal or vertical line.
// their memory layout is the same (packed pixels), so no special
// handling is needed; just pick max dimension.
for(uint y = 0; y < MAX(src_w, src_h); y += 2)
for(uint y = 0; y < std::max(src_w, src_h); y += 2)
{
for(uint i = 0; i < num_components; i++)
{

View File

@ -12,6 +12,7 @@
#include "lib/byte_order.h"
#include "tex_codec.h"
#include "lib/bits.h"
// NOTE: the convention is bottom-up for DDS, but there's no way to tell.
@ -549,7 +550,7 @@ static LibError decode_sd(const DDSURFACEDESC2* sd, uint* w_, uint* h_,
{
// mipmap chain is incomplete
// note: DDS includes the base level in its count, hence +1.
if(mipmap_count != log2(MAX(w,h))+1)
if(mipmap_count != ceil_log2(std::max(w,h))+1)
WARN_RETURN(ERR::TEX_FMT_INVALID);
flags |= TEX_MIPMAPS;
}

View File

@ -16,7 +16,6 @@ extern "C" {
#include <jerror.h>
}
#include "lib/lib.h"
#include "lib/res/res.h"
#include "tex_codec.h"
#include <setjmp.h>

View File

@ -12,7 +12,7 @@
#include "lib/byte_order.h"
#include "tex_codec.h"
#include "lib/bits.h"
#pragma pack(push, 1)

View File

@ -14,7 +14,6 @@
#include <sstream>
#include <map>
#include "lib/lib.h"
#include "lib/ogl.h"
#include "lib/res/res.h"
#include "ogl_tex.h"

View File

@ -16,7 +16,7 @@
#include <stdlib.h>
#include <new> // std::bad_alloc
#include "lib/lib.h"
#include "lib/fnv_hash.h"
#include "lib/allocators.h"

View File

@ -232,8 +232,6 @@ we could switch H_DEREF to throwing an exception on error.
#include <stdarg.h> // type init routines get va_list of args
#include "lib/lib.h"
#ifndef INCLUDED_HANDLE
#include "handle.h"
#endif

View File

@ -16,7 +16,7 @@
#include <map>
#include "lib/posix/posix_pthread.h"
#include "lib/lib.h"
#include "lib/bits.h"
#include "lib/allocators.h" // OverrunProtector
#include "h_mgr.h"

View File

@ -2376,7 +2376,7 @@ static LibError vm_update()
// partition list; the first al_src_cap will be granted a source
// (if they don't have one already), after reclaiming all sources from
// the remainder of the VSrc list entries.
uint first_unimportant = MIN((uint)vsrcs.size(), al_src_cap);
uint first_unimportant = std::min((uint)vsrcs.size(), al_src_cap);
list_foreach(reclaim, first_unimportant, 0);
list_foreach(grant, 0, first_unimportant);

View File

@ -27,9 +27,9 @@ Guidelines
What makes a good self-test?
- They belong in the module being tested to ensure they are kept in
sync with it.
- It is easiest to attach them to low-level functions, e.g. ilog2, rather
than verifying the module's final result (e.g. checking renderer output by
comparing pictures).
- It is easiest to attach them to low-level functions, e.g. log2_of_pow2,
rather than verifying the module's final result (e.g. checking renderer
output by comparing pictures).
- You should cover all cases: expected failures ("does it fail as expected?"),
bad inputs ("does it reject those?"), and successes ("did it have the
expected result?").

View File

@ -14,7 +14,6 @@
#include <string.h>
#include <errno.h>
#include "lib.h"
#include "posix/posix_types.h" // SIZE_MAX
// we were included from wstring_s.cpp; skip all stuff that
@ -127,7 +126,7 @@ int tncpy_s(tchar* dst, size_t max_dst_chars, const tchar* src, size_t max_src_c
// optimized for size (less comparisons than MS impl) and
// speed (due to well-predicted jumps; we don't bother unrolling).
tchar* p = dst;
size_t chars_left = MIN(max_dst_chars, max_src_chars);
size_t chars_left = std::min(max_dst_chars, max_src_chars);
while(chars_left != 0)
{
// success: reached end of string normally.

View File

@ -11,7 +11,7 @@
#include "precompiled.h"
#include "cpu.h"
#include "lib/lib.h"
#include "lib/bits.h"
#include "lib/posix/posix.h"
#if CPU_IA32
# include "lib/sysdep/ia32/ia32.h"

View File

@ -11,7 +11,6 @@
#include "precompiled.h"
#include "gfx.h"
#include "lib/lib.h"
#include "lib/external_libraries/sdl.h"

View File

@ -17,7 +17,7 @@
#include <algorithm>
#include "lib/posix/posix_pthread.h"
#include "lib/lib.h"
#include "lib/bits.h"
#include "lib/timer.h"
#include "lib/sysdep/cpu.h"
@ -456,7 +456,7 @@ static void StoreApicId(void* param)
// 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); // (rounded up)
const uint id_bits = ceil_log2(num_values);
if(id_bits == 0)
return;

View File

@ -297,6 +297,21 @@ sym(ia32_asm_rdtsc_edx_eax):
ret
; extern "C" int ia32_asm_log2_of_pow2(uint n)
global sym(ia32_asm_log2_of_pow2)
sym(ia32_asm_log2_of_pow2):
mov ecx, [esp+4] ; n
or eax, -1 ; return value if not a POT
test ecx, ecx
jz .not_pot
lea edx, [ecx-1]
test ecx, edx
jnz .not_pot
bsf eax, ecx
.not_pot:
ret
; write the current execution state (e.g. all register values) into
; (Win32::CONTEXT*)pcontext (defined as void* to avoid dependency).
; optimized for size; this must be straight asm because ; extern "C"

View File

@ -76,6 +76,14 @@ extern float ia32_asm_fminf(float, float);
extern float ia32_asm_fmaxf(float, float);
// misc
/**
* @return the (integral) base 2 logarithm, or -1 if the number
* is not a power-of-two.
**/
extern int ia32_asm_log2_of_pow2(uint n);
#ifdef __cplusplus
}
#endif

View File

@ -11,7 +11,6 @@
#include "precompiled.h"
#include "snd.h"
#include "lib/lib.h"
char snd_card[SND_CARD_LEN];
char snd_drv_ver[SND_DRV_VER_LEN];

View File

@ -1,4 +1,3 @@
#include "lib/lib.h"
#include "lib/self_test.h"
#include "lib/sysdep/sysdep.h"

View File

@ -3,7 +3,6 @@
#include <map>
#include <string>
#include "lib/lib.h"
#include "lib/res/file/file.h"
#include "lib/sysdep/sysdep.h"
#include "ps/CLogger.h"

View File

@ -1,6 +1,5 @@
#include "precompiled.h"
#include "lib/lib.h"
#include "lib/timer.h"
#include "lib/sysdep/sysdep.h"
#include "lib/debug.h"

View File

@ -5,7 +5,6 @@
#include <wchar.h>
#include "lib/sdl.h"
#include "lib/lib.h"
#include "lib/sysdep/sysdep.h"
#include "udbg.h"

View File

@ -10,7 +10,6 @@
#include <stdlib.h>
#include <Xatom.h>
#include "lib/lib.h"
#include "lib/debug.h"
#include "lib/sysdep/gfx.h"
#include "SDL/SDL.h"

View File

@ -1,6 +1,5 @@
#include "lib/self_test.h"
#include "lib/lib.h"
#include "lib/sysdep/ia32/ia32.h"
// note: ia32_i??_from_*, ia32_rint*, ia32_fm??f are all tested within

View File

@ -11,7 +11,6 @@
#include "precompiled.h"
#include "wcpu.h"
#include "lib/lib.h"
#include "lib/posix/posix_pthread.h"
#include "lib/posix/posix_time.h"
#include "win.h"

View File

@ -15,7 +15,7 @@
#include <stdio.h>
#include <typeinfo>
#include "lib/lib.h"
#include "lib/bits.h"
#include "lib/posix/posix_pthread.h"
#include "lib/byte_order.h" // FOURCC
#include "lib/app_hooks.h"
@ -802,3 +802,4 @@ bool debug_is_stack_ptr(void* p)

View File

@ -15,7 +15,7 @@
#include <stdio.h>
#include <set>
#include "lib/lib.h"
#include "lib/byte_order.h"
#include "lib/sysdep/cpu.h"
#include "lib/debug_stl.h"
@ -141,10 +141,10 @@ struct TI_FINDCHILDREN_PARAMS2
TI_FINDCHILDREN_PARAMS2(DWORD num_children)
{
p.Start = 0;
p.Count = MIN(num_children, MAX_CHILDREN);
p.Count = std::min(num_children, MAX_CHILDREN);
}
static const size_t MAX_CHILDREN = 400;
static const DWORD MAX_CHILDREN = 400;
TI_FINDCHILDREN_PARAMS p;
DWORD additional_children[MAX_CHILDREN-1];
};
@ -787,17 +787,17 @@ static void seq_determine_formatting(size_t el_size, size_t el_count,
if(el_size == sizeof(char))
{
*fits_on_one_line = el_count <= 16;
*num_elements_to_show = MIN(16, el_count);
*num_elements_to_show = std::min(16u, el_count);
}
else if(el_size <= sizeof(int))
{
*fits_on_one_line = el_count <= 8;
*num_elements_to_show = MIN(12, el_count);
*num_elements_to_show = std::min(12u, el_count);
}
else
{
*fits_on_one_line = false;
*num_elements_to_show = MIN(8, el_count);
*num_elements_to_show = std::min(8u, el_count);
}
// make sure empty containers are displayed with [0] {}, otherwise
@ -1035,7 +1035,7 @@ static LibError dump_sym_base_type(DWORD type_id, const u8* p, DumpState state)
// must be declared before goto to avoid W4 warning.
const wchar_t* fmt = L"";
u64 data = movzx_64le(p, size);
u64 data = movzx_le64(p, size);
// if value is 0xCC..CC (uninitialized mem), we display as hex.
// the output would otherwise be garbage; this makes it obvious.
// note: be very careful to correctly handle size=0 (e.g. void*).
@ -1074,7 +1074,7 @@ static LibError dump_sym_base_type(DWORD type_id, const u8* p, DumpState state)
if(size != 1 && size != 2 && size != 4 && size != 8)
debug_warn("dump_sym_base_type: invalid int size");
// need to re-load and sign-extend, because we output 64 bits.
data = movsx_64le(p, size);
data = movsx_le64(p, size);
fmt = L"%I64d";
break;
@ -1223,7 +1223,7 @@ static LibError dump_sym_enum(DWORD type_id, const u8* p, DumpState UNUSED(state
WARN_RETURN(ERR::SYM_TYPE_INFO_UNAVAILABLE);
const size_t size = (size_t)size_;
const i64 enum_value = movsx_64le(p, size);
const i64 enum_value = movsx_le64(p, size);
// get array of child symbols (enumerants).
DWORD num_children;
@ -1337,7 +1337,7 @@ static LibError dump_sym_pointer(DWORD type_id, const u8* p, DumpState state)
const size_t size = (size_t)size_;
// read+output pointer's value.
p = (const u8*)movzx_64le(p, size);
p = (const u8*)movzx_le64(p, size);
out(L"0x%p", p);
// bail if it's obvious the pointer is bogus

View File

@ -15,7 +15,6 @@
#include <map>
#include <list>
#include "lib/lib.h"
#include "lib/path_util.h"
#include "lib/res/file/file.h" // path_is_subpath
#include "win.h"

View File

@ -18,6 +18,7 @@
#include "wfilesystem.h" // mode_t
#include "wtime.h" // timespec
#include "lib/sysdep/cpu.h"
#include "lib/bits.h"
#pragma SECTION_PRE_LIBC(J)
@ -56,9 +57,9 @@ WIN_REGISTER_FUNC(waio_shutdown);
size_t sys_max_sector_size()
{
// users may call us more than once, so cache the results.
static size_t cached_sector_size;
static DWORD cached_sector_size;
if(cached_sector_size)
return cached_sector_size;
return static_cast<size_t>(cached_sector_size);
// currently disabled: DVDs have 2..4KB, but this causes
// waio to unnecessarily align some file transfers (when at EOF)
@ -88,7 +89,7 @@ size_t sys_max_sector_size()
DWORD spc, nfc, tnc; // don't need these
DWORD cur_sector_size;
if(GetDiskFreeSpace(drive_str, &spc, &cur_sector_size, &nfc, &tnc))
cached_sector_size = MAX(cached_sector_size, cur_sector_size);
cached_sector_size = std::max(cached_sector_size, cur_sector_size);
// otherwise, it's probably an empty CD drive. ignore the
// BoundsChecker error; GetDiskFreeSpace seems to be the
// only way of getting at the sector size.

View File

@ -13,6 +13,7 @@
#include "wposix_internal.h"
#include "crt_posix.h" // _getcwd
#include "lib/bits.h"
long sysconf(int name)

View File

@ -1,7 +1,6 @@
#ifndef INCLUDED_WPOSIX_INTERNAL
#define INCLUDED_WPOSIX_INTERNAL
#include "lib/lib.h"
#include "lib/sysdep/win/win.h"
#include "lib/sysdep/win/winit.h"
#include "lib/sysdep/win/wutil.h"

View File

@ -215,11 +215,11 @@ IMP(ssize_t, recvfrom, (int, void*, size_t, int, struct sockaddr*, socklen_t*))
// WSAAsyncSelect event bits
// (values taken from winsock2.h - do not change!)
#define FD_READ BIT(0)
#define FD_WRITE BIT(1)
#define FD_ACCEPT BIT(3)
#define FD_CONNECT BIT(4)
#define FD_CLOSE BIT(5)
#define FD_READ 0x01
#define FD_WRITE 0x02
#define FD_ACCEPT 0x08
#define FD_CONNECT 0x10
#define FD_CLOSE 0x20
#undef IMP

View File

@ -22,7 +22,6 @@
#include <WindowsX.h> // message crackers
#include "lib/posix/posix_pthread.h"
#include "lib/lib.h"
#include "lib/ogl.h" // needed to pull in the delay-loaded opengl32.dll
#include "winit.h"
#include "wutil.h"
@ -100,7 +99,7 @@ static LibError calc_gamma_ramp(float gamma, u16* ramp)
// don't add 1/256 - this isn't time-critical and
// accuracy is more important.
// need a temp variable to disambiguate pow() argument type.
ramp[i] = fp_to_u16(pow(frac, inv_gamma));
ramp[i] = u16_from_double(pow(frac, inv_gamma));
}
return INFO::OK;
@ -924,7 +923,7 @@ static LRESULT OnMouseButton(HWND UNUSED(hWnd), UINT uMsg, int screen_x, int scr
// false due to its window-on-top check, so we better not
// ignore messages based on that. it is safest to clamp coords to
// what the app can handle.
uint x = MAX(client_x, 0), y = MAX(client_y, 0);
uint x = std::max(client_x, 0), y = std::max(client_y, 0);
queue_button_event(button, state, x, y);
return 0;
}

View File

@ -14,7 +14,6 @@
#include "win.h" // includes windows.h; must come before shlobj
#include <shlobj.h> // pick_dir
#include "lib/lib.h"
#include "error_dialog.h"
#include "wutil.h"
@ -609,3 +608,4 @@ LibError sys_pick_directory(char* path, size_t buf_size)

View File

@ -0,0 +1,17 @@
#include "lib/self_test.h"
#include "lib/base32.h"
class TestLib : public CxxTest::TestSuite
{
public:
void test_base32()
{
// compare against previous output (generated via this base32() call)
const u8 in[] = { 0x12, 0x57, 0x85, 0xA2, 0xF9, 0x41, 0xCD, 0x57, 0xF3 };
u8 out[20] = {0};
base32(ARRAY_SIZE(in), in, out);
const u8 correct_out[] = "CJLYLIXZIHGVP4C";
TS_ASSERT_SAME_DATA(out, correct_out, ARRAY_SIZE(correct_out));
}
};

View File

@ -0,0 +1,74 @@
#include "lib/self_test.h"
#include "lib/bits.h"
class TestLib : public CxxTest::TestSuite
{
public:
void test_is_pow2()
{
TS_ASSERT_EQUALS(is_pow2(0u), false);
TS_ASSERT_EQUALS(is_pow2(~0u), false);
TS_ASSERT_EQUALS(is_pow2(0x80000001), false);
TS_ASSERT_EQUALS(is_pow2(1), true);
TS_ASSERT_EQUALS(is_pow2(1u << 31), true);
}
void test_log2_of_pow2()
{
TS_ASSERT_EQUALS(log2_of_pow2(0u), -1);
TS_ASSERT_EQUALS(log2_of_pow2(3u), -1);
TS_ASSERT_EQUALS(log2_of_pow2(0xffffffffu), -1);
TS_ASSERT_EQUALS(log2_of_pow2(1u), 0);
TS_ASSERT_EQUALS(log2_of_pow2(256u), 8);
TS_ASSERT_EQUALS(log2_of_pow2(0x80000000u), 31);
}
void test_ceil_log2()
{
TS_ASSERT_EQUALS(ceil_log2(3u), 2u);
TS_ASSERT_EQUALS(ceil_log2(0xffffffffu), 32u);
TS_ASSERT_EQUALS(ceil_log2(1u), 0u);
TS_ASSERT_EQUALS(ceil_log2(256u), 8u);
TS_ASSERT_EQUALS(ceil_log2(0x80000000u), 31u);
}
void test_ilog2f()
{
TS_ASSERT_EQUALS(ilog2(1.f), 0);
TS_ASSERT_EQUALS(ilog2(3.f), 1);
TS_ASSERT_EQUALS(ilog2(256.f), 8);
}
void test_round_up_to_pow2()
{
TS_ASSERT_EQUALS(round_up_to_pow2(0u), 1u);
TS_ASSERT_EQUALS(round_up_to_pow2(1u), 2u);
TS_ASSERT_EQUALS(round_up_to_pow2(127u), 128u);
TS_ASSERT_EQUALS(round_up_to_pow2(128u), 256u);
TS_ASSERT_EQUALS(round_up_to_pow2(129u), 256u);
}
void test_round_up()
{
TS_ASSERT_EQUALS(round_up( 0u, 16u), 0u);
TS_ASSERT_EQUALS(round_up( 4u, 16u), 16u);
TS_ASSERT_EQUALS(round_up(15u, 16u), 16u);
TS_ASSERT_EQUALS(round_up(20u, 32u), 32u);
TS_ASSERT_EQUALS(round_up(29u, 32u), 32u);
TS_ASSERT_EQUALS(round_up(0x1000u, 0x1000u), 0x1000u);
TS_ASSERT_EQUALS(round_up(0x1001u, 0x1000u), 0x2000u);
TS_ASSERT_EQUALS(round_up(0x1900u, 0x1000u), 0x2000u);
}
void test_round_down()
{
TS_ASSERT_EQUALS(round_down( 0u, 16u), 0u);
TS_ASSERT_EQUALS(round_down( 4u, 16u), 0u);
TS_ASSERT_EQUALS(round_down(15u, 16u), 0u);
TS_ASSERT_EQUALS(round_down(20u, 16u), 16u);
TS_ASSERT_EQUALS(round_down(29u, 16u), 16u);
TS_ASSERT_EQUALS(round_down(0x1900u, 0x1000u), 0x1000u);
TS_ASSERT_EQUALS(round_down(0x2001u, 0x2000u), 0x2000u);
}
};

View File

@ -37,4 +37,39 @@ public:
// note: no need to test read_?e* / write_?e* - they are
// trivial wrappers on top of to_?e*.
}
void test_movzx()
{
const u8 d1[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
const u8 d2[] = { 0x43, 0x12, 0x23, 0xA4 };
TS_ASSERT_EQUALS(movzx_le64(d1, 1), 0x01ull);
TS_ASSERT_EQUALS(movzx_le64(d1, 2), 0x0201ull);
TS_ASSERT_EQUALS(movzx_le64(d1, 8), 0x0807060504030201ull);
TS_ASSERT_EQUALS(movzx_le64(d2, 4), 0xA4231243ull);
TS_ASSERT_EQUALS(movzx_le64(d2+3, 1), 0xA4ull);
TS_ASSERT_EQUALS(movzx_be64(d1, 1), 0x01ull);
TS_ASSERT_EQUALS(movzx_be64(d1, 2), 0x0102ull);
TS_ASSERT_EQUALS(movzx_be64(d1, 8), 0x0102030405060708ull);
TS_ASSERT_EQUALS(movzx_be64(d2, 4), 0x431223A4ull);
TS_ASSERT_EQUALS(movzx_be64(d2+3, 1), 0xA4ull);
}
void test_movsx()
{
const u8 d1[] = { 0x09, 0xFE };
const u8 d2[] = { 0xD9, 0x2C, 0xDD, 0x8F };
const u8 d3[] = { 0x92, 0x26, 0x88, 0xF1, 0x35, 0xAC, 0x01, 0x83 };
TS_ASSERT_EQUALS(movsx_le64(d1, 1), 0x09ull);
TS_ASSERT_EQUALS(movsx_le64(d1, 2), 0xFFFFFFFFFFFFFE09ull);
TS_ASSERT_EQUALS(movsx_le64(d2, 4), 0xFFFFFFFF8FDD2CD9ull);
TS_ASSERT_EQUALS(movsx_le64(d3, 8), 0x8301AC35F1882692ull);
TS_ASSERT_EQUALS(movsx_be64(d1, 1), 0x09ull);
TS_ASSERT_EQUALS(movsx_be64(d1, 2), 0x00000000000009FEull);
TS_ASSERT_EQUALS(movsx_be64(d2, 4), 0xFFFFFFFFD92CDD8Full);
TS_ASSERT_EQUALS(movsx_be64(d3, 8), 0x922688F135AC0183ull);
}
};

View File

@ -0,0 +1,21 @@
#include "lib/self_test.h"
#include "lib/fnv_hash.h"
class TestLib : public CxxTest::TestSuite
{
public:
void test_fnv_hash()
{
TS_ASSERT_EQUALS(fnv_hash(""), 0x811C9DC5u); // verify initial value
const u32 h1 = fnv_hash("abcdef");
TS_ASSERT_EQUALS(h1, 0xFF478A2A); // verify value for simple string
TS_ASSERT_EQUALS(fnv_hash ("abcdef", 6), h1); // same result if hashing buffer
TS_ASSERT_EQUALS(fnv_lc_hash("ABcDeF", 6), h1); // same result if case differs
TS_ASSERT_EQUALS(fnv_hash64(""), 0xCBF29CE484222325ull); // verify initial value
const u64 h2 = fnv_hash64("abcdef");
TS_ASSERT_EQUALS(h2, 0xD80BDA3FBE244A0Aull); // verify value for simple string
TS_ASSERT_EQUALS(fnv_hash64("abcdef", 6), h2); // same result if hashing buffer
}
};

View File

@ -5,87 +5,6 @@
class TestLib : public CxxTest::TestSuite
{
public:
void test_fnv_hash()
{
TS_ASSERT_EQUALS(fnv_hash(""), 0x811C9DC5u); // verify initial value
const u32 h1 = fnv_hash("abcdef");
TS_ASSERT_EQUALS(h1, 0xFF478A2A); // verify value for simple string
TS_ASSERT_EQUALS(fnv_hash ("abcdef", 6), h1); // same result if hashing buffer
TS_ASSERT_EQUALS(fnv_lc_hash("ABcDeF", 6), h1); // same result if case differs
TS_ASSERT_EQUALS(fnv_hash64(""), 0xCBF29CE484222325ull); // verify initial value
const u64 h2 = fnv_hash64("abcdef");
TS_ASSERT_EQUALS(h2, 0xD80BDA3FBE244A0Aull); // verify value for simple string
TS_ASSERT_EQUALS(fnv_hash64("abcdef", 6), h2); // same result if hashing buffer
}
void test_is_pow2()
{
TS_ASSERT_EQUALS(is_pow2(0u), false);
TS_ASSERT_EQUALS(is_pow2(~0u), false);
TS_ASSERT_EQUALS(is_pow2(0x80000001), false);
TS_ASSERT_EQUALS(is_pow2(1), true);
TS_ASSERT_EQUALS(is_pow2(1u << 31), true);
}
void test_ilog2()
{
TS_ASSERT_EQUALS(ilog2(0u), -1);
TS_ASSERT_EQUALS(ilog2(3u), -1);
TS_ASSERT_EQUALS(ilog2(0xffffffffu), -1);
TS_ASSERT_EQUALS(ilog2(1u), 0);
TS_ASSERT_EQUALS(ilog2(256u), 8);
TS_ASSERT_EQUALS(ilog2(0x80000000u), 31);
}
void test_log2()
{
TS_ASSERT_EQUALS(log2(3u), 2u);
TS_ASSERT_EQUALS(log2(0xffffffffu), 32u);
TS_ASSERT_EQUALS(log2(1u), 0u);
TS_ASSERT_EQUALS(log2(256u), 8u);
TS_ASSERT_EQUALS(log2(0x80000000u), 31u);
}
void test_ilog2f()
{
TS_ASSERT_EQUALS(ilog2(1.f), 0);
TS_ASSERT_EQUALS(ilog2(3.f), 1);
TS_ASSERT_EQUALS(ilog2(256.f), 8);
}
void test_round_next_pow2()
{
TS_ASSERT_EQUALS(round_up_to_pow2(0u), 1u);
TS_ASSERT_EQUALS(round_up_to_pow2(1u), 2u);
TS_ASSERT_EQUALS(round_up_to_pow2(127u), 128u);
TS_ASSERT_EQUALS(round_up_to_pow2(128u), 256u);
TS_ASSERT_EQUALS(round_up_to_pow2(129u), 256u);
}
void test_round_up()
{
TS_ASSERT_EQUALS(round_up( 0u, 16u), 0u);
TS_ASSERT_EQUALS(round_up( 4u, 16u), 16u);
TS_ASSERT_EQUALS(round_up(15u, 16u), 16u);
TS_ASSERT_EQUALS(round_up(20u, 32u), 32u);
TS_ASSERT_EQUALS(round_up(29u, 32u), 32u);
TS_ASSERT_EQUALS(round_up(0x1000u, 0x1000u), 0x1000u);
TS_ASSERT_EQUALS(round_up(0x1001u, 0x1000u), 0x2000u);
TS_ASSERT_EQUALS(round_up(0x1900u, 0x1000u), 0x2000u);
}
void test_round_down()
{
TS_ASSERT_EQUALS(round_down( 0u, 16u), 0u);
TS_ASSERT_EQUALS(round_down( 4u, 16u), 0u);
TS_ASSERT_EQUALS(round_down(15u, 16u), 0u);
TS_ASSERT_EQUALS(round_down(20u, 16u), 16u);
TS_ASSERT_EQUALS(round_down(29u, 16u), 16u);
TS_ASSERT_EQUALS(round_down(0x1900u, 0x1000u), 0x1000u);
TS_ASSERT_EQUALS(round_down(0x2001u, 0x2000u), 0x2000u);
}
// 16-bit saturating arithmetic
void test_addusw()
{
@ -105,28 +24,6 @@ public:
TS_ASSERT_EQUALS(subusw(0xFFFFu, 0x0FFFu), 0xF000u);
}
void test_movzx()
{
const u8 d1[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
const u8 d2[] = { 0x43, 0x12, 0x23, 0xA4 };
TS_ASSERT_EQUALS(movzx_64le(d1, 1), 0x01ull);
TS_ASSERT_EQUALS(movzx_64le(d1, 2), 0x0201ull);
TS_ASSERT_EQUALS(movzx_64le(d1, 8), 0x0807060504030201ull);
TS_ASSERT_EQUALS(movzx_64le(d2, 4), 0xA4231243ull);
TS_ASSERT_EQUALS(movzx_64le(d2+3, 1), 0xA4ull);
}
void test_movsx()
{
const u8 d1[] = { 0x09, 0xFE };
const u8 d2[] = { 0xD9, 0x2C, 0xDD, 0x8F };
const u8 d3[] = { 0x92, 0x26, 0x88, 0xF1, 0x35, 0xAC, 0x01, 0x83 };
TS_ASSERT_EQUALS(movsx_64le(d1, 1), 0x09ull);
TS_ASSERT_EQUALS(movsx_64le(d1, 2), 0xFFFFFFFFFFFFFE09ull);
TS_ASSERT_EQUALS(movsx_64le(d2, 4), 0xFFFFFFFF8FDD2CD9ull);
TS_ASSERT_EQUALS(movsx_64le(d3, 8), 0x8301AC35F1882692ull);
}
void test_hi_lo()
{
TS_ASSERT_EQUALS(u64_hi(0x0123456789ABCDEFull), 0x01234567u);
@ -147,59 +44,6 @@ public:
// fp_to_u?? already validate the result.
void test_wildcard()
{
TS_ASSERT_EQUALS(match_wildcard("", ""), 1);
TS_ASSERT_EQUALS(match_wildcard("a", 0), 1); // NULL matches everything
TS_ASSERT_EQUALS(match_wildcard("abc", "abc") , 1); // direct match
TS_ASSERT_EQUALS(match_wildcard("abc", "???") , 1); // only ?
TS_ASSERT_EQUALS(match_wildcard("abc", "*" ) , 1); // only *
TS_ASSERT_EQUALS(match_wildcard("ab" , "a?" ) , 1); // trailing ?
TS_ASSERT_EQUALS(match_wildcard("abc", "a?c") , 1); // middle ?
TS_ASSERT_EQUALS(match_wildcard("abc", "?bc") , 1); // leading ?
TS_ASSERT_EQUALS(match_wildcard("abc", "a*" ) , 1); // trailing *
TS_ASSERT_EQUALS(match_wildcard("abcdef", "ab*ef"), 1); // middle *
TS_ASSERT_EQUALS(match_wildcard("abcdef", "*f" ), 1); // leading *
TS_ASSERT_EQUALS(match_wildcard("abcdef", "a?cd*"), 1); // ? and *
TS_ASSERT_EQUALS(match_wildcard("abcdef", "a*d?f"), 1); // * and ?
TS_ASSERT_EQUALS(match_wildcard("abcdef", "a*d*" ), 1); // multiple *
// unicode test pasted from the above; keep in sync!
TS_ASSERT_EQUALS(match_wildcardw(L"", L""), 1);
TS_ASSERT_EQUALS(match_wildcardw(L"a", 0), 1); // NULL matches everything
TS_ASSERT_EQUALS(match_wildcardw(L"abc", L"abc") , 1); // direct match
TS_ASSERT_EQUALS(match_wildcardw(L"abc", L"???") , 1); // only ?
TS_ASSERT_EQUALS(match_wildcardw(L"abc", L"*" ) , 1); // only *
TS_ASSERT_EQUALS(match_wildcardw(L"ab" , L"a?" ) , 1); // trailing ?
TS_ASSERT_EQUALS(match_wildcardw(L"abc", L"a?c") , 1); // middle ?
TS_ASSERT_EQUALS(match_wildcardw(L"abc", L"?bc") , 1); // leading ?
TS_ASSERT_EQUALS(match_wildcardw(L"abc", L"a*" ) , 1); // trailing *
TS_ASSERT_EQUALS(match_wildcardw(L"abcdef", L"ab*ef"), 1); // middle *
TS_ASSERT_EQUALS(match_wildcardw(L"abcdef", L"*f" ), 1); // leading *
TS_ASSERT_EQUALS(match_wildcardw(L"abcdef", L"a?cd*"), 1); // ? and *
TS_ASSERT_EQUALS(match_wildcardw(L"abcdef", L"a*d?f"), 1); // * and ?
TS_ASSERT_EQUALS(match_wildcardw(L"abcdef", L"a*d*" ), 1); // multiple *
}
void test_base32()
{
// compare against previous output (generated via this base32() call)
const u8 in[] = { 0x12, 0x57, 0x85, 0xA2, 0xF9, 0x41, 0xCD, 0x57, 0xF3 };
u8 out[20] = {0};
base32(ARRAY_SIZE(in), in, out);
const u8 correct_out[] = "CJLYLIXZIHGVP4C";
TS_ASSERT_SAME_DATA(out, correct_out, ARRAY_SIZE(correct_out));
}
void test_rand()
{
// complain if huge interval or min > max

View File

@ -1,6 +1,5 @@
#include "lib/self_test.h"
#include "lib/lib.h"
#include "lib/lockfree.h"
#include "lib/sysdep/cpu.h" // atomic_add
#include "lib/timer.h"

View File

@ -0,0 +1,50 @@
#include "lib/self_test.h"
#include "lib/regex.h"
class TestLib : public CxxTest::TestSuite
{
public:
void test_regex()
{
TS_ASSERT_EQUALS(match_wildcard("", ""), 1);
TS_ASSERT_EQUALS(match_wildcard("a", 0), 1); // NULL matches everything
TS_ASSERT_EQUALS(match_wildcard("abc", "abc") , 1); // direct match
TS_ASSERT_EQUALS(match_wildcard("abc", "???") , 1); // only ?
TS_ASSERT_EQUALS(match_wildcard("abc", "*" ) , 1); // only *
TS_ASSERT_EQUALS(match_wildcard("ab" , "a?" ) , 1); // trailing ?
TS_ASSERT_EQUALS(match_wildcard("abc", "a?c") , 1); // middle ?
TS_ASSERT_EQUALS(match_wildcard("abc", "?bc") , 1); // leading ?
TS_ASSERT_EQUALS(match_wildcard("abc", "a*" ) , 1); // trailing *
TS_ASSERT_EQUALS(match_wildcard("abcdef", "ab*ef"), 1); // middle *
TS_ASSERT_EQUALS(match_wildcard("abcdef", "*f" ), 1); // leading *
TS_ASSERT_EQUALS(match_wildcard("abcdef", "a?cd*"), 1); // ? and *
TS_ASSERT_EQUALS(match_wildcard("abcdef", "a*d?f"), 1); // * and ?
TS_ASSERT_EQUALS(match_wildcard("abcdef", "a*d*" ), 1); // multiple *
// unicode test pasted from the above; keep in sync!
TS_ASSERT_EQUALS(match_wildcardw(L"", L""), 1);
TS_ASSERT_EQUALS(match_wildcardw(L"a", 0), 1); // NULL matches everything
TS_ASSERT_EQUALS(match_wildcardw(L"abc", L"abc") , 1); // direct match
TS_ASSERT_EQUALS(match_wildcardw(L"abc", L"???") , 1); // only ?
TS_ASSERT_EQUALS(match_wildcardw(L"abc", L"*" ) , 1); // only *
TS_ASSERT_EQUALS(match_wildcardw(L"ab" , L"a?" ) , 1); // trailing ?
TS_ASSERT_EQUALS(match_wildcardw(L"abc", L"a?c") , 1); // middle ?
TS_ASSERT_EQUALS(match_wildcardw(L"abc", L"?bc") , 1); // leading ?
TS_ASSERT_EQUALS(match_wildcardw(L"abc", L"a*" ) , 1); // trailing *
TS_ASSERT_EQUALS(match_wildcardw(L"abcdef", L"ab*ef"), 1); // middle *
TS_ASSERT_EQUALS(match_wildcardw(L"abcdef", L"*f" ), 1); // leading *
TS_ASSERT_EQUALS(match_wildcardw(L"abcdef", L"a?cd*"), 1); // ? and *
TS_ASSERT_EQUALS(match_wildcardw(L"abcdef", L"a*d?f"), 1); // * and ?
TS_ASSERT_EQUALS(match_wildcardw(L"abcdef", L"a*d*" ), 1); // multiple *
}
};

View File

@ -1,6 +1,5 @@
#include "lib/self_test.h"
#include "lib/lib.h"
#include "lib/string_s.h"
// note: we only test the char version. this avoids having to

View File

@ -17,12 +17,11 @@
#include <stdarg.h>
#include "lib/posix/posix_time.h"
#include "lib.h"
#include "adts.h"
#include "lib/sysdep/cpu.h"
#if CPU_IA32
# include "lib/sysdep/ia32/ia32.h"
#if CONFIG_TIMER_ALLOW_RDTSC
# include "lib/sysdep/ia32/ia32.h" // ia32_rdtsc
#endif
// rationale for wrapping gettimeofday and clock_gettime, instead of emulating
@ -205,7 +204,7 @@ void calc_fps()
// comes closer to the average again (meaning it probably
// wasn't really changing).
if(same_side >= 2 && !is_close)
bias += MIN(same_side, 4);
bias += std::min(same_side, 4);
}
// bias = 0: no change. > 0: increase (n-th root). < 0: decrease (^n)
@ -322,7 +321,7 @@ void timer_display_client_totals()
}
#if CPU_IA32
#if CONFIG_TIMER_ALLOW_RDTSC
TimerRdtsc::unit TimerRdtsc::get_timestamp() const
{

View File

@ -54,9 +54,10 @@ extern void calc_fps(void);
// note that overflow isn't an issue either way (63 bit cycle counts
// at 10 GHz cover intervals of 29 years).
#if CPU_IA32
#if CONFIG_TIMER_ALLOW_RDTSC
// fast, not usable as wall-clock (http://www.gamedev.net/reference/programming/features/timing)
// fast, IA-32 specific, not usable as wall-clock
// (see http://www.gamedev.net/reference/programming/features/timing)
class TimerRdtsc
{
public:
@ -76,7 +77,7 @@ public:
}
};
#if CPU_IA32 && TIMER_ALLOW_RDTSC
#if CONFIG_TIMER_ALLOW_RDTSC
typedef TimerRdtsc Timer;
#else
typedef TimerSafe Timer;

View File

@ -2,7 +2,6 @@
#include <cstdlib>
#include <cmath>
#include "lib/lib.h"
#include "maths/Matrix3D.h"
#include "maths/Quaternion.h"
@ -66,3 +65,4 @@ public:
}
};

View File

@ -1,7 +1,5 @@
#include "precompiled.h"
#include "lib/lib.h"
#include "scripting/DOMEvent.h"
#include "scripting/JSConversions.h"
#include "scripting/ScriptableObject.h"

View File

@ -1,6 +1,5 @@
#include "precompiled.h"
#include "lib/lib.h"
#include <stdio.h>
#include <map>

Some files were not shown because too many files have changed in this diff Show More