mirror of
https://github.com/Hizenberg469/WheelTimer.git
synced 2026-04-19 18:52:22 +03:00
Timer lib Dev
This commit is contained in:
5
WheelTimer/libtimer/compile.sh
Normal file
5
WheelTimer/libtimer/compile.sh
Normal file
@@ -0,0 +1,5 @@
|
||||
rm *o
|
||||
rm *exe
|
||||
gcc -g -c timerlib.c -o timerlib.o
|
||||
gcc -g -c timerlib_test.c -o timerlib_test.o
|
||||
gcc -g timerlib.o timerlib_test.o -o exe -lrt
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <errno.h>
|
||||
#include "timerlib.h"
|
||||
|
||||
static unsigned long
|
||||
unsigned long
|
||||
timespec_to_millisec(
|
||||
struct timespec *time){
|
||||
|
||||
@@ -34,7 +34,7 @@ timespec_to_millisec(
|
||||
return milli_sec;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
timer_fill_itimerspec(struct timespec *ts,
|
||||
unsigned long msec) {
|
||||
|
||||
@@ -54,13 +54,23 @@ static void
|
||||
timer_callback_wrapper(union sigval arg){
|
||||
|
||||
Timer_t *timer = (Timer_t *)(arg.sival_ptr);
|
||||
|
||||
timer->invocation_counter++;
|
||||
|
||||
if(timer->thresdhold &&
|
||||
(timer->invocation_counter > timer->thresdhold)){
|
||||
cancel_timer(timer);
|
||||
return;
|
||||
}
|
||||
|
||||
(timer->cb)(timer, timer->user_arg);
|
||||
|
||||
if(timer->exponential_backoff){
|
||||
|
||||
assert(timer->exp_back_off_time);
|
||||
reschedule_timer(timer,
|
||||
timer->exp_back_off_time *= 2, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,8 +82,8 @@ setup_timer(
|
||||
unsigned long exp_timer, /* First expiration time interval in msec */
|
||||
unsigned long sec_exp_timer, /* Subsequent expiration time interval in msec */
|
||||
uint32_t threshold, /* Max no of expirations, 0 for infinite*/
|
||||
void *user_arg){ /* Arg to timer callback */
|
||||
|
||||
void *user_arg, /* Arg to timer callback */
|
||||
bool exponential_backoff){ /* Is Timer Exp backoff*/
|
||||
|
||||
Timer_t *timer = calloc(1, sizeof(Timer_t));
|
||||
timer->posix_timer = calloc(1, sizeof(timer_t));
|
||||
@@ -84,6 +94,7 @@ setup_timer(
|
||||
timer->cb = timer_cb;
|
||||
timer->thresdhold = threshold;
|
||||
timer->timer_state = TIMER_INIT;
|
||||
timer->exponential_backoff = exponential_backoff;
|
||||
|
||||
/* Sanity checks */
|
||||
assert(timer->cb); /* Mandatory */
|
||||
@@ -102,8 +113,15 @@ setup_timer(
|
||||
assert(rc >= 0);
|
||||
|
||||
timer_fill_itimerspec(&timer->ts.it_value, timer->exp_timer);
|
||||
timer_fill_itimerspec(&timer->ts.it_interval, timer->sec_exp_timer);
|
||||
|
||||
if(!timer->exponential_backoff){
|
||||
timer_fill_itimerspec(&timer->ts.it_interval, timer->sec_exp_timer);
|
||||
timer->exp_back_off_time = 0;
|
||||
}
|
||||
else{
|
||||
timer->exp_back_off_time = timespec_to_millisec(&timer->ts.it_value);
|
||||
timer_fill_itimerspec(&timer->ts.it_interval, 0);
|
||||
}
|
||||
return timer;
|
||||
}
|
||||
|
||||
@@ -142,6 +160,7 @@ cancel_timer(Timer_t *timer){
|
||||
timer_fill_itimerspec(&timer->ts.it_value, 0);
|
||||
timer_fill_itimerspec(&timer->ts.it_interval, 0);
|
||||
timer->time_remaining = 0;
|
||||
timer->invocation_counter = 0;
|
||||
start_timer(timer);
|
||||
timer->timer_state = TIMER_CANCELLED;
|
||||
}
|
||||
@@ -156,9 +175,7 @@ pause_timer(Timer_t *timer){
|
||||
timer_get_time_remaining_in_mill_sec(timer);
|
||||
|
||||
timer_fill_itimerspec(&timer->ts.it_value, 0);
|
||||
|
||||
/* Do not reset the interval */
|
||||
//timer_fill_itimerspec(&timer->ts.it_interval, 0);
|
||||
timer_fill_itimerspec(&timer->ts.it_interval, 0);
|
||||
|
||||
start_timer(timer);
|
||||
|
||||
@@ -172,9 +189,9 @@ resume_timer(Timer_t *timer){
|
||||
assert(timer->timer_state == TIMER_PAUSED);
|
||||
|
||||
timer_fill_itimerspec(&timer->ts.it_value, timer->time_remaining);
|
||||
timer_fill_itimerspec(&timer->ts.it_interval, timer->sec_exp_timer);
|
||||
timer->time_remaining = 0;
|
||||
start_timer(timer);
|
||||
timer->timer_state = TIMER_RUNNING;
|
||||
}
|
||||
|
||||
unsigned long
|
||||
@@ -207,40 +224,61 @@ timer_get_time_remaining_in_mill_sec(Timer_t *timer){
|
||||
void
|
||||
restart_timer(Timer_t *timer){
|
||||
|
||||
if(timer->timer_state != TIMER_PAUSED ||
|
||||
timer->timer_state != TIMER_RUNNING) {
|
||||
|
||||
assert(0);
|
||||
}
|
||||
assert(timer->timer_state != TIMER_DELETED);
|
||||
|
||||
cancel_timer(timer);
|
||||
|
||||
timer_fill_itimerspec(&timer->ts.it_value, timer->exp_timer);
|
||||
|
||||
if(!timer->exponential_backoff)
|
||||
timer_fill_itimerspec(&timer->ts.it_interval, timer->sec_exp_timer);
|
||||
else
|
||||
timer_fill_itimerspec(&timer->ts.it_interval, 0);
|
||||
|
||||
timer->invocation_counter = 0;
|
||||
timer->time_remaining = 0;
|
||||
timer->exp_back_off_time = timer->exp_timer;
|
||||
start_timer(timer);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
void
|
||||
reschedule_timer(Timer_t *timer,
|
||||
unsigned long exp_ti,
|
||||
unsigned long sec_exp_ti){
|
||||
|
||||
uint32_t invocation_counter;
|
||||
|
||||
if(timer->timer_state == TIMER_DELETED) assert(0);
|
||||
|
||||
invocation_counter = timer->invocation_counter;
|
||||
|
||||
if(timer->timer_state != TIMER_CANCELLED) {
|
||||
cancel_timer(timer);
|
||||
}
|
||||
|
||||
timer->exp_timer = exp_ti;
|
||||
timer->sec_exp_timer = sec_exp_ti;
|
||||
timer->invocation_counter = 0;
|
||||
timer->invocation_counter = invocation_counter;
|
||||
|
||||
timer_fill_itimerspec(&timer->ts.it_value, exp_ti);
|
||||
|
||||
if(!timer->exponential_backoff){
|
||||
timer_fill_itimerspec(&timer->ts.it_interval, sec_exp_ti);
|
||||
}
|
||||
else{
|
||||
timer_fill_itimerspec(&timer->ts.it_interval, 0);
|
||||
timer->exp_back_off_time = exp_ti;
|
||||
}
|
||||
|
||||
timer->time_remaining = 0;
|
||||
start_timer(timer);
|
||||
timer->timer_state = TIMER_RUNNING;
|
||||
}
|
||||
|
||||
void
|
||||
print_timer(Timer_t *timer){
|
||||
|
||||
printf("Counter = %u, time remaining = %lu, state = %d\n",
|
||||
timer->invocation_counter,
|
||||
timer_get_time_remaining_in_mill_sec(timer),
|
||||
timer_get_current_state(timer));
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef enum{
|
||||
|
||||
@@ -43,12 +44,14 @@ typedef struct Timer_{
|
||||
unsigned long sec_exp_timer; /* in milli-sec */
|
||||
uint32_t thresdhold; /* No of times to invoke the timer callback */
|
||||
void (*cb)(struct Timer_ *, void *); /* Timer Callback */
|
||||
bool exponential_backoff;
|
||||
|
||||
/* place holder value to store
|
||||
* dynamic attributes of timer */
|
||||
unsigned long time_remaining; /* Time left for paused timer for next expiration */
|
||||
uint32_t invocation_counter;
|
||||
struct itimerspec ts;
|
||||
unsigned long exp_back_off_time;
|
||||
TIMER_STATE_T timer_state;
|
||||
} Timer_t;
|
||||
|
||||
@@ -65,7 +68,24 @@ setup_timer(
|
||||
/* Max no of expirations, 0 for infinite*/
|
||||
uint32_t,
|
||||
/* Arg to timer callback */
|
||||
void *);
|
||||
void *,
|
||||
/* Is timer Exp back off */
|
||||
bool);
|
||||
|
||||
static inline void
|
||||
timer_delete_user_data(Timer_t *timer){
|
||||
|
||||
if(timer->user_arg) {
|
||||
free(timer->user_arg);
|
||||
timer->user_arg = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static inline TIMER_STATE_T
|
||||
timer_get_current_state(Timer_t *timer){
|
||||
|
||||
return timer->timer_state;
|
||||
}
|
||||
|
||||
void
|
||||
start_timer(Timer_t *timer);
|
||||
@@ -92,8 +112,19 @@ timer_get_time_remaining_in_mill_sec(Timer_t *timer);
|
||||
void
|
||||
restart_timer(Timer_t *timer);
|
||||
|
||||
int
|
||||
void
|
||||
reschedule_timer(Timer_t *timer,
|
||||
unsigned long exp_ti,
|
||||
unsigned long sec_exp_ti);
|
||||
|
||||
void
|
||||
print_timer(Timer_t *timer);
|
||||
|
||||
unsigned long
|
||||
timespec_to_millisec(
|
||||
struct timespec *time);
|
||||
|
||||
void
|
||||
timer_fill_itimerspec(struct timespec *ts,
|
||||
unsigned long msec);
|
||||
#endif /* __TIMER_WRAP__ */
|
||||
|
||||
71
WheelTimer/libtimer/timerlib_test.c
Normal file
71
WheelTimer/libtimer/timerlib_test.c
Normal file
@@ -0,0 +1,71 @@
|
||||
#include <stdio.h>
|
||||
#include "timerlib.h"
|
||||
|
||||
static void
|
||||
app_cb(Timer_t *timer, void *user_data){
|
||||
|
||||
time_t t;
|
||||
time(&t);
|
||||
printf("%s ",ctime(&t));
|
||||
printf("%s() invoked ... name = %s, counter = %u, Threshold = %u, next fire time = %lu\n",
|
||||
__FUNCTION__, (char *)user_data, timer->invocation_counter,
|
||||
timer->thresdhold, timespec_to_millisec(&timer->ts.it_value));
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv){
|
||||
|
||||
char *name = "Abhishek";
|
||||
|
||||
Timer_t *timer = setup_timer(app_cb, 1000 , 1000, 4, name, true);
|
||||
start_timer(timer);
|
||||
|
||||
printf("1. Pause Timer\n");
|
||||
printf("2. Resume Timer\n");
|
||||
printf("3. Restart timer\n");
|
||||
printf("4. Reschedule timer\n");
|
||||
printf("5. Delete timer\n");
|
||||
printf("6. Cancel Timer\n");
|
||||
printf("7. Get Remaining Time\n");
|
||||
printf("8. Print Timer State\n");
|
||||
|
||||
int choice;
|
||||
choice = 0;
|
||||
|
||||
while(1){
|
||||
scanf("%d", &choice);
|
||||
|
||||
switch(choice){
|
||||
|
||||
case 1:
|
||||
pause_timer(timer);
|
||||
break;
|
||||
case 2:
|
||||
resume_timer(timer);
|
||||
break;
|
||||
case 3:
|
||||
restart_timer(timer);
|
||||
break;
|
||||
case 4:
|
||||
reschedule_timer(timer,
|
||||
timer->exp_timer,
|
||||
timer->sec_exp_timer);
|
||||
break;
|
||||
case 5:
|
||||
delete_timer(timer);
|
||||
break;
|
||||
case 6:
|
||||
cancel_timer(timer);
|
||||
break;
|
||||
case 7:
|
||||
printf("Rem Time = %lu\n", timer_get_time_remaining_in_mill_sec(timer));
|
||||
break;
|
||||
case 8:
|
||||
print_timer(timer);
|
||||
break;
|
||||
deafault: ;
|
||||
}
|
||||
}
|
||||
pause();
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user