summaryrefslogtreecommitdiff
path: root/satp/sequence-window.go
diff options
context:
space:
mode:
authorChristian Pointner <equinox@anytun.org>2017-10-13 22:30:44 +0200
committerChristian Pointner <equinox@anytun.org>2017-10-13 22:30:44 +0200
commitf74c90da9c81f2030698346c4b4bbc1af3dc2df8 (patch)
tree2057ad7a62c9c3b37104082da4ca5ca2135fb2fa /satp/sequence-window.go
parentsequence window without advance... (diff)
checkAndSet works now in any case
Diffstat (limited to 'satp/sequence-window.go')
-rw-r--r--satp/sequence-window.go24
1 files changed, 20 insertions, 4 deletions
diff --git a/satp/sequence-window.go b/satp/sequence-window.go
index f529231..9fa4385 100644
--- a/satp/sequence-window.go
+++ b/satp/sequence-window.go
@@ -139,7 +139,23 @@ func (w *SequenceWindow) checkAndSet(sequenceNumber uint32) bool {
}
func (w *SequenceWindow) advanceTop(newTop uint32) {
- // TODO: implement this
+ oldIdx := int(w.top() / 32)
+ newIdx := int(newTop / 32)
+ diff := newIdx - oldIdx
+ if oldIdx > newIdx {
+ diff = oldIdx - newIdx
+ }
+ oldHeadSlice := uint32(w.head)
+ w.head = uint64(newTop) << 32
+ for i := len(w.body) - 1; i >= 0; i-- {
+ if i < (diff - 1) {
+ w.body[i] = 0
+ } else if i < diff {
+ w.body[i] = oldHeadSlice
+ } else {
+ w.body[i] = w.body[i-diff]
+ }
+ }
}
func (w *SequenceWindow) top() uint32 {
@@ -182,10 +198,10 @@ func (w *SequenceWindow) CheckAndSet(sequenceNumber uint32) bool {
if lt && d > uint32(w.size) {
return false
}
- if lt || top/32 == sequenceNumber/32 {
- return w.checkAndSet(sequenceNumber)
+ if lt || top/32 == (sequenceNumber+1)/32 {
+ result := w.checkAndSet(sequenceNumber)
+ return result
}
-
// TODO: only now we would need the writers lock
w.advanceTop(sequenceNumber + 1)
return w.checkAndSet(sequenceNumber)