/// get the working size of the process. // @return minimum working set size // @return maximum working set size. // @function get_working_size def get_working_size() { SIZE_T minsize, maxsize; GetProcessWorkingSetSize(this->hProcess,&minsize,&maxsize); lua_pushnumber(L,minsize/1024); lua_pushnumber(L,maxsize/1024); return 2; }
/// <summary> /// Unlink memory VAD node /// </summary> /// <param name="imageMem">Image to purge</param> /// <returns>bool on success</returns> bool MMap::UnlinkVad( const MemBlock& imageMem ) { HANDLE hFile = CreateFile( _T( "\\\\.\\VadPurge" ), GENERIC_ALL, 0, NULL, OPEN_EXISTING, 0, NULL ); // Load missing driver if (hFile == INVALID_HANDLE_VALUE) { std::wstring drvPath = Utils::GetExeDirectory() + L"\\"; if (IsWindows8Point1OrGreater()) drvPath += L"VadPurge81.sys"; else if(IsWindows8OrGreater()) drvPath += L"VadPurge8.sys"; else if(IsWindows7OrGreater()) drvPath += L"VadPurge7.sys"; NTSTATUS status = Utils::LoadDriver( L"VadPurge", drvPath ); if (status != ERROR_SUCCESS && status != STATUS_IMAGE_ALREADY_LOADED) return false; hFile = CreateFile( _T( "\\\\.\\VadPurge" ), GENERIC_ALL, 0, NULL, OPEN_EXISTING, 0, NULL ); } // // Lock pages in working set before unlinking // UserMode page faults can't be resolved without VAD record // if (hFile != INVALID_HANDLE_VALUE) { // // Adjust working set and lock pages // SIZE_T sizeMin = 0, sizeMax = 0; BOOL ret = FALSE; GetProcessWorkingSetSize( _process.core().handle(), &sizeMin, &sizeMax ); SetProcessWorkingSetSize( _process.core().handle(), sizeMin + imageMem.size(), sizeMax + imageMem.size() ); PVOID pBase = imageMem.ptr<PVOID>(); ULONG size = static_cast<ULONG>(imageMem.size()); NTSTATUS status = GET_IMPORT( NtLockVirtualMemory )(_process.core().handle(), &pBase, &size, 1); // Continue only if pages are locked if (status == STATUS_SUCCESS) { PURGE_DATA data = { _process.core().pid(), 1, { imageMem.ptr<ULONGLONG>(), imageMem.size() } }; DWORD junk = 0; ret = DeviceIoControl( hFile, static_cast<DWORD>(IOCTL_VADPURGE_PURGE), &data, sizeof(data), NULL, 0, &junk, NULL ); } CloseHandle( hFile ); return (status == STATUS_SUCCESS && ret == TRUE) ? true : false; } return false; }
BOOL My_GetProcessWorkingSetSize() { HANDLE hProcess=NULL; PSIZE_T lpMinimumWorkingSetSize=NULL; PSIZE_T lpMaximumWorkingSetSize=NULL; BOOL returnVal_Real = NULL; BOOL returnVal_Intercepted = NULL; DWORD error_Real = 0; DWORD error_Intercepted = 0; __try{ disableInterception(); returnVal_Real = GetProcessWorkingSetSize (hProcess,lpMinimumWorkingSetSize,lpMaximumWorkingSetSize); error_Real = GetLastError(); enableInterception(); returnVal_Intercepted = GetProcessWorkingSetSize (hProcess,lpMinimumWorkingSetSize,lpMaximumWorkingSetSize); error_Intercepted = GetLastError(); }__except(puts("in filter"), 1){puts("exception caught");} return ((returnVal_Real == returnVal_Intercepted) && (error_Real == error_Intercepted)); }
void print_rusage (void) { #if defined(WIN32) //int i; static SIZE_T previous = 0; DWORD minWSS, maxWSS; GetProcessWorkingSetSize (GetCurrentProcess(), &minWSS, &maxWSS); #if 0 const DWORD maxH = 100; HANDLE heaps[maxH], nbrh; nbrh = GetProcessHeaps (maxH, heaps); if (nbrh > maxH) nbrh = maxH; unsigned long hsize = 0; for (i = 0; i < nbrh; ++i) hsize += HeapSize (heaps[i], 0, heaps[i]); MEMORY_BASIC_INFORMATION mbi; mbi.RegionSize = 1234; if (VirtualQuery (NULL, &mbi, sizeof(mbi)) != sizeof(mbi)) { } printf ("RUSAGE: VQ=%ld minWSS=%ld maxWSS=%ld\n", mbi.RegionSize, minWSS, maxWSS); #endif PROCESS_MEMORY_COUNTERS PMC; memset(&PMC, 0, sizeof(PMC)); // Set size of structure PMC.cb = sizeof(PMC); // Get memory usage GetProcessMemoryInfo(GetCurrentProcess(), &PMC, sizeof(PMC)); printf ("RUSAGE: PFU += %6ld kb peakPFU=%3ld.%03ld peakWSS=%3ld.%03ld (Mbytes)\n", (PMC.PeakPagefileUsage-previous)/1024, PMC.PeakPagefileUsage/(1024*1024), (PMC.PeakPagefileUsage%(1024*1024))/1000, PMC.PeakWorkingSetSize/(1024*1024), (PMC.PeakWorkingSetSize%(1024*1024))/1000); previous = PMC.PeakPagefileUsage; #endif }
int uGetCurProcessWorkingSetSize(usize_t *MinWorkingSetSize, usize_t *MaxWorkingSetSize, sys_call_error_fun fun) { #ifdef _WIN32 BOOL res = GetProcessWorkingSetSize( GetCurrentProcess(), // handle to the process MinWorkingSetSize, // minimum working set size MaxWorkingSetSize // maximum working set size ); if (res == 0) { sys_call_error("GetProcessWorkingSetSize"); return 1; } return 0; #else *MinWorkingSetSize = *MaxWorkingSetSize = 0; return 0; #endif }
static int extend_memory(size_t size) { // page commit SIZE_T minimum=0,maximum=0; if(GetProcessWorkingSetSize(GetCurrentProcess(),&minimum,&maximum)) { debug("btw, min=%d max=%d\n",minimum/1024,maximum/1024); minimum+=size; if(maximum<minimum+size) maximum=minimum+size; debug("kxasio: extending working space by %d bytes [min=%d max=%d]...\n",size,minimum,maximum); if(SetProcessWorkingSetSize(GetCurrentProcess(),minimum,maximum)==0) { char tmp_str[128]; sprintf(tmp_str,"Error increasing current process's virtual memory amount. You should have Administrator privileges. Error code: %x\n",GetLastError()); MessageBox(NULL,tmp_str,"kX ASIO",MB_OK|MB_ICONSTOP); return ASE_NoMemory; } } else debug("!! kxasio: GetProcessWorkingSetSize error\n",GetLastError()); return 0; }
static int memlimit_rlimit(size_t * memlimit) { SYSTEM_INFO sysinfo; HANDLE hproc; SIZE_T dwmin = 0; SIZE_T dwmax = 345; /* Seems like the default max from msdn */ sysinfo.dwPageSize = 4096; /* Default to 4K */ GetSystemInfo(&sysinfo); hproc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, _getpid()); if (!GetProcessWorkingSetSize(hproc, &dwmin, &dwmax)) { #ifdef DEBUG fprintf(stderr, "failed to get max working set size. E=%d\n", GetLastError()); #endif } CloseHandle(hproc); *memlimit = dwmax * sysinfo.dwPageSize; return (0); }
int mem_usage(double& vm_usage, double& resident_set) { #ifdef _WIN32 // Figure out if we're on WinNT OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof(osvi); GetVersionEx( &osvi ); if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) { SIZE_T lpMinimumWorkingSetSize; SIZE_T lpMaximumWorkingSetSize; GetProcessWorkingSetSize( GetCurrentProcess(), &lpMinimumWorkingSetSize, &lpMaximumWorkingSetSize ); vm_usage = (double)lpMinimumWorkingSetSize; resident_set = (double)lpMaximumWorkingSetSize; } else { return ERR_NOT_IMPLEMENTED; } return 0; #else #if defined(HAVE_PROCFS_H) && defined(HAVE__PROC_SELF_PSINFO) FILE* f; // guess that this is solaris // need psinfo_t from procfs.h // if ((f = fopen("/proc/self/psinfo", "r")) != 0) { psinfo_t psinfo; if (fread(&psinfo, sizeof(psinfo_t), 1, f) == 1) { vm_usage = psinfo.pr_size*1024.; resident_set = psinfo.pr_rssize*1024.; fclose(f); return 0; } else { fclose(f); return ERR_FREAD; } } #endif #if defined(HAVE__PROC_SELF_STAT) FILE* f; // guess that this is linux // if ((f = fopen("/proc/self/stat", "r")) != 0) { char buf[256]; char* p; int i; unsigned long tmp; i = fread(buf, sizeof(char), 255, f); buf[i] = '\0'; // terminate string p = &buf[0]; // skip over first 22 fields // for (i = 0; i < 22; ++i) { p = strchr(p, ' '); if (!p) break; ++p; // move past space } if (!p) { return ERR_NOT_IMPLEMENTED; } // read virtual memory size in bytes. // vm_usage = atof(p); p = strchr(p, ' '); // read resident set size: number of pages the process has in // real memory, minus 3 for administrative purposes. // tmp = strtol(p, 0, 0); resident_set = (double)(tmp + 3)*getpagesize(); fclose(f); return 0; } #endif return ERR_NOT_IMPLEMENTED; #endif }
/* This is the fastpoll function which gathers up info by calling various api's */ BOOL FastPoll (void) { int nOriginalRandIndex = nRandIndex; static BOOL addedFixedItems = FALSE; FILETIME creationTime, exitTime, kernelTime, userTime; SIZE_T minimumWorkingSetSize, maximumWorkingSetSize; LARGE_INTEGER performanceCount; MEMORYSTATUS memoryStatus; HANDLE handle; POINT point; /* Get various basic pieces of system information */ RandaddIntPtr (GetActiveWindow ()); /* Handle of active window */ RandaddIntPtr (GetCapture ()); /* Handle of window with mouse capture */ RandaddIntPtr (GetClipboardOwner ()); /* Handle of clipboard owner */ RandaddIntPtr (GetClipboardViewer ()); /* Handle of start of clpbd.viewer list */ RandaddIntPtr (GetCurrentProcess ()); /* Pseudohandle of current process */ RandaddInt32 (GetCurrentProcessId ()); /* Current process ID */ RandaddIntPtr (GetCurrentThread ()); /* Pseudohandle of current thread */ RandaddInt32 (GetCurrentThreadId ()); /* Current thread ID */ RandaddInt32 (GetCurrentTime ()); /* Milliseconds since Windows started */ RandaddIntPtr (GetDesktopWindow ()); /* Handle of desktop window */ RandaddIntPtr (GetFocus ()); /* Handle of window with kb.focus */ RandaddInt32 (GetInputState ()); /* Whether sys.queue has any events */ RandaddInt32 (GetMessagePos ()); /* Cursor pos.for last message */ RandaddInt32 (GetMessageTime ()); /* 1 ms time for last message */ RandaddIntPtr (GetOpenClipboardWindow ()); /* Handle of window with clpbd.open */ RandaddIntPtr (GetProcessHeap ()); /* Handle of process heap */ RandaddIntPtr (GetProcessWindowStation ()); /* Handle of procs window station */ RandaddInt32 (GetQueueStatus (QS_ALLEVENTS)); /* Types of events in input queue */ /* Get multiword system information */ GetCaretPos (&point); /* Current caret position */ RandaddBuf ((unsigned char *) &point, sizeof (POINT)); GetCursorPos (&point); /* Current mouse cursor position */ RandaddBuf ((unsigned char *) &point, sizeof (POINT)); /* Get percent of memory in use, bytes of physical memory, bytes of free physical memory, bytes in paging file, free bytes in paging file, user bytes of address space, and free user bytes */ memoryStatus.dwLength = sizeof (MEMORYSTATUS); GlobalMemoryStatus (&memoryStatus); RandaddBuf ((unsigned char *) &memoryStatus, sizeof (MEMORYSTATUS)); /* Get thread and process creation time, exit time, time in kernel mode, and time in user mode in 100ns intervals */ handle = GetCurrentThread (); GetThreadTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime); RandaddBuf ((unsigned char *) &creationTime, sizeof (FILETIME)); RandaddBuf ((unsigned char *) &exitTime, sizeof (FILETIME)); RandaddBuf ((unsigned char *) &kernelTime, sizeof (FILETIME)); RandaddBuf ((unsigned char *) &userTime, sizeof (FILETIME)); handle = GetCurrentProcess (); GetProcessTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime); RandaddBuf ((unsigned char *) &creationTime, sizeof (FILETIME)); RandaddBuf ((unsigned char *) &exitTime, sizeof (FILETIME)); RandaddBuf ((unsigned char *) &kernelTime, sizeof (FILETIME)); RandaddBuf ((unsigned char *) &userTime, sizeof (FILETIME)); /* Get the minimum and maximum working set size for the current process */ GetProcessWorkingSetSize (handle, &minimumWorkingSetSize, &maximumWorkingSetSize); RandaddIntPtr (minimumWorkingSetSize); RandaddIntPtr (maximumWorkingSetSize); /* The following are fixed for the lifetime of the process so we only add them once */ if (addedFixedItems == 0) { STARTUPINFO startupInfo; /* Get name of desktop, console window title, new window position and size, window flags, and handles for stdin, stdout, and stderr */ startupInfo.cb = sizeof (STARTUPINFO); GetStartupInfo (&startupInfo); RandaddBuf ((unsigned char *) &startupInfo, sizeof (STARTUPINFO)); addedFixedItems = TRUE; } /* The docs say QPC can fail if appropriate hardware is not available. It works on 486 & Pentium boxes, but hasn't been tested for 386 or RISC boxes */ if (QueryPerformanceCounter (&performanceCount)) RandaddBuf ((unsigned char *) &performanceCount, sizeof (LARGE_INTEGER)); else { /* Millisecond accuracy at best... */ DWORD dwTicks = GetTickCount (); RandaddBuf ((unsigned char *) &dwTicks, sizeof (dwTicks)); } // CryptoAPI: We always have a valid CryptoAPI context when we arrive here but // we keep the check for clarity purpose if ( !CryptoAPIAvailable ) return FALSE; if (CryptGenRandom (hCryptProv, sizeof (buffer), buffer)) { RandaddBuf (buffer, sizeof (buffer)); burn (buffer, sizeof(buffer)); } else { /* return error in case CryptGenRandom fails */ CryptoAPILastError = GetLastError (); return FALSE; } /* Apply the pool mixing function */ Randmix(); /* Restore the original pool cursor position. If this wasn't done, mouse coordinates could be written to a limited area of the pool, especially when moving the mouse uninterruptedly. The severity of the problem would depend on the length of data written by FastPoll (if it was equal to the size of the pool, mouse coordinates would be written only to a particular 4-byte area, whenever moving the mouse uninterruptedly). */ nRandIndex = nOriginalRandIndex; return TRUE; }
int _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t, int), int requester ) { static int addedFixedItems = 0; if ( debug_me ) log_debug ("rndw32#gather_random_fast: req=%d\n", requester ); /* Get various basic pieces of system information: Handle of active * window, handle of window with mouse capture, handle of clipboard owner * handle of start of clpboard viewer list, pseudohandle of current * process, current process ID, pseudohandle of current thread, current * thread ID, handle of desktop window, handle of window with keyboard * focus, whether system queue has any events, cursor position for last * message, 1 ms time for last message, handle of window with clipboard * open, handle of process heap, handle of procs window station, types of * events in input queue, and milliseconds since Windows was started */ { byte buffer[20*sizeof(ulong)], *bufptr; bufptr = buffer; #define ADD(f) do { ulong along = (ulong)(f); \ memcpy (bufptr, &along, sizeof (along) ); \ bufptr += sizeof (along); } while (0) ADD ( GetActiveWindow ()); ADD ( GetCapture ()); ADD ( GetClipboardOwner ()); ADD ( GetClipboardViewer ()); ADD ( GetCurrentProcess ()); ADD ( GetCurrentProcessId ()); ADD ( GetCurrentThread ()); ADD ( GetCurrentThreadId ()); ADD ( GetDesktopWindow ()); ADD ( GetFocus ()); ADD ( GetInputState ()); ADD ( GetMessagePos ()); ADD ( GetMessageTime ()); ADD ( GetOpenClipboardWindow ()); ADD ( GetProcessHeap ()); ADD ( GetProcessWindowStation ()); ADD ( GetQueueStatus (QS_ALLEVENTS)); ADD ( GetTickCount ()); assert ( bufptr-buffer < sizeof (buffer) ); (*add) ( buffer, bufptr-buffer, requester ); #undef ADD } /* Get multiword system information: Current caret position, current * mouse cursor position */ { POINT point; GetCaretPos (&point); (*add) ( &point, sizeof (point), requester ); GetCursorPos (&point); (*add) ( &point, sizeof (point), requester ); } /* Get percent of memory in use, bytes of physical memory, bytes of free * physical memory, bytes in paging file, free bytes in paging file, user * bytes of address space, and free user bytes */ { MEMORYSTATUS memoryStatus; memoryStatus.dwLength = sizeof (MEMORYSTATUS); GlobalMemoryStatus (&memoryStatus); (*add) ( &memoryStatus, sizeof (memoryStatus), requester ); } /* Get thread and process creation time, exit time, time in kernel mode, and time in user mode in 100ns intervals */ { HANDLE handle; FILETIME creationTime, exitTime, kernelTime, userTime; DWORD minimumWorkingSetSize, maximumWorkingSetSize; handle = GetCurrentThread (); GetThreadTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime); (*add) ( &creationTime, sizeof (creationTime), requester ); (*add) ( &exitTime, sizeof (exitTime), requester ); (*add) ( &kernelTime, sizeof (kernelTime), requester ); (*add) ( &userTime, sizeof (userTime), requester ); handle = GetCurrentProcess (); GetProcessTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime); (*add) ( &creationTime, sizeof (creationTime), requester ); (*add) ( &exitTime, sizeof (exitTime), requester ); (*add) ( &kernelTime, sizeof (kernelTime), requester ); (*add) ( &userTime, sizeof (userTime), requester ); /* Get the minimum and maximum working set size for the current process */ GetProcessWorkingSetSize (handle, &minimumWorkingSetSize, &maximumWorkingSetSize); (*add) ( &minimumWorkingSetSize, sizeof (minimumWorkingSetSize), requester ); (*add) ( &maximumWorkingSetSize, sizeof (maximumWorkingSetSize), requester ); } /* The following are fixed for the lifetime of the process so we only * add them once */ if (!addedFixedItems) { STARTUPINFO startupInfo; /* Get name of desktop, console window title, new window position and * size, window flags, and handles for stdin, stdout, and stderr */ startupInfo.cb = sizeof (STARTUPINFO); GetStartupInfo (&startupInfo); (*add) ( &startupInfo, sizeof (STARTUPINFO), requester ); addedFixedItems = 1; } /* The performance of QPC varies depending on the architecture it's * running on and on the OS. Under NT it reads the CPU's 64-bit timestamp * counter (at least on a Pentium and newer '486's, it hasn't been tested * on anything without a TSC), under Win95 it reads the 1.193180 MHz PIC * timer. There are vague mumblings in the docs that it may fail if the * appropriate hardware isn't available (possibly '386's or MIPS machines * running NT), but who's going to run NT on a '386? */ { LARGE_INTEGER performanceCount; if (QueryPerformanceCounter (&performanceCount)) { if ( debug_me ) log_debug ("rndw32#gather_random_fast: perf data\n"); (*add) (&performanceCount, sizeof (performanceCount), requester); } else { /* Millisecond accuracy at best... */ DWORD aword = GetTickCount (); (*add) (&aword, sizeof (aword), requester ); } } return 0; }
void _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t, enum random_origins), enum random_origins origin) { static int addedFixedItems = 0; if ( debug_me ) log_debug ("rndw32#gather_random_fast: ori=%d\n", origin ); /* Get various basic pieces of system information: Handle of active window, handle of window with mouse capture, handle of clipboard owner handle of start of clpboard viewer list, pseudohandle of current process, current process ID, pseudohandle of current thread, current thread ID, handle of desktop window, handle of window with keyboard focus, whether system queue has any events, cursor position for last message, 1 ms time for last message, handle of window with clipboard open, handle of process heap, handle of procs window station, types of events in input queue, and milliseconds since Windows was started. */ { byte buffer[20*sizeof(ulong)], *bufptr; bufptr = buffer; #define ADD(f) do { ulong along = (ulong)(f); \ memcpy (bufptr, &along, sizeof (along) ); \ bufptr += sizeof (along); \ } while (0) ADD ( GetActiveWindow ()); ADD ( GetCapture ()); ADD ( GetClipboardOwner ()); ADD ( GetClipboardViewer ()); ADD ( GetCurrentProcess ()); ADD ( GetCurrentProcessId ()); ADD ( GetCurrentThread ()); ADD ( GetCurrentThreadId ()); ADD ( GetDesktopWindow ()); ADD ( GetFocus ()); ADD ( GetInputState ()); ADD ( GetMessagePos ()); ADD ( GetMessageTime ()); ADD ( GetOpenClipboardWindow ()); ADD ( GetProcessHeap ()); ADD ( GetProcessWindowStation ()); ADD ( GetQueueStatus (QS_ALLEVENTS)); ADD ( GetTickCount ()); gcry_assert ( bufptr-buffer < sizeof (buffer) ); (*add) ( buffer, bufptr-buffer, origin ); #undef ADD } /* Get multiword system information: Current caret position, current mouse cursor position. */ { POINT point; GetCaretPos (&point); (*add) ( &point, sizeof (point), origin ); GetCursorPos (&point); (*add) ( &point, sizeof (point), origin ); } /* Get percent of memory in use, bytes of physical memory, bytes of free physical memory, bytes in paging file, free bytes in paging file, user bytes of address space, and free user bytes. */ { MEMORYSTATUS memoryStatus; memoryStatus.dwLength = sizeof (MEMORYSTATUS); GlobalMemoryStatus (&memoryStatus); (*add) ( &memoryStatus, sizeof (memoryStatus), origin ); } /* Get thread and process creation time, exit time, time in kernel mode, and time in user mode in 100ns intervals. */ { HANDLE handle; FILETIME creationTime, exitTime, kernelTime, userTime; DWORD minimumWorkingSetSize, maximumWorkingSetSize; handle = GetCurrentThread (); GetThreadTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime); (*add) ( &creationTime, sizeof (creationTime), origin ); (*add) ( &exitTime, sizeof (exitTime), origin ); (*add) ( &kernelTime, sizeof (kernelTime), origin ); (*add) ( &userTime, sizeof (userTime), origin ); handle = GetCurrentProcess (); GetProcessTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime); (*add) ( &creationTime, sizeof (creationTime), origin ); (*add) ( &exitTime, sizeof (exitTime), origin ); (*add) ( &kernelTime, sizeof (kernelTime), origin ); (*add) ( &userTime, sizeof (userTime), origin ); /* Get the minimum and maximum working set size for the current process. */ GetProcessWorkingSetSize (handle, &minimumWorkingSetSize, &maximumWorkingSetSize); (*add) ( &minimumWorkingSetSize, sizeof (minimumWorkingSetSize), origin ); (*add) ( &maximumWorkingSetSize, sizeof (maximumWorkingSetSize), origin ); } /* The following are fixed for the lifetime of the process so we only * add them once */ if (!addedFixedItems) { STARTUPINFO startupInfo; /* Get name of desktop, console window title, new window position and size, window flags, and handles for stdin, stdout, and stderr. */ startupInfo.cb = sizeof (STARTUPINFO); GetStartupInfo (&startupInfo); (*add) ( &startupInfo, sizeof (STARTUPINFO), origin ); addedFixedItems = 1; } /* The performance of QPC varies depending on the architecture it's running on and on the OS, the MS documentation is vague about the details because it varies so much. Under Win9x/ME it reads the 1.193180 MHz PIC timer. Under NT/Win2K/XP it may or may not read the 64-bit TSC depending on the HAL and assorted other circumstances, generally on machines with a uniprocessor HAL KeQueryPerformanceCounter() uses a 3.579545MHz timer and on machines with a multiprocessor or APIC HAL it uses the TSC (the exact time source is controlled by the HalpUse8254 flag in the kernel). That choice of time sources is somewhat peculiar because on a multiprocessor machine it's theoretically possible to get completely different TSC readings depending on which CPU you're currently running on, while for uniprocessor machines it's not a problem. However, the kernel appears to synchronise the TSCs across CPUs at boot time (it resets the TSC as part of its system init), so this shouldn't really be a problem. Under WinCE it's completely platform- dependant, if there's no hardware performance counter available, it uses the 1ms system timer. Another feature of the TSC (although it doesn't really affect us here) is that mobile CPUs will turn off the TSC when they idle, Pentiums will change the rate of the counter when they clock-throttle (to match the current CPU speed), and hyperthreading Pentiums will turn it off when both threads are idle (this more or less makes sense, since the CPU will be in the halted state and not executing any instructions to count). To make things unambiguous, we detect a CPU new enough to call RDTSC directly by checking for CPUID capabilities, and fall back to QPC if this isn't present. */ #ifdef __GNUC__ /* FIXME: We would need to implement the CPU feature tests first. */ /* if (cpu_has_feature_rdtsc) */ /* { */ /* uint32_t lo, hi; */ /* We cannot use "=A", since this would use %rax on x86_64. */ /* __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); */ /* Ignore high 32 bits, hwich are >1s res. */ /* (*add) (&lo, 4, origin ); */ /* } */ /* else */ #endif /*!__GNUC__*/ { LARGE_INTEGER performanceCount; if (QueryPerformanceCounter (&performanceCount)) { if ( debug_me ) log_debug ("rndw32#gather_random_fast: perf data\n"); (*add) (&performanceCount, sizeof (performanceCount), origin); } else { /* Millisecond accuracy at best... */ DWORD aword = GetTickCount (); (*add) (&aword, sizeof (aword), origin ); } } }
int _tmain(int argc, _TCHAR* argv[]) { // コンソール出力か? bool useConsole = _isatty(_fileno(stdout)) != 0; // メモリ状況の取得 MEMORYSTATUSEX meminfo = {0}; meminfo.dwLength = sizeof(MEMORYSTATUSEX); if (!GlobalMemoryStatusEx(&meminfo)) { _ftprintf( stderr, _T("GlobalMemoryStatusEx: errorcode: %ld\n"), GetLastError() ); exit(1); } // 物理メモリ使用状況の表示 size_t unit = 1024 * 1024; // 1 MegaBytes _ftprintf( stdout, _T("Phys: %I64d/%I64d MBytes\n"), meminfo.ullAvailPhys / unit, meminfo.ullTotalPhys / unit ); // 最大ループ回数 = 空き物理メモリ(MB単位) size_t maxLoopCount = static_cast<size_t>(meminfo.ullAvailPhys / unit); if (argc > 1) { maxLoopCount = _ttoi(argv[1]); } // 現在のワーキングセットの取得 HANDLE hProcess = GetCurrentProcess(); SIZE_T curMinSize = 0; SIZE_T curMaxSize = 0; GetProcessWorkingSetSize(hProcess, &curMinSize, &curMaxSize); // ワーキングセットの設定 SIZE_T maxMem = (maxLoopCount + 1) * unit + curMaxSize; if (!SetProcessWorkingSetSize( hProcess, maxMem, maxMem)) { _ftprintf( stderr, _T("SetProcessWorkingSetSizeEx: errorcode: %ld\n"), GetLastError() ); // とりあえず継続してみる } // メモリを最大まで確保する. if (maxLoopCount > 0) { std::vector<void *> buf(maxLoopCount); for (size_t loopCount = 0; loopCount < maxLoopCount; loopCount++) { // コンソール出力であればプログレス表示 if (useConsole) { _ftprintf(stderr, _T("allocating... %ld/%ld MBytes \r"), loopCount + 1, maxLoopCount); } // メモリの確保 void *p = VirtualAlloc(NULL, unit, MEM_COMMIT, PAGE_READWRITE); if (p == NULL) { DWORD errcode = GetLastError(); if (useConsole) { _ftprintf(stderr, _T("\n")); } _ftprintf(stderr, _T("VirtualAlloc: errorcode: %ld\n"), errcode); break; } // 確保済みメモリとして記憶する. buf[loopCount] = p; // 物理メモリをロックする if (!VirtualLock(p, unit)) { DWORD errcode = GetLastError(); if (useConsole) { _ftprintf(stderr, _T("\n")); } _ftprintf(stderr, _T("VirtualLock: errorcode: %ld\n"), errcode); break; } } if (useConsole) { _ftprintf(stderr, _T("\n")); } // メモリを解放する for (size_t loopCount = 0; loopCount < maxLoopCount; loopCount++) { void *p = buf[loopCount]; if (p) { VirtualUnlock(p, unit); VirtualFree(p, unit, MEM_DECOMMIT); } } } return 0; }