phobos/internal/gc/win32.d
2007-09-10 03:56:33 +00:00

147 lines
3.3 KiB
D

// Copyright (C) 2001-2002 by Digital Mars
// All Rights Reserved
// www.digitalmars.com
// Written by Walter Bright
import std.c.windows.windows;
alias int pthread_t;
/***********************************
* Map memory.
*/
void *os_mem_map(uint nbytes)
{
return VirtualAlloc(null, nbytes, MEM_RESERVE, PAGE_READWRITE);
}
/***********************************
* Commit memory.
* Returns:
* 0 success
* !=0 failure
*/
int os_mem_commit(void *base, uint offset, uint nbytes)
{
void *p;
p = VirtualAlloc(base + offset, nbytes, MEM_COMMIT, PAGE_READWRITE);
return (p == null);
}
/***********************************
* Decommit memory.
* Returns:
* 0 success
* !=0 failure
*/
int os_mem_decommit(void *base, uint offset, uint nbytes)
{
return VirtualFree(base + offset, nbytes, MEM_DECOMMIT) == 0;
}
/***********************************
* Unmap memory allocated with os_mem_map().
* Memory must have already been decommitted.
* Returns:
* 0 success
* !=0 failure
*/
int os_mem_unmap(void *base, uint nbytes)
{
return VirtualFree(base, 0, MEM_RELEASE) == 0;
}
/********************************************
*/
pthread_t pthread_self()
{
//printf("pthread_self() = %x\n", GetCurrentThreadId());
return cast(pthread_t) GetCurrentThreadId();
}
/**********************************************
* Determine "bottom" of stack (actually the top on Win32 systems).
*/
void *os_query_stackBottom()
{
asm
{
naked ;
mov EAX,FS:4 ;
ret ;
}
}
/**********************************************
* Determine base address and size of static data segment.
*/
extern (C)
{
extern int _xi_a; // &_xi_a just happens to be start of data segment
extern int _edata; // &_edata is start of BSS segment
extern int _end; // &_end is past end of BSS
}
void os_query_staticdataseg(void **base, uint *nbytes)
{
*base = cast(void *)&_xi_a;
*nbytes = cast(uint)(cast(char *)&_end - cast(char *)&_xi_a);
}
/++++
void os_query_staticdataseg(void **base, uint *nbytes)
{
static char dummy = 6;
SYSTEM_INFO si;
MEMORY_BASIC_INFORMATION mbi;
char *p;
void *bottom = null;
uint size = 0;
// Tests show the following does not work reliably.
// The reason is that the data segment is arbitrarilly divided
// up into PAGE_READWRITE and PAGE_WRITECOPY.
// This means there are multiple regions to query, and
// can even wind up including the code segment.
assert(0); // fix implementation
GetSystemInfo(&si);
p = (char *)((uint)(&dummy) & ~(si.dwPageSize - 1));
while (VirtualQuery(p, &mbi, sizeof(mbi)) == sizeof(mbi) &&
mbi.Protect & (PAGE_READWRITE | PAGE_WRITECOPY) &&
!(mbi.Protect & PAGE_GUARD) &&
mbi.AllocationBase != 0)
{
bottom = (void *)mbi.BaseAddress;
size = (uint)mbi.RegionSize;
printf("dwPageSize = x%x\n", si.dwPageSize);
printf("&dummy = %p\n", &dummy);
printf("BaseAddress = %p\n", mbi.BaseAddress);
printf("AllocationBase = %p\n", mbi.AllocationBase);
printf("AllocationProtect = x%x\n", mbi.AllocationProtect);
printf("RegionSize = x%x\n", mbi.RegionSize);
printf("State = x%x\n", mbi.State);
printf("Protect = x%x\n", mbi.Protect);
printf("Type = x%x\n\n", mbi.Type);
p -= si.dwPageSize;
}
*base = bottom;
*nbytes = size;
}
++++/