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:
janwas 2011-01-28 13:40:07 +00:00
parent 0d8ffa58dc
commit fd46b9e370
10 changed files with 103 additions and 69 deletions

View File

@ -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;
}
}

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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);
//-----------------------------------------------------------------------------

View File

@ -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

View File

@ -460,8 +460,7 @@ static void UnloadAllDlls()
::FreeLibrary(hmod);
*phmod = NULL;
delete reinterpret_cast<ULI*> (pui);
// changes __puiHead!
delete (ULI*)pui; // changes __puiHead!
}
}

View File

@ -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();

View File

@ -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.

View File

@ -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;
}