Chinaunix首页 | 论坛 | 博客
  • 博客访问: 535876
  • 博文数量: 142
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1452
  • 用 户 组: 普通用户
  • 注册时间: 2013-09-12 16:28
文章分类

全部博文(142)

文章存档

2016年(10)

2015年(60)

2014年(72)

我的朋友

分类: C/C++

2015-03-04 18:26:23

使用方法:
1.在进程中先调用ah_pmpt_timer_init,创建一个定时器线程
2.在另一个使用定时器的线程调用ah_pmpt_timer_create创建定时器
3.调用ah_pmpt_timer_start,将定时器挂接到定时器链表中,设置定时时间以开启定时器
4.调用ah_pmpt_timer_continue重新赋值时间,重新开启定时器 (因为该定时器超时后,定时器默认就删除了,如果要循环使用,必须重新调用
ah_pmpt_timer_continue

点击(此处)折叠或打开

  1. #define AP_PTIMER_STOPPED 0x01 /* timer already stopped */
  2. #define AP_PTIMER_CALLING 0x02 /* timer is calling */
  3. struct ah_ptimer_ {
  4.     struct ah_ptimer_ *ap_prev; /* double link list */
  5.     struct ah_ptimer_ *ap_next;
  6.     uint8 ap_flag;
  7.     int16 ap_count;
  8.     uint32 ap_fire; /* when to fire the timer, sec since this instance is started */
  9.     ah_ptimer_callback_t ap_func;
  10.     void *ap_data;
  11. };
  12. typedef struct ah_ptimer_ ah_ptimer_t;
  13. typedef void (*ah_ptimer_callback_t)(ah_ptimer_t*, void *);

  14. #define is_ah_ptimer_stopped(t) ( (t)->ap_flag & AP_PTIMER_STOPPED)
  15. #define is_ah_ptimer_calling(t) ( (t)->ap_flag & AP_PTIMER_CALLING)
  16. #define set_ah_ptimer_stopped(t) do{ (t)->ap_flag |= AP_PTIMER_STOPPED; } while(0)
  17. #define unset_ah_ptimer_stopped(t) do{ (t)->ap_flag &= ~AP_PTIMER_STOPPED; } while(0)
  18. #define set_ah_ptimer_calling(t) do{ (t)->ap_flag |= AP_PTIMER_CALLING; } while(0)
  19. #define unset_ah_ptimer_calling(t) do{ (t)->ap_flag &= ~AP_PTIMER_CALLING; } while(0)


  20. #define PTIME_TIC_SEC 1 /* tic every 1 second */
  21. #define PTIMER_TIC_SYS 128 /* every how many <tic> to make sys call to get current time */

  22. static boolean timer_thread_running = FALSE;
  23. /* timer-queue-lock */
  24. static pthread_mutex_t pmpt_timer_lock = PTHREAD_MUTEX_INITIALIZER;
  25. static ah_ptimer_t *pmpt_timer_head; /* all timers in double link-list */
  26. static ah_ptimer_t *pmpt_timer_tail;

  27. struct itimerval {
  28.      struct timeval it_interval; /* next value */
  29.      struct timeval it_value; /* current value */
  30. };

  31. struct timeval {
  32.      long tv_sec; /* seconds */
  33.      long tv_usec; /* microseconds */
  34. };

  35. /*
  36.  * sys alarm sig handler
  37.  *每128s去重新通过_ah_sys_up_sec()获取当前系统时间,128s内直接通过加法实现时间的增加
  38.  */
  39. static void ptimer_tic (int sig)
  40. {
  41.         static uint32 tic_count=PTIMER_TIC_SYS;
  42.         int time_now;

  43.         /* not do sys call each sec */
  44.         if ( ! (--tic_count) ) {
  45.                 /* try the sys call get time */
  46.                 time_now = _ah_sys_up_sec();

  47.             /* sys call fail */
  48.             if (time_now < 0) {
  49.                     ap_sys_up_sec += PTIME_TIC_SEC;
  50.                     tic_count = 1;
  51.             }else {/* sys call ok */
  52.                     ap_sys_up_sec = time_now;
  53.                     tic_count = PTIMER_TIC_SYS;
  54.             }
  55.         }
  56.         else {
  57.                 ap_sys_up_sec += PTIME_TIC_SEC;
  58.         }

  59.     /* linux follow System V semantics, reset signal handler to dflt.
  60.      * so no same alarm would prempt this handler. we set the tic handler again
  61.      * after poll all the timer, so we are non-prempt at process level
  62.      */
  63. #if 0
  64.         if( signal(SIGALRM, ptimer_tic) == SIG_ERR ) {
  65.             ah_err("proc %d fail install SIGALRM handler\n",getpid());
  66.                     ah_assert(FALSE);
  67.         }
  68. #endif
  69.         return;
  70. }

  71. /* init preempt timer */
  72. static int ah_pmpt_timer_setup(void)
  73. {
  74.         struct itimerval alarm_tic;

  75.         if (timer_thread_running) { /*如果定时器线程已经启动,直接返回*/
  76.                 return 0;
  77.         }

  78.         pmpt_timer_head = pmpt_timer_tail = NULL;/*初始化定时器链表*/
  79.         ap_sys_up_sec = _ah_sys_up_sec(); /*获取系统启动时间*/

  80.         if (ap_sys_up_sec < 0) { /*系统启动时间小于0,出错,返回*/
  81.                 return -1;
  82.         }

  83.         /* sys timer will send SIGALRM */
  84.         if( signal(SIGALRM, ptimer_tic) == SIG_ERR ) { /*定义信号SIGALRM的信号处理函数*/
  85.                 return -1;
  86.         }

  87.         /* setup sys tic */
  88.         memset((void*)&alarm_tic, 0, sizeof(alarm_tic));
  89.         alarm_tic.it_interval.tv_sec = PTIME_TIC_SEC;/*1s*/
  90.         alarm_tic.it_value.tv_sec = PTIME_TIC_SEC;
  91.         /*ITIMER_REAL decrements in real time, and delivers SIGALRM upon expiration.*/
  92.         setitimer(ITIMER_REAL, &alarm_tic, NULL); /*设置1s定时器,1s后发送SIGALRM信号*/

  93.         return 0;
  94. }

  95. void ah_signal_mask(int block, int signum)
  96. {
  97.         sigset_t mask; /*定义信号集mask*/

  98.         sigemptyset(&mask); /*初始化清空信号集mask*/
  99.         sigaddset(&mask, signum);/*将信号signum加入到信号集mask*/
  100.         
  101.         if (block)
  102.                 pthread_sigmask(SIG_BLOCK, &mask, NULL);/*将信号集mask加入到信号屏蔽字中*/
  103.         else
  104.                 pthread_sigmask(SIG_UNBLOCK, &mask, NULL);/*将信号集mask从信号屏蔽字中清除*/
  105. }
  106. /* must call it when pmpt_timer_lock is locked */
  107. static void ah_pmpt_timer_dec_ref(ah_ptimer_t *t)
  108. {
  109.         --t->ap_count;
  110.         if (t->ap_count < 0) {
  111.                 ah_log(LOG_CRIT, "preempt timer: double free.");
  112.         }
  113.         if (0 == t->ap_count) {
  114.                 ah_assert(is_ah_ptimer_stopped(t));
  115.                 free(t);
  116.         }

  117.         return;
  118. }
  119. /*
  120.  * poll the timer queue, call any expired timer's callback.
  121.  */
  122. void ah_pmpt_timer_poll(void)
  123. {
  124.         ah_ptimer_t *t=NULL;

  125.         for ( ; ; ) {
  126.                 if (pthread_mutex_lock(&pmpt_timer_lock) != 0) {
  127.                         ah_assert(FALSE);
  128.                         return;
  129.                 }

  130.                 if ( (NULL == pmpt_timer_head) /*定时器连边为空,直接返回*/
  131.                     || (pmpt_timer_head->ap_fire > ap_sys_up_sec) ) { /*头结点的定时时间没有到,直接返回*/
  132.                         pthread_mutex_unlock(&pmpt_timer_lock);
  133.                         break;
  134.                 }
  135.                 /*。。。。。。。。。。。。头结点的定时时间到了。。。。。。。。。*/
  136.                 t = pmpt_timer_head; /*获取定时器链表头结点*/
  137.                 pmpt_timer_head = t->ap_next;/*更新pmpt_timer_head为下一个节点*/

  138.                 if( NULL == pmpt_timer_head ) {
  139.                         pmpt_timer_tail = NULL;
  140.                 } else {
  141.                         pmpt_timer_head->ap_prev = NULL;
  142.                 }
  143.                 /*将节点t从链表中摘除*/
  144.                 /* clean up t's forw/back ptr */
  145.                 t->ap_prev = NULL;
  146.                 t->ap_next = NULL;

  147.                 /* prevent it be deleted when calling timer's callback */
  148.                 ++t->ap_count;/*防止定时器被删除,删除的判断是ap_count==0*/

  149.                 set_ah_ptimer_calling(t);/*设置标记,表明定时器正在被调用*/
  150.                 pthread_mutex_unlock(&pmpt_timer_lock);

  151.                 /* NOTE: it's the callback's responsibility to free/reset/etc.
  152.                    to handle the timer ptr correctly */
  153.                 ah_assert(NULL != t->ap_func);
  154.                 t->ap_func(t, t->ap_data);/*调用定时器的回调函数*/
  155.                 if (pthread_mutex_lock(&pmpt_timer_lock) != 0) {
  156.                         ah_assert(FALSE);
  157.                         return;
  158.                 }
  159.                 unset_ah_ptimer_calling(t);/*将被调用的标记删除*/
  160.                 ah_pmpt_timer_dec_ref(t);/*将技术值ap_count减1,如果减法后变为0,则删除定时器*/
  161.                 pthread_mutex_unlock(&pmpt_timer_lock);
  162.         }

  163.         return;
  164. }

  165. static void *ah_pmpt_timer_thread(void *arg)
  166. {
  167.         ah_signal_mask(FALSE, SIGALRM);
  168.         if (ah_pmpt_timer_setup() < 0) {
  169.                 return NULL;
  170.         }

  171.         timer_thread_running = TRUE;
  172.         for ( ; ; ) {
  173.                 /* select(0, NULL, NULL, NULL, NULL); */
  174.                 ah_sleep(1);
  175.                 ah_pmpt_timer_poll();
  176.         }
  177.         return NULL;
  178. }


  179. /* should call it in main function firstly */
  180. int ah_pmpt_timer_init(pthread_t *timer_id)
  181. {
  182.         int count = 0;

  183.         ah_signal_mask(TRUE, SIGALRM);
  184.         /* Create event sub-thread *//*起一个线程进程定时器计算*/
  185.         if (ah_pthread_create(timer_id, ah_pmpt_timer_thread,
  186.                               NULL, SCHED_RR,
  187.                               AH_PRIORITY_CTRL, 0) != 0) {
  188.                 ah_err("ah_pthread_create failed");
  189.                 return -1;
  190.         }
  191.         /* Check if sub-thread is actually succeeded */
  192.         while ( (!timer_thread_running) && ((count++) < 10)) {
  193.                 ah_sleep(1);
  194.         }

  195.         if (!timer_thread_running) {
  196.                 ah_err("Can not run timer thread");
  197.                 if (NULL != timer_id) {
  198.                         *timer_id = -1;
  199.                 }
  200.                 return -1;
  201.         }

  202.         return 0;
  203. }


  204. ah_ptimer_t* ah_pmpt_timer_create(ah_ptimer_callback_t callback, void *arg)
  205. {
  206.         ah_ptimer_t *t;

  207.         if (NULL == callback) { /*定时器没有回调函数,直接退出*/
  208.                 return NULL;
  209.         }

  210.         t = (ah_ptimer_t*)ah_calloc(1,sizeof(ah_ptimer_t)); /*分配定时器*/
  211.         if (NULL == t) {
  212.                 return NULL;
  213.         }

  214.         t->ap_func = callback;
  215.         t->ap_data = arg;
  216.         t->ap_count = 1;

  217.         return t;
  218. }


  219. /* must call it when pmpt_timer_lock is locked */
  220. static void ah_pmpt_timer_stop_internal(ah_ptimer_t *t)
  221. {
  222.         set_ah_ptimer_stopped(t); /*设置定时器t的标记位为STOPPED*/
  223.         if ((NULL == t->ap_prev) && (NULL == t->ap_next) && (t != pmpt_timer_head)){
  224.                 return;
  225.         }
  226.         if( t->ap_prev ) {
  227.                 t->ap_prev->ap_next = t->ap_next;
  228.         } else {
  229.                 pmpt_timer_head = t->ap_next;
  230.         }

  231.         if(NULL != t
阅读(937) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~