Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 28 additions & 38 deletions time2/wheel.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
package time2

import (
"container/list"
"sync"
"time"
)

const (
tvn_bits uint64 = 6
tvr_bits uint64 = 8
tvn_size uint64 = 64 //1 << tvn_bits
tvr_size uint64 = 256 //1 << tvr_bits
tvn_size uint64 = 64 // 1 << tvn_bits
tvr_size uint64 = 256 // 1 << tvr_bits

tvn_mask uint64 = 63 //tvn_size - 1
tvr_mask uint64 = 255 //tvr_size -1
)

const (
defaultTimerSize = 128
tvn_mask uint64 = 63 // tvn_size - 1
tvr_mask uint64 = 255 // tvr_size -1
)

type timer struct {
Expand All @@ -28,20 +25,20 @@ type timer struct {

w *Wheel

vec []*timer
index int
vec *list.List
e *list.Element
}

type Wheel struct {
sync.Mutex

jiffies uint64

tv1 [][]*timer
tv2 [][]*timer
tv3 [][]*timer
tv4 [][]*timer
tv5 [][]*timer
tv1 []*list.List
tv2 []*list.List
tv3 []*list.List
tv4 []*list.List
tv5 []*list.List

tick time.Duration

Expand All @@ -54,10 +51,10 @@ func NewWheel(tick time.Duration) *Wheel {

w.quit = make(chan struct{})

f := func(size int) [][]*timer {
tv := make([][]*timer, size)
f := func(size int) []*list.List {
tv := make([]*list.List, size)
for i := range tv {
tv[i] = make([]*timer, 0, defaultTimerSize)
tv[i] = list.New()
}

return tv
Expand All @@ -80,7 +77,7 @@ func (w *Wheel) addTimerInternal(t *timer) {
expires := t.expires
idx := t.expires - w.jiffies

var tv [][]*timer
var tv []*list.List
var i uint64

if idx < tvr_size {
Expand Down Expand Up @@ -109,18 +106,16 @@ func (w *Wheel) addTimerInternal(t *timer) {
tv = w.tv5
}

tv[i] = append(tv[i], t)

t.e = tv[i].PushBack(t)
t.vec = tv[i]
t.index = len(tv[i]) - 1
}

func (w *Wheel) cascade(tv [][]*timer, index int) int {
func (w *Wheel) cascade(tv []*list.List, index int) int {
vec := tv[index]
tv[index] = vec[0:0:defaultTimerSize]
tv[index] = list.New()

for _, t := range vec {
w.addTimerInternal(t)
for e := vec.Front(); e != nil; e = e.Next() {
w.addTimerInternal(e.Value.(*timer))
}

return index
Expand All @@ -145,17 +140,14 @@ func (w *Wheel) onTick() {
w.jiffies++

vec := w.tv1[index]
w.tv1[index] = vec[0:0:defaultTimerSize]
w.tv1[index] = list.New()

w.Unlock()

f := func(vec []*timer) {
f := func(vec *list.List) {
now := time.Now()
for _, t := range vec {
if t == nil {
continue
}

for e := vec.Front(); e != nil; e = e.Next() {
t := e.Value.(*timer)
t.f(now, t.arg)

if t.period > 0 {
Expand All @@ -165,7 +157,7 @@ func (w *Wheel) onTick() {
}
}

if len(vec) > 0 {
if vec.Len() > 0 {
go f(vec)
}
}
Expand All @@ -178,11 +170,9 @@ func (w *Wheel) addTimer(t *timer) {

func (w *Wheel) delTimer(t *timer) {
w.Lock()
vec := t.vec
index := t.index

if len(vec) > index && vec[index] == t {
vec[index] = nil
if t.vec.Remove(t.e) != t {
panic("internal error")
}

w.Unlock()
Expand Down