Search code examples
ctimerclockround-robin

How does time.h clock() work under Windows?


I am trying to create a simple queue schedule for an embedded System in C. The idea is that within a Round Robin some functions are called based on the time constraints declared in the Tasks[] array.

#include <time.h>
#include <stdio.h>
#include <windows.h>
#include <stdint.h>

//Constants
#define SYS_TICK_INTERVAL   1000UL
#define INTERVAL_0MS        0
#define INTERVAL_10MS       (100000UL / SYS_TICK_INTERVAL)
#define INTERVAL_50MS       (500000UL / SYS_TICK_INTERVAL)

//Function calls
void task_1(clock_t tick);
void task_2(clock_t tick);
uint8_t get_NumberOfTasks(void);

//Define the schedule structure
typedef struct
{
    double Interval;
    double LastTick;
    void (*Function)(clock_t tick);
}TaskType;

//Creating the schedule itself
TaskType Tasks[] =
{
    {INTERVAL_10MS, 0, task_1},
    {INTERVAL_50MS, 0, task_2},
};

int main(void)
{
    //Get the number of tasks to be executed
    uint8_t task_number = get_NumberOfTasks();

    //Initializing the clocks
    for(int i = 0; i < task_number; i++)
    {
        clock_t myClock1 = clock();
        Tasks[i].LastTick = myClock1;
        printf("Task %d clock has been set to %f\n", i, myClock1);
    }

    //Round Robin
    while(1)
    {       
        //Go through all tasks in the schedule
        for(int i = 0; i < task_number; i++)
        {
            //Check if it is time to execute it
            if((Tasks[i].LastTick - clock()) > Tasks[i].Interval)
            {
                //Execute it
                clock_t myClock2 = clock();
                (*Tasks[i].Function)(myClock2);
                //Update the last tick
                Tasks[i].LastTick = myClock2;
            }
        }
        Sleep(SYS_TICK_INTERVAL);       
    }
}

void task_1(clock_t tick)
{
    printf("%f - Hello from task 1\n", tick);
}

void task_2(clock_t tick)
{
    printf("%f - Hello from task 2\n", tick);
}

uint8_t get_NumberOfTasks(void)
{
    return sizeof(Tasks) / sizeof(*Tasks);
}

The code compiles without a single warning, but I guess I don't understand how the command clock() work.

Here you can see what I get when I run the program:

F:\AVR Microcontroller>timer
Task 0 clock has been set to 0.000000
Task 1 clock has been set to 0.000000

I tried changing Interval and LastTick from float to double just to make sure this was not a precision error, but still it does not work.


Solution

  • %f is not the right formatting specifier to print out myClock1 as clock_t is likely not double. You shouldn't assume that clock_t is double. If you want to print myClock1 as a floating point number you have to manually convert it to double:

    printf("Task %d clock has been set to %f\n", i, (double)myClock1);
    

    Alternatively, use the macro CLOCKS_PER_SEC to turn myClock1 into a number of seconds:

    printf("Task %d clock has been set to %f seconds\n", i,
        (double)myClock1 / CLOCKS_PER_SEC);
    

    Additionally, your subtraction in the scheduler loop is wrong. Think about it: clock() grows larger with the time, so Tasks[i].LastTick - clock() always yields a negative value. I think you want clock() - Tasks[i].LastTick instead.