summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@anytun.org>2017-09-19 22:07:17 +0200
committerChristian Pointner <equinox@anytun.org>2017-09-19 22:07:17 +0200
commita798752efe899180ffa0958507101cc9c07e22ac (patch)
tree820a83a7d839fc17fc70c696dc0358ebdeb146cc
parentsequence window partially implemented (diff)
properly intialize sequence window with top value
-rw-r--r--satp/sequence-window.go37
-rw-r--r--satp/sequence-window_test.go52
2 files changed, 54 insertions, 35 deletions
diff --git a/satp/sequence-window.go b/satp/sequence-window.go
index 94a7b0b..4c53ee5 100644
--- a/satp/sequence-window.go
+++ b/satp/sequence-window.go
@@ -33,14 +33,13 @@ package satp
import (
"errors"
"sync"
- "sync/atomic"
)
type SequenceWindow struct {
- size int
- head uint64
- body []uint32
- mutex *sync.RWMutex
+ size int
+ head uint64
+ body []uint32
+ mtx *sync.RWMutex
}
func (w *SequenceWindow) Size() int {
@@ -48,18 +47,18 @@ func (w *SequenceWindow) Size() int {
}
func (w *SequenceWindow) Top() uint32 {
- if w.size > 0 {
- w.mutex.RLock()
- defer w.mutex.RUnlock()
- }
- v := atomic.LoadUint64(&w.head)
- return uint32(v >> 32)
+ w.mtx.RLock()
+ defer w.mtx.RUnlock()
+ // return uint32(atomic.LoadUint64(&w.head) >> 32)
+ return uint32(w.head >> 32)
}
func (w *SequenceWindow) Check(sequenceNumber uint32) (bool, error) {
if w.size <= 0 {
return false, nil
}
+ w.mtx.RLock()
+ defer w.mtx.RUnlock()
// TODO: implement this
return false, nil
}
@@ -68,25 +67,31 @@ func (w *SequenceWindow) CheckAndSet(sequenceNumber uint32) (bool, error) {
if w.size <= 0 {
return false, nil
}
+ w.mtx.Lock()
+ defer w.mtx.Unlock()
// TODO: implement this
return false, nil
}
-func NewSequenceWindow(size int) (w *SequenceWindow, err error) {
+func NewSequenceWindow(size int, top uint32) (w *SequenceWindow, err error) {
if size < 0 {
return nil, errors.New("invalid sequence window size")
}
- w = &SequenceWindow{size: size, head: 0}
+ w = &SequenceWindow{size: size, head: uint64(top) << 32, mtx: &sync.RWMutex{}}
if w.size > 0 {
- bodyLen := (w.size / 32)
+ bodyLen := w.size / 32
if (w.size % 32) != 0 {
bodyLen++
}
w.body = make([]uint32, bodyLen, bodyLen)
+
+ remain := uint(top % 32)
+ for i := uint(0); i < remain; i++ {
+ w.head |= 1 << i
+ }
for i := range w.body {
- w.body[i] = 0
+ w.body[i] = 0xFFFFFFFF
}
- w.mutex = &sync.RWMutex{}
}
return
}
diff --git a/satp/sequence-window_test.go b/satp/sequence-window_test.go
index 4fc244a..2f38a23 100644
--- a/satp/sequence-window_test.go
+++ b/satp/sequence-window_test.go
@@ -37,23 +37,37 @@ import (
func TestSequenceWindowNew(t *testing.T) {
testvectors := []struct {
size int
+ top uint32
+ head uint64
bodyLen int
valid bool
}{
- {-1, 0, false},
- {0, 0, true},
- {1, 1, true},
- {10, 1, true},
- {32, 1, true},
- {33, 2, true},
- {63, 2, true},
- {64, 2, true},
- {65, 3, true},
- {100, 4, true},
+ {-1, 0, 0, 0, false},
+ {0, 0, 0, 0, true},
+ {1, 0, 0, 1, true},
+ {10, 0, 0, 1, true},
+ {10, 0x4, 0x40000000F, 1, true},
+ {10, 0x12, 0x120003FFFF, 1, true},
+ {32, 0, 0, 1, true},
+ {32, 0x1F, 0x1F7FFFFFFF, 1, true},
+ {32, 0x20, 0x2000000000, 1, true},
+ {33, 0, 0, 2, true},
+ {33, 1, 0x100000001, 2, true},
+ {63, 0, 0, 2, true},
+ {64, 0, 0, 2, true},
+ {65, 0, 0, 3, true},
+ {100, 0, 0, 4, true},
+ {100, 0xFFFF0000, 0xFFFF000000000000, 4, true},
+ {100, 0xFFFF0001, 0xFFFF000100000001, 4, true},
+ {100, 0xFFFF0002, 0xFFFF000200000003, 4, true},
+ {100, 0xFFFF0003, 0xFFFF000300000007, 4, true},
+ {100, 0xFFFF0004, 0xFFFF00040000000F, 4, true},
+ {100, 0xFFFF0005, 0xFFFF00050000001F, 4, true},
+ {100, 0xAAAA5555, 0xAAAA5555001FFFFF, 4, true},
}
for _, vector := range testvectors {
- w, err := NewSequenceWindow(vector.size)
+ w, err := NewSequenceWindow(vector.size, vector.top)
if vector.valid {
if err != nil {
t.Fatal("unexpected error:", err)
@@ -61,28 +75,28 @@ func TestSequenceWindowNew(t *testing.T) {
if w.Size() != vector.size {
t.Fatalf("sequence-window has wrong size, is: %d, should be %d", w.Size(), vector.size)
}
- if w.Top() != 0 {
- t.Fatalf("sequence-window(%d) top value not 0: 0x%08X", vector.size, w.Top())
+ if w.Top() != vector.top {
+ t.Fatalf("sequence-window(%d/%d) top value invalid, is: 0x%08X, should be 0x%08X", vector.size, vector.top, w.Top(), vector.top)
}
- if w.head != 0 {
- t.Fatalf("sequence-window(%d) head not 0: 0x%16X", vector.size, w.head)
+ if w.head != vector.head {
+ t.Fatalf("sequence-window(%d/%d) head invalid, is: 0x%016X, should be 0x%016X", vector.size, vector.top, w.head, vector.head)
}
bodyLen := len(w.body)
if bodyLen != vector.bodyLen {
- t.Fatalf("sequence-window(%d) body length has invalid length, is: %d, should be %d", vector.size, bodyLen, vector.bodyLen)
+ t.Fatalf("sequence-window(%d/%d) body length has invalid length, is: %d, should be %d", vector.size, vector.top, bodyLen, vector.bodyLen)
}
isEmpty := true
for _, v := range w.body {
- if v != 0 {
+ if v != 0xFFFFFFFF {
isEmpty = false
}
}
if !isEmpty {
- t.Fatalf("sequence-window(%d) body not empty, is: %v", vector.size, w.body)
+ t.Fatalf("sequence-window(%d/%d) body not full, is: %v", vector.size, vector.top, w.body)
}
} else {
if err == nil {
- t.Fatalf("creating sequence-window(%d) should give an error", vector.size)
+ t.Fatalf("creating sequence-window(%d/%d) should give an error", vector.size, vector.top)
}
}
}