2

I am using below programs on linux and windows to get cpu utilization of current processes.

Linux:

int main()
{
      int ret;
      char *buf;
      int i=0;
      int who= RUSAGE_SELF;
      struct rusage usage;
      struct rusage *p=&usage;

      ret=getrusage(who,p);
      printf("user time used: %16lf  %16lf\n",p->ru_utime.tv_sec,p->ru_utime.tv_usec);
    printf("system time used: %16lf  %16lf\n",p->ru_stime.tv_sec,p->ru_stime.tv_usec);

      system("ls");
      printf("user time used: %16lf  %16lf\n",p->ru_utime.tv_sec,p->ru_utime.tv_usec);
    printf("system time used: %16lf  %16lf\n", p->ru_stime.tv_sec,p->ru_stime.tv_usec);    

    return 0;
}

Output on linux:

user time used: 0.000000 -1.999568
system time used: 0.000000 -1.999568
a.out check.c
user time used: 0.000000 -1.999568
system time used: 0.000000 -1.999568

Does this mean that the system("ls") command did not take any cpu cycles to execute? How do i get the exact cpu cycles used by any command or program?

I am facing similar problems on windows. for the below code.

Windows:

int main()
{
    int i=0;
    HANDLE hProcess = GetCurrentProcess();
    FILETIME ftCreation, ftExit, ftKernel, ftUser;
    SYSTEMTIME stKernel;
    SYSTEMTIME stUser;

    GetProcessTimes(hProcess, &ftCreation, &ftExit, &ftKernel, &ftUser);
    FileTimeToSystemTime(&ftKernel, &stKernel);
    FileTimeToSystemTime(&ftUser, &stUser);

    printf("\nTime in kernel mode = %uh %um %us %ums", stKernel.wHour,stKernel.wMinute, stKernel.wSecond, stKernel.wMilliseconds);
    printf("\nTime in user mode = %uh %um %us %ums \n", stUser.wHour,stUser.wMinute, stUser.wSecond, stUser.wMilliseconds);

    system("dir");

    GetProcessTimes(hProcess, &ftCreation, &ftExit, &ftKernel, &ftUser);
    FileTimeToSystemTime(&ftKernel, &stKernel);
    FileTimeToSystemTime(&ftUser, &stUser);

    printf("\nTime in kernel mode = %uh %um %us %ums", stKernel.wHour,stKernel.wMinute, stKernel.wSecond, stKernel.wMilliseconds);
    printf("\nTime in user mode = %uh %um %us %ums \n", stUser.wHour,stUser.wMinute, stUser.wSecond, stUser.wMilliseconds);
    system("PAUSE");
    return 0;
}

Above program output on windows dev c++:

Time in kernel mode: 0h 0m 0s 15ms
Time in user mode: 0h 0m 0s 15ms
<directory listing>
Time in kernel mode: 0h 0m 0s 15ms
Time in user mode: 0h 0m 0s 15ms

Can you please let me know how can we get correct cpu usage for the above programs? Also is there a way to get to know IO usage or number of characters read and write to disk/memory? Thanks in advance.

Enjoy coding
  • 4,268
  • 12
  • 40
  • 50
  • See my another question for better understanding... http://stackoverflow.com/questions/5181628/standard-way-of-tracking-calculating-cpu-and-io-usage-of-process – Enjoy coding Mar 11 '11 at 11:51
  • Did the previous answer's answer your question? Or do you want to get those updating numbers that the windows task-mananger shows? – Bernd Elkemann Mar 11 '11 at 14:24

3 Answers3

2

In the Linux version you've asked for RUSAGE_SELF, which is all threads of the parent process, rather than RUSAGE_CHILDREN for child processes. For IO usage under Linux you'll need a kernel after 2.6.20, and look in /proc/[pid]/io.

I think you have a similar problem on Windows. You'll need to use CreateProcess rather than system, so that you can get a handle to the child process and record its times. For IO usage on windows I think you'll need to use WMI, which is a large subject.

Adrian Cox
  • 6,204
  • 5
  • 41
  • 68
  • Thanks for your reply. I have tried fork option on the Linux. But that is still giving the same times.Same case with windows. Am I missing some thing? Are there any examples similar to the above programs? I am using RUSAGE_CHILDREN as you have suggested. – Enjoy coding Mar 11 '11 at 13:43
  • @EnjoyCoding - On closer reading RUSAGE_CHILDREN will only return accounting for child processes that have terminated and been cleaned up by `wait`. So I was wrong in my first answer, and `system` should be adequate. – Adrian Cox Mar 11 '11 at 14:05
0

You made a few errors in the linux version here.

  1. As Adrian pointed out, you should use RUSAGE_CHILDREN to count in the resource consumed by the child process.
  2. You did not call getrusage() again after you invoked system().
  3. In your printf(), you should not use %lf which represents a long double type. tv_sec is of type time_t and tv_usec is of type susecond_t. In 64-bit linux, they are both signed long, which is incompatible with long double (note you have negative result here). For portability, you should have used explicit cast, such as:

    printf("user time used: %ld  %ld\n",(long)p->ru_utime.tv_sec,(long)p->ru_utime.tv_usec);
    
0

It is the correct output. ls is not the current process; whilst ls is executing, no CPU time is spent on your process.

BTW Dev-C++ is just a [bad, unmaintained] IDE, not a compiler. You probably meant to say MinGW.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • MinGW is not a compiler either :-) naaa, i know what you mean of course: gcc is the compiler that is bundled with it and mingw supplies the headers and libraries. – Bernd Elkemann Mar 11 '11 at 14:11
  • @eznme: No, it's more than that. The binutils and GCC itself that MinGW ships with libraries and headers are native software ports. – Lightness Races in Orbit Mar 11 '11 at 14:19
  • yes ofcourse. I was just mentioning Dev C++ default installation so that you can get to know what it holds and compiles with. Thanks for your help. – Enjoy coding Mar 11 '11 at 14:20