package base import ( "Server-Core/Server/Base/Log" "sync" "time" ) const ( TimerNearShift = 8 TimerNear = 1 << TimerNearShift TimerNearMask = TimerNear - 1 TimerLevelShift = 6 TimerLevel = 1 << TimerLevelShift TimerLevelMask = TimerLevel - 1 ) type Timer struct { near [TimerNear]linkList t [4][TimerLevel]linkList lock sync.Locker time uint32 startTime uint32 current uint64 } type timerNode struct { next *timerNode expire uint32 f func([]interface{}) argv []interface{} } type linkList struct { head timerNode tail *timerNode } func CreateTimer() (timer *Timer) { timer = new(Timer) timer.lock = NewSpinLock() for i := range timer.near { linkClear(&timer.near[i]) } for i := range timer.t { for j := range timer.t[i] { linkClear(&timer.t[i][j]) } } timer.startTime, timer.current = sysTime() return } func (timer *Timer) Run() { _, cs := sysTime() if cs < timer.current { log.Error("time diff error from:%d", timer.current) } else { diff := cs - timer.current timer.current += diff for i := 0; i < int(diff); i++ { timer.update() } } } func (timer *Timer) Add(time int, f func([]interface{}), argv ...interface{}) { node := new(timerNode) timer.lock.Lock() defer timer.lock.Unlock() node.expire = uint32(time) + timer.time node.f = f node.argv = argv timer.addNode(node) } func (timer *Timer) update() { timer.lock.Lock() defer timer.lock.Unlock() timer.execute() timer.shift() timer.execute() } func (timer *Timer) execute() { idx := timer.time & TimerNearMask for timer.near[idx].head.next != nil { node := linkClear(&timer.near[idx]) timer.lock.Unlock() dispatch(node) timer.lock.Lock() } } func (timer *Timer) shift() { mask := uint32(TimerNear) timer.time++ ct := timer.time if ct == 0 { timer.moveList(3, 0) } else { time := ct >> TimerNearShift for i := 0; (ct & (mask - 1)) == 0; i++ { idx := time & TimerLevelMask if idx != 0 { timer.moveList(i, idx) break } mask <<= TimerLevelShift time >>= TimerLevelShift } } } func (timer *Timer) moveList(level int, idx uint32) { current := linkClear(&timer.t[level][idx]) for current != nil { next := current.next timer.addNode(current) current = next } } func (timer *Timer) addNode(node *timerNode) { time := node.expire currentTime := timer.time if (time | TimerNearMask) == (currentTime | TimerNearMask) { link(&timer.near[time&TimerNearMask], node) } else { var i int var mask uint32 = TimerNear << TimerLevelShift for i = 0; i < 3; i++ { if (time | (mask - 1)) == (currentTime | (mask - 1)) { break } mask <<= TimerLevelShift } link(&timer.t[i][((time>>(TimerNearShift+i*TimerLevelShift))&TimerLevelMask)], node) } } func sysTime() (sec uint32, cs uint64) { t := time.Now() sec = uint32(t.Unix()) cs = uint64(t.UnixNano() / 10000000) return } func linkClear(list *linkList) (node *timerNode) { node = list.head.next list.head.next = nil list.tail = &list.head return } func link(list *linkList, node *timerNode) { list.tail.next = node list.tail = node node.next = nil } func dispatch(node *timerNode) { for node != nil { node.f(node.argv) node = node.next } }