mirror of
https://github.com/isar/libmdbx.git
synced 2025-11-07 07:18:56 +08:00
mdbx: изменение лицензии и реструктуризация исходного кода.
This commit is contained in:
158
src/windows-import.c
Normal file
158
src/windows-import.c
Normal file
@@ -0,0 +1,158 @@
|
||||
/// \copyright SPDX-License-Identifier: Apache-2.0
|
||||
/// \author Леонид Юрьев aka Leonid Yuriev <leo@yuriev.ru> \date 2015-2024
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
||||
#include "internals.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Stub for slim read-write lock
|
||||
// Portion Copyright (C) 1995-2002 Brad Wilson
|
||||
|
||||
static void WINAPI stub_srwlock_Init(osal_srwlock_t *srwl) {
|
||||
srwl->readerCount = srwl->writerCount = 0;
|
||||
}
|
||||
|
||||
static void WINAPI stub_srwlock_AcquireShared(osal_srwlock_t *srwl) {
|
||||
while (true) {
|
||||
assert(srwl->writerCount >= 0 && srwl->readerCount >= 0);
|
||||
|
||||
// If there's a writer already, spin without unnecessarily
|
||||
// interlocking the CPUs
|
||||
if (srwl->writerCount != 0) {
|
||||
SwitchToThread();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add to the readers list
|
||||
_InterlockedIncrement(&srwl->readerCount);
|
||||
|
||||
// Check for writers again (we may have been preempted). If
|
||||
// there are no writers writing or waiting, then we're done.
|
||||
if (srwl->writerCount == 0)
|
||||
break;
|
||||
|
||||
// Remove from the readers list, spin, try again
|
||||
_InterlockedDecrement(&srwl->readerCount);
|
||||
SwitchToThread();
|
||||
}
|
||||
}
|
||||
|
||||
static void WINAPI stub_srwlock_ReleaseShared(osal_srwlock_t *srwl) {
|
||||
assert(srwl->readerCount > 0);
|
||||
_InterlockedDecrement(&srwl->readerCount);
|
||||
}
|
||||
|
||||
static void WINAPI stub_srwlock_AcquireExclusive(osal_srwlock_t *srwl) {
|
||||
while (true) {
|
||||
assert(srwl->writerCount >= 0 && srwl->readerCount >= 0);
|
||||
|
||||
// If there's a writer already, spin without unnecessarily
|
||||
// interlocking the CPUs
|
||||
if (srwl->writerCount != 0) {
|
||||
SwitchToThread();
|
||||
continue;
|
||||
}
|
||||
|
||||
// See if we can become the writer (expensive, because it inter-
|
||||
// locks the CPUs, so writing should be an infrequent process)
|
||||
if (_InterlockedExchange(&srwl->writerCount, 1) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
// Now we're the writer, but there may be outstanding readers.
|
||||
// Spin until there aren't any more; new readers will wait now
|
||||
// that we're the writer.
|
||||
while (srwl->readerCount != 0) {
|
||||
assert(srwl->writerCount >= 0 && srwl->readerCount >= 0);
|
||||
SwitchToThread();
|
||||
}
|
||||
}
|
||||
|
||||
static void WINAPI stub_srwlock_ReleaseExclusive(osal_srwlock_t *srwl) {
|
||||
assert(srwl->writerCount == 1 && srwl->readerCount >= 0);
|
||||
srwl->writerCount = 0;
|
||||
}
|
||||
|
||||
static uint64_t WINAPI stub_GetTickCount64(void) {
|
||||
LARGE_INTEGER Counter, Frequency;
|
||||
return (QueryPerformanceFrequency(&Frequency) &&
|
||||
QueryPerformanceCounter(&Counter))
|
||||
? Counter.QuadPart * 1000ul / Frequency.QuadPart
|
||||
: 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
struct libmdbx_imports imports;
|
||||
|
||||
#if __GNUC_PREREQ(8, 0)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
#endif /* GCC/MINGW */
|
||||
|
||||
#define MDBX_IMPORT(HANDLE, ENTRY) \
|
||||
imports.ENTRY = (MDBX_##ENTRY)GetProcAddress(HANDLE, #ENTRY)
|
||||
|
||||
void windows_import(void) {
|
||||
const HINSTANCE hNtdll = GetModuleHandleA("ntdll.dll");
|
||||
if (hNtdll) {
|
||||
globals.running_under_Wine = !!GetProcAddress(hNtdll, "wine_get_version");
|
||||
if (!globals.running_under_Wine) {
|
||||
MDBX_IMPORT(hNtdll, NtFsControlFile);
|
||||
MDBX_IMPORT(hNtdll, NtExtendSection);
|
||||
ENSURE(nullptr, imports.NtExtendSection);
|
||||
}
|
||||
}
|
||||
|
||||
const HINSTANCE hKernel32dll = GetModuleHandleA("kernel32.dll");
|
||||
if (hKernel32dll) {
|
||||
MDBX_IMPORT(hKernel32dll, GetFileInformationByHandleEx);
|
||||
MDBX_IMPORT(hKernel32dll, GetTickCount64);
|
||||
if (!imports.GetTickCount64)
|
||||
imports.GetTickCount64 = stub_GetTickCount64;
|
||||
if (!globals.running_under_Wine) {
|
||||
MDBX_IMPORT(hKernel32dll, SetFileInformationByHandle);
|
||||
MDBX_IMPORT(hKernel32dll, GetVolumeInformationByHandleW);
|
||||
MDBX_IMPORT(hKernel32dll, GetFinalPathNameByHandleW);
|
||||
MDBX_IMPORT(hKernel32dll, PrefetchVirtualMemory);
|
||||
MDBX_IMPORT(hKernel32dll, SetFileIoOverlappedRange);
|
||||
}
|
||||
}
|
||||
|
||||
const osal_srwlock_t_function srwlock_init =
|
||||
(osal_srwlock_t_function)(hKernel32dll
|
||||
? GetProcAddress(hKernel32dll,
|
||||
"InitializeSRWLock")
|
||||
: nullptr);
|
||||
if (srwlock_init) {
|
||||
imports.srwl_Init = srwlock_init;
|
||||
imports.srwl_AcquireShared = (osal_srwlock_t_function)GetProcAddress(
|
||||
hKernel32dll, "AcquireSRWLockShared");
|
||||
imports.srwl_ReleaseShared = (osal_srwlock_t_function)GetProcAddress(
|
||||
hKernel32dll, "ReleaseSRWLockShared");
|
||||
imports.srwl_AcquireExclusive = (osal_srwlock_t_function)GetProcAddress(
|
||||
hKernel32dll, "AcquireSRWLockExclusive");
|
||||
imports.srwl_ReleaseExclusive = (osal_srwlock_t_function)GetProcAddress(
|
||||
hKernel32dll, "ReleaseSRWLockExclusive");
|
||||
} else {
|
||||
imports.srwl_Init = stub_srwlock_Init;
|
||||
imports.srwl_AcquireShared = stub_srwlock_AcquireShared;
|
||||
imports.srwl_ReleaseShared = stub_srwlock_ReleaseShared;
|
||||
imports.srwl_AcquireExclusive = stub_srwlock_AcquireExclusive;
|
||||
imports.srwl_ReleaseExclusive = stub_srwlock_ReleaseExclusive;
|
||||
}
|
||||
|
||||
const HINSTANCE hAdvapi32dll = GetModuleHandleA("advapi32.dll");
|
||||
if (hAdvapi32dll) {
|
||||
MDBX_IMPORT(hAdvapi32dll, RegGetValueA);
|
||||
}
|
||||
}
|
||||
|
||||
#undef MDBX_IMPORT
|
||||
|
||||
#if __GNUC_PREREQ(8, 0)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif /* GCC/MINGW */
|
||||
|
||||
#endif /* Windows */
|
||||
Reference in New Issue
Block a user