diff --git a/source/lib/file/file.cpp b/source/lib/file/file.cpp index 16f84e839c..2d591c2052 100644 --- a/source/lib/file/file.cpp +++ b/source/lib/file/file.cpp @@ -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; } } diff --git a/source/lib/pch/pch_warnings.h b/source/lib/pch/pch_warnings.h index 0d6b135574..138f9f2d73 100644 --- a/source/lib/pch/pch_warnings.h +++ b/source/lib/pch/pch_warnings.h @@ -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 diff --git a/source/lib/precompiled.h b/source/lib/precompiled.h index d7f5d04c67..188369dbae 100644 --- a/source/lib/precompiled.h +++ b/source/lib/precompiled.h @@ -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 diff --git a/source/lib/sysdep/arch/x86_x64/topology.cpp b/source/lib/sysdep/arch/x86_x64/topology.cpp index b517b0a50d..585ba3c502 100644 --- a/source/lib/sysdep/arch/x86_x64/topology.cpp +++ b/source/lib/sysdep/arch/x86_x64/topology.cpp @@ -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(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(logicalWidth); + cpuTopology.core.mask = bit_mask(coreWidth); + cpuTopology.package.mask = bit_mask(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 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; } diff --git a/source/lib/sysdep/arch/x86_x64/topology.h b/source/lib/sysdep/arch/x86_x64/topology.h index 3d12bd6199..27b587d034 100644 --- a/source/lib/sysdep/arch/x86_x64/topology.h +++ b/source/lib/sysdep/arch/x86_x64/topology.h @@ -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); //----------------------------------------------------------------------------- diff --git a/source/lib/sysdep/os/win/wcpu.cpp b/source/lib/sysdep/os/win/wcpu.cpp index 407699222d..df92e671f5 100644 --- a/source/lib/sysdep/os/win/wcpu.cpp +++ b/source/lib/sysdep/os/win/wcpu.cpp @@ -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 diff --git a/source/lib/sysdep/os/win/wdll_delay_load.cpp b/source/lib/sysdep/os/win/wdll_delay_load.cpp index c7c43176e7..a183e7f203 100644 --- a/source/lib/sysdep/os/win/wdll_delay_load.cpp +++ b/source/lib/sysdep/os/win/wdll_delay_load.cpp @@ -460,8 +460,7 @@ static void UnloadAllDlls() ::FreeLibrary(hmod); *phmod = NULL; - delete reinterpret_cast (pui); - // changes __puiHead! + delete (ULI*)pui; // changes __puiHead! } } diff --git a/source/lib/sysdep/os/win/wposix/waio.cpp b/source/lib/sysdep/os/win/wposix/waio.cpp index 6e3eb15941..348e0abc62 100644 --- a/source/lib/sysdep/os/win/wposix/waio.cpp +++ b/source/lib/sysdep/os/win/wposix/waio.cpp @@ -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(); diff --git a/source/lib/sysdep/os/win/wposix/wfilesystem.cpp b/source/lib/sysdep/os/win/wposix/wfilesystem.cpp index 37d7d00cc7..8408dfe59c 100644 --- a/source/lib/sysdep/os/win/wposix/wfilesystem.cpp +++ b/source/lib/sysdep/os/win/wposix/wfilesystem.cpp @@ -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. diff --git a/source/lib/sysdep/os/win/wsysdep.cpp b/source/lib/sysdep/os/win/wsysdep.cpp index f56ba9d924..5688fae1ef 100644 --- a/source/lib/sysdep/os/win/wsysdep.cpp +++ b/source/lib/sysdep/os/win/wsysdep.cpp @@ -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; }