⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timer.cpp

📁 C++ patterns设计模式
💻 CPP
字号:
////////////////////////////////////////////////////////////////////////////////
// 定时器
////////////////////////////////////////////////////////////////////////////////
// Author      : 黎达文                                                        
// Description : 
//
// Version     : 2.0
//
// Standard include files : 
//
// Start Date  : 2003年12月4日
//
// Change Log  : 2003年12月4日 by 黎达文 -- Created
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "timer.h"

namespace kernel
{
    TimerLogic::TimerLogic()
    {
        memset(&tv1, 0, sizeof(tv1));
        memset(&tv2, 0, sizeof(tv2));
        memset(&tv3, 0, sizeof(tv3));
        memset(&tv4, 0, sizeof(tv4));
        memset(&tv5, 0, sizeof(tv5));
        tvecs[0] = (TimerVec *)&tv1;
        tvecs[1] = &tv2;
        tvecs[2] = &tv3;
        tvecs[3] = &tv4;
        tvecs[4] = &tv5;
        tickCount = 0;
    }

    // 将一个定时器插入到合适的盘子合适的刻度
    bool TimerLogic::insert (TimerList *timer)
    {
        unsigned int expires    = timer->expires;
        unsigned int idx        = expires - tickCount;
        TimerList **vec;

        if(idx < TVR_SIZE) 
        {
            int i = expires & TVR_MASK;
            vec = tv1.vec + i;
        } 
		else if (idx < 1 << (TVR_BITS + TVN_BITS)) 
        {
            int i = (expires >> TVR_BITS) & TVN_MASK;
            vec = tv2.vec + i;
        } 
		else if (idx < 1 << (TVR_BITS + 2 * TVN_BITS)) 
        {
            int i = (expires >> (TVR_BITS + TVN_BITS)) & TVN_MASK;
            vec = tv3.vec + i;
        } 
		else if (idx < 1 << (TVR_BITS + 3 * TVN_BITS)) 
        {
            int i = (expires >> (TVR_BITS + 2 * TVN_BITS)) & TVN_MASK;
            vec = tv4.vec + i;
        } 
		else if ((signed long) idx < 0) 
        {
            // can happen if you add a timer with expires == jiffies,
            // or you set a timer to go off in the past
            vec = tv1.vec + tv1.index;
        } 
		else if (idx <= 0xffffffffUL)
        {
            int i = (expires >> (TVR_BITS + 3 * TVN_BITS)) & TVN_MASK;
            vec = tv5.vec + i;
        } 
		else 
        {
            return false;
        }
        if ((timer->next = *vec))   // 赋值next指针
            (*vec)->prev = timer;
        *vec = timer;
        timer->prev = (TimerList *)vec;
        return true;
    }
    void TimerLogic::erase  (TimerList *curr)
    {
        TimerList  *prev = curr->prev;
        if (prev)
        {
            TimerList *next = curr->next;
            prev->next = next;
            if (next)
                next->prev = prev;
            curr->next = curr->prev = 0;
        }
    }
    void TimerLogic::cascade(TimerVec  *tv)
    {
        // cascade all the timers from tv up one level 
        TimerList *timer;
        timer = tv->vec[tv->index];
        TimerList *tmp = NULL;
        while (timer)
        {
            tmp   = timer;
            timer = timer->next;
            insert(tmp);
        }
        tv->vec[tv->index] = NULL;
        tv->index = (tv->index + 1) & TVN_MASK;
    }

    GeneralTimer::GeneralTimer(unsigned int timeslice)
        : m_exit_signaled(false)
    {
        if(timeslice < MIN_TIMESLICE)
            m_timeslice = MIN_TIMESLICE;
        else
            m_timeslice = timeslice;
        startThread();
    }

    GeneralTimer::~GeneralTimer()
    {
        m_exit_signaled = true;
        waitFinish(5000);
    }

    TimerID GeneralTimer::set(TimerTask *owner, unsigned int expires, unsigned int userdata)
    {
        TimerList *timer = new TimerList;
        timer->expires    = expires/m_timeslice;    // 计算tick数目
        timer->owner_type = OT_TASK;
        timer->task       = owner;    
        timer->userdata   = userdata;
        if(!insert(timer))
        {
			delete timer;
            return 0;
        }
        return timer;
    }

    TimerID GeneralTimer::set(TimerProc function, unsigned int expires, unsigned int userdata)
    {
        TimerList *timer = new TimerList;
        timer->expires    = expires/m_timeslice;
        timer->owner_type = OT_FUNCTION;
        timer->function   = function;    
        timer->userdata   = userdata;
        if(!insert(timer))
        {
			delete timer;
            return 0;
        }
        return timer;
    }

    void GeneralTimer::unset(TimerID timerid)
    {
        if(timerid)
            erase(timerid);
        delete timerid;
    }

    void GeneralTimer::threadProcess()
    {
        TimerList *curr  = NULL;
        TimerList *timer = NULL;
        while(!m_exit_signaled)
        {
            ::Sleep(m_timeslice);

            // 大盘已经转一周了,将下面的定时器往上移动
            if (tv1.index == 0)
            {
                int n = 1;
                do{
                    cascade(tvecs[n]);
                } while (tvecs[n]->index == 1 && ++n < NOOF_TVECS);
            }

            // 检查当前时刻的定时器列表,一一触发他们
            while ((curr = tv1.vec[tv1.index]))
            {
                if(curr->owner_type == OT_TASK)
                    curr->task->onTimer(curr->userdata);
                else if(curr->owner_type == OT_FUNCTION)
                    curr->function(curr->userdata);
                // 移走已经触发的定时器
                unset(curr);
                curr = NULL;
            }
            // 时钟计数
            tickCount++;
            // 时钟刻度走一格
            tv1.index = (tv1.index + 1) & TVR_MASK;
        }
    }

    unsigned int HashTimer::set(TimerTask *owner, unsigned int expires, unsigned int userdata)
    {
        CTScopeCS scopeLock(m_cs);
        TimerID timerid = GeneralTimer::set(owner, expires, userdata);
        unsigned int      id = INVALID_ID;
        if(timerid)
        {
            id = nextid();
            m_idmap.insert(std::make_pair(id, timerid));
        }
        return id;
    }

    unsigned int HashTimer::set(TimerProc function, unsigned int expires, unsigned int userdata)
    {
        CTScopeCS scopeLock(m_cs);
        TimerID timerid = GeneralTimer::set(function, expires, userdata);
        unsigned int      id = INVALID_ID;
        if(timerid)
        {
            id = nextid();
            m_idmap.insert(std::make_pair(id, timerid));
        }
        return id;
    }
    void  HashTimer::unset(unsigned int id)
    {
        CTScopeCS scopeLock(m_cs);
        IDTYPE::iterator it = m_idmap.find(id);
        if(it != m_idmap.end())
            GeneralTimer::unset(it->second);
    }
    unsigned int HashTimer::nextid()
    {    
        if(m_id++ > MAX_ID)
            m_id = MIN_ID;
        return m_id;
    }

    //not implement yet!
    unsigned int  SetTimer(TimerTask *owner, unsigned int expires, unsigned int userdata)
    {
        return 0;
    }
    unsigned int  SetTimer(TimerProc function, unsigned int expires, unsigned int userdata)
    {
        return 0;
    }
    void KillTimer(unsigned int id)
    {
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -