Menu

#8 Use nanosleep() instead of sleep() in main loop to increase sleep granulatiry

accepted
nobody
None
3
2019-07-03
2019-07-03
Fernando
No

Hi,

I'm using nmon on my sytem to collect data in a csv file every second. I'm also using the NMON_SNAP enviroment variable to execute a script and record some extra information.

I'm facing a problem that happens sometimes when the child process, started by nmon, sends a SIGCHILD signal that interrupts the sleep() function. This leads to nmon taking more that one statistic in one second e.g.:

ZZZZ,T0020,11:05:02,01-JUL-2019
CPU001,T0020,24.0,2.0,0.0,74.0,0.0
...
ERROR,T0020, sleep interrupted, sleep(1 seconds), return value=0, errno=4
ZZZZ,T0021,11:05:02,01-JUL-2019
CPU001,T0021,100.0,0.0,0.0,0.0,0.0
...
ERROR,T0021, sleep interrupted, sleep(1 seconds), return value=0, errno=4
ZZZZ,T0022,11:05:02,01-JUL-2019
CPU001,T0022,0.0,0.0,0.0,100.0,0.0
...
ERROR,T0022, sleep interrupted, sleep(1 seconds), return value=0, errno=4
ZZZZ,T0023,11:05:02,01-JUL-2019

Woud it be possible to replace sleep() with nanosleep()? hence when nanosleep() gets interrupted it can sleep for the remaining time when it gets interrupted.

Thanks

Discussion

  • Fernando

    Fernando - 2019-07-03

    Here the changes I did to try it out:

    --- lmon16i.c   2019-07-03 09:54:57.877252371 +0200
    +++ lmon16i_new.c   2019-07-03 09:54:05.505250566 +0200
    @@ -4283,6 +4283,8 @@
         char * slabstr;
         char truncated_command[257]; /* 256 +1 */
    
    
    +    struct timespec sleep_time;  /* Fernando Addition */
    +    struct timespec sleep_rem_time;  /* Fernando Addition */
    
     #define MAXROWS 256
     #define MAXCOLS 150        /* changed to allow maximum column widths */
    @@ -8606,17 +8608,20 @@
            nmon_run_time -= (double) seconds_over;
            }
            if (secs < 1)   /* sanity check in case CPUs are flat out and nmon taking far to long to complete */
    
    -       secs = 1;
    +           secs = 1;
    +
    +       sleep_time.tv_sec = secs; /* Fernando Addition */
    +       sleep_time.tv_nsec = 0; /* Fernando Addition */
    
          redo:
            errno = 0;
    
    -       ret = sleep(secs);
    +       ret = nanosleep(&sleep_time, &sleep_rem_time); /* Fernando Modification: replace sleep with nanosleep */
            if ((ret != 0 || errno != 0) && loop != maxloops) {
            fprintf(fp,
                "ERROR,%s, sleep interrupted, sleep(%d seconds), return value=%d",
                LOOP, secs, ret);
            fprintf(fp, ", errno=%d\n", errno);
    -       secs = ret;
    +       sleep_time = sleep_rem_time; /* Fernando Modification: use timespec to set remaining time */
            goto redo;
            }
            gettimeofday(&nmon_tv, 0);
    
     
  • Nigel Griffiths

    Nigel Griffiths - 2019-07-03
    • status: open --> accepted
    • Priority: 5 --> 3
     
  • Nigel Griffiths

    Nigel Griffiths - 2019-07-03

    This is a good idea but has the potential of going horribly wrong with old and odd-ball Linux kernels. I thought nanoseconds was a "new fangles thing" but I find references to in back in 2001 so probaly older than that.

    I will add this to the next major release as it is more than a simple bug fix.
    That has no set date at the moment.
    Good to know you are a capableC coder so you can have your nmon version fixed right now.
    Question does: sleep_time = sleep_rem_time;
    compile OK - these are two data structures?
    Examples I have seen use just the one variable for both requested and remainer structures

     
    • Fernando

      Fernando - 2019-07-03

      Thanks for integrating it!

      Question does: sleeptime = sleepremtime;
      compile OK - these are two data structures?

      Yes, it compiles fine and works fine. As struct timespec does not contain any pointers it is possible to copy it just like that.

      Examples I have seen use just the one variable for both requested and remainer structures

      This might work as well. Probably better as my proposed solution because there would be one less copy.

       

Log in to post a comment.

MongoDB Logo MongoDB