0ad/source/lib/sysdep/win/wposix/wposix.cpp
2007-05-24 12:31:16 +00:00

126 lines
3.2 KiB
C++

/**
* =========================================================================
* File : wposix.cpp
* Project : 0 A.D.
* Description : emulate a subset of POSIX on Win32.
* =========================================================================
*/
// license: GPL; see lib/license.txt
#include "precompiled.h"
#include "wposix.h"
#include "wposix_internal.h"
#include "crt_posix.h" // _getcwd
#include "lib/bits.h"
#pragma SECTION_PRE_LIBC(J)
WIN_REGISTER_FUNC(wposix_Init);
#pragma FORCE_INCLUDE(wposix_Init)
#pragma SECTION_RESTORE
//-----------------------------------------------------------------------------
// sysconf
// used by _SC_PAGESIZE and _SC_*_PAGES
static DWORD page_size;
static BOOL (WINAPI *pGlobalMemoryStatusEx)(MEMORYSTATUSEX*);
static void InitSysconf()
{
// get page size
// (used by _SC_PAGESIZE and _SC_*_PAGES)
SYSTEM_INFO si;
GetSystemInfo(&si); // can't fail => page_size always > 0.
page_size = si.dwPageSize;
// import GlobalMemoryStatusEx - it's not defined by the VC6 PSDK.
// used by _SC_*_PAGES if available (provides better results).
const HMODULE hKernel32Dll = LoadLibrary("kernel32.dll");
*(void**)&pGlobalMemoryStatusEx = GetProcAddress(hKernel32Dll, "GlobalMemoryStatusEx");
FreeLibrary(hKernel32Dll);
}
long sysconf(int name)
{
debug_assert(page_size); // must not be called before InitSysconf
switch(name)
{
case _SC_PAGESIZE:
// note: no separate case for _SC_PAGE_SIZE - they are
// different names but have the same value.
return page_size;
case _SC_PHYS_PAGES:
case _SC_AVPHYS_PAGES:
{
u64 total_phys_mem;
u64 avail_phys_mem;
// first query GlobalMemoryStatus - cannot fail.
// override its results if GlobalMemoryStatusEx is available.
{
MEMORYSTATUS ms;
GlobalMemoryStatus(&ms);
total_phys_mem = ms.dwTotalPhys;
avail_phys_mem = ms.dwAvailPhys;
}
// newer API is available: use it to report correct results
// (no overflow or wraparound) on systems with > 4 GB of memory.
{
MEMORYSTATUSEX mse = { sizeof(mse) };
if(pGlobalMemoryStatusEx && pGlobalMemoryStatusEx(&mse))
{
total_phys_mem = mse.ullTotalPhys;
avail_phys_mem = mse.ullAvailPhys;
}
// else: not an error, since this isn't available before Win2k / XP.
// we have results from GlobalMemoryStatus anyway.
}
// Richter, "Programming Applications for Windows": the reported
// value doesn't include non-paged pool reserved during boot;
// it's not considered available to kernel. (size is 528 KiB on
// a 512 MiB WinXP/Win2k machine)
// something similar may happen on other OSes, so it is fixed
// by cpu.cpp instead of here.
if(name == _SC_PHYS_PAGES)
return (long)(total_phys_mem / page_size);
else
return (long)(avail_phys_mem / page_size);
}
default:
return -1;
}
}
//-----------------------------------------------------------------------------
#ifdef REDEFINED_NEW
# include "lib/nommgr.h"
#endif
char* getcwd(char* buf, size_t buf_size)
{
return _getcwd(buf, (int)buf_size);
}
#ifdef REDEFINED_NEW
# include "lib/mmgr.h"
#endif
//-----------------------------------------------------------------------------
static LibError wposix_Init()
{
InitSysconf();
return INFO::OK;
}