The following example demonstrates how to utilize an auto-reset timer object for task synchronization. Among all tasks pending on the timer, only the task at the head of the wait queue is released every second. Each resumed task executes its workload-which may vary in duration-before re-entering the wait state to synchronize with the next timer interval.
#include <stdio.h> #include <stdlib.h> #include "OS_API.h" #define TASK_COUNT 5 #define TIMER_NAME "Timer1" TIME StartupTime; unsigned seed = 0; ERROR Task(PVOID Arg) { TIME JobTime; HANDLE TimerHandle; /* Initialize random number generator */ srand(seed++); /* Open the timer */ TimerHandle = osOpenTimer(TIMER_NAME); /* Infinite loop */ while(1) { /* Wait for timer for synchronization */ osWaitForObject(TimerHandle, OS_INFINITE); printf("%8lu: Task%i starts job... ", arGetTickCount() - StartupTime, (int) Arg); /* Perform work of varying length (from 100 up to 800 milliseconds) */ JobTime = 100 + rand() % 701; osSleep(JobTime * AR_TICKS_PER_SECOND / 1000); printf("done after %lu ms.\n", JobTime); } } int main(void) { int i; HANDLE TimerHandle; /* Initialization */ arInit(); stInit(); osInit(); /* Get startup time */ StartupTime = arGetTickCount(); /* Create timer object */ TimerHandle = osCreateTimer(TIMER_NAME, FALSE); osSetTimer(TimerHandle, AR_TICKS_PER_SECOND, 0); /* Create tasks */ for(i = 0; i < TASK_COUNT; i++) osCreateTask(Task, (PVOID) (i + 1), 0, 0, FALSE); /* Start the operating system */ osStart(); /* Deinitialization */ osDeinit(); arDeinit(); return 0; }
The result on the console should look as follows:
1000: Task1 starts job... done after 446 ms.
2000: Task2 starts job... done after 230 ms.
3000: Task3 starts job... done after 536 ms.
4000: Task4 starts job... done after 321 ms.
5000: Task5 starts job... done after 105 ms.
6000: Task1 starts job... done after 230 ms.
7000: Task2 starts job... done after 567 ms.
8000: Task3 starts job... done after 203 ms.
9000: Task4 starts job... done after 540 ms.
10000: Task5 starts job... done after 355 ms.
11000: Task1 starts job... done after 567 ms.
12000: Task2 starts job... done after 489 ms.
13000: Task3 starts job... done after 233 ms.
14000: Task4 starts job... done after 155 ms.
15000: Task5 starts job... done after 778 ms.
16000: Task1 starts job... done after 489 ms.