summaryrefslogtreecommitdiff
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
parentsequence window without advance... (diff)
checkAndSet works now in any case
-rw-r--r--satp/sequence-window.go24
-rw-r--r--satp/sequence-window_test.go11
2 files changed, 29 insertions, 6 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)
diff --git a/satp/sequence-window_test.go b/satp/sequence-window_test.go
index 91211cd..41ee713 100644
--- a/satp/sequence-window_test.go
+++ b/satp/sequence-window_test.go
@@ -196,12 +196,18 @@ func TestSequenceWindowCheckAndSet(t *testing.T) {
}{
{0, 0, []uint32{0, 1, 2, 3, 4}, true},
{0, 0, []uint32{^uint32(0)}, true},
+ {1, 0, []uint32{0}, true},
{10, 0, []uint32{^uint32(0)}, false},
- {10, 20, []uint32{^uint32(0), 5, 9, 10}, false},
+ {10, 20, []uint32{^uint32(0), 5, 9, 10, 12, 13}, false},
+ {10, 20, []uint32{20, 23, 31, 32, 35}, true},
{32, 0, []uint32{0, 1, 2, 3, 4}, true},
{32, 10, []uint32{0, 1, 2, 3, 4}, false},
{32, 10, []uint32{10, 11, 12, 13, 14}, true},
{32, 0, []uint32{10, 17, 23, 0, 1, 18, 9, 8, 31}, true},
+ {32, 30, []uint32{30, 31, 32, 33, 34}, true},
+ {32, 0, []uint32{95, 100, 96, 97, 99, 98}, true},
+ {50, 0, []uint32{31, 32, 35, 33, 34, 64}, true},
+ {30, ^uint32(0) - 10, []uint32{0, 1, 2, 3, ^uint32(0), ^uint32(0) - 2}, true},
}
for _, vector := range testvectors {
@@ -209,12 +215,13 @@ func TestSequenceWindowCheckAndSet(t *testing.T) {
if err != nil {
t.Fatal("unexpected error:", err)
}
+ t.Logf("--------------, %v", w)
for _, seq := range vector.seqs {
result := w.CheckAndSet(seq)
if result != vector.result {
t.Fatalf("check-and-set %d on %s returned %v but should be %v", seq, w, result, vector.result)
}
- t.Log(w)
+ t.Logf("chk %10d, %v", seq, w)
}
}
}