void get_cpu_usage(double &user, double &system) { struct _FILETIME creation_time, exit_time, kernel_time, user_time; GetProcessTimes(GetCurrentProcess(), &creation_time, &exit_time, &kernel_time, &user_time); user = filetime_to_double(user_time); system = filetime_to_double(kernel_time); }
static int GetProcessAttribute(HANDLE hProcess,int attr,int type,int count,double *lastValue) { double value; PROCESS_MEMORY_COUNTERS mc; IO_COUNTERS ioCounters; FILETIME ftCreate,ftExit,ftKernel,ftUser; /* Get value for current process instance */ switch(attr) { case 0: /* vmsize */ GetProcessMemoryInfo(hProcess,&mc,sizeof(PROCESS_MEMORY_COUNTERS)); value=(double)mc.PagefileUsage/1024; /* Convert to Kbytes */ break; case 1: /* wkset */ GetProcessMemoryInfo(hProcess,&mc,sizeof(PROCESS_MEMORY_COUNTERS)); value=(double)mc.WorkingSetSize/1024; /* Convert to Kbytes */ break; case 2: /* pf */ GetProcessMemoryInfo(hProcess,&mc,sizeof(PROCESS_MEMORY_COUNTERS)); value=(double)mc.PageFaultCount; break; case 3: /* ktime */ case 4: /* utime */ GetProcessTimes(hProcess,&ftCreate,&ftExit,&ftKernel,&ftUser); value = ConvertProcessTime(attr==3 ? &ftKernel : &ftUser); break; case 5: /* gdiobj */ case 6: /* userobj */ if(NULL == zbx_GetGuiResources) return SYSINFO_RET_FAIL; value = (double)zbx_GetGuiResources(hProcess,attr==5 ? 0 : 1); break; case 7: /* io_read_b */ if(NULL == zbx_GetProcessIoCounters) return SYSINFO_RET_FAIL; zbx_GetProcessIoCounters(hProcess,&ioCounters); value=(double)((__int64)ioCounters.ReadTransferCount); break; case 8: /* io_read_op */ if(NULL == zbx_GetProcessIoCounters) return SYSINFO_RET_FAIL; zbx_GetProcessIoCounters(hProcess,&ioCounters); value=(double)((__int64)ioCounters.ReadOperationCount); break; case 9: /* io_write_b */ if(NULL == zbx_GetProcessIoCounters) return SYSINFO_RET_FAIL; zbx_GetProcessIoCounters(hProcess,&ioCounters); value=(double)((__int64)ioCounters.WriteTransferCount); break; case 10: /* io_write_op */ if(NULL == zbx_GetProcessIoCounters) return SYSINFO_RET_FAIL; zbx_GetProcessIoCounters(hProcess,&ioCounters); value=(double)((__int64)ioCounters.WriteOperationCount); break; case 11: /* io_other_b */ if(NULL == zbx_GetProcessIoCounters) return SYSINFO_RET_FAIL; zbx_GetProcessIoCounters(hProcess,&ioCounters); value=(double)((__int64)ioCounters.OtherTransferCount); break; case 12: /* io_other_op */ if(NULL == zbx_GetProcessIoCounters) return SYSINFO_RET_FAIL; zbx_GetProcessIoCounters(hProcess,&ioCounters); value=(double)((__int64)ioCounters.OtherOperationCount); break; default: /* Unknown attribute */ return SYSINFO_RET_FAIL; } /* Recalculate final value according to selected type */ switch (type) { case 0: /* min */ if (count == 0 || value < *lastValue) *lastValue = value; break; case 1: /* max */ if (count == 0 || value > *lastValue) *lastValue = value; break; case 2: /* avg */ *lastValue = (*lastValue * count + value) / (count + 1); break; case 3: /* sum */ *lastValue += value; break; default: return SYSINFO_RET_FAIL; } return SYSINFO_RET_OK; }
void InspIRCd::Run() { #ifdef INSPIRCD_ENABLE_TESTSUITE /* See if we're supposed to be running the test suite rather than entering the mainloop */ if (do_testsuite) { TestSuite* ts = new TestSuite; delete ts; return; } #endif UpdateTime(); time_t OLDTIME = TIME.tv_sec; while (true) { #ifndef _WIN32 static rusage ru; #endif /* Check if there is a config thread which has finished executing but has not yet been freed */ if (this->ConfigThread && this->ConfigThread->IsDone()) { /* Rehash has completed */ this->Logs->Log("CONFIG", LOG_DEBUG, "Detected ConfigThread exiting, tidying up..."); this->ConfigThread->Finish(); ConfigThread->join(); delete ConfigThread; ConfigThread = NULL; } UpdateTime(); /* Run background module timers every few seconds * (the docs say modules shouldnt rely on accurate * timing using this event, so we dont have to * time this exactly). */ if (TIME.tv_sec != OLDTIME) { #ifndef _WIN32 getrusage(RUSAGE_SELF, &ru); stats->LastSampled = TIME; stats->LastCPU = ru.ru_utime; #else if(QueryPerformanceCounter(&stats->LastSampled)) { FILETIME CreationTime; FILETIME ExitTime; FILETIME KernelTime; FILETIME UserTime; GetProcessTimes(GetCurrentProcess(), &CreationTime, &ExitTime, &KernelTime, &UserTime); stats->LastCPU.dwHighDateTime = KernelTime.dwHighDateTime + UserTime.dwHighDateTime; stats->LastCPU.dwLowDateTime = KernelTime.dwLowDateTime + UserTime.dwLowDateTime; } #endif /* Allow a buffer of two seconds drift on this so that ntpdate etc dont harass admins */ if (TIME.tv_sec < OLDTIME - 2) { SNO->WriteToSnoMask('d', "\002EH?!\002 -- Time is flowing BACKWARDS in this dimension! Clock drifted backwards %lu secs.", (unsigned long)OLDTIME-TIME.tv_sec); } else if (TIME.tv_sec > OLDTIME + 2) { SNO->WriteToSnoMask('d', "\002EH?!\002 -- Time is jumping FORWARDS! Clock skipped %lu secs.", (unsigned long)TIME.tv_sec - OLDTIME); } OLDTIME = TIME.tv_sec; if ((TIME.tv_sec % 3600) == 0) { Users->GarbageCollect(); FOREACH_MOD(OnGarbageCollect, ()); } Timers.TickTimers(TIME.tv_sec); Users->DoBackgroundUserStuff(); if ((TIME.tv_sec % 5) == 0) { FOREACH_MOD(OnBackgroundTimer, (TIME.tv_sec)); SNO->FlushSnotices(); } }
//--------------------------------------------------------------------------- // KillProcessTreeWinHelper // // Terminates all the processes started by the specified process and then // terminates the process itself. When determining which processes were // started by the specified process, the following criteria are taken into // consideration: // - The PPID of the process // - The creation time of the process // // Because Windows processes do not reparent (changing their PPID when their // real parent process terminates before they do), the PPID of a process is // not enough to safely kill a hierarchy. PID reuse can result in a process // appearing to be the parent of processes it didn't actually start. To try // and guard against this, the creation time (start time) for the process to // terminate is compared to the creation time of any process that appears to // be in its hierarchy. If the creation time of the child is before that of // its parent, it is assumed that the parent "inherited" the child and did // not actually start it. Such "inherited" children are not killed. // // Parameters: // dwProcessId - identifier of the process to terminate // // Returns: // Win32 error code. // DWORD WINAPI KillProcessTreeWinHelper(DWORD dwProcessId) { // first, open a handle to the process with sufficient access to query for // its times. those are needed in order to filter "children" because Windows // processes, unlike Unix/Linux processes, do not reparent when the process // that created them exits. as a result, any process could reuse a PID and // end up looking like it spawned many processes it didn't actually spawn auto_handle hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessId); if (!hProcess) { return GetLastError(); } // note: processCreated will be retained as the creation time for the root // process. the other variables only exist because GetProcessTimes requires // all 4 pointers FILETIME processCreated; FILETIME exitTime; // unused FILETIME kernelTime; // unused FILETIME userTime; // unused if (!GetProcessTimes(hProcess, &processCreated, &exitTime, &kernelTime, &userTime)) { // if unable to check the creation time for the process, it is impossible // to safely kill any children processes; just kill the root process and // leave it at that return KillProcess(dwProcessId); } // next, create a snapshot of all the running processes. this will be used // build a graph of processes which: // 1. have a parent related to the root process // 2. were started after the root process auto_handle hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (!hSnapshot) { // if unable to open a snapshot of the currently-running processes, just // kill the root process and leave it at that return KillProcess(dwProcessId); } PROCESSENTRY32 pEntry; pEntry.dwSize = sizeof(PROCESSENTRY32); HANDLE hHeap = GetProcessHeap(); if (!hHeap) { return KillProcess(dwProcessId); } PTREE_PROCESS root = (PTREE_PROCESS) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(TREE_PROCESS)); if (!root) { // couldn't allocate memory for the TREE_PROCESS, which means we won't be able // to build the list; just kill the root process and leave it at that return KillProcess(dwProcessId); } root->processId = dwProcessId; PTREE_PROCESS current = root; PTREE_PROCESS last = root; FILETIME creationTime; // used when getting a child's creation time DWORD processId; // holds the ID of the process being processed while (current) { // extract the process ID for processing, but do not move the current pointer; // since children have not been processed yet, current->next may not have been // set at this time. move it after the loop instead processId = current->processId; if (!Process32First(hSnapshot, &pEntry)) { return FreeProcessList(hHeap, root); } // find the children for the current process do { DWORD pid = pEntry.th32ProcessID; DWORD ppid = pEntry.th32ParentProcessID; // first checks are the simplest; we can perform them with the data from // the PROCESSENTRY32 structure: // 1. does the process have a parent? // 2. is the process the one we're currently checking? // 3. does the process's parent match the one we're checking? if (ppid == 0 || processId == pid || ppid != processId) { // if any of the checks "fail", then this process is not a candidate // for being killed continue; } // next check: was this process, which supposedly is in our hierarchy, // created before our process was? to find this out, we must open the // process and check its creation time. if we cannot open the process, // or we cannot get its process times, or its creation time is before // its supposed parent, it is not a candidate for being killed auto_handle hChild = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); if (hChild && GetProcessTimes(hChild, &creationTime, &exitTime, &kernelTime, &userTime) && CompareFileTime(&processCreated, &creationTime) < 1) { // if we make it here, it means we were able to open the process, // get its process times and its creation time is at or after the // root process, so this process should be killed too PTREE_PROCESS child = (PTREE_PROCESS) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(TREE_PROCESS)); if (!child) { return FreeProcessList(hHeap, root); } child->previous = last; child->processId = pid; last->next = child; last = child; } } while (Process32Next(hSnapshot, &pEntry)); // after processing all potential children for the current process, move the // pointer forward and process children for the next process in the list current = current->next; } // after building the complete list, kill the processes in reverse order. the first // entry in the list, and therefore the last killed, will be the root process DWORD result; PTREE_PROCESS temp; while (last) { result = KillProcess(last->processId); temp = last; last = last->previous; HeapFree(hHeap, 0, temp); } return result; }
int ProcessWatch::GetProcessCpuUsage(int pid) { static int processor_count_ = -1; static __int64 last_time_ = 0; static __int64 last_system_time_ = 0; FILETIME now; FILETIME creation_time; FILETIME exit_time; FILETIME kernel_time; FILETIME user_time; __int64 system_time; __int64 time; // __int64 system_time_delta; // __int64 time_delta; double cpu = -1; if(processor_count_ == -1) { processor_count_ = GetProcessorNumber(); } GetSystemTimeAsFileTime(&now); HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION/*PROCESS_ALL_ACCESS*/, false, pid); if (!hProcess) { return -1; } if (!GetProcessTimes(hProcess, &creation_time, &exit_time, &kernel_time, &user_time)) { return -1; } system_time = (FileTimeToInt64(kernel_time) + FileTimeToInt64(user_time)) / processor_count_; time = FileTimeToInt64(now); last_system_time_ = system_time; last_time_ = time; CloseHandle( hProcess ); Sleep(30); hProcess = OpenProcess(PROCESS_QUERY_INFORMATION/*PROCESS_ALL_ACCESS*/, false, pid); if (!hProcess) { return -1; } if (!GetProcessTimes(hProcess, &creation_time, &exit_time, &kernel_time, &user_time)) { return -1; } GetSystemTimeAsFileTime(&now); system_time = (FileTimeToInt64(kernel_time) + FileTimeToInt64(user_time)) / processor_count_; time = FileTimeToInt64(now); CloseHandle( hProcess ); cpu = ((double)(system_time - last_system_time_) / (double)(time - last_time_)) * 100; return (int)cpu; }
int CollectorWin::preCollect(const CollectorHints& hints, uint64_t /* iTick */) { LogFlowThisFuncEnter(); uint64_t user, kernel, idle, total; int rc = getRawHostCpuLoad(&user, &kernel, &idle); if (RT_FAILURE(rc)) return rc; total = user + kernel + idle; DWORD dwError; const CollectorHints::ProcessList& processes = hints.getProcessFlags(); CollectorHints::ProcessList::const_iterator it; mProcessStats.clear(); for (it = processes.begin(); it != processes.end() && RT_SUCCESS(rc); it++) { RTPROCESS process = it->first; HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, process); if (!h) { dwError = GetLastError(); Log (("OpenProcess() -> 0x%x\n", dwError)); rc = RTErrConvertFromWin32(dwError); break; } VMProcessStats vmStats; if ((it->second & COLLECT_CPU_LOAD) != 0) { FILETIME ftCreate, ftExit, ftKernel, ftUser; if (!GetProcessTimes(h, &ftCreate, &ftExit, &ftKernel, &ftUser)) { dwError = GetLastError(); Log (("GetProcessTimes() -> 0x%x\n", dwError)); rc = RTErrConvertFromWin32(dwError); } else { vmStats.cpuKernel = FILETTIME_TO_100NS(ftKernel); vmStats.cpuUser = FILETTIME_TO_100NS(ftUser); vmStats.cpuTotal = total; } } if (RT_SUCCESS(rc) && (it->second & COLLECT_RAM_USAGE) != 0) { PROCESS_MEMORY_COUNTERS pmc; if (!GetProcessMemoryInfo(h, &pmc, sizeof(pmc))) { dwError = GetLastError(); Log (("GetProcessMemoryInfo() -> 0x%x\n", dwError)); rc = RTErrConvertFromWin32(dwError); } else vmStats.ramUsed = pmc.WorkingSetSize; } CloseHandle(h); mProcessStats[process] = vmStats; } LogFlowThisFuncLeave(); return rc; }
int InspIRCd::Run() { /* See if we're supposed to be running the test suite rather than entering the mainloop */ if (Config->cmdline.TestSuite) { TestSuite* ts = new TestSuite; delete ts; Exit(0); } UpdateTime(); time_t OLDTIME = TIME.tv_sec; while (true) { #ifndef _WIN32 static rusage ru; #endif /* Check if there is a config thread which has finished executing but has not yet been freed */ if (this->ConfigThread && this->ConfigThread->IsDone()) { /* Rehash has completed */ this->Logs->Log("CONFIG",LOG_DEBUG,"Detected ConfigThread exiting, tidying up..."); this->ConfigThread->Finish(); ConfigThread->join(); delete ConfigThread; ConfigThread = NULL; } UpdateTime(); /* Run background module timers every few seconds * (the docs say modules shouldnt rely on accurate * timing using this event, so we dont have to * time this exactly). */ if (TIME.tv_sec != OLDTIME) { #ifndef _WIN32 getrusage(RUSAGE_SELF, &ru); stats->LastSampled = TIME; stats->LastCPU = ru.ru_utime; #else if(QueryPerformanceCounter(&stats->LastSampled)) { FILETIME CreationTime; FILETIME ExitTime; FILETIME KernelTime; FILETIME UserTime; GetProcessTimes(GetCurrentProcess(), &CreationTime, &ExitTime, &KernelTime, &UserTime); stats->LastCPU.dwHighDateTime = KernelTime.dwHighDateTime + UserTime.dwHighDateTime; stats->LastCPU.dwLowDateTime = KernelTime.dwLowDateTime + UserTime.dwLowDateTime; } #endif /* Allow a buffer of two seconds drift on this so that ntpdate etc dont harass admins */ if (TIME.tv_sec < OLDTIME - 2) { SNO->WriteToSnoMask('d', "\002EH?!\002 -- Time is flowing BACKWARDS in this dimension! Clock drifted backwards %lu secs.", (unsigned long)OLDTIME-TIME.tv_sec); } else if (TIME.tv_sec > OLDTIME + 2) { SNO->WriteToSnoMask('d', "\002EH?!\002 -- Time is jumping FORWARDS! Clock skipped %lu secs.", (unsigned long)TIME.tv_sec - OLDTIME); } OLDTIME = TIME.tv_sec; if ((TIME.tv_sec % 3600) == 0) { Users->GarbageCollect(); FOREACH_MOD(I_OnGarbageCollect, OnGarbageCollect()); } Timers->TickTimers(TIME.tv_sec); this->DoBackgroundUserStuff(); if ((TIME.tv_sec % 5) == 0) { FOREACH_MOD(I_OnBackgroundTimer,OnBackgroundTimer(TIME.tv_sec)); SNO->FlushSnotices(); } } /* Call the socket engine to wait on the active * file descriptors. The socket engine has everything's * descriptors in its list... dns, modules, users, * servers... so its nice and easy, just one call. * This will cause any read or write events to be * dispatched to their handlers. */ this->SE->DispatchTrialWrites(); this->SE->DispatchEvents(); /* if any users were quit, take them out */ GlobalCulls.Apply(); AtomicActions.Run(); if (s_signal) { this->SignalHandler(s_signal); s_signal = 0; } } return 0; }
int process_time(pid_t pid, time64_t* createTime, time64_t* kernelTime, time64_t* userTime) { #if defined(_WIN32) HANDLE handle; FILETIME ftCreateTime, ftExitTime, ftKernelTime, ftUserTime; SYSTEMTIME stime; FILETIME ftime; ULONGLONG rt; ULARGE_INTEGER kt, ut; memset(&ftUserTime, 0xCC, sizeof(ftUserTime)); handle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); if(!handle) return (int)GetLastError(); if(!GetProcessTimes(handle, &ftCreateTime, &ftExitTime, &ftKernelTime, &ftUserTime)) { CloseHandle(handle); return (int)GetLastError(); } CloseHandle(handle); GetSystemTime(&stime); SystemTimeToFileTime(&stime, &ftime); kt = FILETIME2UINT64(&ftime); ut = FILETIME2UINT64(&ftCreateTime); rt = kt.QuadPart > ut.QuadPart ? kt.QuadPart-ut.QuadPart : 0; // for resolution problem kt = FILETIME2UINT64(&ftKernelTime); ut = FILETIME2UINT64(&ftUserTime); *createTime = rt/10000; // nanosecond -> millisecond *userTime = ut.QuadPart/10000; *kernelTime = kt.QuadPart/10000; return 0; #else char content[2*1024] = {0}; int r; unsigned long int utime, stime; unsigned long long starttime; float uptime = 0.0f; sprintf(content, "/proc/%d/stat", pid); r = tools_cat(content, content, sizeof(content)); if(r < 0) return r; // linux: man proc // cat proc/self/stat // (1-pid-%d, 2-filename-%s, 3-state-%c, 4-ppid-%d, 5-pgrp-%d, // 6-session-%d, 7-tty_nr-%d, 8-tpgid-%d, 9-flags-%u, 10-minflt-%lu, // 11-cminflt-%lu, 12-majflt-%lu, 13-cmajflt-%lu, 14-utime-%lu, 15-stime-%lu, // 16-cutime-%ld, 17-cstime-%ld, 18-priority-%ld, 19-nice-%ld, 20-num_threads-%ld, // 21-itrealvalue-%ld, 22-starttime-%llu, 23-vsize-%lu, 24-rss-%ld, 25-rsslim-%lu, // 26-startcode-%lu, 27-endcode-%lu, 28-startstack-%lu, 29-kstkesp-%lu, 30-kstkeip-%lu, // 31-signal-%lu, 32-blocked-%lu, 33-sigignore-%lu, 34-sigcatch-%lu, 35-wchan-%lu, // 36-nswap-%lu, 37-cnswap-%lu, 38-exit_signal-%d, 39-processor-%d, 40-rt_priority-%u, // 41-policy-%u, 42-delayacct_blkio_ticks-%llu, 43-guest_time-%lu, 44-cguest_time-%ld) if(3 != sscanf(content, // warning: use of assignment suppression and length modifier together in gnu_scanf format [-Wformat] //"%*d %*s %*c %*d %*d %*d %*d %*d %*u %*lu %*lu %*lu %*lu %lu %lu %*ld %*ld %*ld %*ld %*ld %*ld %llu", "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu %lu %*d %*d %*d %*d %*d %*d %llu", &utime, &stime, &starttime)) return -(int)EINVAL; assert(sysconf(_SC_CLK_TCK) == HZ); system_uptime(&uptime); *createTime = (time64_t)uptime*1000 - starttime*1000/HZ; // jiffies -> millisecond *userTime = utime * 1000 / HZ; *kernelTime = stime * 1000 / HZ; return 0; #endif }
void InspIRCd::Run() { #ifdef INSPIRCD_ENABLE_TESTSUITE /* See if we're supposed to be running the test suite rather than entering the mainloop */ if (do_testsuite) { TestSuite* ts = new TestSuite; delete ts; return; } #endif UpdateTime(); time_t OLDTIME = TIME.tv_sec; while (true) { #ifndef _WIN32 static rusage ru; #endif /* Check if there is a config thread which has finished executing but has not yet been freed */ if (this->ConfigThread && this->ConfigThread->IsDone()) { /* Rehash has completed */ this->Logs.Log("CONFIG", LOG_DEBUG, "Detected ConfigThread exiting, tidying up..."); this->ConfigThread->Finish(); ConfigThread->join(); delete ConfigThread; ConfigThread = NULL; } UpdateTime(); /* Run background module timers every few seconds * (the docs say modules shouldnt rely on accurate * timing using this event, so we dont have to * time this exactly). */ if (TIME.tv_sec != OLDTIME) { #ifndef _WIN32 getrusage(RUSAGE_SELF, &ru); stats.LastSampled = TIME; stats.LastCPU = ru.ru_utime; #else if(QueryPerformanceCounter(&stats.LastSampled)) { FILETIME CreationTime; FILETIME ExitTime; FILETIME KernelTime; FILETIME UserTime; GetProcessTimes(GetCurrentProcess(), &CreationTime, &ExitTime, &KernelTime, &UserTime); stats.LastCPU.dwHighDateTime = KernelTime.dwHighDateTime + UserTime.dwHighDateTime; stats.LastCPU.dwLowDateTime = KernelTime.dwLowDateTime + UserTime.dwLowDateTime; } #endif if (Config->TimeSkipWarn) { time_t timediff = TIME.tv_sec - OLDTIME; if (timediff > Config->TimeSkipWarn) SNO.WriteToSnoMask('a', "\002Performance warning!\002 Server clock jumped forwards by %lu seconds!", timediff); else if (timediff < -Config->TimeSkipWarn) SNO.WriteToSnoMask('a', "\002Performance warning!\002 Server clock jumped backwards by %lu seconds!", labs(timediff)); } OLDTIME = TIME.tv_sec; if ((TIME.tv_sec % 3600) == 0) { FOREACH_MOD(OnGarbageCollect, ()); // HACK: ELines are not expired properly at the moment but it can't be fixed as // the 2.0 XLine system is a spaghetti nightmare. Instead we skip over expired // ELines in XLineManager::CheckELines() and expire them here instead. XLines->GetAll("E"); } Timers.TickTimers(TIME.tv_sec); Users.DoBackgroundUserStuff(); if ((TIME.tv_sec % 5) == 0) { FOREACH_MOD(OnBackgroundTimer, (TIME.tv_sec)); SNO.FlushSnotices(); } }
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 ); } } }
__int64 gpt() { FILETIME a,b,c,d; GetProcessTimes(GetCurrentProcess(), &a,&b,&c,&d); return *(__int64*)&d; }
double hb_secondsCPU( int n ) { double d = 0.0; #if defined( HB_OS_WIN ) && ! defined( HB_OS_WIN_CE ) && ! defined( HB_OS_UNIX ) FILETIME Create, Exit, Kernel, User; #endif #if defined( HB_OS_OS2 ) static ULONG s_timer_interval = 0; QSGREC ** pBuf; #endif if( ( n < 1 || n > 3 ) && ( n < 11 || n > 13 ) ) n = 3; #if defined( HB_OS_UNIX ) && ! defined( HB_OS_VXWORKS ) { struct tms tm; times( &tm ); if( n > 10 ) { n -= 10; if( n & 1 ) d += tm.tms_cutime; if( n & 2 ) d += tm.tms_cstime; } if( n & 1 ) d += tm.tms_utime; if( n & 2 ) d += tm.tms_stime; /* In POSIX-1996 the CLK_TCK symbol is mentioned as obsolescent */ #if 0 d /= CLK_TCK; #endif d /= ( double ) sysconf( _SC_CLK_TCK ); } #else if( n > 10 ) n -= 10; #if defined( HB_OS_WIN ) && ! defined( HB_OS_WIN_CE ) if( hb_iswinnt() && GetProcessTimes( GetCurrentProcess(), &Create, &Exit, &Kernel, &User ) ) { if( n & 1 ) { d += ( double ) ( ( ( HB_MAXINT ) User.dwHighDateTime << 32 ) + ( HB_MAXINT ) User.dwLowDateTime ); } if( n & 2 ) { d += ( double ) ( ( ( HB_MAXINT ) Kernel.dwHighDateTime << 32 ) + ( HB_MAXINT ) Kernel.dwLowDateTime ); } d /= 10000000.0; } else #elif defined( HB_OS_OS2 ) if( s_timer_interval == 0 ) DosQuerySysInfo( QSV_TIMER_INTERVAL, QSV_TIMER_INTERVAL, ( PVOID ) &s_timer_interval, sizeof( ULONG ) ); pBuf = ( QSGREC ** ) hb_xalloc( BUFSIZE ); if( pBuf ) { #if defined( __GNUC__ ) APIRET rc = DosQuerySysState( QS_PROCESS, 0L, _getpid(), 0L, pBuf, BUFSIZE ); #else APIRET rc = DosQuerySysState( QS_PROCESS, 0L, getpid(), 0L, pBuf, BUFSIZE ); #endif if( rc == NO_ERROR ) { QSGREC * pGrec = *pBuf; QSPREC * pPrec = ( QSPREC * ) ( ( ULONG ) pGrec + sizeof( QSGREC ) ); QSTREC * pTrec = pPrec->pThrdRec; int i; for( i = 0; i < pPrec->cTCB; i++, pTrec++ ) { if( n & 1 ) d += pTrec->usertime; if( n & 2 ) d += pTrec->systime; } d = d * 10.0 / s_timer_interval; } hb_xfree( pBuf ); } else #endif { /* TODO: this code is only for DOS and other platforms which cannot calculate process time */ if( n & 1 ) d = hb_dateSeconds(); } #endif return d; }
process::process(DWORD pid) : _process_id(pid) { // NT API Support: // 5.0 GetModuleFileNameEx // 5.1 GetProcessImageFileName // 5.0 GetProcessTimes // 5.0 GetTokenInformation // 5.0 LookupAccountSid // 5.0 OpenProcess // 5.0 OpenProcessToken // 6.0 QueryFullProcessImageName #if _WIN32_WINNT < 0x0600 //HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid); #else //HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid); #endif HANDLE hProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, pid); if (NULL != hProcess) { FILETIME ctime = { 0, 0 }; FILETIME etime = { 0, 0 }; FILETIME ktime = { 0, 0 }; FILETIME utime = { 0, 0 }; if (GetProcessTimes(hProcess, &ctime, &etime, &ktime, &utime)) { _creation_time = ctime; } else { std::tcerr << std::dec << pid << ": GetProcessTimes failed: " << std::hex << std::setw(8) << std::setfill(_T('0')) << GetLastError() << std::endl; } #if _WIN32_WINNT < 0x0600 std::tstring image(MAX_PATH, '\0'); // This needs PROCESS_VM_READ. DWORD image_length = GetModuleFileNameEx(hProcess, NULL, &image[0], image.size()); if (image_length > 0) { image.resize(image_length); } else { std::tcerr << std::dec << pid << ": GetModuleFileNameEx failed: " << std::hex << std::setw(8) << std::setfill(_T('0')) << GetLastError() << std::endl; } #else std::tstring image(MAX_PATH, '\0'); DWORD image_length = image.size(); // This needs PROCESS_QUERY_LIMITED_INFORMATION. if (QueryFullProcessImageName(hProcess, 0, &image[0], &image_length)) { image.resize(image_length); } else { std::tcerr << std::dec << pid << ": QueryFullProcessImageName failed: " << std::hex << std::setw(8) << std::setfill(_T('0')) << GetLastError() << std::endl; } #endif _image_filepath.assign(image); std::tstring::size_type last_slash = _image_filepath.rfind('\\'); if (last_slash != std::tstring::npos) { _image_filename = _image_filepath.substr(++last_slash, _image_filepath.size()); } HANDLE hProcessToken; if (OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken)) { DWORD data_length = 0; if (!GetTokenInformation(hProcessToken, TokenUser, NULL, 0, &data_length) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { void* data = new byte[data_length]; if (GetTokenInformation(hProcessToken, TokenUser, data, data_length, &data_length)) { TOKEN_USER* user = static_cast<TOKEN_USER*>(data); std::tstring name(MAX_NAME, '\0'); DWORD name_length = name.size(); std::tstring domain(MAX_NAME, '\0'); DWORD domain_length = domain.size(); SID_NAME_USE type; if (LookupAccountSid(NULL, user->User.Sid, &name[0], &name_length, &domain[0], &domain_length, &type)) { name.resize(name_length); domain.resize(domain_length); _username = _T(""); if (domain.size()) { _username += domain; _username += _T("\\"); } _username += name; } else { std::tcerr << std::dec << pid << ": LookupAccountSid failed: " << std::hex << std::setw(8) << std::setfill(_T('0')) << GetLastError() << std::endl; } } else { std::tcerr << std::dec << pid << ": GetTokenInformation(2) failed: " << std::hex << std::setw(8) << std::setfill(_T('0')) << GetLastError() << std::endl; } delete data; } else { std::tcerr << std::dec << pid << ": GetTokenInformation failed: " << std::hex << std::setw(8) << std::setfill(_T('0')) << GetLastError() << std::endl; } CloseHandle(hProcessToken); } else { std::tcerr << std::dec << pid << ": OpenProcessToken failed: " << std::hex << std::setw(8) << std::setfill(_T('0')) << GetLastError() << std::endl; } CloseHandle(hProcess); } }
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; }
u64 OS::cpuTime( void ) noexcept{ FILETIME ct, et, kt, ut; GetProcessTimes( GetCurrentProcess(), &ct, &et, &kt, &ut ); return ( u64( ut.dwHighDateTime ) << 32 ) + ut.dwLowDateTime + ( u64( kt.dwHighDateTime ) << 32 ) + kt.dwLowDateTime; }
/* This code works on: * univel * solaris_i386 * sco * solaris_sparc * svr4 * hpux 9.* * win32 * which currently is all the supported platforms that don't have a * native version of getrusage(). So, if configure decides to compile * this file at all, we just use this version unconditionally. */ int getrusage(int who, struct rusage * rusage) { #ifdef __WIN32__ FILETIME starttime; FILETIME exittime; FILETIME kerneltime; FILETIME usertime; ULARGE_INTEGER li; if (who != RUSAGE_SELF) { /* Only RUSAGE_SELF is supported in this implementation for now */ errno = EINVAL; return -1; } if (rusage == (struct rusage *) NULL) { errno = EFAULT; return -1; } memset(rusage, 0, sizeof(struct rusage)); if (GetProcessTimes(GetCurrentProcess(), &starttime, &exittime, &kerneltime, &usertime) == 0) { _dosmaperr(GetLastError()); return -1; } /* Convert FILETIMEs (0.1 us) to struct timeval */ memcpy(&li, &kerneltime, sizeof(FILETIME)); li.QuadPart /= 10L; /* Convert to microseconds */ rusage->ru_stime.tv_sec = li.QuadPart / 1000000L; rusage->ru_stime.tv_usec = li.QuadPart % 1000000L; memcpy(&li, &usertime, sizeof(FILETIME)); li.QuadPart /= 10L; /* Convert to microseconds */ rusage->ru_utime.tv_sec = li.QuadPart / 1000000L; rusage->ru_utime.tv_usec = li.QuadPart % 1000000L; #else /* all but __WIN32__ */ struct tms tms; int tick_rate = CLK_TCK; /* ticks per second */ clock_t u, s; if (rusage == (struct rusage *) NULL) { errno = EFAULT; return -1; } if (times(&tms) < 0) { /* errno set by times */ return -1; } switch (who) { case RUSAGE_SELF: u = tms.tms_utime; s = tms.tms_stime; break; case RUSAGE_CHILDREN: u = tms.tms_cutime; s = tms.tms_cstime; break; default: errno = EINVAL; return -1; } #define TICK_TO_SEC(T, RATE) ((T)/(RATE)) #define TICK_TO_USEC(T,RATE) (((T)%(RATE)*1000000)/RATE) rusage->ru_utime.tv_sec = TICK_TO_SEC(u, tick_rate); rusage->ru_utime.tv_usec = TICK_TO_USEC(u, tick_rate); rusage->ru_stime.tv_sec = TICK_TO_SEC(s, tick_rate); rusage->ru_stime.tv_usec = TICK_TO_USEC(u, tick_rate); #endif /* __WIN32__ */ return 0; }
Chrono::Chrono(Type type) { #ifdef __linux__ switch (type) { case Type::REAL_TIME: m_clockId = CLOCK_MONOTONIC_RAW; break; case Type::PROCESS_TIME: m_clockId = CLOCK_PROCESS_CPUTIME_ID; break; case Type::THREAD_TIME: m_clockId = CLOCK_THREAD_CPUTIME_ID; break; } timespec now = {}; if (clock_gettime(m_clockId, &now)) { m_clockId = CLOCK_MONOTONIC; if (clock_gettime(m_clockId, &now)) { m_clockId = CLOCK_REALTIME; if (clock_gettime(m_clockId, &now)) { m_clockId = -1; m_timestamp = 0; return; } } } m_timestamp = now.tv_sec * 1000000000 + now.tv_nsec; #elif defined(_WIN32) m_type = type; switch (m_type) { case Type::REAL_TIME: if (QueryPerformanceFrequency(&m_counterFreq)) { LARGE_INTEGER counter; if (QueryPerformanceCounter(&counter)) { m_timestamp = counter.QuadPart; return; } } break; case Type::PROCESS_TIME: { FILETIME time[4]; if (GetProcessTimes(GetCurrentProcess(), time, time + 1, time + 2, time + 3)) { m_timestamp = static_cast<long long>(time[2].dwHighDateTime) << 32 | time[2].dwLowDateTime; m_timestamp += static_cast<long long>(time[3].dwHighDateTime) << 32 | time[3].dwLowDateTime; return; } } break; case Type::THREAD_TIME: { FILETIME time[4]; if (GetThreadTimes(GetCurrentThread(), time, time + 1, time + 2, time + 3)) { m_timestamp = static_cast<long long>(time[2].dwHighDateTime) << 32 | time[2].dwLowDateTime; m_timestamp += static_cast<long long>(time[3].dwHighDateTime) << 32 | time[3].dwLowDateTime; return; } } break; } m_counterFreq.QuadPart = 0; m_timestamp = 0; #endif //__linux__ }
int getrusage (int who, struct rusage *usage_p) { if (who == RUSAGE_SELF || who == RUSAGE_CHILDREN) { /* Clear all unsupported members of 'struct rusage'. */ memset (usage_p, '\0', sizeof (struct rusage)); #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ if (who == RUSAGE_SELF) { /* Fill in the ru_utime and ru_stime members. */ FILETIME creation_time; FILETIME exit_time; FILETIME kernel_time; FILETIME user_time; if (GetProcessTimes (GetCurrentProcess (), &creation_time, &exit_time, &kernel_time, &user_time)) { /* Convert to microseconds, rounding. */ uint64_t kernel_usec = ((((uint64_t) kernel_time.dwHighDateTime << 32) | (uint64_t) kernel_time.dwLowDateTime) + 5) / 10; uint64_t user_usec = ((((uint64_t) user_time.dwHighDateTime << 32) | (uint64_t) user_time.dwLowDateTime) + 5) / 10; usage_p->ru_utime.tv_sec = user_usec / 1000000U; usage_p->ru_utime.tv_usec = user_usec % 1000000U; usage_p->ru_stime.tv_sec = kernel_usec / 1000000U; usage_p->ru_stime.tv_usec = kernel_usec % 1000000U; } } #else /* Fill in the ru_utime and ru_stime members. */ { struct tms time; if (times (&time) != (clock_t) -1) { /* Number of clock ticks per second. */ unsigned int clocks_per_second = sysconf (_SC_CLK_TCK); if (clocks_per_second > 0) { clock_t user_ticks; clock_t system_ticks; uint64_t user_usec; uint64_t system_usec; if (who == RUSAGE_CHILDREN) { user_ticks = time.tms_cutime; system_ticks = time.tms_cstime; } else { user_ticks = time.tms_utime; system_ticks = time.tms_stime; } user_usec = (((uint64_t) user_ticks * (uint64_t) 1000000U) + clocks_per_second / 2) / clocks_per_second; system_usec = (((uint64_t) system_ticks * (uint64_t) 1000000U) + clocks_per_second / 2) / clocks_per_second; usage_p->ru_utime.tv_sec = user_usec / 1000000U; usage_p->ru_utime.tv_usec = user_usec % 1000000U; usage_p->ru_stime.tv_sec = system_usec / 1000000U; usage_p->ru_stime.tv_usec = system_usec % 1000000U; } } } #endif return 0; } else { errno = EINVAL; return -1; } }
static PyObject* py_process_time(_Py_clock_info_t *info) { #if defined(MS_WINDOWS) HANDLE process; FILETIME creation_time, exit_time, kernel_time, user_time; ULARGE_INTEGER large; double total; BOOL ok; process = GetCurrentProcess(); ok = GetProcessTimes(process, &creation_time, &exit_time, &kernel_time, &user_time); if (!ok) return PyErr_SetFromWindowsErr(0); large.u.LowPart = kernel_time.dwLowDateTime; large.u.HighPart = kernel_time.dwHighDateTime; total = (double)large.QuadPart; large.u.LowPart = user_time.dwLowDateTime; large.u.HighPart = user_time.dwHighDateTime; total += (double)large.QuadPart; if (info) { info->implementation = "GetProcessTimes()"; info->resolution = 1e-7; info->monotonic = 1; info->adjustable = 0; } return PyFloat_FromDouble(total * 1e-7); #else #if defined(HAVE_SYS_RESOURCE_H) struct rusage ru; #endif #ifdef HAVE_TIMES struct tms t; static long ticks_per_second = -1; #endif #if defined(HAVE_CLOCK_GETTIME) \ && (defined(CLOCK_PROCESS_CPUTIME_ID) || defined(CLOCK_PROF)) struct timespec tp; #ifdef CLOCK_PROF const clockid_t clk_id = CLOCK_PROF; const char *function = "clock_gettime(CLOCK_PROF)"; #else const clockid_t clk_id = CLOCK_PROCESS_CPUTIME_ID; const char *function = "clock_gettime(CLOCK_PROCESS_CPUTIME_ID)"; #endif if (clock_gettime(clk_id, &tp) == 0) { if (info) { struct timespec res; info->implementation = function; info->monotonic = 1; info->adjustable = 0; if (clock_getres(clk_id, &res) == 0) info->resolution = res.tv_sec + res.tv_nsec * 1e-9; else info->resolution = 1e-9; } return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9); } #endif #if defined(HAVE_SYS_RESOURCE_H) if (getrusage(RUSAGE_SELF, &ru) == 0) { double total; total = ru.ru_utime.tv_sec + ru.ru_utime.tv_usec * 1e-6; total += ru.ru_stime.tv_sec + ru.ru_stime.tv_usec * 1e-6; if (info) { info->implementation = "getrusage(RUSAGE_SELF)"; info->monotonic = 1; info->adjustable = 0; info->resolution = 1e-6; } return PyFloat_FromDouble(total); } #endif #ifdef HAVE_TIMES if (times(&t) != (clock_t)-1) { double total; if (ticks_per_second == -1) { #if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) ticks_per_second = sysconf(_SC_CLK_TCK); if (ticks_per_second < 1) ticks_per_second = -1; #elif defined(HZ) ticks_per_second = HZ; #else ticks_per_second = 60; /* magic fallback value; may be bogus */ #endif } if (ticks_per_second != -1) { total = (double)t.tms_utime / ticks_per_second; total += (double)t.tms_stime / ticks_per_second; if (info) { info->implementation = "times()"; info->monotonic = 1; info->adjustable = 0; info->resolution = 1.0 / ticks_per_second; } return PyFloat_FromDouble(total); } } #endif return floatclock(info); #endif }
int main(int argc, char *argv[]) { const char *usage = "usage: flactimer [-1 | -2 | -o outputfile] command\n"; FILE *fout = stderr; if(argc == 1 || (argc > 1 && 0 == strcmp(argv[1], "-h"))) { fprintf(stderr, usage); return 0; } argv++; argc--; if(0 == strcmp(argv[0], "-1") || 0 == strcmp(argv[0], "/1")) { fout = stdout; argv++; argc--; } else if(0 == strcmp(argv[0], "-2") || 0 == strcmp(argv[0], "/2")) { fout = stdout; argv++; argc--; } else if(0 == strcmp(argv[0], "-o")) { if(argc < 2) { fprintf(stderr, usage); return 1; } fout = fopen(argv[1], "w"); if(!fout) { fprintf(fout, "ERROR opening file %s for writing\n", argv[1]); return 1; } argv += 2; argc -= 2; } if(argc <= 0) { fprintf(fout, "ERROR, no command!\n\n"); fprintf(fout, usage); fclose(fout); return 1; } // improvement: double-quote all args int i, n = 0; for(i = 0; i < argc; i++) { if(i > 0) n++; n += strlen(argv[i]); } char *args = (char*)malloc(n+1); if(!args) { fprintf(fout, "ERROR, no memory\n"); fclose(fout); return 1; } args[0] = '\0'; for(i = 0; i < argc; i++) { if(i > 0) safe_strncat(args, " ", sizeof(args)); safe_strncat(args, argv[i], sizeof(args)); } //fprintf(stderr, "@@@ cmd=[%s] args=[%s]\n", argv[0], args); STARTUPINFO si; GetStartupInfo(&si); DWORD wallclock_msec = GetTickCount(); PROCESS_INFORMATION pi; BOOL ok = CreateProcess( argv[0], // lpApplicationName args, // lpCommandLine NULL, // lpProcessAttributes NULL, // lpThreadAttributes FALSE, // bInheritHandles 0, // dwCreationFlags NULL, // lpEnvironment NULL, // lpCurrentDirectory &si, // lpStartupInfo (inherit from this proc?) &pi // lpProcessInformation ); if(!ok) { fprintf(fout, "ERROR running command\n"); free(args); //@@@ ok to free here or have to wait to wait till process is reaped? fclose(fout); return 1; } //fprintf(stderr, "@@@ waiting...\n"); WaitForSingleObject(pi.hProcess, INFINITE); //fprintf(stderr, "@@@ done\n"); wallclock_msec = GetTickCount() - wallclock_msec; FILETIME creation_time; FILETIME exit_time; FILETIME kernel_time; FILETIME user_time; if(!GetProcessTimes(pi.hProcess, &creation_time, &exit_time, &kernel_time, &user_time)) { fprintf(fout, "ERROR getting time info\n"); free(args); //@@@ ok to free here or have to wait to wait till process is reaped? fclose(fout); return 1; } uint64_t kernel_nsec = time2nsec(kernel_time); uint64_t user_nsec = time2nsec(user_time); fprintf(fout, "Kernel Time = "); printtime(fout, kernel_nsec, (uint64_t)wallclock_msec * 1000000); fprintf(fout, "User Time = "); printtime(fout, user_nsec, (uint64_t)wallclock_msec * 1000000); fprintf(fout, "Process Time = "); printtime(fout, kernel_nsec+user_nsec, (uint64_t)wallclock_msec * 1000000); fprintf(fout, "Global Time = "); printtime(fout, (uint64_t)wallclock_msec * 1000000, (uint64_t)wallclock_msec * 1000000); CloseHandle(pi.hThread); CloseHandle(pi.hProcess); free(args); //@@@ always causes crash, maybe CreateProcess takes ownership? fclose(fout); return 0; }
int __cdecl main( int argc, char **argv ) { int i, j, k; int *total; HANDLE hProcess; FILETIME createTime; FILETIME exitTime; FILETIME kernelTime1; FILETIME userTime1; FILETIME kernelTime2; FILETIME userTime2; DWORD dwError; /* initialize the PAL */ if( PAL_Initialize(argc, argv) != 0 ) { return( FAIL ); } /* get our own process handle */ hProcess = GetCurrentProcess(); if( hProcess == NULL ) { Fail( "GetCurrentProcess() returned a NULL handle.\n" ); } /* zero our time structures */ ZeroMemory( &createTime, sizeof(createTime) ); ZeroMemory( &exitTime, sizeof(exitTime) ); ZeroMemory( &kernelTime1, sizeof(kernelTime1) ); ZeroMemory( &userTime1, sizeof(userTime1) ); ZeroMemory( &kernelTime2, sizeof(kernelTime2) ); ZeroMemory( &userTime2, sizeof(userTime2) ); /* check the process times for the child process */ if( ! GetProcessTimes( hProcess, &createTime, &exitTime, &kernelTime1, &userTime1 ) ) { dwError = GetLastError(); Fail( "GetProcessTimes() call failed with error code %d\n", dwError ); } /* simulate some activity */ for( i=0; i<1000; i++ ) { for( j=0; j<1000; j++ ) { /* do kernel work to increase system usage counters */ total = malloc(1024 * 1024); *total = j * i; for( k=0; k<1000; k++ ) { *total += k + i; } free(total); } } /* check the process times for the child process */ if( ! GetProcessTimes( hProcess, &createTime, &exitTime, &kernelTime2, &userTime2 ) ) { dwError = GetLastError(); Fail( "GetProcessTimes() call failed with error code %d\n", dwError ); } /* very simple logical checking of the results */ if( CompareFileTime( &kernelTime1, &kernelTime2 ) > 0 ) { Fail( "Unexpected kernel time value reported.\n" ); } if( CompareFileTime( &userTime1, &userTime2 ) > 0 ) { Fail( "Unexpected user time value reported.\n" ); } /* terminate the PAL */ PAL_Terminate(); /* return success */ return PASS; }
/* 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; DWORD minimumWorkingSetSize, maximumWorkingSetSize; LARGE_INTEGER performanceCount; MEMORYSTATUS memoryStatus; HANDLE handle; POINT point; /* Get various basic pieces of system information */ RandaddInt32 (GetActiveWindow ()); /* Handle of active window */ RandaddInt32 (GetCapture ()); /* Handle of window with mouse capture */ RandaddInt32 (GetClipboardOwner ()); /* Handle of clipboard owner */ RandaddInt32 (GetClipboardViewer ()); /* Handle of start of clpbd.viewer list */ RandaddInt32 (GetCurrentProcess ()); /* Pseudohandle of current process */ RandaddInt32 (GetCurrentProcessId ()); /* Current process ID */ RandaddInt32 (GetCurrentThread ()); /* Pseudohandle of current thread */ RandaddInt32 (GetCurrentThreadId ()); /* Current thread ID */ RandaddInt32 (GetCurrentTime ()); /* Milliseconds since Windows started */ RandaddInt32 (GetDesktopWindow ()); /* Handle of desktop window */ RandaddInt32 (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 */ RandaddInt32 (GetOpenClipboardWindow ()); /* Handle of window with clpbd.open */ RandaddInt32 (GetProcessHeap ()); /* Handle of process heap */ RandaddInt32 (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); RandaddInt32 (minimumWorkingSetSize); RandaddInt32 (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 if (CryptoAPIAvailable && CryptGenRandom (hCryptProv, sizeof (buffer), buffer)) RandaddBuf (buffer, sizeof (buffer)); /* 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; }
/* The following block is copied from the Java source code. It documents the counters array. * @param counters the results are returned in this array. * <ol> * <li>working set in bytes for this process * <li>peak working set in bytes for this process * <li>elapsed time in milliseconds * <li>user time in milliseconds * <li>kernel time in milliseconds * <li>page faults for the process * <li>commit charge total in bytes (working set for the entire machine). On some * machines we have problems getting this value so we return -1 in that case. * <li>number of GDI objects in the process * <li>number of USER objects in the process * <li>number of open handles in the process. returns -1 if this information is not available * <li>Number of read operations * <li>Number of write operations * <li>Number of bytes read * <li>Number of bytes written * </ol> */ JNIEXPORT jboolean JNICALL Java_org_eclipse_perfmsr_core_PerformanceMonitor_nativeGetPerformanceCounters (JNIEnv * jniEnv, jclass jniClass, jlongArray counters) { FILETIME creationTime, exitTime, kernelTime, userTime, systemTime; ULARGE_INTEGER uliCreation, uliSystem, uliKernel, uliUser; ULONGLONG diff; IO_COUNTERS ioCounters; jboolean result = TRUE; jsize len = (*jniEnv)->GetArrayLength(jniEnv, counters); jlong *body = (*jniEnv)->GetLongArrayElements(jniEnv, counters, 0); HANDLE me = GetCurrentProcess(); PROCESS_MEMORY_COUNTERS memCounters; DWORD cb = sizeof(PROCESS_MEMORY_COUNTERS); BOOL rc = GetProcessMemoryInfo(me, &memCounters, cb); if (rc != 0) { body[0] = memCounters.WorkingSetSize; body[1] = memCounters.PeakWorkingSetSize; body[5] = memCounters.PageFaultCount; } else { handleSystemError(jniEnv); return FALSE; } if (!GetProcessTimes(me, &creationTime, &exitTime, &kernelTime, &userTime)) { handleSystemError(jniEnv); return FALSE; } GetSystemTimeAsFileTime(&systemTime); memcpy(&uliCreation, &creationTime, sizeof(uliCreation)); memcpy(&uliSystem, &systemTime, sizeof(uliSystem)); memcpy(&uliKernel, &kernelTime, sizeof(uliSystem)); memcpy(&uliUser, &userTime, sizeof(ULARGE_INTEGER)); diff = uliSystem.QuadPart - uliCreation.QuadPart; body[2] = diff / 10000; body[3] = uliUser.QuadPart / 10000; body[4] = uliKernel.QuadPart / 10000; body[6] = getTotalCommitted(jniEnv); body[7] = GetGuiResources(me, GR_GDIOBJECTS); body[8] = GetGuiResources(me, GR_USEROBJECTS); body[9] = getHandleCount(jniEnv, me); if (!GetProcessIoCounters(me, &ioCounters)) { handleSystemError(jniEnv); return FALSE; } body[10] = ioCounters.ReadOperationCount; body[11] = ioCounters.WriteOperationCount; body[12] = ioCounters.ReadTransferCount; body[13] = ioCounters.WriteTransferCount; (*jniEnv)->ReleaseLongArrayElements(jniEnv, counters, body, 0); return result; }
bool ErrorReport::GetMiscCrashInfo() { // Get crash time m_CrashDateTime = QDateTime::currentDateTime(); m_ProcessArchitecture = ARX_ARCH_NAME; #ifdef HAVE_WINAPI // Open parent process handle HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, m_pCrashInfo->processId); if(hProcess != NULL) { // Get memory usage info PROCESS_MEMORY_COUNTERS meminfo; BOOL bGetMemInfo = GetProcessMemoryInfo(hProcess, &meminfo, sizeof(PROCESS_MEMORY_COUNTERS)); if(bGetMemInfo) m_ProcessMemoryUsage = meminfo.WorkingSetSize; // Determine the period of time the process is working. FILETIME CreationTime, ExitTime, KernelTime, UserTime; BOOL bGetTimes = GetProcessTimes(hProcess, &CreationTime, &ExitTime, &KernelTime, &UserTime); if(bGetTimes) { SYSTEMTIME AppStartTime; FileTimeToSystemTime(&CreationTime, &AppStartTime); SYSTEMTIME CurTime; GetSystemTime(&CurTime); ULONG64 uCurTime = ConvertSystemTimeToULONG64(CurTime); ULONG64 uStartTime = ConvertSystemTimeToULONG64(AppStartTime); // Check that the application works for at least one minute before crash. // This might help to avoid cyclic error report generation when the applciation // crashes on startup. m_RunningTimeSec = (double)(uCurTime-uStartTime)*10E-08; } } else { m_DetailedError = QString("Unable to obtain an handle to the crashed process (Error %1).").arg(QString::number(GetLastError())); return false; } // Get operating system friendly name from registry. char OSNameBuf[256]; if(!GetWindowsVersionName(OSNameBuf, 256)) { m_DetailedError = QString("A failure occured when obtaining Windows version name (Error %1).").arg(QString::number(GetLastError())); return false; } m_OSName = OSNameBuf; // Determine if Windows is 64-bit. m_OSArchitecture = Is64BitWindows() ? ARX_ARCH_NAME_X86_64 : ARX_ARCH_NAME_X86; if(m_pCrashInfo->exceptionCode != 0) { QString exceptionStr = GetExceptionString(m_pCrashInfo->exceptionCode).c_str(); if(!exceptionStr.isEmpty()) { m_ReportDescription += "\nException code:\n "; m_ReportDescription += exceptionStr; m_ReportDescription += "\n"; } } std::string callStack, callstackTop; u32 callstackCrc; bool bCallstack = GetCallStackInfo(hProcess, m_pCrashInfo->threadHandle, &m_pCrashInfo->contextRecord, callStack, callstackTop, callstackCrc); if(!bCallstack) { m_DetailedError = "A failure occured when obtaining information regarding the callstack."; return false; } m_ReportUniqueID = QString("[%1]").arg(QString::number(callstackCrc, 16).toUpper()); m_ReportDescription = m_pCrashInfo->detailedCrashInfo; m_ReportDescription += "\nCallstack:\n"; m_ReportDescription += callStack.c_str(); m_ReportTitle = QString("%1 %2").arg(m_ReportUniqueID, callstackTop.c_str()); QString registers(GetRegisters(&m_pCrashInfo->contextRecord).c_str()); if(!registers.isEmpty()) { m_ReportDescription += "\nRegisters:\n"; m_ReportDescription += registers; } CloseHandle(hProcess); m_ReportDescriptionText = m_ReportDescription; #else // !HAVE_WINAPI getResourceUsage(m_pCrashInfo->processId, m_ProcessMemoryUsage, m_RunningTimeSec); #ifdef HAVE_UNAME struct utsname buf; if(uname(&buf) == 0) { m_OSName = QString(buf.sysname) + " " + buf.release; m_OSArchitecture = buf.machine; } #endif m_OSDistribution = getLinuxDistribution(); #endif // !HAVE_WINAPI return true; }
int main(int argc, char** argv) { #if !defined(_WIN32) && !defined(_WIN64) printf("Only Windows OS is supported.\n"); #else if(argc < 3) { printf("usage: %s <dir> <command>\n", argv[0]); return -1; } char path[512]; sprintf_s(path, 511, "%s\\%s.pid", argv[1], argv[2]); DWORD pid = 0; FILE* f = NULL; fopen_s(&f, path, "r"); if(!f) { fprintf(stderr, "Can't open file %s\n", path); } else { char* pidbuf[32]; int numread = fread(pidbuf, sizeof(char), 31, f); if(numread > 0) { pidbuf[numread] = '\0'; pid = atoi((const char*)pidbuf); } } if(pid > 0) { printf("ProcessID: %d\n", pid); HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, false, pid); if(h <= 0) { fprintf(stderr, "Process %d can't be opened.\n", pid); printf("ProcessUpTime: \n"); } else { //Process elapsed time. BIGTIME CreateTime, ExitTime, ElapsedTime, Now; FILETIME KernelTime, UserTime; GetProcessTimes(h, &CreateTime.ft, &ExitTime.ft, &KernelTime, &UserTime); if(ExitTime.li > CreateTime.li) ElapsedTime.li = ExitTime.li - CreateTime.li; else { GetSystemTimeAsFileTime(&Now.ft); ElapsedTime.li = Now.li - CreateTime.li; } unsigned elapsedsecs = (unsigned)(ElapsedTime.li/10000000); TSpan span(elapsedsecs); printf("ProcessUpTime: %d-%02d:%02d:%02d\n", span.d, span.h, span.m, span.s); } } else { printf("ProcessID: \nProcessUpTime: \n"); } //CPU usage BIGTIME idle1, kernel1, user1, idle2, kernel2, user2; GetSystemTimes(&idle1.ft, &kernel1.ft, &user1.ft); Sleep(1000); GetSystemTimes(&idle2.ft, &kernel2.ft, &user2.ft); int IdleTime = (int)(idle2.li - idle1.li); int TotalTime = (int)((kernel2.li + user2.li) - (kernel1.li + user1.li)); int idleRate = (int)(100.0 * IdleTime / TotalTime); printf("CPU-Idle: %d%%\n", idleRate); //Computer uptime LARGE_INTEGER ticks, unit; QueryPerformanceCounter(&ticks); QueryPerformanceFrequency(&unit); int secs = (int)(ticks.QuadPart/unit.QuadPart); TSpan u((int)secs); printf("ComputerUpTime: %d days, %d:%d\n", u.d, u.h, u.m); printf("---SpaceUsedAndFree---\n"); //Physical and virtual memory usage. MEMORYSTATUS memstatus; GlobalMemoryStatus(&memstatus); printf("Physical Memory: %d %d\nVirtual Memory: %d %d\n", (memstatus.dwTotalPhys - memstatus.dwAvailPhys)/1024, memstatus.dwAvailPhys/1024, (memstatus.dwTotalVirtual - memstatus.dwAvailVirtual)/1024, memstatus.dwAvailVirtual/1024); // Disk Usage char drivePath[] = "?:\\"; char driveName; for( driveName = 'A'; driveName <= 'Z'; driveName++ ) { drivePath[0] = driveName; int dtype = GetDriveTypeA(drivePath); if(dtype == DRIVE_FIXED || dtype == DRIVE_RAMDISK || dtype == DRIVE_REMOVABLE || dtype == DRIVE_CDROM) { ULARGE_INTEGER diskAvailStruct; ULARGE_INTEGER diskTotalStruct; diskAvailStruct.QuadPart = 0; diskTotalStruct.QuadPart = 0; GetDiskFreeSpaceExA(drivePath, &diskAvailStruct, &diskTotalStruct, 0); double DiskSize = diskTotalStruct.QuadPart / 1024.0; double FreeSize = diskAvailStruct.QuadPart / 1024.0; printf("%s: %.0f %.0f\n", drivePath, DiskSize - FreeSize, FreeSize); } } #endif return 0; }
void CommandStats::DoStats(char statschar, User* user, string_list &results) { bool isPublic = ServerInstance->Config->UserStats.find(statschar) != std::string::npos; bool isRemoteOper = IS_REMOTE(user) && (user->IsOper()); bool isLocalOperWithPrivs = IS_LOCAL(user) && user->HasPrivPermission("servers/auspex"); if (!isPublic && !isRemoteOper && !isLocalOperWithPrivs) { ServerInstance->SNO->WriteToSnoMask('t', "%s '%c' denied for %s (%s@%s)", (IS_LOCAL(user) ? "Stats" : "Remote stats"), statschar, user->nick.c_str(), user->ident.c_str(), user->host.c_str()); results.push_back("481 " + user->nick + " :Permission denied - STATS " + statschar + " requires the servers/auspex priv."); return; } ModResult MOD_RESULT; FIRST_MOD_RESULT(OnStats, MOD_RESULT, (statschar, user, results)); if (MOD_RESULT == MOD_RES_DENY) { results.push_back("219 "+user->nick+" "+statschar+" :End of /STATS report"); ServerInstance->SNO->WriteToSnoMask('t',"%s '%c' requested by %s (%s@%s)", (IS_LOCAL(user) ? "Stats" : "Remote stats"), statschar, user->nick.c_str(), user->ident.c_str(), user->host.c_str()); return; } switch (statschar) { /* stats p (show listening ports) */ case 'p': { for (std::vector<ListenSocket*>::const_iterator i = ServerInstance->ports.begin(); i != ServerInstance->ports.end(); ++i) { ListenSocket* ls = *i; std::string ip = ls->bind_addr; if (ip.empty()) ip.assign("*"); std::string type = ls->bind_tag->getString("type", "clients"); std::string hook = ls->bind_tag->getString("ssl", "plaintext"); results.push_back("249 "+user->nick+" :"+ ip + ":"+ConvToStr(ls->bind_port)+ " (" + type + ", " + hook + ")"); } } break; /* These stats symbols must be handled by a linking module */ case 'n': case 'c': break; case 'i': { for (ClassVector::iterator i = ServerInstance->Config->Classes.begin(); i != ServerInstance->Config->Classes.end(); i++) { ConnectClass* c = *i; std::stringstream res; res << "215 " << user->nick << " I " << c->name << ' '; if (c->type == CC_ALLOW) res << '+'; if (c->type == CC_DENY) res << '-'; if (c->type == CC_NAMED) res << '*'; else res << c->host; res << ' ' << c->config->getString("port", "*") << ' '; res << c->GetRecvqMax() << ' ' << c->GetSendqSoftMax() << ' ' << c->GetSendqHardMax() << ' ' << c->GetCommandRate() << ' ' << c->GetPenaltyThreshold(); if (c->fakelag) res << '*'; results.push_back(res.str()); } } break; case 'Y': { int idx = 0; for (ClassVector::iterator i = ServerInstance->Config->Classes.begin(); i != ServerInstance->Config->Classes.end(); i++) { ConnectClass* c = *i; results.push_back("215 "+user->nick+" i NOMATCH * "+c->GetHost()+" "+ConvToStr(c->limit ? c->limit : SocketEngine::GetMaxFds())+" "+ConvToStr(idx)+" "+ServerInstance->Config->ServerName+" *"); results.push_back("218 "+user->nick+" Y "+ConvToStr(idx)+" "+ConvToStr(c->GetPingTime())+" 0 "+ConvToStr(c->GetSendqHardMax())+" :"+ ConvToStr(c->GetRecvqMax())+" "+ConvToStr(c->GetRegTimeout())); idx++; } } break; case 'P': { unsigned int idx = 0; const UserManager::OperList& opers = ServerInstance->Users->all_opers; for (UserManager::OperList::const_iterator i = opers.begin(); i != opers.end(); ++i) { User* oper = *i; if (!oper->server->IsULine()) { LocalUser* lu = IS_LOCAL(oper); results.push_back("249 " + user->nick + " :" + oper->nick + " (" + oper->ident + "@" + oper->dhost + ") Idle: " + (lu ? ConvToStr(ServerInstance->Time() - lu->idle_lastmsg) + " secs" : "unavailable")); idx++; } } results.push_back("249 "+user->nick+" :"+ConvToStr(idx)+" OPER(s)"); } break; case 'k': ServerInstance->XLines->InvokeStats("K",216,user,results); break; case 'g': ServerInstance->XLines->InvokeStats("G",223,user,results); break; case 'q': ServerInstance->XLines->InvokeStats("Q",217,user,results); break; case 'Z': ServerInstance->XLines->InvokeStats("Z",223,user,results); break; case 'e': ServerInstance->XLines->InvokeStats("E",223,user,results); break; case 'E': { const SocketEngine::Statistics& stats = SocketEngine::GetStats(); results.push_back("249 "+user->nick+" :Total events: "+ConvToStr(stats.TotalEvents)); results.push_back("249 "+user->nick+" :Read events: "+ConvToStr(stats.ReadEvents)); results.push_back("249 "+user->nick+" :Write events: "+ConvToStr(stats.WriteEvents)); results.push_back("249 "+user->nick+" :Error events: "+ConvToStr(stats.ErrorEvents)); break; } /* stats m (list number of times each command has been used, plus bytecount) */ case 'm': for (Commandtable::iterator i = ServerInstance->Parser->cmdlist.begin(); i != ServerInstance->Parser->cmdlist.end(); i++) { if (i->second->use_count) { /* RPL_STATSCOMMANDS */ results.push_back("212 "+user->nick+" "+i->second->name+" "+ConvToStr(i->second->use_count)); } } break; /* stats z (debug and memory info) */ case 'z': { results.push_back("249 "+user->nick+" :Users: "+ConvToStr(ServerInstance->Users->GetUsers().size())); results.push_back("249 "+user->nick+" :Channels: "+ConvToStr(ServerInstance->GetChans().size())); results.push_back("249 "+user->nick+" :Commands: "+ConvToStr(ServerInstance->Parser->cmdlist.size())); float kbitpersec_in, kbitpersec_out, kbitpersec_total; char kbitpersec_in_s[30], kbitpersec_out_s[30], kbitpersec_total_s[30]; SocketEngine::GetStats().GetBandwidth(kbitpersec_in, kbitpersec_out, kbitpersec_total); snprintf(kbitpersec_total_s, 30, "%03.5f", kbitpersec_total); snprintf(kbitpersec_out_s, 30, "%03.5f", kbitpersec_out); snprintf(kbitpersec_in_s, 30, "%03.5f", kbitpersec_in); results.push_back("249 "+user->nick+" :Bandwidth total: "+ConvToStr(kbitpersec_total_s)+" kilobits/sec"); results.push_back("249 "+user->nick+" :Bandwidth out: "+ConvToStr(kbitpersec_out_s)+" kilobits/sec"); results.push_back("249 "+user->nick+" :Bandwidth in: "+ConvToStr(kbitpersec_in_s)+" kilobits/sec"); #ifndef _WIN32 /* Moved this down here so all the not-windows stuff (look w00tie, I didn't say win32!) is in one ifndef. * Also cuts out some identical code in both branches of the ifndef. -- Om */ rusage R; /* Not sure why we were doing '0' with a RUSAGE_SELF comment rather than just using RUSAGE_SELF -- Om */ if (!getrusage(RUSAGE_SELF,&R)) /* RUSAGE_SELF */ { results.push_back("249 "+user->nick+" :Total allocation: "+ConvToStr(R.ru_maxrss)+"K"); results.push_back("249 "+user->nick+" :Signals: "+ConvToStr(R.ru_nsignals)); results.push_back("249 "+user->nick+" :Page faults: "+ConvToStr(R.ru_majflt)); results.push_back("249 "+user->nick+" :Swaps: "+ConvToStr(R.ru_nswap)); results.push_back("249 "+user->nick+" :Context Switches: Voluntary; "+ConvToStr(R.ru_nvcsw)+" Involuntary; "+ConvToStr(R.ru_nivcsw)); char percent[30]; float n_elapsed = (ServerInstance->Time() - ServerInstance->stats->LastSampled.tv_sec) * 1000000 + (ServerInstance->Time_ns() - ServerInstance->stats->LastSampled.tv_nsec) / 1000; float n_eaten = ((R.ru_utime.tv_sec - ServerInstance->stats->LastCPU.tv_sec) * 1000000 + R.ru_utime.tv_usec - ServerInstance->stats->LastCPU.tv_usec); float per = (n_eaten / n_elapsed) * 100; snprintf(percent, 30, "%03.5f%%", per); results.push_back("249 "+user->nick+" :CPU Use (now): "+percent); n_elapsed = ServerInstance->Time() - ServerInstance->startup_time; n_eaten = (float)R.ru_utime.tv_sec + R.ru_utime.tv_usec / 100000.0; per = (n_eaten / n_elapsed) * 100; snprintf(percent, 30, "%03.5f%%", per); results.push_back("249 "+user->nick+" :CPU Use (total): "+percent); } #else PROCESS_MEMORY_COUNTERS MemCounters; if (GetProcessMemoryInfo(GetCurrentProcess(), &MemCounters, sizeof(MemCounters))) { results.push_back("249 "+user->nick+" :Total allocation: "+ConvToStr((MemCounters.WorkingSetSize + MemCounters.PagefileUsage) / 1024)+"K"); results.push_back("249 "+user->nick+" :Pagefile usage: "+ConvToStr(MemCounters.PagefileUsage / 1024)+"K"); results.push_back("249 "+user->nick+" :Page faults: "+ConvToStr(MemCounters.PageFaultCount)); } FILETIME CreationTime; FILETIME ExitTime; FILETIME KernelTime; FILETIME UserTime; LARGE_INTEGER ThisSample; if(GetProcessTimes(GetCurrentProcess(), &CreationTime, &ExitTime, &KernelTime, &UserTime) && QueryPerformanceCounter(&ThisSample)) { KernelTime.dwHighDateTime += UserTime.dwHighDateTime; KernelTime.dwLowDateTime += UserTime.dwLowDateTime; double n_eaten = (double)( ( (uint64_t)(KernelTime.dwHighDateTime - ServerInstance->stats->LastCPU.dwHighDateTime) << 32 ) + (uint64_t)(KernelTime.dwLowDateTime - ServerInstance->stats->LastCPU.dwLowDateTime) )/100000; double n_elapsed = (double)(ThisSample.QuadPart - ServerInstance->stats->LastSampled.QuadPart) / ServerInstance->stats->QPFrequency.QuadPart; double per = (n_eaten/n_elapsed); char percent[30]; snprintf(percent, 30, "%03.5f%%", per); results.push_back("249 "+user->nick+" :CPU Use (now): "+percent); n_elapsed = ServerInstance->Time() - ServerInstance->startup_time; n_eaten = (double)(( (uint64_t)(KernelTime.dwHighDateTime) << 32 ) + (uint64_t)(KernelTime.dwLowDateTime))/100000; per = (n_eaten / n_elapsed); snprintf(percent, 30, "%03.5f%%", per); results.push_back("249 "+user->nick+" :CPU Use (total): "+percent); } #endif } break; case 'T': { results.push_back("249 "+user->nick+" :accepts "+ConvToStr(ServerInstance->stats->statsAccept)+" refused "+ConvToStr(ServerInstance->stats->statsRefused)); results.push_back("249 "+user->nick+" :unknown commands "+ConvToStr(ServerInstance->stats->statsUnknown)); results.push_back("249 "+user->nick+" :nick collisions "+ConvToStr(ServerInstance->stats->statsCollisions)); results.push_back("249 "+user->nick+" :dns requests "+ConvToStr(ServerInstance->stats->statsDnsGood+ServerInstance->stats->statsDnsBad)+" succeeded "+ConvToStr(ServerInstance->stats->statsDnsGood)+" failed "+ConvToStr(ServerInstance->stats->statsDnsBad)); results.push_back("249 "+user->nick+" :connection count "+ConvToStr(ServerInstance->stats->statsConnects)); results.push_back(InspIRCd::Format("249 %s :bytes sent %5.2fK recv %5.2fK", user->nick.c_str(), ServerInstance->stats->statsSent / 1024.0, ServerInstance->stats->statsRecv / 1024.0)); } break; /* stats o */ case 'o': { ConfigTagList tags = ServerInstance->Config->ConfTags("oper"); for(ConfigIter i = tags.first; i != tags.second; ++i) { ConfigTag* tag = i->second; results.push_back("243 "+user->nick+" O "+tag->getString("host")+" * "+ tag->getString("name") + " " + tag->getString("type")+" 0"); } } break; case 'O': { for (OperIndex::const_iterator i = ServerInstance->Config->OperTypes.begin(); i != ServerInstance->Config->OperTypes.end(); ++i) { OperInfo* tag = i->second; tag->init(); std::string umodes; std::string cmodes; for(char c='A'; c < 'z'; c++) { ModeHandler* mh = ServerInstance->Modes->FindMode(c, MODETYPE_USER); if (mh && mh->NeedsOper() && tag->AllowedUserModes[c - 'A']) umodes.push_back(c); mh = ServerInstance->Modes->FindMode(c, MODETYPE_CHANNEL); if (mh && mh->NeedsOper() && tag->AllowedChanModes[c - 'A']) cmodes.push_back(c); } results.push_back("243 "+user->nick+" O "+tag->name.c_str() + " " + umodes + " " + cmodes); } } break; /* stats l (show user I/O stats) */ case 'l': results.push_back("211 "+user->nick+" :nick[ident@host] sendq cmds_out bytes_out cmds_in bytes_in time_open"); for (LocalUserList::iterator n = ServerInstance->Users->local_users.begin(); n != ServerInstance->Users->local_users.end(); n++) { LocalUser* i = *n; results.push_back("211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->dhost+"] "+ConvToStr(i->eh.getSendQSize())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(ServerInstance->Time() - i->age)); } break; /* stats L (show user I/O stats with IP addresses) */ case 'L': results.push_back("211 "+user->nick+" :nick[ident@ip] sendq cmds_out bytes_out cmds_in bytes_in time_open"); for (LocalUserList::iterator n = ServerInstance->Users->local_users.begin(); n != ServerInstance->Users->local_users.end(); n++) { LocalUser* i = *n; results.push_back("211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->GetIPString()+"] "+ConvToStr(i->eh.getSendQSize())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(ServerInstance->Time() - i->age)); } break; /* stats u (show server uptime) */ case 'u': { time_t current_time = 0; current_time = ServerInstance->Time(); time_t server_uptime = current_time - ServerInstance->startup_time; struct tm* stime; stime = gmtime(&server_uptime); /* i dont know who the hell would have an ircd running for over a year nonstop, but * Craig suggested this, and it seemed a good idea so in it went */ if (stime->tm_year > 70) { results.push_back(InspIRCd::Format("242 %s :Server up %d years, %d days, %.2d:%.2d:%.2d", user->nick.c_str(), stime->tm_year - 70, stime->tm_yday, stime->tm_hour, stime->tm_min, stime->tm_sec)); } else { results.push_back(InspIRCd::Format("242 %s :Server up %d days, %.2d:%.2d:%.2d", user->nick.c_str(), stime->tm_yday, stime->tm_hour, stime->tm_min, stime->tm_sec)); } } break; default: break; } results.push_back("219 "+user->nick+" "+statschar+" :End of /STATS report"); ServerInstance->SNO->WriteToSnoMask('t',"%s '%c' requested by %s (%s@%s)", (IS_LOCAL(user) ? "Stats" : "Remote stats"), statschar, user->nick.c_str(), user->ident.c_str(), user->host.c_str()); return; }
double __po_hi_get_CPU_time( ) { #if defined(_WIN32) /* Windows -------------------------------------------------- */ FILETIME createTime; FILETIME exitTime; FILETIME kernelTime; FILETIME userTime; if ( GetProcessTimes( GetCurrentProcess( ), &createTime, &exitTime, &kernelTime, &userTime ) != -1 ) { SYSTEMTIME userSystemTime; if ( FileTimeToSystemTime( &userTime, &userSystemTime ) != -1 ) return (double)userSystemTime.wHour * 3600.0 + (double)userSystemTime.wMinute * 60.0 + (double)userSystemTime.wSecond + (double)userSystemTime.wMilliseconds / 1000.0; } #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) /* AIX, BSD, Cygwin, HP-UX, Linux, OSX, and Solaris --------- */ #if _POSIX_TIMERS > 0 /* Prefer high-res POSIX timers, when available. */ { clockid_t id; struct timespec ts; #if _POSIX_CPUTIME > 0 /* Clock ids vary by OS. Query the id, if possible. */ if ( clock_getcpuclockid( 0, &id ) == -1 ) #endif #if defined(CLOCK_PROCESS_CPUTIME_ID) /* Use known clock id for AIX, Linux, or Solaris. */ id = CLOCK_PROCESS_CPUTIME_ID; #elif defined(CLOCK_VIRTUAL) /* Use known clock id for BSD or HP-UX. */ id = CLOCK_VIRTUAL; #else id = (clockid_t)-1; #endif if ( id != (clockid_t)-1 && clock_gettime( id, &ts ) != -1 ) return (double)ts.tv_sec + (double)ts.tv_nsec / 1000000000.0; } #endif #if defined(RUSAGE_SELF) { struct rusage rusage; if ( getrusage( RUSAGE_SELF, &rusage ) != -1 ) return (double)rusage.ru_utime.tv_sec + (double)rusage.ru_utime.tv_usec / 1000000.0; } #endif #if defined(_SC_CLK_TCK) { const double ticks = (double)sysconf( _SC_CLK_TCK ); struct tms tms; if ( times( &tms ) != (clock_t)-1 ) return (double)tms.tms_utime / ticks; } #endif #if defined(CLOCKS_PER_SEC) { clock_t cl = clock( ); if ( cl != (clock_t)-1 ) return (double)cl / (double)CLOCKS_PER_SEC; } #endif #endif return -1.0; /* Failed. */ }
extern "C" int clock_gettime(clockid_t clock_id, struct timespec* tp) { if (!tp) { errno = EFAULT; return -1; } const auto unanosToTimespec = [](timespec* tp, unsigned_nanos t) -> int { static constexpr unsigned_nanos one_sec(std::chrono::seconds(1)); tp->tv_sec = time_t(std::chrono::duration_cast<std::chrono::seconds>(t).count()); tp->tv_nsec = long((t % one_sec).count()); return 0; }; FILETIME createTime, exitTime, kernalTime, userTime; switch (clock_id) { case CLOCK_REALTIME: { auto now = std::chrono::system_clock::now().time_since_epoch(); duration_to_ts(now, tp); return 0; } case CLOCK_MONOTONIC: { auto now = std::chrono::steady_clock::now().time_since_epoch(); duration_to_ts(now, tp); return 0; } case CLOCK_PROCESS_CPUTIME_ID: { if (!GetProcessTimes( GetCurrentProcess(), &createTime, &exitTime, &kernalTime, &userTime)) { errno = EINVAL; return -1; } return unanosToTimespec( tp, filetimeToUnsignedNanos(kernalTime) + filetimeToUnsignedNanos(userTime)); } case CLOCK_THREAD_CPUTIME_ID: { if (!GetThreadTimes( GetCurrentThread(), &createTime, &exitTime, &kernalTime, &userTime)) { errno = EINVAL; return -1; } return unanosToTimespec( tp, filetimeToUnsignedNanos(kernalTime) + filetimeToUnsignedNanos(userTime)); } default: errno = EINVAL; return -1; } }
double dtime_ (real tarray[2]) { #if defined (_WIN32) static int win32_platform = -1; if (win32_platform == -1) { OSVERSIONINFO osv; osv.dwOSVersionInfoSize = sizeof (osv); GetVersionEx (&osv); win32_platform = osv.dwPlatformId; } /* We need to use this hack on non-NT platforms, where the first call returns 0.0 and subsequent ones return the correct value. */ if (win32_platform != VER_PLATFORM_WIN32_NT) { static unsigned long long clock_freq; static unsigned long long old_count; unsigned long long count; double delta; LARGE_INTEGER counter_val; if (clock_freq == 0) { LARGE_INTEGER freq; if (!QueryPerformanceFrequency (&freq)) { errno = ENOSYS; return 0.0; } else { clock_freq = ((unsigned long long) freq.HighPart << 32) + ((unsigned) freq.LowPart); } } if (!QueryPerformanceCounter (&counter_val)) return -1.0; count = ((unsigned long long) counter_val.HighPart << 32) + (unsigned) counter_val.LowPart; delta = ((double) (count - old_count)) / clock_freq; tarray[0] = (float) delta; tarray[1] = 0.0; old_count = count; } else { static unsigned long long old_utime, old_stime; unsigned long long utime, stime; FILETIME creation_time, exit_time, kernel_time, user_time; GetProcessTimes (GetCurrentProcess (), &creation_time, &exit_time, &kernel_time, &user_time); utime = ((unsigned long long) user_time.dwHighDateTime << 32) + (unsigned) user_time.dwLowDateTime; stime = ((unsigned long long) kernel_time.dwHighDateTime << 32) + (unsigned) kernel_time.dwLowDateTime; tarray[0] = (utime - old_utime) / 1.0e7; tarray[1] = (stime - old_stime) / 1.0e7; old_utime = utime; old_stime = stime; } return tarray[0] + tarray[1]; #elif defined (HAVE_GETRUSAGE) || defined (HAVE_TIMES) /* The getrusage version is only the default for convenience. */ #ifdef HAVE_GETRUSAGE float utime, stime; static float old_utime = 0.0, old_stime = 0.0; struct rusage rbuff; if (getrusage (RUSAGE_SELF, &rbuff) != 0) abort (); utime = (float) (rbuff.ru_utime).tv_sec + (float) (rbuff.ru_utime).tv_usec / 1000000.0; tarray[0] = utime - (float) old_utime; stime = (float) (rbuff.ru_stime).tv_sec + (float) (rbuff.ru_stime).tv_usec / 1000000.0; tarray[1] = stime - old_stime; #else /* HAVE_GETRUSAGE */ /* For dtime, etime we store the clock tick parameter (clk_tck) the first time either of them is invoked rather than each time. This approach probably speeds up each invocation by avoiding a system call each time, but means that the overhead of the first call is different to all others. */ static long clk_tck = 0; time_t utime, stime; static time_t old_utime = 0, old_stime = 0; struct tms buffer; /* NeXTStep seems to define _SC_CLK_TCK but not to have sysconf; fixme: does using _POSIX_VERSION help? */ # if defined _SC_CLK_TCK && defined _POSIX_VERSION if (!clk_tck) clk_tck = sysconf (_SC_CLK_TCK); # elif defined CLOCKS_PER_SECOND if (!clk_tck) clk_tck = CLOCKS_PER_SECOND; # elif defined CLK_TCK if (!clk_tck) clk_tck = CLK_TCK; # elif defined HZ if (!clk_tck) clk_tck = HZ; # elif defined HAVE_GETRUSAGE # else #error Dont know clock tick length # endif if (times (&buffer) == (clock_t) - 1) return -1.0; utime = buffer.tms_utime; stime = buffer.tms_stime; tarray[0] = ((float) (utime - old_utime)) / (float) clk_tck; tarray[1] = ((float) (stime - old_stime)) / (float) clk_tck; #endif /* HAVE_GETRUSAGE */ old_utime = utime; old_stime = stime; return (tarray[0] + tarray[1]); #else /* ! HAVE_GETRUSAGE && ! HAVE_TIMES */ errno = ENOSYS; return 0.0; #endif /* ! HAVE_GETRUSAGE && ! HAVE_TIMES */ }
/* * FillRunTimeLog fill the global Result array with runtime timing parameters. * * Accepts: * ------- * hProcess - handle to the process. * test_id - test id. */ void FillRunTimeLog(HANDLE hProcess,int test_id) { SYSTEMTIME UTC_Time, LocalTime; FILETIME CreationTime, ExitTime, KernelTime, UserTime, TotalTime; int time_in_ms,kernel_time,user_time; int len1,len2,len3,len4; char test_id_str[MAX_INT_TO_STRING]; char time_in_ms_str[MAX_INT_TO_STRING]; char kernel_time_str[MAX_INT_TO_STRING]; char user_time_str[MAX_INT_TO_STRING]; char start_time_str[HH_MM_SS_MMM]; GetProcessTimes( hProcess, &CreationTime, &ExitTime, &KernelTime, &UserTime ); itoa(test_id,test_id_str,10); len1 = strlen(test_id_str); FileTimeToSystemTime(&CreationTime, /* input */ &UTC_Time); SystemTimeToTzSpecificLocalTime(NULL, /* use default time zone */ &UTC_Time, /* input */ &LocalTime); /* output */ sprintf(start_time_str,"%02d:%02d:%02d:%02d",LocalTime.wHour,LocalTime.wMinute, LocalTime.wSecond,LocalTime.wMilliseconds); TotalTime = SubtractFiletimes(ExitTime, CreationTime); time_in_ms = TotalTime.dwLowDateTime / FILETIME_UNITS_PER_MILLISECOND; itoa(time_in_ms,time_in_ms_str,10); len2 = strlen(time_in_ms_str); FileTimeToSystemTime(&TotalTime, /* input */ &UTC_Time); /* output */ if ((KernelTime.dwHighDateTime == 0) && (UserTime.dwHighDateTime == 0)) { kernel_time = KernelTime.dwLowDateTime / FILETIME_UNITS_PER_MILLISECOND; itoa(kernel_time,kernel_time_str,10); len3 = strlen(kernel_time_str); user_time = UserTime.dwLowDateTime / FILETIME_UNITS_PER_MILLISECOND; itoa(user_time,user_time_str,10); len4 = strlen(user_time_str); } else { printf("This function can only print the Kernel Time and User Time " "if they are small enough to be held in a single DWORD each. " "That is not true, so they will not be printed. "); } shared_result[test_id-1].runtime_log_line = (char*)malloc(sizeof(char)*(HH_MM_SS_MMM + LOG_RUNTIME_LINE + len1 + len2 + len3 + len4) + 1); if(shared_result[test_id-1].runtime_log_line == NULL) { printf("Failed to allocate memory for FillRunTimeLog function \n"); exit(1); } sprintf(shared_result[test_id-1].runtime_log_line,"Test #%s : start_time=%s total_time=%s user_time=%s kernel_time=%s",test_id_str,start_time_str,time_in_ms_str,user_time_str,kernel_time_str); shared_result[test_id-1].result_id = test_id; }