Re: 'top' command always reports 0.0% cpu usage

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: 'top' command always reports 0.0% cpu usage

Corinna Vinschen-2
Hi Chris,

On Feb 16 15:56, Manuel Gonzalez Montoya wrote:

> All,
>  
>     I just installed the lastest cygwin version on an XP Professional
> SP2 machine and noticed the output of the top command always reports
> wrong info (0.0%) about the CPU usage summary as you can see in the
> example:
>  
> Tasks:  10 total,   1 running,   9 sleeping,   0 stopped,   0 zombie
> Cpu0  :   0.0% user,   0.0% system,   0.0% nice,   0.0% idle
> Mem:    522776k total,   308740k used,   214036k free,        0k buffers
> Swap:  2097152k total,    70060k used,  2027092k free,        0k cached
>  
>   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
>  3080 manuel.g   8   0 22976  20m  448 R  3.5  3.9   0:59.29 top
>  2304 manuel.g   8   0 28416 1216    0 S  0.0  0.2   0:00.59 bash
>  2920 manuel.g   8   0 16640  26m 1344 S  0.0  5.2   0:00.09 man
>  2148 manuel.g   8   0 26112  43m  832 S  0.0  8.6   0:00.06 sh
>  3380 manuel.g   8   0 24640  33m  960 S  0.0  6.6   0:00.06 sh
>   684 manuel.g   8   0 26432  46m 1024 S  0.0  9.1   0:00.07 sh
>   900 manuel.g   8   0 19520  26m 1152 S  0.0  5.1   0:00.04 less
>  3828 manuel.g   8   0 15936  26m  832 S  0.0  5.2   0:00.06 groff
>  3252 manuel.g   8   0 29440  24m  896 S  0.0  4.9   0:00.40 bash
>  3936 manuel.g   8   0 23552  31m  640 S  0.0  6.1   0:00.21 grotty
>
>
> Is that an error or just the normal behavior?

I investigated this problem and it turns out that top is relying on
undocumented behaviour.

What it does to read /proc/stat is this, basically:

  if (!fp)
    fp = fopen ("/proc/stat", "r");
  rewind(fp);
  fflush(fp);
  fread(fp);

It relies on the fact that a rewind/fflush would call lseek.  However,
this might be true for glibc, but it's not true for newlib.  If the
file pointer is opened for reading only, the fseek function called by
rewind optimizes the lseek call away, if it can satisfy the seek within
the given FILE buffer.  Then it relies on fflush clearing the buffer
to force another underlying read call, but that, too, is undefined
behaviour, since fflush is only documented to do something of value,
if the file pointer is opened for writing.

So, what I did to circumvent the reliance on undefined behaviour is
to set the file pointer to unbuffered mode:

  if (!fp)
    {
      fp = fopen ("/proc/stat", "r");
      setvbuf (fp, NULL, _IONBF, 0);
    }
  rewind(fp);
  fflush(fp);
  fread(fp);

That works nicely, obviously.  Would you mind to release a new version
of procps with the above or a similar patch?


Thanks,
Corinna

--
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat
Reply | Threaded
Open this post in threaded view
|

Re: 'top' command always reports 0.0% cpu usage

Chris January-2
On 17/02/06, Corinna Vinschen <[hidden email]> wrote:

> Hi Chris,
>
> On Feb 16 15:56, Manuel Gonzalez Montoya wrote:
> > All,
> >
> >     I just installed the lastest cygwin version on an XP Professional
> > SP2 machine and noticed the output of the top command always reports
> > wrong info (0.0%) about the CPU usage summary as you can see in the
> > example:
> >
> > Tasks:  10 total,   1 running,   9 sleeping,   0 stopped,   0 zombie
> > Cpu0  :   0.0% user,   0.0% system,   0.0% nice,   0.0% idle
> > Mem:    522776k total,   308740k used,   214036k free,        0k buffers
> > Swap:  2097152k total,    70060k used,  2027092k free,        0k cached
> >
> >   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
> >  3080 manuel.g   8   0 22976  20m  448 R  3.5  3.9   0:59.29 top
> >  2304 manuel.g   8   0 28416 1216    0 S  0.0  0.2   0:00.59 bash
> >  2920 manuel.g   8   0 16640  26m 1344 S  0.0  5.2   0:00.09 man
> >  2148 manuel.g   8   0 26112  43m  832 S  0.0  8.6   0:00.06 sh
> >  3380 manuel.g   8   0 24640  33m  960 S  0.0  6.6   0:00.06 sh
> >   684 manuel.g   8   0 26432  46m 1024 S  0.0  9.1   0:00.07 sh
> >   900 manuel.g   8   0 19520  26m 1152 S  0.0  5.1   0:00.04 less
> >  3828 manuel.g   8   0 15936  26m  832 S  0.0  5.2   0:00.06 groff
> >  3252 manuel.g   8   0 29440  24m  896 S  0.0  4.9   0:00.40 bash
> >  3936 manuel.g   8   0 23552  31m  640 S  0.0  6.1   0:00.21 grotty
> >
> >
> > Is that an error or just the normal behavior?
>
> I investigated this problem and it turns out that top is relying on
> undocumented behaviour.
>
> What it does to read /proc/stat is this, basically:
>
>   if (!fp)
>     fp = fopen ("/proc/stat", "r");
>   rewind(fp);
>   fflush(fp);
>   fread(fp);
>
> It relies on the fact that a rewind/fflush would call lseek.  However,
> this might be true for glibc, but it's not true for newlib.  If the
> file pointer is opened for reading only, the fseek function called by
> rewind optimizes the lseek call away, if it can satisfy the seek within
> the given FILE buffer.  Then it relies on fflush clearing the buffer
> to force another underlying read call, but that, too, is undefined
> behaviour, since fflush is only documented to do something of value,
> if the file pointer is opened for writing.
>
> So, what I did to circumvent the reliance on undefined behaviour is
> to set the file pointer to unbuffered mode:
>
>   if (!fp)
>     {
>       fp = fopen ("/proc/stat", "r");
>       setvbuf (fp, NULL, _IONBF, 0);
>     }
>   rewind(fp);
>   fflush(fp);
>   fread(fp);
>
> That works nicely, obviously.  Would you mind to release a new version
> of procps with the above or a similar patch?

Sure, although it might be a little while before I have time. I'll
submit the patch upstream as well.

Cheers,
Chris
Reply | Threaded
Open this post in threaded view
|

Re: 'top' command always reports 0.0% cpu usage

Corinna Vinschen-2
On Feb 17 11:20, Chris January wrote:
> On 17/02/06, Corinna Vinschen <[hidden email]> wrote:

http://cygwin.com/acronyms/#PCYMTNQREAIYR

> >   if (!fp)
> >     {
> >       fp = fopen ("/proc/stat", "r");
> >       setvbuf (fp, NULL, _IONBF, 0);
> >     }
> >   rewind(fp);
> >   fflush(fp);
> >   fread(fp);
> >
> > That works nicely, obviously.  Would you mind to release a new version
> > of procps with the above or a similar patch?
>
> Sure, although it might be a little while before I have time. I'll
> submit the patch upstream as well.

Thanks.  In theory, this problem might be present in reading other
/proc files, too, but I just looked into the /proc/stat problem.


Corinna

--
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat