📄 mem_win32.c
字号:
if (!p->Length)
{
int Align = Phy & 4095;
Phy -= Align;
Length = (Length + Align + 4095) & ~4095;
p->Virt = (char*) VirtualAlloc(0, Length, MEM_RESERVE, PAGE_NOACCESS);
if (p->Virt)
{
int Mode = PAGE_READWRITE | PAGE_PHYSICAL;
if (!Cached)
Mode |= PAGE_NOCACHE;
if (FuncVirtualCopy(p->Virt,(LPVOID)(Phy >> 8), Length, Mode))
{
p->RefCount = 1;
p->Phy = Phy;
p->Length = Length;
p->BlockCount = 1;
#ifdef ARM
if (Cached && FuncVirtualSetAttributes && (QueryPlatform(PLATFORM_CAPS) & CAPS_ARM_XSCALE))
FuncVirtualSetAttributes(p->Virt,Length,TBL_CACHE|TBL_BUFFER,TBL_CACHE|TBL_BUFFER,NULL);
#endif
return p->Virt + Align;
}
VirtualFree(p->Virt,0,MEM_RELEASE);
}
return NULL;
}
}
}
#endif
return NULL;
}
void PhyMemEnd(void* Virt)
{
#if defined(TARGET_WINCE)
if (Virt)
{
phymem* p;
for (p=PhyMem;p!=PhyMem+MAXPHY;++p)
if (p->RefCount && p->Virt <= (char*)Virt && p->Virt+p->Length > (char*)Virt)
{
--p->RefCount;
break;
}
}
#endif
}
bool_t MemGetInfo(memoryinfo* p)
{
return 0;
}
void* CodeAlloc(int Size)
{
void* p;
do
{
p = VirtualAlloc(NULL,Size,MEM_COMMIT,PAGE_EXECUTE_READ);
}
while (!p && Size && NodeHibernate());
return p;
}
void CodeFree(void* Code,int Size)
{
VirtualFree(Code,Size,MEM_DECOMMIT);
VirtualFree(Code,0,MEM_RELEASE);
}
void CodeLock(void* Code,int Size)
{
DWORD Protect;
VirtualProtect(Code,Size,PAGE_READWRITE|PAGE_NOCACHE,&Protect);
}
void CodeUnlock(void* Code,int Size)
{
DWORD Protect;
VirtualProtect(Code,Size,PAGE_EXECUTE_READ,&Protect);
#if defined(TARGET_WINCE)
if (FuncCacheSync)
FuncCacheSync(CACHE_SYNC_INSTRUCTIONS);
#endif
}
void CodeFindPages(void* Ptr,uint8_t** PMin,uint8_t** PMax,uintptr_t* PPageSize)
{
uint8_t* Min;
uint8_t* Max;
uintptr_t PageSize =
#if defined(MIPS)
1024;
#else
4096;
#endif
if (PPageSize)
*PPageSize = PageSize;
Min = Max = (uint8_t*)((uintptr_t)Ptr & ~(PageSize-1));
while (!IsBadCodePtr((FARPROC)(Min-PageSize)))
Min -= PageSize;
while (!IsBadCodePtr((FARPROC)Max))
Max += PageSize;
*PMin = Min;
*PMax = Max;
}
void CheckHeap()
{
#if defined(_DEBUG) && defined(_MSC_VER) && (_MSC_VER < 1400)
assert(_CrtCheckMemory());
#endif
}
//#define FIND 0xAD1A30
size_t AvailMemory()
{
MEMORYSTATUS Status;
Status.dwLength = sizeof(Status);
GlobalMemoryStatus(&Status);
return Status.dwAvailPhys;
}
void WriteBlock(block* Block,int Ofs,const void* Src,int Length)
{
memcpy((uint8_t*)Block->Ptr+Ofs,Src,Length);
}
void FreeBlock(block* p)
{
if (p)
{
#ifdef BLOCKGROUP
if (p->Id) //group
{
blockgroup* g = ARRAYBEGIN(BlockGroup,blockgroup)+(p->Id>>8);
int Bit = 1 << ((p->Id & 255)-1);
if (g<ARRAYEND(BlockGroup,blockgroup) && g->Mask & Bit)
{
g->Mask &= ~Bit;
if (!g->Mask)
FreeBlock(&g->Block);
}
p->Ptr = NULL;
p->Id = 0;
return;
}
#endif
#ifndef NDEBUG
if (VirtualFree((void*)p->Ptr,0,MEM_RELEASE))
--BlockAllocated;
#else
VirtualFree((void*)p->Ptr,0,MEM_RELEASE);
#endif
p->Ptr = NULL;
p->Id = 0;
}
}
bool_t SetHeapBlock(int n,block* Block,int Heap)
{
return 0;
}
#ifdef BLOCKGROUP
static bool_t AllocBlockGroup(block* Block, bool_t Optional)
{
int n;
blockgroup* g;
for (g=ARRAYBEGIN(BlockGroup,blockgroup);g!=ARRAYEND(BlockGroup,blockgroup);++g)
if (g->Mask && g->Mask != (1<<BLOCKGROUP)-1)
break;
if (g==ARRAYEND(BlockGroup,blockgroup))
{
if (!Optional)
return 0;
for (g=ARRAYBEGIN(BlockGroup,blockgroup);g!=ARRAYEND(BlockGroup,blockgroup);++g)
if (!g->Mask)
break;
if (g==ARRAYEND(BlockGroup,blockgroup))
{
if (!ArrayAppend(&BlockGroup,NULL,sizeof(blockgroup),64))
return 0;
g=ARRAYEND(BlockGroup,blockgroup)-1;
g->Mask = 0;
}
if (!AllocBlock(BLOCKSIZE*BLOCKGROUP,&g->Block,1,HEAP_ANY))
return 0;
}
for (n=0;n<BLOCKGROUP;++n)
if (!(g->Mask & (1<<n)))
{
g->Mask |= (1<<n);
Block->Id = ((g-ARRAYBEGIN(BlockGroup,blockgroup))<<8)+(n+1);
Block->Ptr = g->Block.Ptr + n*BLOCKSIZE;
return 1;
}
return 0;
}
#endif
bool_t AllocBlock(size_t n,block* Block,bool_t Optional,int Heap)
{
void* p;
if (Optional && AvailMemory() < (256+64)*1024+n) // we want to avoid OS low memory warning
return 0;
#ifdef BLOCKGROUP
if (n == BLOCKSIZE && AllocBlockGroup(Block,Optional))
return 1;
#endif
do
{
p = VirtualAlloc(NULL,n,MEM_COMMIT,PAGE_READWRITE);
}
while (!p && !Optional && n && NodeHibernate());
Block->Ptr = p;
Block->Id = 0;
#ifndef NDEBUG
if (p) ++BlockAllocated;
#endif
return p!=NULL;
}
#undef malloc
#undef realloc
#undef free
#ifdef SAFEGUARD
void* safeset(uint8_t* p,int n,bool_t clear)
{
if (p)
{
*(int*)p = n;
p += sizeof(int);
memset(p,0xDA,SAFEGUARD);
p += SAFEGUARD;
if (clear)
memset(p,0xCC,n);
p += n;
memset(p,0xDE,SAFEGUARD);
p -= n;
}
return p;
}
void* safeget(uint8_t* p,bool_t clear)
{
if (p)
{
int n = *(int*)(p-SAFEGUARD-sizeof(int));
int i;
for (i=0;i<SAFEGUARD;++i)
assert(p[-i-1] == 0xDA);
for (i=0;i<SAFEGUARD;++i)
assert(p[n+i] == 0xDE);
p -= SAFEGUARD+sizeof(int);
if (clear)
memset(p,0xEE,n+SAFEGUARD*2+sizeof(int));
}
return p;
}
#endif
void* malloc_win32(size_t n)
{
void* p = NULL;
if (n)
{
do
{
#ifdef SAFEGUARD
p = safeset(malloc(n+SAFEGUARD*2+sizeof(int)),n,1);
#else
p = malloc(n);
#endif
#ifdef FIND
if ((int)p == FIND)
DebugBreak();
#endif
} while (!p && NodeHibernate());
}
return p;
}
void* realloc_win32(void* p,size_t n)
{
do
{
#ifdef SAFEGUARD
p = safeset(realloc(safeget(p,0),n+SAFEGUARD*2+sizeof(int)),n,p==NULL);
#else
p = realloc(p,n);
#endif
#ifdef FIND
if ((int)p == FIND)
DebugBreak();
#endif
} while (!p && n && NodeHibernate());
return p;
}
void free_win32(void* p)
{
#ifdef SAFEGUARD
free(safeget(p,1));
#else
free(p);
#endif
}
void ShowOutOfMemory()
{
}
void EnableOutOfMemory()
{
}
void DisableOutOfMemory()
{
}
void Mem_Init()
{
SYSTEM_INFO SysInfo;
#if defined(_DEBUG) && defined(_MSC_VER) && !defined(TARGET_WINCE)
int Flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
Flag |= _CRTDBG_LEAK_CHECK_DF;
Flag |= _CRTDBG_CHECK_ALWAYS_DF;
_CrtSetDbgFlag(Flag);
#endif
#if defined(TARGET_WINCE)
CoreDLL = LoadLibrary(T("coredll.dll"));
if (CoreDLL)
{
*(FARPROC*)&FuncCacheSync = GetProcAddress(CoreDLL,T("CacheSync"));
*(FARPROC*)&FuncVirtualCopy = GetProcAddress(CoreDLL,T("VirtualCopy"));
*(FARPROC*)&FuncVirtualSetAttributes = GetProcAddress(CoreDLL,T("VirtualSetAttributes"));
*(FARPROC*)&FuncFreePhysMem = GetProcAddress(CoreDLL,T("FreePhysMem"));
*(FARPROC*)&FuncAllocPhysMem = GetProcAddress(CoreDLL,T("AllocPhysMem"));
*(FARPROC*)&FuncLockPages = GetProcAddress(CoreDLL,T("LockPages"));
*(FARPROC*)&FuncUnlockPages = GetProcAddress(CoreDLL,T("UnlockPages"));
}
#endif
GetSystemInfo(&SysInfo);
PageSize = SysInfo.dwPageSize;
}
void Mem_Done()
{
#if defined(TARGET_WINCE)
phymem* p;
for (p=PhyMem;p!=PhyMem+MAXPHY;++p)
if (p->Length)
{
free(p->Blocks);
SafeVirtualFree(p->Virt,p->Length);
memset(p,0,sizeof(phymem));
}
if (CoreDLL) FreeLibrary(CoreDLL);
#endif
#ifndef NDEBUG
assert(BlockAllocated==0);
#endif
ArrayClear(&BlockGroup);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -