Skip to content

Commit

Permalink
race condition
Browse files Browse the repository at this point in the history
Signed-off-by: crowu <y.wu4515@gmail.com>
  • Loading branch information
5antelope committed Nov 24, 2020
1 parent 308772c commit 2c9b959
Showing 1 changed file with 13 additions and 5 deletions.
18 changes: 13 additions & 5 deletions go/stats/ring.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,40 @@ import (
"bytes"
"encoding/json"
"fmt"
"sync"
"sync/atomic"
)

// Ring of int64 values
// Not thread safe
type RingInt64 struct {
position int
position int64
values []int64
mu sync.RWMutex
}

func NewRingInt64(capacity int) *RingInt64 {
return &RingInt64{values: make([]int64, 0, capacity)}
}

func (ri *RingInt64) Add(val int64) {
if len(ri.values) == cap(ri.values) {
if int(ri.position) == cap(ri.values)-1 {
ri.mu.Lock()
ri.values[ri.position] = val
ri.position = (ri.position + 1) % cap(ri.values)
ri.position = (ri.position + 1) % int64(cap(ri.values))
ri.mu.Unlock()
} else {
ri.values = append(ri.values, val)
// add 1 atomically so that next call will see the most up to update position
pos := int(atomic.AddInt64(&ri.position, 1))
ri.values[pos-1] = val
}
}

func (ri *RingInt64) Values() (values []int64) {
pos := int(ri.position)
values = make([]int64, len(ri.values))
for i := 0; i < len(ri.values); i++ {
values[i] = ri.values[(ri.position+i)%cap(ri.values)]
values[i] = ri.values[(pos+i)%cap(ri.values)]
}
return values
}
Expand Down

0 comments on commit 2c9b959

Please sign in to comment.