Advertisement
YShinkarev

Untitled

Sep 16th, 2015
195
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* TimeMem.c - Windows port of Unix time utility */
  2.  
  3. #include <Windows.h>
  4. #include <Psapi.h>
  5. #include <stdio.h>
  6. #include <tchar.h>
  7.  
  8. /* Displays usage help for this program. */
  9. static void usage()
  10. {
  11.     _tprintf(_T("Usage: TimeMem command [args...]\n"));
  12. }
  13.  
  14. /* Converts FILETIME to ULONGLONG. */
  15. static ULONGLONG ConvertFileTime(const FILETIME *t)
  16. {
  17.     ULARGE_INTEGER i;
  18.     CopyMemory(&i, t, sizeof(ULARGE_INTEGER));
  19.     return i.QuadPart;
  20. }
  21.  
  22. /* Displays information about a process. */
  23. static int info(HANDLE hProcess)
  24. {
  25.     DWORD dwExitCode;
  26.     FILETIME ftCreation, ftExit, ftKernel, ftUser;
  27.     double tElapsed, tKernel, tUser;
  28.     PROCESS_MEMORY_COUNTERS pmc = { sizeof(PROCESS_MEMORY_COUNTERS) };
  29.  
  30.     /* Exit code */
  31.     if (!GetExitCodeProcess(hProcess, &dwExitCode))
  32.         return 1;
  33.  
  34.     /* CPU info */
  35.     if (!GetProcessTimes(hProcess, &ftCreation, &ftExit, &ftKernel, &ftUser))
  36.     {
  37.         return 1;
  38.     }
  39.     tElapsed = 1.0e-7 * (ConvertFileTime(&ftExit) - ConvertFileTime(&ftCreation));
  40.     tKernel = 1.0e-7 * ConvertFileTime(&ftKernel);
  41.     tUser = 1.0e-7 * ConvertFileTime(&ftUser);
  42.  
  43.     /* Memory info */
  44.     // Print information about the memory usage of the process.
  45.     if (!GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc)))
  46.         return 1;
  47.  
  48.     /* Display info. */
  49.     _tprintf(_T("Exit code      : %u\n"), dwExitCode);
  50.  
  51.     _tprintf(_T("Elapsed time   : %.2lf\n"), tElapsed);
  52.     _tprintf(_T("Kernel time    : %.2lf (%.1lf%%)\n"), tKernel, 100.0*tKernel/tElapsed);
  53.     _tprintf(_T("User time      : %.2lf (%.1lf%%)\n"), tUser, 100.0*tUser/tElapsed);
  54.  
  55.     _tprintf(_T("page fault #   : %u\n"), pmc.PageFaultCount);
  56.     _tprintf(_T("Working set    : %u KB\n"), pmc.PeakWorkingSetSize/1024);
  57.     _tprintf(_T("Paged pool     : %u KB\n"), pmc.QuotaPeakPagedPoolUsage/1024);
  58.     _tprintf(_T("Non-paged pool : %u KB\n"), pmc.QuotaPeakNonPagedPoolUsage/1024);
  59.     _tprintf(_T("Page file size : %u KB\n"), pmc.PeakPagefileUsage/1024);
  60.  
  61.     return 0;
  62. }
  63.  
  64. /* Todo:
  65.  * - mimic linux time utility interface; e.g. see http://linux.die.net/man/1/time
  66.  * - build under 64-bit
  67.  * - display detailed error message
  68.  */
  69.  
  70. int _tmain(
  71. #ifndef NDEBUG
  72.     int argc, _TCHAR *argv[]
  73. #endif
  74.     )
  75. {
  76.     LPTSTR szCmdLine;
  77.     LPTSTR szBegin;
  78.     STARTUPINFO si = { sizeof(STARTUPINFO) };
  79.     PROCESS_INFORMATION pi;
  80.     int ret;
  81.  
  82.     /* Read the command line. */
  83.     szCmdLine = GetCommandLine();
  84.  
  85.     /* Strip the first token from the command line. */
  86.     if (szCmdLine[0] == '"')
  87.     {
  88.         /* The first token is double-quoted. Note that we don't need to
  89.          * worry about escaped quote, because a quote is not a valid
  90.          * path name under Windows.
  91.          */
  92.         LPTSTR p = szCmdLine + 1;
  93.         while (*p && *p != '"')
  94.             ++p;
  95.         szBegin = (*p == '"')? p + 1 : p;
  96.     }
  97.     else
  98.     {
  99.         /* The first token is deliminated by a space or tab.
  100.          * See "Parsing C++ Command Line Arguments" below:
  101.          * http://msdn.microsoft.com/en-us/library/windows/desktop/17w5ykft(v=vs.85).aspx
  102.          */
  103.         LPTSTR p = szCmdLine;
  104.         while (*p && *p != ' ' && *p != '\t')
  105.             ++p;
  106.         szBegin = p;
  107.     }
  108.  
  109.     /* Skip white spaces. */
  110.     while (*szBegin == ' ' || *szBegin == '\t')
  111.         ++szBegin;
  112.  
  113.     /* If we have no more arguments, display usage info and exit. */
  114.     if (*szBegin == 0)
  115.     {
  116.         usage();
  117.         return 1;
  118.     }
  119.  
  120.     /* Display argc,argv and command line for debugging purpose. */
  121. #ifndef NDEBUG
  122.     {
  123.         int i;
  124.         for (i = 0; i < argc; i++)
  125.             _tprintf(_T("argv[%d]=%s\n"), i, argv[i]);
  126.         _tprintf(_T("CmdLine=%s\n"), szCmdLine);
  127.         _tprintf(_T("Invoked=%s\n"), szBegin);
  128.     }
  129. #endif
  130.  
  131.     /* Create the process. */
  132.     if (!CreateProcess(NULL, szBegin, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
  133.     {
  134.         _tprintf(_T("Error: Cannot create process.\n"));
  135.         return 1;
  136.     }
  137.  
  138.     /* Wait for the process to finish. */
  139.     if (WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_OBJECT_0)
  140.     {
  141.         _tprintf(_T("Error: Cannot wait for process.\n"));
  142.         return 1;
  143.     }
  144.  
  145.     /* Display process statistics. */
  146.     ret = info(pi.hProcess);
  147.  
  148.     /* Close process handles. */
  149.     CloseHandle(pi.hThread);
  150.     CloseHandle(pi.hProcess);
  151.  
  152. #ifndef NDEBUG
  153.     _tprintf(_T("\nPress any key to exit...\n"));
  154.     getch();
  155. #endif
  156.  
  157.     return ret;
  158. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement