Tuesday, 21 January 2014

Multiple User Timers in Linux using C

User Level Timers for Linux System. Small Demo Code for How to Implement User Level Timers In C

Main Small Implementation of Timer.


#include <stdio.h>
#include <string.h>
//#include <unistd.h>
#include <time.h>
#include <stdlib.h>
unsigned int IS_TIMER_TH_RUN;
unsigned int ST_TIMER_TH;
struct mytimer;
struct mytimer{
        time_t tm_start;
        time_t tm_ticks;
        unsigned int ui_auto_reload;
        unsigned int ui_timer_id;
        unsigned int si_is_active;
        void (*callback)(const char *name, unsigned int id);
        struct mytimer *link;
        char pc_name[32];
};      
typedef struct mytimer mytimer_t;
/*
struct mylist{
        struct mylist *link;
        mytimer_t data;
};      
*/              
static mytimer_t *timer_list_head;
static mytimer_t *timer_list_tail;
                        
int timer_list_add(mytimer_t *new){
        if(new == NULL)
                return 0;
        if(timer_list_head == NULL){
                timer_list_tail = new;
                timer_list_head = new;
        }else{ 
                timer_list_tail->link = new;
                timer_list_tail = new;
        }
        return 1;
}       

int timer_list_free(mytimer_t *head){
        mytimer_t *temp;
        while(head){
                temp = head;
                head = head->link;
                free(temp);
        }
}
int timer_list_remove(mytimer_t *prev, mytimer_t *node){

        if(prev == timer_list_head){
                timer_list_head=node->link;
                //timer_list_head = NULL;

                //timer_list_tail = NULL;
        }else{
                prev->link = node->link;
                if(node->link == NULL){
                        timer_list_tail=prev;
                }
        }
        free(node);
        return 1;
}

void * timer_thread(void *arg){
        mytimer_t *iterator,*temp;
        time_t tm_cur_time;
        ST_TIMER_TH = 1;
        while(IS_TIMER_TH_RUN){
                if(timer_list_head==NULL){
                        usleep(10000);
                        continue;
                }
                iterator = timer_list_head;
                while(iterator){
                        if(iterator->si_is_active){
                                tm_cur_time = time(NULL);
                                temp = iterator;
                                iterator = iterator->link;
                                if((tm_cur_time - (temp->tm_start )) >= (temp->tm_ticks)){
                                        if(temp->callback != NULL){
                                                printf("Calling Call Back timer=%p cur= %u start=%u ticks=%u \n", temp, tm_cur_time,temp->tm_start,temp->tm_ticks);
                                                (*(temp->callback))(temp->pc_name,temp->ui_timer_id);
                                                //printf("sucess Call Back\n");

                                                temp->si_is_active=0;
                                                //mytimer_stop(temp);
                                        }
                                        //if auto reload re-start
                                        //remove from list here only
                                }
                        }else{
                                iterator = iterator->link;
                        }
                        usleep(5000);
                }
        }
        ST_TIMER_TH = 0;
}

int mytimer_init(void){
        pthread_t thId;
        timer_list_head = NULL;
        timer_list_tail = NULL;
        IS_TIMER_TH_RUN = 1;
        ST_TIMER_TH =0;

        if(pthread_create(&thId, NULL, timer_thread, NULL)==0){
                return 1;
        }
        else{
                return 0;
        }

}

void mytimer_cleanup(void){
        IS_TIMER_TH_RUN=0;
        timer_list_free(timer_list_head);
}

mytimer_t * mytimer_create(const char *pc_name, time_t t_ticks, unsigned int ui_auto_reload, unsigned int ui_timer_id, void (*callback)(const char *name, unsigned int id)){
        mytimer_t *tmp;
        printf("size of timer_t=%d and struct =%d \n",sizeof(timer_t),sizeof(struct mytimer));
        tmp = (mytimer_t *) malloc(sizeof(struct mytimer));
        if(tmp == NULL){
                return NULL;
        }
        memset(tmp,0x00,sizeof(timer_t));
        tmp->tm_start = 0;
        strcpy((tmp->pc_name), pc_name);
        tmp->tm_ticks = t_ticks;
        tmp->ui_auto_reload = ui_auto_reload;
        tmp->ui_timer_id=ui_timer_id;
        tmp->callback=callback;
        tmp->link = NULL;
        printf("Ticks = %u\n", tmp->tm_ticks);
        return tmp;
}

int mytimer_start(mytimer_t *obj){
        obj->tm_start = time(NULL);
        obj->si_is_active = 1;
        timer_list_add(obj);
        return 1;
}
int mytimer_stop(mytimer_t *obj){
        mytimer_t *iterator,*prev;
        iterator = timer_list_head;
        while(iterator){
                if(iterator->link == obj){
                        break;
                }else{
                        iterator = iterator->link;

                }
        }
        if(iterator == NULL)
                return 0;
        timer_list_remove(iterator,obj);
        return 1;
}

int mytimer_is_expire(mytimer_t *obj){
        time_t tm_cur_time;
        tm_cur_time = time(NULL);

        if((tm_cur_time - obj->tm_start) >= obj->tm_ticks){
                return 1;
        }else{
                return 0;
        }
}

int myimer_auto_reload(mytimer_t *obj){
        return 1;
}

Header File For mytimer.c file


#ifndef __MY_TIMER_H_
#define __MY_TIMER_H_
#include <string.h>
#include <stdlib.h>
#include <time.h>

struct mytimer;
typedef struct mytimer mytimer_t;

int mytimer_init(void);
void mytimer_cleanup(void);
mytimer_t * mytimer_create(const char *pc_name, time_t t_ticks, unsigned int ui_auto_reload, unsigned int ui_timer_id, void (*callback)(const char *name, unsigned int id));
int mytimer_start(mytimer_t *obj);
int mytimer_stop(mytimer_t *obj);
int mytimer_is_expire(mytimer_t *obj);
int myimer_auto_reload(mytimer_t *obj);

#endif

Main File to Check The Code


#include <stdio.h>
#include "timer.h"
int IS_RUN;
int timer_cnt;
void timeout_fun(const char *name, unsigned int id){
        printf("timer ID=%d NAME=%s is over flow\n", id, name);
        timer_cnt--;
        if(timer_cnt <=0)
                IS_RUN = 0;
}

int main(int argc, char *argv[]){
        mytimer_t *t1,*t2,*t3,*t4;
        timer_cnt=0;
        IS_RUN=1;
        mytimer_init();
//      const char *pc_name, const time_t t_ticks, unsigned int ui_auto_reload, unsigned int ui_timer_id,
        t1 = mytimer_create("rajesh",10,0,20,timeout_fun);
        printf("t1=%p\n",t1);
        mytimer_start(t1);
        timer_cnt++;
        t2 = mytimer_create("rajesh1",20,0,2,timeout_fun);
        printf("t2=%p\n",t2);
        mytimer_start(t2);
        timer_cnt++;
        t3 = mytimer_create("rajesh3",30,0,3,timeout_fun);
        printf("t3=%p\n",t3);
        mytimer_start(t3);
        timer_cnt++;
        t4 = mytimer_create("rajesh4",10,0,4,timeout_fun);
        mytimer_start(t4);
        printf("t4=%p\n",t4);
        timer_cnt++;
        
        while(IS_RUN){
                sleep(10);
                printf("In main Sleep for 10 Sec\n");
        }
        
        return 0;
}

No comments:

Post a Comment