抛弃GdCpp*.dll/pdb历史重新建库。libhv和Sqlite的dll保留

This commit is contained in:
Zhang Jianjun
2026-02-02 16:09:02 +08:00
parent f148ca49e3
commit 4a2a284ac0
292 changed files with 350450 additions and 0 deletions

478
source/Mem/CMem.cpp Normal file
View File

@@ -0,0 +1,478 @@
#include "pch.h"
#include "Mem\CMem.h"
#include <Windows.h>
#include "AlignSize.h"
//#include "CSystemSemaphore.h"
#include "aLog.h"
// 静态成员变量
size_t CMemUsage::totalContainerSize=0;
size_t CMemUsage::totalMemSize=0;
std::list<CMemUsage*> CMemUsage::MemList;
std::mutex CMemUsage::MemListLock;
std::mutex CMem::uplocker;
void CMemUsage::report(std::wstring& str)
{
std::lock_guard guard(MemListLock); // 加锁
_updateUsage();
str = L"内存使用统计:\n";
for (auto mem : MemList)
{
if(mem->memName.empty()) {
str += fmt::format(L"未命名, {}, {}k/{}k, {}M/{}M\n", mem->memType.c_str(), mem->memSize / 1_K, mem->containerSize / 1_K, mem->memSize / 1_M, mem->containerSize / 1_M);
}else {
str += fmt::format(L"{}, {}, {}k/{}k, {}M/{}M\n", mem->memName.c_str(), mem->memType.c_str(), mem->memSize / 1_K, mem->containerSize / 1_K, mem->memSize / 1_M, mem->containerSize / 1_M);
}
}
str += fmt::format(L"\n总内存:{}M/{}M\n", totalMemSize / 1_M, totalContainerSize / 1_M);
}
bool CMem::_allocVirtual(void* addr, size_t size, bool commit)
{
const DWORD flag = (commit) ? (MEM_RESERVE | MEM_COMMIT) : MEM_RESERVE;
// 执行windows api
Addr = static_cast<uint8_t*>(VirtualAlloc(
addr, // 0: 系统自动分配地址, 其他值:指定未使用的内存地址
size, // Size of allocation
flag,
PAGE_READWRITE)); //只支持Read + Write未考虑其他情况
// 结果
if (Addr) { // 分配成功
containerSize = size;
memSize = (commit) ? size : 0;
selfAlloc = true;
return true;
}
else { // 调用处来处理不成功的情况,这里不管
containerSize = 0;
memSize = 0;
selfAlloc = false;
return false;
}
}
uint8_t* CMem::allocVirtual(size_t size)
{
// 执行windows api
return static_cast<uint8_t*>(VirtualAlloc(
nullptr, // 0: 系统自动分配地址, 其他值:指定未使用的内存地址
size, // Size of allocation
MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE)); //只支持Read + Write未考虑其他情况
}
void CMem::freeVirtual(uint8_t* addr)
{
if(addr) VirtualFree(addr, 0, MEM_RELEASE);
// 未处理失败情况,假设不会失败
// 此处addr未清零在dealloc()中清零
}
bool CMem::_allocUpperVirtual(size_t size, bool commit)
{
const DWORD flag = (commit) ? (MEM_RESERVE | MEM_TOP_DOWN | MEM_COMMIT) : (MEM_RESERVE | MEM_TOP_DOWN);
// 执行windows api
Addr = static_cast<uint8_t*>(VirtualAlloc(
nullptr, // System selects address
size, // Size of allocation
flag,
PAGE_READWRITE)); //只支持Read + Write未考虑其他情况
// 结果
if (Addr) {
containerSize = size;
memSize = 0;
selfAlloc = true;
return true;
}
else { // 调用处来处理不成功的情况,这里不管
containerSize = 0;
memSize = 0;
selfAlloc = false;
return false;
}
}
// 分配虚拟内存
bool CWinMem::alloc(void* addr, size_t container, size_t size)
{
// addr可以为0或指定某个未分配的地址
ASSERT(container != 0); //虚拟内存大小不能为0
ASSERT(size <= container);//物理内存大小不超过虚拟内存大小可以为0
AlignUp(container, 64 * 1024); // 调整虚拟内存大小对齐到64k。win默认按64k分配虚拟内存
AlignUp(size, 4 * 1024); // 调整物理内存大小对齐到4k。win默认按4k分配物理内存
if (size == 0) {
return _allocVirtual(addr, container, false); // 不分配物理内存
} else if (size == container) {
return _allocVirtual(addr, container, true); // 分配全部物理内存
} else {
const bool ret = _allocVirtual(addr, container, false);
if (!ret) {
selfAlloc = false;
return false;
}
if (nullptr != VirtualAlloc(Addr, size, MEM_COMMIT, PAGE_READWRITE)) { // 分配指定大小的物理内存
memSize = size;
selfAlloc = true;
} else {
selfAlloc = true; // 虽然没有物理内存, 分到虚拟内存了也算selfAlloc
return false;
}
}
return true;
}
bool CWinMem::allocUpper(size_t container, size_t size)
{
ASSERT(container != 0);
ASSERT(size <= container);
AlignUp(container, 64_K);
AlignUp(size, 4_K);
std::lock_guard guard(uplocker);
if (size == 0) {
return _allocUpperVirtual(container, false);
}
else if (size == container) {
return _allocUpperVirtual(container, true);
}
else {
const bool ret = _allocUpperVirtual(container, false);
if (!ret) {
selfAlloc = false;
return false;
}
if (nullptr != VirtualAlloc(Addr, size, MEM_COMMIT, PAGE_READWRITE)) {
memSize = size;
selfAlloc = true;
}
else {
selfAlloc = true; // 虽然没有物理内存, 分到虚拟内存了也算selfAlloc
return false;
}
}
return true;
}
// 调整大小不影响containerSize、Addr和selfAlloc
bool CWinMem::resize(size_t size)
{
if (containerSize == 0) return false;
AlignUp(size, 4 * 1024);
if (size > containerSize) return false;
if (size == memSize) {
return true;
}
else if (size > memSize) {
if (nullptr != VirtualAlloc(Addr + memSize, size - memSize, MEM_COMMIT, PAGE_READWRITE)) {
memSize = size;
return true;
}
else {
return false;
}
}
else {
VirtualFree(Addr + size, memSize - size, MEM_DECOMMIT); // 有多的释放掉
memSize = size;
return true;
}
};
// 调整大小不影响containerSize、Addr和selfAlloc
bool CWinMem::reserve(size_t size)
{
if (containerSize == 0) return false;
AlignUp(size, 4 * 1024);
if (size > containerSize) return false;
if (size == memSize) return true;
else if (size > memSize) {
if (nullptr != VirtualAlloc(Addr + memSize, size - memSize, MEM_COMMIT, PAGE_READWRITE)) {
memSize = size;
return true;
}
else {
return false;
}
}else {
//VirtualFree(Addr + size, memSize - size, MEM_DECOMMIT); // 有多的不释放
return true;
}
}
void CWinMem::dealloc()
{
if (Addr) {
VirtualFree(Addr, 0, MEM_RELEASE); // 只能release整个区域
}
CMem::dealloc();
}
std::wstring CWinMem::details()
{
std::wstring str = fmt::format(L"虚拟内存地址:{}, 大小{}M物理内存大小{}M\n", (void*)Addr, containerSize / 1_M, memSize / 1_M);
return str;
}
bool CFileMapMem2::allocNamed(const std::wstring& name, size_t container, size_t size)
{
// 确认调用前的状态,避免逻辑错误
ASSERT(hand == nullptr); // 未创建内存映射文件
ASSERT(containerSize == 0); // 未映射文件
ASSERT(allMem.containerSize == 0); // 未分配虚拟内存
ASSERT(allMem.Addr == nullptr);
ASSERT(memSize == 0); // 未映射文件
// 确认参数有效
ASSERT(container > 0);
ASSERT(isAlign(container, 64_K));
ASSERT(size ==0);
_nativeKey = std::wstring(L"Ks_Grabber_MemMapFile_") + name;
std::lock_guard guard(uplocker);
allMem.Addr = static_cast<uint8_t*>(VirtualAlloc(
nullptr, // System selects address
container * 2, // Size of allocation
MEM_RESERVE | MEM_TOP_DOWN,
PAGE_READWRITE)); //只支持Read + Write未考虑其他情况
if(!allMem.Addr) return false;
allMem.containerSize = container * 2;
allMem.memSize = 0;
// Create the file mapping.
hand = CreateFileMapping(INVALID_HANDLE_VALUE
, nullptr
, PAGE_READWRITE | SEC_COMMIT // 不能加SEC_NOCACHE
, container >> 32, container & 0xFFFFFFFFu,
_nativeKey.c_str());
if (!hand) {
VirtualFree(allMem.Addr, 0, MEM_RELEASE); // 释放虚拟内存空间
allMem.containerSize = 0;
selfAlloc = false;
return false;
}
// 供外部访问的内存属性
Addr = nullptr; //地址后面mapFile()时再计算,反正只有映射了才能真正访问到。
containerSize = container; // 容量可以先保存下来。
memSize = 0;
memName = name;
selfAlloc = true;
return true;
}
void CFileMapMem2::dealloc()
{
std::lock_guard guard(uplocker);
unmapFile(false);
if(hand)
{
CloseHandle(hand);
hand = nullptr;
}
selfAlloc = false;
}
bool CFileMapMem2::resize(size_t size)
{
std::lock_guard guard(uplocker);
if (containerSize == 0) return false;
if (size > containerSize) return false;
if (size == 0) {
if (memSize == containerSize) {
unmapFile(true);
}
else if (memSize == 0) {
return true;
}
else {
return false;
}
}
else if (size == containerSize) {
if (memSize == containerSize) {
return true; // nothing todo
}
else if (memSize == 0) {
return mapFile();
}
else {
return false;
}
}
else {
return false;
}
return true;
}
bool CFileMapMem2::mapFile()
{
ASSERT(hand != nullptr);
ASSERT(allMem.containerSize > 0);
size_t fileSize = allMem.containerSize / 2;
size_t halfSize1 = fileSize / 2;
AlignDown(halfSize1, 64_K);
size_t halfSize2 = allMem.containerSize/2 - halfSize1;
ULARGE_INTEGER fileOffset1, fileOffset2;
fileOffset1.QuadPart = 0;
fileOffset2.QuadPart = halfSize1;
VirtualFree(allMem.Addr, 0, MEM_RELEASE); // 释放虚拟内存空间
//但内存总容量allMem.containerSize保持不变
// 内存 映像文件
// -------------
// | 2 |
// ============== --- ==============
// | 1 | | 1 |
// -------------- --------------
// | 2 | | 2 |
// ============== --- ==============
// | 1 |
// --------------
Addr = (uint8_t*)MapViewOfFileEx(hand, FILE_MAP_ALL_ACCESS
, fileOffset1.HighPart, fileOffset1.LowPart
, fileSize, allMem.Addr + halfSize2);
if(!Addr)
{
return false;
}
containerSize = memSize = allMem.containerSize/2;
BottomMem.Addr = (uint8_t*)MapViewOfFileEx(hand, FILE_MAP_READ
, fileOffset1.HighPart, fileOffset1.LowPart
, halfSize1, allMem.Addr + halfSize2 + fileSize);
TopMem.Addr = (uint8_t*)MapViewOfFileEx(hand, FILE_MAP_READ
, fileOffset2.HighPart, fileOffset2.LowPart
, halfSize2, allMem.Addr);
if(!TopMem.Addr || !BottomMem.Addr) // 前面成功了,这里不大可能失败,稳妥起见加上
{
UnmapViewOfFile(Addr);
Addr = nullptr;
containerSize = memSize = 0;
if (TopMem.Addr) UnmapViewOfFile(TopMem.Addr);
if (BottomMem.Addr) UnmapViewOfFile(BottomMem.Addr);
TopMem.dealloc();
BottomMem.dealloc();
return false;
}else
{
TopMem.containerSize = halfSize2;
TopMem.memSize = 0;
BottomMem.containerSize = halfSize1;
TopMem.memSize = 0;
}
verifyMap();
return true;
}
void CFileMapMem2::unmapFile(bool realloc)
{
if (containerSize == 0 || hand == nullptr) return;
if (memSize == containerSize) {
if (TopMem.Addr) UnmapViewOfFile(TopMem.Addr);
if (BottomMem.Addr) UnmapViewOfFile(BottomMem.Addr);
if (Addr) UnmapViewOfFile(Addr);
TopMem.dealloc();
BottomMem.dealloc();
Addr = nullptr;
containerSize = memSize = 0;
if (realloc) {
_allocVirtual(allMem.Addr, allMem.containerSize, false);
}
else {
allMem.dealloc();
}
}
}
bool CFileMapMem2::verifyMap(bool compare_content)
{
ASSERT(hand != nullptr);
// 验证容量
ASSERT(containerSize != 0);
ASSERT(memSize = containerSize);
ASSERT(containerSize = allMem.containerSize / 2);
ASSERT(TopMem.containerSize + BottomMem.containerSize == containerSize);
// 验证地址
ASSERT(allMem.Addr);
ASSERT(TopMem.Addr == allMem.Addr);
ASSERT(Addr == allMem.Addr + TopMem.containerSize);
ASSERT(BottomMem.Addr = Addr + containerSize);
// 验证内容
bool succ = true;
if(compare_content)
{
uint64_t* p = (uint64_t*)(Addr);
for(int i=0; i<containerSize/8; i++)
{
*p++ = i;
}
if (memcmp(Addr, BottomMem.Addr, BottomMem.containerSize) != 0)
{
alog->error("memcmp(Addr, BottomMem.Addr, BottomMem.containerSize) != 0");
succ = false;
}
else {
alog->info("底部映射验证通过");
}
if (memcmp(Addr + BottomMem.containerSize, TopMem.Addr, TopMem.containerSize) != 0)
{
alog->error("Addr + BottomMem.containerSize, TopMem.Addr, TopMem.containerSize) != 0");
succ = false;
}
else {
alog->info("顶部映射验证通过");
}
}
return succ;
}
std::wstring CFileMapMem2::details()
{
std::wstring str = fmt::format(L"虚拟内存地址:{}, 大小{}M\n", (void *)allMem.Addr, allMem.containerSize/1_M);
str += fmt::format(L"数据内存地址:{}, 偏移量:{}M大小{}M\n", (void*)Addr, (Addr - allMem.Addr) / 1_M, memSize / 1_M);
str += fmt::format(L"底部内存地址:{}, 偏移量:{:4d}M大小{:4d}M映射到偏移量{:4d}M\n"
, (void*)BottomMem.Addr, (BottomMem.Addr - allMem.Addr) / 1_M, BottomMem.containerSize / 1_M, (Addr - allMem.Addr) / 1_M);
str += fmt::format(L"顶部内存地址:{}, 偏移量:{:4d}M大小{:4d}M映射到偏移量{:4d}M\n"
, (void*)TopMem.Addr, (TopMem.Addr - allMem.Addr) / 1_M, TopMem.containerSize / 1_M, (TopMem.containerSize+ BottomMem.containerSize) / 1_M);
return str;
}