forked from 0ad/0ad
fixes/improvements from work:
file/wfilesystem: avoid error dialog when opening a file that doesn't exist precompiled/pch_warnings: remove push/pop that prevented our warning disables to applying to other code. update comments topology: refactor APIC field access and add support for constructing APIC ID from topology waio: add file_attribute_normal wsysdep: slightly safer sys_generate_random_bytes implementation This was SVN commit r8869.
This commit is contained in:
parent
0d8ffa58dc
commit
fd46b9e370
@ -61,7 +61,7 @@ LibError Open(const fs::wpath& pathname, wchar_t accessType, int& fd)
|
||||
const mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH; // 0644
|
||||
fd = wopen(pathname.string().c_str(), oflag, mode);
|
||||
if(fd < 0)
|
||||
return LibError_from_errno();
|
||||
return LibError_from_errno(false);
|
||||
|
||||
stats_open();
|
||||
return INFO::OK;
|
||||
@ -70,10 +70,10 @@ LibError Open(const fs::wpath& pathname, wchar_t accessType, int& fd)
|
||||
|
||||
void Close(int& fd)
|
||||
{
|
||||
if(fd)
|
||||
if(fd >= 0)
|
||||
{
|
||||
wclose(fd);
|
||||
fd = 0;
|
||||
fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,10 +3,10 @@
|
||||
#include "lib/sysdep/compiler.h" // MSC_VERSION
|
||||
|
||||
#if MSC_VERSION
|
||||
// .. temporarily disabled W4 (unimportant but ought to be fixed)
|
||||
// .. unimportant but not entirely senseless W4
|
||||
# pragma warning(disable:4201) // nameless struct (Matrix3D)
|
||||
# pragma warning(disable:4244) // conversion from uintN to uint8
|
||||
// .. permanently disabled W4
|
||||
// .. always disabled W4
|
||||
# pragma warning(disable:4103) // alignment changed after including header (boost has #pragma pack/pop in separate headers)
|
||||
# pragma warning(disable:4127) // conditional expression is constant; rationale: see STMT in lib.h.
|
||||
# pragma warning(disable:4351) // yes, default init of array entries is desired
|
||||
@ -14,8 +14,6 @@
|
||||
# pragma warning(disable:4718) // recursive call has no side effects, deleting
|
||||
# pragma warning(disable:4786) // identifier truncated to 255 chars
|
||||
# pragma warning(disable:4996) // function is deprecated
|
||||
// .. disabled only for the precompiled headers
|
||||
# pragma warning(disable:4702) // unreachable code (frequent in STL)
|
||||
// .. VS2005 code analysis (very frequent ones)
|
||||
# if MSC_VERSION >= 1400
|
||||
# pragma warning(disable:6011) // dereferencing NULL pointer
|
||||
@ -31,22 +29,23 @@
|
||||
# pragma warning(disable:1786) // function is deprecated (disabling 4996 isn't sufficient)
|
||||
# pragma warning(disable:2415) // variable of static storage duration was declared but never referenced (raised by Boost)
|
||||
# endif
|
||||
// .. ENABLE ones disabled even in W4
|
||||
// .. disabled by default in W4, ENABLE them
|
||||
# pragma warning(default:4062) // enumerator is not handled
|
||||
//# pragma warning(default:4191) // unsafe conversion (false alarms for function pointers)
|
||||
# pragma warning(default:4254) // [bit field] conversion, possible loss of data
|
||||
//# pragma warning(default:4263) // member function does not override any base class virtual member function (happens in GUI)
|
||||
# pragma warning(default:4265) // class has virtual functions, but destructor is not virtual
|
||||
# pragma warning(default:4296) // [unsigned comparison vs. 0 =>] expression is always false
|
||||
# pragma warning(default:4545 4546 4547 4549) // ill-formed comma expressions; exclude 4548 since _SECURE_SCL triggers it frequently
|
||||
//# pragma warning(default:4555) // expression has no effect (triggered by STL unused)
|
||||
# pragma warning(default:4557) // __assume contains effect
|
||||
//# pragma warning(default:4619) // #pragma warning: there is no [such] warning number (false alarms in STL)
|
||||
//# pragma warning(default:4668) // not defined as a preprocessor macro, replacing with '0' (frequent in Windows)
|
||||
# pragma warning(default:4710) // function not inlined
|
||||
# pragma warning(default:4836) // local types or unnamed types cannot be used as template arguments
|
||||
# pragma warning(default:4905) // wide string literal cast to LPSTR
|
||||
# pragma warning(default:4906) // string literal cast to LPWSTR
|
||||
# pragma warning(default:4928) // illegal copy-initialization; more than one user-defined conversion has been implicitly applied
|
||||
# pragma warning(default:4946) // reinterpret_cast used between related classes
|
||||
// .. disabled by default in W4, leave them that way
|
||||
//# pragma warning(default:4191) // unsafe conversion (false alarms for function pointers)
|
||||
//# pragma warning(default:4263) // member function does not override any base class virtual member function (happens in GUI)
|
||||
//# pragma warning(default:4555) // expression has no effect (triggered by STL unused)
|
||||
//# pragma warning(default:4619) // #pragma warning: there is no [such] warning number (false alarms in STL)
|
||||
//# pragma warning(default:4668) // not defined as a preprocessor macro, replacing with '0' (frequent in Windows)
|
||||
#endif
|
||||
|
@ -48,9 +48,6 @@
|
||||
// disable some common and annoying warnings
|
||||
// must come after compiler.h, but as soon as possible so that
|
||||
// headers below are covered
|
||||
#if MSC_VERSION
|
||||
# pragma warning(push)
|
||||
#endif
|
||||
#include "lib/pch/pch_warnings.h"
|
||||
|
||||
#if ICC_VERSION
|
||||
@ -108,8 +105,3 @@ using std::tr1::shared_ptr;
|
||||
#include "lib/pch/pch_stdlib.h"
|
||||
|
||||
#endif // #if CONFIG_ENABLE_PCH && HAVE_PCH
|
||||
|
||||
// restore temporarily-disabled warnings
|
||||
#if MSC_VERSION
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
@ -177,26 +177,41 @@ const u8* ApicIds()
|
||||
}
|
||||
|
||||
|
||||
// (if maxValues == 1, the field is zero-width and thus zero)
|
||||
static size_t ApicField(size_t apicId, size_t indexOfLowestBit, size_t maxValues)
|
||||
size_t ProcessorFromApicId(size_t apicId)
|
||||
{
|
||||
const size_t numBits = ceil_log2(maxValues);
|
||||
const size_t mask = bit_mask<size_t>(numBits);
|
||||
return (apicId >> indexOfLowestBit) & mask;
|
||||
const u8* apicIds = ApicIds();
|
||||
const u8* end = apicIds + os_cpu_NumProcessors();
|
||||
const u8* pos = std::find(apicIds, end, apicId);
|
||||
if(pos == end)
|
||||
{
|
||||
debug_assert(0);
|
||||
return 0;
|
||||
}
|
||||
return pos - apicIds; // index
|
||||
}
|
||||
|
||||
|
||||
struct ApicField // POD
|
||||
{
|
||||
size_t operator()(size_t bits) const
|
||||
{
|
||||
return (bits >> shift) & mask;
|
||||
}
|
||||
|
||||
size_t mask; // zero for zero-width fields
|
||||
size_t shift;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CPU topology interface
|
||||
|
||||
|
||||
struct CpuTopology // POD
|
||||
{
|
||||
size_t maxLogicalPerCore;
|
||||
size_t maxCoresPerPackage;
|
||||
|
||||
size_t logicalOffset;
|
||||
size_t coreOffset;
|
||||
size_t packageOffset;
|
||||
ApicField logical;
|
||||
ApicField core;
|
||||
ApicField package;
|
||||
|
||||
// how many are actually enabled
|
||||
size_t logicalPerCore;
|
||||
@ -208,33 +223,42 @@ static ModuleInitState cpuInitState;
|
||||
|
||||
static LibError InitCpuTopology()
|
||||
{
|
||||
cpuTopology.maxLogicalPerCore = MaxLogicalPerCore();
|
||||
cpuTopology.maxCoresPerPackage = MaxCoresPerPackage();
|
||||
const size_t maxLogicalPerCore = MaxLogicalPerCore();
|
||||
const size_t maxCoresPerPackage = MaxCoresPerPackage();
|
||||
const size_t maxPackages = 256; // "enough"
|
||||
|
||||
cpuTopology.logicalOffset = 0;
|
||||
cpuTopology.coreOffset = ceil_log2(cpuTopology.maxLogicalPerCore);
|
||||
cpuTopology.packageOffset = cpuTopology.coreOffset + ceil_log2(cpuTopology.maxCoresPerPackage);
|
||||
const size_t logicalWidth = ceil_log2(maxLogicalPerCore);
|
||||
const size_t coreWidth = ceil_log2(maxCoresPerPackage);
|
||||
const size_t packageWidth = ceil_log2(maxPackages);
|
||||
|
||||
cpuTopology.logical.mask = bit_mask<size_t>(logicalWidth);
|
||||
cpuTopology.core.mask = bit_mask<size_t>(coreWidth);
|
||||
cpuTopology.package.mask = bit_mask<size_t>(packageWidth);
|
||||
|
||||
cpuTopology.logical.shift = 0;
|
||||
cpuTopology.core.shift = logicalWidth;
|
||||
cpuTopology.package.shift = logicalWidth + coreWidth;
|
||||
|
||||
const u8* apicIds = ApicIds();
|
||||
if(apicIds)
|
||||
{
|
||||
struct NumUniqueValuesInField
|
||||
{
|
||||
size_t operator()(const u8* apicIds, size_t indexOfLowestBit, size_t numValues) const
|
||||
size_t operator()(const u8* apicIds, const ApicField& apicField) const
|
||||
{
|
||||
std::set<size_t> values;
|
||||
for(size_t processor = 0; processor < os_cpu_NumProcessors(); processor++)
|
||||
{
|
||||
const size_t value = ApicField(apicIds[processor], indexOfLowestBit, numValues);
|
||||
const size_t value = apicField(apicIds[processor]);
|
||||
values.insert(value);
|
||||
}
|
||||
return values.size();
|
||||
}
|
||||
};
|
||||
|
||||
cpuTopology.logicalPerCore = NumUniqueValuesInField()(apicIds, cpuTopology.logicalOffset, cpuTopology.maxLogicalPerCore);
|
||||
cpuTopology.coresPerPackage = NumUniqueValuesInField()(apicIds, cpuTopology.coreOffset, cpuTopology.maxCoresPerPackage);
|
||||
cpuTopology.numPackages = NumUniqueValuesInField()(apicIds, cpuTopology.packageOffset, 256);
|
||||
cpuTopology.logicalPerCore = NumUniqueValuesInField()(apicIds, cpuTopology.logical);
|
||||
cpuTopology.coresPerPackage = NumUniqueValuesInField()(apicIds, cpuTopology.core);
|
||||
cpuTopology.numPackages = NumUniqueValuesInField()(apicIds, cpuTopology.package);
|
||||
}
|
||||
else // the processor lacks an xAPIC, or the IDs are invalid
|
||||
{
|
||||
@ -254,20 +278,20 @@ static LibError InitCpuTopology()
|
||||
// we can't differentiate between cores and logical processors.
|
||||
// since the former are less likely to be disabled, we seek the
|
||||
// maximum feasible number of cores and minimal number of packages:
|
||||
const size_t minPackages = MinPackages()(cpuTopology.maxCoresPerPackage, cpuTopology.maxLogicalPerCore);
|
||||
const size_t minPackages = MinPackages()(maxCoresPerPackage, maxLogicalPerCore);
|
||||
const size_t numProcessors = os_cpu_NumProcessors();
|
||||
for(size_t numPackages = minPackages; numPackages <= numProcessors; numPackages++)
|
||||
{
|
||||
if(numProcessors % numPackages != 0)
|
||||
continue;
|
||||
const size_t logicalPerPackage = numProcessors / numPackages;
|
||||
const size_t minCoresPerPackage = DivideRoundUp(logicalPerPackage, cpuTopology.maxLogicalPerCore);
|
||||
for(size_t coresPerPackage = cpuTopology.maxCoresPerPackage; coresPerPackage >= minCoresPerPackage; coresPerPackage--)
|
||||
const size_t minCoresPerPackage = DivideRoundUp(logicalPerPackage, maxLogicalPerCore);
|
||||
for(size_t coresPerPackage = maxCoresPerPackage; coresPerPackage >= minCoresPerPackage; coresPerPackage--)
|
||||
{
|
||||
if(logicalPerPackage % coresPerPackage != 0)
|
||||
continue;
|
||||
const size_t logicalPerCore = logicalPerPackage / coresPerPackage;
|
||||
if(logicalPerCore <= cpuTopology.maxLogicalPerCore)
|
||||
if(logicalPerCore <= maxLogicalPerCore)
|
||||
{
|
||||
debug_assert(numProcessors == numPackages*coresPerPackage*logicalPerCore);
|
||||
cpuTopology.logicalPerCore = logicalPerCore;
|
||||
@ -305,19 +329,37 @@ size_t cpu_topology_LogicalPerCore()
|
||||
size_t cpu_topology_LogicalFromApicId(size_t apicId)
|
||||
{
|
||||
ModuleInit(&cpuInitState, InitCpuTopology);
|
||||
return ApicField(apicId, cpuTopology.logicalOffset, cpuTopology.maxLogicalPerCore);
|
||||
return cpuTopology.logical(apicId);
|
||||
}
|
||||
|
||||
size_t cpu_topology_CoreFromApicId(size_t apicId)
|
||||
{
|
||||
ModuleInit(&cpuInitState, InitCpuTopology);
|
||||
return ApicField(apicId, cpuTopology.coreOffset, cpuTopology.maxCoresPerPackage);
|
||||
return cpuTopology.core(apicId);
|
||||
}
|
||||
|
||||
size_t cpu_topology_PackageFromApicId(size_t apicId)
|
||||
{
|
||||
ModuleInit(&cpuInitState, InitCpuTopology);
|
||||
return ApicField(apicId, cpuTopology.packageOffset, 256);
|
||||
return cpuTopology.package(apicId);
|
||||
}
|
||||
|
||||
size_t cpu_topology_ApicId(size_t idxLogical, size_t idxCore, size_t idxPackage)
|
||||
{
|
||||
ModuleInit(&cpuInitState, InitCpuTopology);
|
||||
|
||||
size_t apicId = 0;
|
||||
|
||||
debug_assert(idxPackage <= cpuTopology.package.mask);
|
||||
apicId |= idxPackage << cpuTopology.package.shift;
|
||||
|
||||
debug_assert(idxCore <= cpuTopology.core.mask);
|
||||
apicId |= idxCore << cpuTopology.core.shift;
|
||||
|
||||
debug_assert(idxLogical <= cpuTopology.logical.mask);
|
||||
apicId |= idxLogical << cpuTopology.logical.shift;
|
||||
|
||||
return apicId;
|
||||
}
|
||||
|
||||
|
||||
|
@ -36,6 +36,8 @@
|
||||
**/
|
||||
LIB_API const u8* ApicIds();
|
||||
|
||||
LIB_API size_t ProcessorFromApicId(size_t apicId);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// cpu
|
||||
@ -65,9 +67,11 @@ LIB_API size_t cpu_topology_CoresPerPackage();
|
||||
LIB_API size_t cpu_topology_LogicalPerCore();
|
||||
|
||||
|
||||
LIB_API size_t cpu_topology_LogicalFromApicId(size_t apicId);
|
||||
LIB_API size_t cpu_topology_CoreFromApicId(size_t apicId);
|
||||
LIB_API size_t cpu_topology_PackageFromApicId(size_t apicId);
|
||||
LIB_API size_t cpu_topology_CoreFromApicId(size_t apicId);
|
||||
LIB_API size_t cpu_topology_LogicalFromApicId(size_t apicId);
|
||||
|
||||
LIB_API size_t cpu_topology_ApicId(size_t idxPackage, size_t idxCore, size_t idxLogical);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -202,7 +202,7 @@ DWORD_PTR wcpu_AffinityFromProcessorMask(DWORD_PTR processAffinity, uintptr_t pr
|
||||
{
|
||||
if(IsBitSet(processAffinity, processorNumber))
|
||||
{
|
||||
++processor; // now corresponds to processorNumber
|
||||
++processor; // index among the affinity's set bits
|
||||
|
||||
if(IsBitSet(processorMask, processor))
|
||||
affinity |= DWORD_PTR(1) << processorNumber;
|
||||
@ -236,8 +236,6 @@ uintptr_t wcpu_ProcessorMaskFromAffinity(DWORD_PTR processAffinity, DWORD_PTR af
|
||||
|
||||
static void VerifyRunningOnCorrectProcessors(DWORD_PTR affinity)
|
||||
{
|
||||
// note: we don't need to expose this to callers because the
|
||||
// higher-level code ensures processor == omp_get_thread_num().
|
||||
DWORD currentProcessor;
|
||||
|
||||
// note: NtGetCurrentProcessorNumber and RtlGetCurrentProcessorNumber aren't
|
||||
|
@ -460,8 +460,7 @@ static void UnloadAllDlls()
|
||||
::FreeLibrary(hmod);
|
||||
*phmod = NULL;
|
||||
|
||||
delete reinterpret_cast<ULI*> (pui);
|
||||
// changes __puiHead!
|
||||
delete (ULI*)pui; // changes __puiHead!
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,7 @@ LibError waio_reopen(int fd, const wchar_t* pathname, int oflag, ...)
|
||||
return INFO::SKIPPED;
|
||||
|
||||
// open file
|
||||
const DWORD flags = FILE_FLAG_OVERLAPPED|FILE_FLAG_NO_BUFFERING|FILE_FLAG_SEQUENTIAL_SCAN;
|
||||
const DWORD flags = FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED|FILE_FLAG_NO_BUFFERING|FILE_FLAG_SEQUENTIAL_SCAN|FILE_FLAG_WRITE_THROUGH;
|
||||
const HANDLE hFile = CreateFileW(pathname, access, share, 0, create, flags, 0);
|
||||
if(hFile == INVALID_HANDLE_VALUE)
|
||||
return LibError_from_GLE();
|
||||
|
@ -345,11 +345,11 @@ int wopen(const wchar_t* pathname, int oflag, mode_t mode_arg)
|
||||
if(ret != 0)
|
||||
{
|
||||
errno = ret;
|
||||
WARN_ERR(LibError_from_errno());
|
||||
return -1;
|
||||
return -1; // NOWARN
|
||||
}
|
||||
|
||||
WARN_ERR(waio_reopen(fd, pathname, oflag));
|
||||
if(waio_reopen(fd, pathname, oflag) != INFO::OK)
|
||||
return -1;
|
||||
|
||||
// CRT doesn't like more than 255 files open.
|
||||
// warn now, so that we notice why so many are open.
|
||||
|
@ -454,18 +454,18 @@ LibError sys_open_url(const std::string& url)
|
||||
WARN_RETURN(ERR::FAIL);
|
||||
}
|
||||
|
||||
LibError sys_generate_random_bytes(u8* buf, size_t count)
|
||||
LibError sys_generate_random_bytes(u8* buffer, size_t size)
|
||||
{
|
||||
HCRYPTPROV hCryptProv;
|
||||
HCRYPTPROV hCryptProv = 0;
|
||||
if(!CryptAcquireContext(&hCryptProv, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
|
||||
return LibError_from_GLE();
|
||||
|
||||
if(!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0))
|
||||
WARN_RETURN(ERR::FAIL);
|
||||
memset(buffer, 0, size);
|
||||
if(!CryptGenRandom(hCryptProv, (DWORD)size, (BYTE*)buffer))
|
||||
return LibError_from_GLE();
|
||||
|
||||
if(!CryptGenRandom(hCryptProv, (DWORD)count, buf))
|
||||
WARN_RETURN(ERR::FAIL);
|
||||
|
||||
if (!CryptReleaseContext(hCryptProv, 0))
|
||||
WARN_RETURN(ERR::FAIL);
|
||||
if(!CryptReleaseContext(hCryptProv, 0))
|
||||
return LibError_from_GLE();
|
||||
|
||||
return INFO::OK;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user