diff --git a/a8/timer.cc b/a8/timer.cc deleted file mode 100644 index 95e3b7c..0000000 --- a/a8/timer.cc +++ /dev/null @@ -1,441 +0,0 @@ -#include - -#include - -#if 0 -const int g_time_zone = 8; // 默认东八区 - -static time_t GetDaySeconds(time_t time, int incdays = 0) -{ - return time_t((time + g_time_zone * 3600)/3600/24 + incdays) * 3600 * 24 - 3600 * g_time_zone; -} - -#endif - -#define CONFIG_BASE_SMALL 0 -#define TVN_BITS (CONFIG_BASE_SMALL ? 4 : 6) -#define TVR_BITS (CONFIG_BASE_SMALL ? 6 : 8) -#define TVN_SIZE (1 << TVN_BITS) -#define TVR_SIZE (1 << TVR_BITS) -#define TVN_MASK (TVN_SIZE - 1) -#define TVR_MASK (TVR_SIZE - 1) -#define INDEX(N) ((base->timer_tick >> (TVR_BITS + (N) * TVN_BITS)) & TVN_MASK) - -struct tvec { - struct list_head vec[TVN_SIZE]; -}; - -struct tvec_root { - struct list_head vec[TVR_SIZE]; -}; - -struct tvec_base { - struct timer_list *running_timer; - long long timer_tick; - list_head free_timer; - int free_timer_num; - struct tvec_root tv1; - struct tvec tv2; - struct tvec tv3; - struct tvec tv4; - struct tvec tv5; -}; - -struct timer_list { - struct list_head entry; - struct list_head attach_entry; - int timer_type; // 0:deadline 1: repeattimer 2:fixedtimer outher:deadline - long long expires; - int milli_seconds; - int fixed_timer_execute_times; - struct tvec_base *base; - - a8::TimerFunc timer_func; - a8::TimerAfterFunc timer_after_func; - a8::XParams param; -}; - -static void InternalAddTimer(struct tvec_base *base, struct timer_list *timer) -{ - long long expires = timer->expires; - long long idx = expires - base->timer_tick; - struct list_head *vec; - - if (idx < 0) { - vec = base->tv1.vec + (base->timer_tick & TVR_MASK); - }else if (idx < TVR_SIZE) { - int i = expires & TVR_MASK; - vec = base->tv1.vec + i; - } else if (idx < 1 << (TVR_BITS + TVN_BITS)) { - int i = (expires >> TVR_BITS) & TVN_MASK; - vec = base->tv2.vec + i; - } else if (idx < 1 << (TVR_BITS + 2 * TVN_BITS)) { - int i = (expires >> (TVR_BITS + TVN_BITS)) & TVN_MASK; - vec = base->tv3.vec + i; - } else if (idx < 1 << (TVR_BITS + 3 * TVN_BITS)) { - int i = (expires >> (TVR_BITS + 2 * TVN_BITS)) & TVN_MASK; - vec = base->tv4.vec + i; - } else { - int i = (expires >> (TVR_BITS + 3 * TVN_BITS)) & TVN_MASK; - vec = base->tv5.vec + i; - } - list_add_tail(&timer->entry, vec); -} - -static int Cascade(struct tvec_base *base, struct tvec *tv, int index) -{ - /* cascade all the timers from tv up one level */ - struct timer_list *timer, *tmp; - struct list_head tv_list; - - // 将tv数组中以index为下标的定时器队列取出,准备搬移 - list_replace_init(tv->vec + index, &tv_list); - - // 根据超时时间,将队列中的定时器重新排队。定时器往上一级时间轮排队的过程就 // 在这里发生。 - list_for_each_entry_safe(timer, tmp, &tv_list, entry) { - InternalAddTimer(base, timer); - } - return index; -} - -static inline int DetachTimer(struct timer_list *timer) -{ - if (!list_empty(&timer->entry)) { - list_del_init(&timer->entry); - } - return 1; -} - -static inline void InitTimerList(tvec_base* base, timer_list* timer, int timer_type, - int milli_seconds, a8::XParams& param, - a8::TimerFunc timer_func, a8::TimerAfterFunc timer_after_func) -{ - INIT_LIST_HEAD(&timer->entry); - INIT_LIST_HEAD(&timer->attach_entry); - timer->timer_type = timer_type; - timer->expires = a8::XGetTickCount() + milli_seconds; - timer->milli_seconds = milli_seconds; - timer->fixed_timer_execute_times = 0; - timer->base = base; - timer->timer_func = timer_func; - timer->timer_after_func = timer_after_func; - timer->param = param; -} - -namespace a8 -{ - - void Timer::Init() - { - base_ = new tvec_base(); - base_->running_timer = nullptr; - base_->timer_tick = a8::XGetTickCount(); - INIT_LIST_HEAD(&base_->free_timer); - base_->free_timer_num = 0; - for (int j = 0; j < TVN_SIZE; j++) { - INIT_LIST_HEAD(base_->tv5.vec + j); - INIT_LIST_HEAD(base_->tv4.vec + j); - INIT_LIST_HEAD(base_->tv3.vec + j); - INIT_LIST_HEAD(base_->tv2.vec + j); - } - for (int j = 0; j < TVR_SIZE; j++) { - INIT_LIST_HEAD(base_->tv1.vec + j); - } - AddRepeatTimer(1000 * 60 * 5, - a8::XParams().SetSender(this), - &Timer::GC_TimerFunc); - } - - void Timer::UnInit() - { - Clear(); - delete base_; - base_ = nullptr; - } - - void Timer::Update() - { -#ifdef MONITOR - long long start_ns_tick = XGetNanoSeconds(); -#endif - if (a8::XGetTickCount() >= base_->timer_tick) { - UpdateTimer(); - } -#ifdef MONITOR - long long end_ns_tick = XGetNanoSeconds(); - if (end_ns_tick - start_ns_tick > g_monitor->timer_max_ns) { - g_monitor->timer_max_ns = end_ns_tick - start_ns_tick; - } -#endif - } - - timer_list* Timer::AddDeadLineTimer(int milli_seconds, a8::XParams param, a8::TimerFunc timer_func, - a8::TimerAfterFunc timer_after_func) - { - timer_list *timer = NewTimerList(); - InitTimerList(base_, timer, 0, milli_seconds, param, timer_func, timer_after_func); - ModifyTimer(timer, milli_seconds); - return timer; - } - - timer_list* Timer::AddDeadLineTimerAndAttach(int milli_seconds, a8::XParams param, a8::TimerFunc timer_func, - list_head* attach_list, a8::TimerAfterFunc timer_after_func) - { - timer_list* timer = AddDeadLineTimer(milli_seconds, param, timer_func, timer_after_func); - list_add_tail(&timer->attach_entry, attach_list); - return timer; - } - - timer_list* Timer::AddRepeatTimer(int milli_seconds, a8::XParams param, a8::TimerFunc timer_func) - { - timer_list *timer = NewTimerList(); - InitTimerList(base_, timer, 1, milli_seconds, param, timer_func, nullptr); - ModifyTimer(timer, milli_seconds); - return timer; - } - - timer_list* Timer::AddRepeatTimerAndAttach(int milli_seconds, - a8::XParams param, - a8::TimerFunc timer_func, - list_head* attach_list, - a8::TimerAfterFunc timer_after_func) - { - timer_list* timer = AddRepeatTimer(milli_seconds, param, timer_func); - list_add_tail(&timer->attach_entry, attach_list); - return timer; - } - - timer_list* Timer::AddFixedTimer(int milli_seconds, a8::XParams param, a8::TimerFunc timer_func, - a8::TimerAfterFunc timer_after_func) - { - timer_list *timer = NewTimerList(); - InitTimerList(base_, timer, 2, milli_seconds, param, timer_func, timer_after_func); - ModifyTimer(timer, milli_seconds); - return timer; - } - - timer_list* Timer::AddFixedTimerAndAttach(int milli_seconds, - a8::XParams param, - a8::TimerFunc timer_func, - list_head* attach_list, - a8::TimerAfterFunc timer_after_func) - { - timer_list *timer = AddFixedTimer(milli_seconds, param, timer_func, timer_after_func); - list_add_tail(&timer->attach_entry, attach_list); - return timer; - } - - void Timer::ModifyTimer(timer_list* timer, int milli_seconds) - { - DetachTimer(timer); - timer->milli_seconds = milli_seconds; - if (timer->timer_type == 2) { - long long tick = a8::XGetTickCount(); - long long today_passed_seconds = time(nullptr) - a8::GetDaySeconds(time(nullptr), 0); - timer->expires = (tick - today_passed_seconds * 1000) + milli_seconds; - if (timer->fixed_timer_execute_times > 0) { - if (timer->expires <= tick) { //已过期 - timer->expires += 1000 * 3600 * 24; - } - } - }else { - timer->expires = a8::XGetTickCount() + milli_seconds; - } - InternalAddTimer(base_, timer); - } - - void Timer::DeleteTimer(timer_list* timer) - { - if (!timer) { - abort(); - } - if (base_->running_timer == timer) { - base_->running_timer = nullptr; - } - if (timer->timer_after_func) { - timer->timer_after_func(timer->param); - } - DetachTimer(timer); - if (!list_empty(&timer->attach_entry)) { - list_del_init(&timer->attach_entry); - } - AddToFreeList(timer); - } - - timer_list* Timer::GetTimerByAttach(list_head* attach_entry) - { - if (attach_entry) { - timer_list* timer = list_entry(attach_entry, struct timer_list, attach_entry); - return timer; - } else { - return nullptr; - } - } - - a8::XParams* Timer::MutableParams(timer_list* timer) - { - if (!timer) { - abort(); - } - return &timer->param; - } - - void Timer::RemoveTimerAfterFunc(timer_list* timer) - { - if (!timer) { - abort(); - } - timer->timer_after_func = nullptr; - } - - long long Timer::GetRemainTime(timer_list* timer) - { - if (!timer) { - abort(); - } - long long remain_time = timer->expires - a8::XGetTickCount(); - return std::max(remain_time, (long long)0); - } - - timer_list* Timer::GetRunningTimer() - { - return base_->running_timer; - } - - int Timer::GetIdleableMillSeconds() - { - #if 0 - struct tvec_base *base = base_; - #endif - int idle_time = 1; - for (int lv1_idx = base_->timer_tick & TVR_MASK; lv1_idx < TVR_SIZE; ++lv1_idx) { - if (!list_empty(base_->tv1.vec + lv1_idx)) { - return idle_time <= 1 ? 1 : idle_time - 1; - } - ++idle_time; - } - #if 0 - for (int lv2_idx = INDEX(0); lv2_idx < TVN_SIZE; ++lv2_idx) { - if (!list_empty(base_->tv2.vec + lv2_idx)) { - return idle_time; - } - idle_time += TVR_SIZE; - } - #endif - return idle_time <= 1 ? 1 : idle_time - 1; - } - - void Timer::UpdateTimer() - { - struct tvec_base *base = base_; - while (a8::XGetTickCount() >= base->timer_tick) { - struct list_head work_list; - struct list_head *head = &work_list; - int index = base->timer_tick & TVR_MASK; - - if (!index && - (!Cascade(base, &base->tv2, INDEX(0))) && - (!Cascade(base, &base->tv3, INDEX(1))) && - !Cascade(base, &base->tv4, INDEX(2))) { - Cascade(base, &base->tv5, INDEX(3)); - } - ++base->timer_tick; - list_replace_init(base->tv1.vec + index, &work_list); - while (!list_empty(head)) { - struct timer_list *timer; - timer = list_first_entry(head, struct timer_list,entry); - base->running_timer = timer; - if (timer->timer_func) { - timer->timer_func(timer->param); - } - if (timer->timer_after_func) { - timer->timer_after_func(timer->param); - } - if (base_->running_timer) { - switch (timer->timer_type) { - case 1: - case 2: //循环类定时 fixed timer也是循环定时器 - { - if (timer->timer_type == 2) { - timer->fixed_timer_execute_times++; - } - ModifyTimer(timer, timer->milli_seconds); - } - break; - default: //deadline timer - { - DetachTimer(timer); - if (!list_empty(&timer->attach_entry)) { - list_del_init(&timer->attach_entry); - } - AddToFreeList(timer); - } - break; - } - } - } - } - base->running_timer = nullptr; - } - - timer_list* Timer::NewTimerList() - { - if (!list_empty(&base_->free_timer)) { - timer_list* timer = list_first_entry(&base_->free_timer, struct timer_list,entry); - list_del_init(&timer->entry); - base_->free_timer_num--; - return timer; - } else { - return new timer_list(); - } - } - - void Timer::AddToFreeList(timer_list* timer) - { - list_add_tail(&timer->entry, &base_->free_timer); - base_->free_timer_num++; - } - - void Timer::Clear() - { - auto free_timers = - [] (list_head* head) - { - while (!list_empty(head)) { - struct timer_list *timer; - timer = list_first_entry(head, struct timer_list,entry); - DetachTimer(timer); - if (!list_empty(&timer->attach_entry)) { - list_del_init(&timer->attach_entry); - } - delete timer; - } - }; - for (int j = 0; j < TVN_SIZE; j++) { - free_timers(base_->tv5.vec + j); - free_timers(base_->tv4.vec + j); - free_timers(base_->tv3.vec + j); - free_timers(base_->tv2.vec + j); - } - for (int j = 0; j < TVR_SIZE; j++) { - free_timers(base_->tv1.vec + j); - } - free_timers(&base_->free_timer); - } - - void Timer::GC_TimerFunc(const a8::XParams& param) - { - Timer* timer = (Timer*)param.sender.GetUserData(); - int i = 0; - while (!list_empty(&timer->base_->free_timer) && - timer->base_->free_timer_num > 1000 && i < 1000) { - timer_list* timer1 = list_first_entry(&timer->base_->free_timer, struct timer_list, entry); - list_del_init(&timer1->entry); - delete timer1; - - timer->base_->free_timer_num--; - i++; - } - } - -} diff --git a/a8/timer.h b/a8/timer.h deleted file mode 100644 index b62b2c1..0000000 --- a/a8/timer.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 仿照linux2.6内核定时器实现 - */ -#pragma once - -#include - -struct timer_list; -struct tvec_base; - -namespace a8 -{ - typedef void (*TimerFunc)(const a8::XParams& param); - typedef void (*TimerAfterFunc)(const a8::XParams& param); - - class Timer : public a8::Singleton - { - private: - Timer() {}; - friend class a8::Singleton; - - public: - void Init(); - void UnInit(); - void Update(); - - //添加截止时间定时器(一次性定时器) - timer_list* AddDeadLineTimer(int milli_seconds, a8::XParams param, a8::TimerFunc timer_func, - a8::TimerAfterFunc timer_after_func = nullptr); - timer_list* AddDeadLineTimerAndAttach(int milli_seconds, a8::XParams, - a8::TimerFunc timer_func, - list_head* attach_list, - a8::TimerAfterFunc timer_after_func = nullptr); - //添加重复执行定时器(周期性定时器) - timer_list* AddRepeatTimer(int milli_seconds, a8::XParams param, a8::TimerFunc timer_func); - timer_list* AddRepeatTimerAndAttach(int milli_seconds, - a8::XParams param, - a8::TimerFunc timer_func, - list_head* attach_list, - a8::TimerAfterFunc timer_after_func = nullptr); - //添加固定时间定时器(每天,每次重启一天里可能会多次调用) - timer_list* AddFixedTimer(int milli_seconds, a8::XParams param, a8::TimerFunc timer_func, - a8::TimerAfterFunc timer_after_func = nullptr); - timer_list* AddFixedTimerAndAttach(int milli_seconds, - a8::XParams param, - a8::TimerFunc timer_func, - list_head* attach_list, - a8::TimerAfterFunc timer_after_func = nullptr); - //修改定时器参数 - void ModifyTimer(timer_list* timer, int milli_seconds); - //删除定时器 - void DeleteTimer(timer_list* timer); - //通过关联的list_head获取定时器对象 - timer_list* GetTimerByAttach(list_head* attach_entry); - //获取定时器关联参数 - a8::XParams* MutableParams(timer_list* timer); - void RemoveTimerAfterFunc(timer_list* timer); - //获取定时器剩余时间 - long long GetRemainTime(timer_list* timer); - //获取当前正在运行的定时器 - timer_list* GetRunningTimer(); - //获取定时器可怠速时间mill seconds - int GetIdleableMillSeconds(); - - private: - void UpdateTimer(); - timer_list* NewTimerList(); - void AddToFreeList(timer_list* timer); - void Clear(); - static void GC_TimerFunc(const a8::XParams& param); - - private: - tvec_base* base_ = nullptr; - }; - -} diff --git a/a8/timer_attacher.cc b/a8/timer_attacher.cc index b77cb0b..552d220 100644 --- a/a8/timer_attacher.cc +++ b/a8/timer_attacher.cc @@ -1,32 +1,11 @@ #include -#include #include #include namespace a8 { - TimerAttacher::TimerAttacher() - { - INIT_LIST_HEAD(&timer_list_); - } - - TimerAttacher::~TimerAttacher() - { - ClearTimerList(); - } - - void TimerAttacher::ClearTimerList() - { - struct list_head* pos = nullptr; - struct list_head* n = nullptr; - list_for_each_safe(pos, n, &timer_list_){ - timer_list* tmp_timer = a8::Timer::Instance()->GetTimerByAttach(pos); - a8::Timer::Instance()->DeleteTimer(tmp_timer); - } - } - Attacher::Attacher() { INIT_LIST_HEAD(&timer_list_); diff --git a/a8/timer_attacher.h b/a8/timer_attacher.h index 64c99c1..afbce1e 100644 --- a/a8/timer_attacher.h +++ b/a8/timer_attacher.h @@ -2,17 +2,6 @@ namespace a8 { - - class TimerAttacher - { - public: - list_head timer_list_; - - TimerAttacher(); - ~TimerAttacher(); - void ClearTimerList(); - }; - class XTimer; class Attacher {