Search code examples
clinuxtimer

Tracking a task's execution time in C (ignoring time task is suspended)


I have to track how long a task executes for. I am working on Linux, but I do not have access to the kernel itself.

My task simply busy-loops until the process has been executing for a certain amount of time. Then the process is supposed to break out of this loop.

I had a somewhat working version that used clock_gettime() from time.h. I stored the time since Epoch right before I busy looped in a "start" variable. Then in each iteration of the loop, I checked the time since Epoch again in another variable called "current".

Oh each iteration of the loop, I took the difference between "current" and "start". If that difference was greater than or equal to my requested execution time, I broke out of the loop.

The trouble is clock_gettime() does not factor in suspension of a task. So if my task suspends, the way I am doing this now will treat the time a task is suspended as if it were still executing.

Does anyone have an alternative to clock_gettime() that will allow a timer to somehow ignore the suspension time? Code of my current method below.

//DOES NOT HANDLE TASK SUSPENSION 
#include <time.h> 
#define BILLION 1E9

//Set execution time to 2 seconds
double executionTime = 2; 

//Variable used later to compute difference in time
double  elapsedTime = -1;

struct timespec start;
struct timespec current;

//Get time before we busy-loop
clock_gettime(CLOCK_REALTIME, &start);

int i; 
for (i = 0; i < 10000000000; i++)
{
    //Get time on each busy-loop iteration
    clock_gettime(CLOCK_REALTIME, &current);

        elapsedTime = (current.tv_sec - start.tv_sec) + ((current.tv_nsec - start.tv_nsec) / BILLION);

        //If we have been executing for the specified execution time, break. 
        if (elapsedTime >= executionTime)
        {
            break;
        }
    } 

Solution

  • Change CLOCK_REALTIME to CLOCK_PROCESS_CPU_TIME.
    using sleep() takes several seconds to accumulate a small amount of CPU time.

    #include <stdio.h>
    #include <unistd.h>
    #include <time.h>
    #define BILLION 1E9
    int main ( void) {
        double executionTime = 0.0001;
    
        double  elapsedTime = -1;
        double  elapsedTimertc = -1;
    
        struct timespec startrtc;
        struct timespec start;
        struct timespec currentrtc;
        struct timespec current;
    
        clock_gettime(CLOCK_REALTIME, &startrtc);
        clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);
    
        for (;;)
        {
            sleep ( 1);
            clock_gettime(CLOCK_REALTIME, &currentrtc);
            clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &current);
    
            elapsedTime = (current.tv_sec - start.tv_sec) + ((current.tv_nsec - start.tv_nsec) / BILLION);
            elapsedTimertc = (currentrtc.tv_sec - startrtc.tv_sec) + ((currentrtc.tv_nsec - startrtc.tv_nsec) / BILLION);
    
            if (elapsedTime >= executionTime)
            {
                break;
            }
        }
        printf ( "elapsed time %f\n", elapsedTime);
        printf ( "elapsed time %f\n", elapsedTimertc);
    }