Skip to content

Commit

Permalink
Fix not aligned uint64 variable
Browse files Browse the repository at this point in the history
When using atomic operations from sync/atomic on 64 bit variables on 32
bit architecture care must be taken to assure the variables are 8 byte
aligned.

Issue: golang/go#599

Applying a hack from:
https://go101.org/article/memory-layout.html

Fix execution error:

runtime: unexpected return pc for armXadd64 called from 0x0
  • Loading branch information
comzyh committed Apr 14, 2021
1 parent 3a197f6 commit 50e1e70
Showing 1 changed file with 13 additions and 3 deletions.
16 changes: 13 additions & 3 deletions pkg/tcpip/tcpip.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import (
"strings"
"sync/atomic"
"time"
"unsafe"

"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/waiter"
Expand Down Expand Up @@ -1198,7 +1199,16 @@ type NetworkProtocolNumber uint32

// A StatCounter keeps track of a statistic.
type StatCounter struct {
count uint64
count [15]byte // instead of "count uint64"
}

// Reference code:
// https://go101.org/article/memory-layout.html
func (s *StatCounter) xAddr() *uint64 {
// The return must be 8-byte aligned.
return (*uint64)(unsafe.Pointer(
uintptr(unsafe.Pointer(&s.count)) + 8 -
uintptr(unsafe.Pointer(&s.count))%8))
}

// Increment adds one to the counter.
Expand All @@ -1213,12 +1223,12 @@ func (s *StatCounter) Decrement() {

// Value returns the current value of the counter.
func (s *StatCounter) Value() uint64 {
return atomic.LoadUint64(&s.count)
return atomic.LoadUint64(s.xAddr())
}

// IncrementBy increments the counter by v.
func (s *StatCounter) IncrementBy(v uint64) {
atomic.AddUint64(&s.count, v)
atomic.AddUint64(s.xAddr(), v)
}

func (s *StatCounter) String() string {
Expand Down

0 comments on commit 50e1e70

Please sign in to comment.