mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
switch remaining sync/atomic to atomicbitops for 32 bit values
PiperOrigin-RevId: 443571047
This commit is contained in:
committed by
gVisor bot
parent
9050184c20
commit
39790bd3a1
@@ -23,6 +23,9 @@
|
||||
// coverage surface. This causes bazel to use the Go cover tool manually to
|
||||
// generate instrumented files. It injects a hook that registers all coverage
|
||||
// data with the coverdata package.
|
||||
//
|
||||
// Using coverdata.Counters requires sync/atomic integers.
|
||||
// +checkalignedignore
|
||||
package coverage
|
||||
|
||||
import (
|
||||
|
||||
@@ -15,6 +15,7 @@ go_library(
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/abi/linux",
|
||||
"//pkg/atomicbitops",
|
||||
"//pkg/log",
|
||||
"//pkg/memutil",
|
||||
"//pkg/sync",
|
||||
|
||||
+12
-12
@@ -21,13 +21,13 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"sync/atomic"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/atomicbitops"
|
||||
"gvisor.dev/gvisor/pkg/log"
|
||||
)
|
||||
|
||||
type endpointControlImpl struct {
|
||||
state int32
|
||||
state atomicbitops.Int32
|
||||
}
|
||||
|
||||
// Bits in endpointControlImpl.state.
|
||||
@@ -54,7 +54,7 @@ func (ep *Endpoint) ctrlConnect() error {
|
||||
if err := json.NewEncoder(w).Encode(struct{}{}); err != nil {
|
||||
return fmt.Errorf("error writing connection request: %v", err)
|
||||
}
|
||||
*ep.dataLen() = w.Len()
|
||||
*ep.dataLen() = atomicbitops.FromUint32(w.Len())
|
||||
|
||||
// Exchange control with the server.
|
||||
if err := ep.futexSetPeerActive(); err != nil {
|
||||
@@ -69,7 +69,7 @@ func (ep *Endpoint) ctrlConnect() error {
|
||||
|
||||
// Read the connection response.
|
||||
var resp struct{}
|
||||
respLen := atomic.LoadUint32(ep.dataLen())
|
||||
respLen := ep.dataLen().Load()
|
||||
if respLen > ep.dataCap {
|
||||
return fmt.Errorf("invalid connection response length %d (maximum %d)", respLen, ep.dataCap)
|
||||
}
|
||||
@@ -92,7 +92,7 @@ func (ep *Endpoint) ctrlWaitFirst() error {
|
||||
}
|
||||
|
||||
// Read the connection request.
|
||||
reqLen := atomic.LoadUint32(ep.dataLen())
|
||||
reqLen := ep.dataLen().Load()
|
||||
if reqLen > ep.dataCap {
|
||||
return fmt.Errorf("invalid connection request length %d (maximum %d)", reqLen, ep.dataCap)
|
||||
}
|
||||
@@ -106,7 +106,7 @@ func (ep *Endpoint) ctrlWaitFirst() error {
|
||||
if err := json.NewEncoder(w).Encode(struct{}{}); err != nil {
|
||||
return fmt.Errorf("error writing connection response: %v", err)
|
||||
}
|
||||
*ep.dataLen() = w.Len()
|
||||
*ep.dataLen() = atomicbitops.FromUint32(w.Len())
|
||||
|
||||
// Return control to the client.
|
||||
raceBecomeInactive()
|
||||
@@ -147,11 +147,11 @@ func (ep *Endpoint) ctrlWakeLast() error {
|
||||
}
|
||||
|
||||
func (ep *Endpoint) enterFutexWait() error {
|
||||
switch eps := atomic.AddInt32(&ep.ctrl.state, epsBlocked); eps {
|
||||
switch eps := ep.ctrl.state.Add(epsBlocked); eps {
|
||||
case epsBlocked:
|
||||
return nil
|
||||
case epsBlocked | epsShutdown:
|
||||
atomic.AddInt32(&ep.ctrl.state, -epsBlocked)
|
||||
ep.ctrl.state.Add(-epsBlocked)
|
||||
return ShutdownError{}
|
||||
default:
|
||||
// Most likely due to ep.enterFutexWait() being called concurrently
|
||||
@@ -161,7 +161,7 @@ func (ep *Endpoint) enterFutexWait() error {
|
||||
}
|
||||
|
||||
func (ep *Endpoint) exitFutexWait() {
|
||||
switch eps := atomic.AddInt32(&ep.ctrl.state, -epsBlocked); eps {
|
||||
switch eps := ep.ctrl.state.Add(-epsBlocked); eps {
|
||||
case 0:
|
||||
return
|
||||
case epsShutdown:
|
||||
@@ -175,7 +175,7 @@ func (ep *Endpoint) exitFutexWait() {
|
||||
|
||||
func (ep *Endpoint) ctrlShutdown() {
|
||||
// Set epsShutdown to ensure that future calls to ep.enterFutexWait() fail.
|
||||
if atomic.AddInt32(&ep.ctrl.state, epsShutdown)&epsBlocked != 0 {
|
||||
if ep.ctrl.state.Add(epsShutdown)&epsBlocked != 0 {
|
||||
// Wake the blocked thread. This must loop because it's possible that
|
||||
// FUTEX_WAKE occurs after the waiter sets epsBlocked, but before it
|
||||
// blocks in FUTEX_WAIT.
|
||||
@@ -187,7 +187,7 @@ func (ep *Endpoint) ctrlShutdown() {
|
||||
break
|
||||
}
|
||||
yieldThread()
|
||||
if atomic.LoadInt32(&ep.ctrl.state)&epsBlocked == 0 {
|
||||
if ep.ctrl.state.Load()&epsBlocked == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -199,7 +199,7 @@ func (ep *Endpoint) ctrlShutdown() {
|
||||
}
|
||||
|
||||
func (ep *Endpoint) shutdownConn() {
|
||||
switch cs := atomic.SwapUint32(ep.connState(), csShutdown); cs {
|
||||
switch cs := ep.connState().Swap(csShutdown); cs {
|
||||
case ep.activeState:
|
||||
if err := ep.futexWakeConnState(1); err != nil {
|
||||
log.Warningf("failed to FUTEX_WAKE peer Endpoint for shutdown: %v", err)
|
||||
|
||||
@@ -19,9 +19,9 @@ package flipcall
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"sync/atomic"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
"gvisor.dev/gvisor/pkg/atomicbitops"
|
||||
"gvisor.dev/gvisor/pkg/memutil"
|
||||
)
|
||||
|
||||
@@ -53,9 +53,8 @@ type Endpoint struct {
|
||||
inactiveState uint32
|
||||
|
||||
// shutdown is non-zero if Endpoint.Shutdown() has been called, or if the
|
||||
// Endpoint has acknowledged shutdown initiated by the peer. shutdown is
|
||||
// accessed using atomic memory operations.
|
||||
shutdown uint32
|
||||
// Endpoint has acknowledged shutdown initiated by the peer.
|
||||
shutdown atomicbitops.Uint32
|
||||
|
||||
ctrl endpointControlImpl
|
||||
}
|
||||
@@ -144,7 +143,7 @@ func (ep *Endpoint) unmapPacket() {
|
||||
// Shutdown is the only Endpoint method that may be called concurrently with
|
||||
// other methods on the same Endpoint.
|
||||
func (ep *Endpoint) Shutdown() {
|
||||
if atomic.SwapUint32(&ep.shutdown, 1) != 0 {
|
||||
if ep.shutdown.Swap(1) != 0 {
|
||||
// ep.Shutdown() has previously been called.
|
||||
return
|
||||
}
|
||||
@@ -153,7 +152,7 @@ func (ep *Endpoint) Shutdown() {
|
||||
|
||||
// isShutdownLocally returns true if ep.Shutdown() has been called.
|
||||
func (ep *Endpoint) isShutdownLocally() bool {
|
||||
return atomic.LoadUint32(&ep.shutdown) != 0
|
||||
return ep.shutdown.Load() != 0
|
||||
}
|
||||
|
||||
// ShutdownError is returned by most Endpoint methods after Endpoint.Shutdown()
|
||||
@@ -204,7 +203,7 @@ func (ep *Endpoint) RecvFirst() (uint32, error) {
|
||||
return 0, err
|
||||
}
|
||||
raceBecomeActive()
|
||||
recvDataLen := atomic.LoadUint32(ep.dataLen())
|
||||
recvDataLen := ep.dataLen().Load()
|
||||
if recvDataLen > ep.dataCap {
|
||||
return 0, fmt.Errorf("received packet with invalid datagram length %d (maximum %d)", recvDataLen, ep.dataCap)
|
||||
}
|
||||
@@ -248,13 +247,13 @@ func (ep *Endpoint) sendRecv(dataLen uint32, mayRetainP bool) (uint32, error) {
|
||||
// synchronize with the receiver. We will not read from ep.dataLen() until
|
||||
// after ep.ctrlRoundTrip(), so if the peer is mutating it concurrently then
|
||||
// they can only shoot themselves in the foot.
|
||||
*ep.dataLen() = dataLen
|
||||
ep.dataLen().RacyStore(dataLen)
|
||||
raceBecomeInactive()
|
||||
if err := ep.ctrlRoundTrip(mayRetainP); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
raceBecomeActive()
|
||||
recvDataLen := atomic.LoadUint32(ep.dataLen())
|
||||
recvDataLen := ep.dataLen().Load()
|
||||
if recvDataLen > ep.dataCap {
|
||||
return 0, fmt.Errorf("received packet with invalid datagram length %d (maximum %d)", recvDataLen, ep.dataCap)
|
||||
}
|
||||
@@ -274,7 +273,7 @@ func (ep *Endpoint) SendLast(dataLen uint32) error {
|
||||
if dataLen > ep.dataCap {
|
||||
panic(fmt.Sprintf("attempting to send packet with datagram length %d (maximum %d)", dataLen, ep.dataCap))
|
||||
}
|
||||
*ep.dataLen() = dataLen
|
||||
ep.dataLen().RacyStore(dataLen)
|
||||
raceBecomeInactive()
|
||||
if err := ep.ctrlWakeLast(); err != nil {
|
||||
return err
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"reflect"
|
||||
"unsafe"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/atomicbitops"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
)
|
||||
|
||||
@@ -40,12 +41,12 @@ const (
|
||||
PacketHeaderBytes = 16
|
||||
)
|
||||
|
||||
func (ep *Endpoint) connState() *uint32 {
|
||||
return (*uint32)(unsafe.Pointer(ep.packet))
|
||||
func (ep *Endpoint) connState() *atomicbitops.Uint32 {
|
||||
return (*atomicbitops.Uint32)(unsafe.Pointer(ep.packet))
|
||||
}
|
||||
|
||||
func (ep *Endpoint) dataLen() *uint32 {
|
||||
return (*uint32)(unsafe.Pointer(ep.packet + 4))
|
||||
func (ep *Endpoint) dataLen() *atomicbitops.Uint32 {
|
||||
return (*atomicbitops.Uint32)(unsafe.Pointer(ep.packet + 4))
|
||||
}
|
||||
|
||||
// Data returns the datagram part of ep's packet window as a byte slice.
|
||||
|
||||
@@ -20,17 +20,16 @@ package flipcall
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"sync/atomic"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
)
|
||||
|
||||
func (ep *Endpoint) futexSetPeerActive() error {
|
||||
if atomic.CompareAndSwapUint32(ep.connState(), ep.activeState, ep.inactiveState) {
|
||||
if ep.connState().CompareAndSwap(ep.activeState, ep.inactiveState) {
|
||||
return nil
|
||||
}
|
||||
switch cs := atomic.LoadUint32(ep.connState()); cs {
|
||||
switch cs := ep.connState().Load(); cs {
|
||||
case csShutdown:
|
||||
return ShutdownError{}
|
||||
default:
|
||||
@@ -47,7 +46,7 @@ func (ep *Endpoint) futexWakePeer() error {
|
||||
|
||||
func (ep *Endpoint) futexWaitUntilActive() error {
|
||||
for {
|
||||
switch cs := atomic.LoadUint32(ep.connState()); cs {
|
||||
switch cs := ep.connState().Load(); cs {
|
||||
case ep.activeState:
|
||||
return nil
|
||||
case ep.inactiveState:
|
||||
|
||||
+4
-5
@@ -15,8 +15,7 @@
|
||||
package lisafs
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/atomicbitops"
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/fspath"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
@@ -69,7 +68,7 @@ type Node struct {
|
||||
// anymore. This node may have been replaced with something hazardous.
|
||||
// deleted is protected by opMu. deleted must only be accessed/mutated using
|
||||
// atomics; see markDeletedRecursive for more details.
|
||||
deleted uint32
|
||||
deleted atomicbitops.Uint32
|
||||
|
||||
// name is the name of the file represented by this Node in parent. If this
|
||||
// FD represents the root directory, then name is an empty string. name is
|
||||
@@ -185,7 +184,7 @@ func (n *Node) FilePath() string {
|
||||
}
|
||||
|
||||
func (n *Node) isDeleted() bool {
|
||||
return atomic.LoadUint32(&n.deleted) != 0
|
||||
return n.deleted.Load() != 0
|
||||
}
|
||||
|
||||
func (n *Node) removeFD(fd *ControlFD) {
|
||||
@@ -279,7 +278,7 @@ func (n *Node) forEachChild(fn func(*Node)) {
|
||||
// Precondition: opMu must be locked for writing on the root node being marked
|
||||
// as deleted.
|
||||
func (n *Node) markDeletedRecursive() {
|
||||
atomic.StoreUint32(&n.deleted, 1)
|
||||
n.deleted.Store(1)
|
||||
|
||||
// No need to hold opMu for children as it introduces lock ordering issues
|
||||
// because forEachChild locks childrenMu. Locking opMu after childrenMu
|
||||
|
||||
+8
-5
@@ -29,6 +29,8 @@
|
||||
// This is because the log.Debugf(...) statement alone will generate a
|
||||
// significant amount of garbage and churn in many cases, even if no log
|
||||
// message is ultimately emitted.
|
||||
//
|
||||
// +checkalignedignore
|
||||
package log
|
||||
|
||||
import (
|
||||
@@ -92,7 +94,8 @@ type Writer struct {
|
||||
// errors counts failures to write log messages so it can be reported
|
||||
// when writer start to work again. Needs to be accessed using atomics
|
||||
// to make race detector happy because it's read outside the mutex.
|
||||
errors int32
|
||||
// +checklocks
|
||||
atomicErrors int32
|
||||
}
|
||||
|
||||
// Write writes out the given bytes, handling non-blocking sockets.
|
||||
@@ -112,7 +115,7 @@ func (l *Writer) Write(data []byte) (int, error) {
|
||||
// Some other error?
|
||||
if err != nil {
|
||||
l.mu.Lock()
|
||||
atomic.AddInt32(&l.errors, 1)
|
||||
atomic.AddInt32(&l.atomicErrors, 1)
|
||||
l.mu.Unlock()
|
||||
return n, err
|
||||
}
|
||||
@@ -124,15 +127,15 @@ func (l *Writer) Write(data []byte) (int, error) {
|
||||
}
|
||||
|
||||
// Dirty read in case there were errors (rare).
|
||||
if atomic.LoadInt32(&l.errors) > 0 {
|
||||
if atomic.LoadInt32(&l.atomicErrors) > 0 {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
|
||||
// Recheck condition under lock.
|
||||
if e := atomic.LoadInt32(&l.errors); e > 0 {
|
||||
if e := atomic.LoadInt32(&l.atomicErrors); e > 0 {
|
||||
msg := fmt.Sprintf("\n*** Dropped %d log messages ***\n", e)
|
||||
if _, err := l.Next.Write([]byte(msg)); err == nil {
|
||||
atomic.StoreInt32(&l.errors, 0)
|
||||
atomic.StoreInt32(&l.atomicErrors, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+33
-33
@@ -18,9 +18,9 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"sync/atomic"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
"gvisor.dev/gvisor/pkg/atomicbitops"
|
||||
"gvisor.dev/gvisor/pkg/fd"
|
||||
"gvisor.dev/gvisor/pkg/log"
|
||||
)
|
||||
@@ -64,12 +64,12 @@ type clientFile struct {
|
||||
fid FID
|
||||
|
||||
// closed indicates whether this file has been closed.
|
||||
closed uint32
|
||||
closed atomicbitops.Uint32
|
||||
}
|
||||
|
||||
// Walk implements File.Walk.
|
||||
func (c *clientFile) Walk(names []string) ([]QID, File, error) {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return nil, nil, unix.EBADF
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ func (c *clientFile) Walk(names []string) ([]QID, File, error) {
|
||||
|
||||
// WalkGetAttr implements File.WalkGetAttr.
|
||||
func (c *clientFile) WalkGetAttr(components []string) ([]QID, File, AttrMask, Attr, error) {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return nil, nil, AttrMask{}, Attr{}, unix.EBADF
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ func (c *clientFile) WalkGetAttr(components []string) ([]QID, File, AttrMask, At
|
||||
}
|
||||
|
||||
func (c *clientFile) MultiGetAttr(names []string) ([]FullStat, error) {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return nil, unix.EBADF
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ func (c *clientFile) MultiGetAttr(names []string) ([]FullStat, error) {
|
||||
|
||||
// StatFS implements File.StatFS.
|
||||
func (c *clientFile) StatFS() (FSStat, error) {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return FSStat{}, unix.EBADF
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ func (c *clientFile) StatFS() (FSStat, error) {
|
||||
|
||||
// FSync implements File.FSync.
|
||||
func (c *clientFile) FSync() error {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return unix.EBADF
|
||||
}
|
||||
|
||||
@@ -206,7 +206,7 @@ func (c *clientFile) FSync() error {
|
||||
|
||||
// GetAttr implements File.GetAttr.
|
||||
func (c *clientFile) GetAttr(req AttrMask) (QID, AttrMask, Attr, error) {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return QID{}, AttrMask{}, Attr{}, unix.EBADF
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ func (c *clientFile) GetAttr(req AttrMask) (QID, AttrMask, Attr, error) {
|
||||
|
||||
// SetAttr implements File.SetAttr.
|
||||
func (c *clientFile) SetAttr(valid SetAttrMask, attr SetAttr) error {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return unix.EBADF
|
||||
}
|
||||
|
||||
@@ -229,7 +229,7 @@ func (c *clientFile) SetAttr(valid SetAttrMask, attr SetAttr) error {
|
||||
|
||||
// GetXattr implements File.GetXattr.
|
||||
func (c *clientFile) GetXattr(name string, size uint64) (string, error) {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return "", unix.EBADF
|
||||
}
|
||||
if !versionSupportsGetSetXattr(c.client.version) {
|
||||
@@ -246,7 +246,7 @@ func (c *clientFile) GetXattr(name string, size uint64) (string, error) {
|
||||
|
||||
// SetXattr implements File.SetXattr.
|
||||
func (c *clientFile) SetXattr(name, value string, flags uint32) error {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return unix.EBADF
|
||||
}
|
||||
if !versionSupportsGetSetXattr(c.client.version) {
|
||||
@@ -258,7 +258,7 @@ func (c *clientFile) SetXattr(name, value string, flags uint32) error {
|
||||
|
||||
// ListXattr implements File.ListXattr.
|
||||
func (c *clientFile) ListXattr(size uint64) (map[string]struct{}, error) {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return nil, unix.EBADF
|
||||
}
|
||||
if !versionSupportsListRemoveXattr(c.client.version) {
|
||||
@@ -279,7 +279,7 @@ func (c *clientFile) ListXattr(size uint64) (map[string]struct{}, error) {
|
||||
|
||||
// RemoveXattr implements File.RemoveXattr.
|
||||
func (c *clientFile) RemoveXattr(name string) error {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return unix.EBADF
|
||||
}
|
||||
if !versionSupportsListRemoveXattr(c.client.version) {
|
||||
@@ -291,7 +291,7 @@ func (c *clientFile) RemoveXattr(name string) error {
|
||||
|
||||
// Allocate implements File.Allocate.
|
||||
func (c *clientFile) Allocate(mode AllocateMode, offset, length uint64) error {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return unix.EBADF
|
||||
}
|
||||
if !versionSupportsTallocate(c.client.version) {
|
||||
@@ -307,7 +307,7 @@ func (c *clientFile) Allocate(mode AllocateMode, offset, length uint64) error {
|
||||
// considered deprecated.
|
||||
func (c *clientFile) Remove() error {
|
||||
// Avoid double close.
|
||||
if !atomic.CompareAndSwapUint32(&c.closed, 0, 1) {
|
||||
if !c.closed.CompareAndSwap(0, 1) {
|
||||
return unix.EBADF
|
||||
}
|
||||
|
||||
@@ -328,7 +328,7 @@ func (c *clientFile) Remove() error {
|
||||
// Close implements File.Close.
|
||||
func (c *clientFile) Close() error {
|
||||
// Avoid double close.
|
||||
if !atomic.CompareAndSwapUint32(&c.closed, 0, 1) {
|
||||
if !c.closed.CompareAndSwap(0, 1) {
|
||||
return unix.EBADF
|
||||
}
|
||||
|
||||
@@ -361,7 +361,7 @@ func (c *clientFile) SetAttrClose(valid SetAttrMask, attr SetAttr) error {
|
||||
}
|
||||
|
||||
// Avoid double close.
|
||||
if !atomic.CompareAndSwapUint32(&c.closed, 0, 1) {
|
||||
if !c.closed.CompareAndSwap(0, 1) {
|
||||
return unix.EBADF
|
||||
}
|
||||
|
||||
@@ -380,7 +380,7 @@ func (c *clientFile) SetAttrClose(valid SetAttrMask, attr SetAttr) error {
|
||||
|
||||
// Open implements File.Open.
|
||||
func (c *clientFile) Open(flags OpenFlags) (*fd.FD, QID, uint32, error) {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return nil, QID{}, 0, unix.EBADF
|
||||
}
|
||||
|
||||
@@ -393,7 +393,7 @@ func (c *clientFile) Open(flags OpenFlags) (*fd.FD, QID, uint32, error) {
|
||||
}
|
||||
|
||||
func (c *clientFile) Bind(sockType uint32, sockName string, uid UID, gid GID) (File, QID, AttrMask, Attr, error) {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return nil, QID{}, AttrMask{}, Attr{}, unix.EBADF
|
||||
}
|
||||
|
||||
@@ -425,7 +425,7 @@ func (c *clientFile) Bind(sockType uint32, sockName string, uid UID, gid GID) (F
|
||||
|
||||
// Connect implements File.Connect.
|
||||
func (c *clientFile) Connect(socketType SocketType) (*fd.FD, error) {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return nil, unix.EBADF
|
||||
}
|
||||
|
||||
@@ -494,7 +494,7 @@ func (c *clientFile) ReadAt(p []byte, offset uint64) (int, error) {
|
||||
}
|
||||
|
||||
func (c *clientFile) readAt(p []byte, offset uint64) (int, error) {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return 0, unix.EBADF
|
||||
}
|
||||
|
||||
@@ -525,7 +525,7 @@ func (c *clientFile) WriteAt(p []byte, offset uint64) (int, error) {
|
||||
}
|
||||
|
||||
func (c *clientFile) writeAt(p []byte, offset uint64) (int, error) {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return 0, unix.EBADF
|
||||
}
|
||||
|
||||
@@ -590,7 +590,7 @@ func (r *ReadWriterFile) WriteAt(p []byte, offset int64) (int, error) {
|
||||
|
||||
// Rename implements File.Rename.
|
||||
func (c *clientFile) Rename(dir File, name string) error {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return unix.EBADF
|
||||
}
|
||||
|
||||
@@ -604,7 +604,7 @@ func (c *clientFile) Rename(dir File, name string) error {
|
||||
|
||||
// Create implements File.Create.
|
||||
func (c *clientFile) Create(name string, openFlags OpenFlags, permissions FileMode, uid UID, gid GID) (*fd.FD, File, QID, uint32, error) {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return nil, nil, QID{}, 0, unix.EBADF
|
||||
}
|
||||
|
||||
@@ -635,7 +635,7 @@ func (c *clientFile) Create(name string, openFlags OpenFlags, permissions FileMo
|
||||
|
||||
// Mkdir implements File.Mkdir.
|
||||
func (c *clientFile) Mkdir(name string, permissions FileMode, uid UID, gid GID) (QID, error) {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return QID{}, unix.EBADF
|
||||
}
|
||||
|
||||
@@ -665,7 +665,7 @@ func (c *clientFile) Mkdir(name string, permissions FileMode, uid UID, gid GID)
|
||||
|
||||
// Symlink implements File.Symlink.
|
||||
func (c *clientFile) Symlink(oldname string, newname string, uid UID, gid GID) (QID, error) {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return QID{}, unix.EBADF
|
||||
}
|
||||
|
||||
@@ -695,7 +695,7 @@ func (c *clientFile) Symlink(oldname string, newname string, uid UID, gid GID) (
|
||||
|
||||
// Link implements File.Link.
|
||||
func (c *clientFile) Link(target File, newname string) error {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return unix.EBADF
|
||||
}
|
||||
|
||||
@@ -709,7 +709,7 @@ func (c *clientFile) Link(target File, newname string) error {
|
||||
|
||||
// Mknod implements File.Mknod.
|
||||
func (c *clientFile) Mknod(name string, mode FileMode, major uint32, minor uint32, uid UID, gid GID) (QID, error) {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return QID{}, unix.EBADF
|
||||
}
|
||||
|
||||
@@ -741,7 +741,7 @@ func (c *clientFile) Mknod(name string, mode FileMode, major uint32, minor uint3
|
||||
|
||||
// RenameAt implements File.RenameAt.
|
||||
func (c *clientFile) RenameAt(oldname string, newdir File, newname string) error {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return unix.EBADF
|
||||
}
|
||||
|
||||
@@ -755,7 +755,7 @@ func (c *clientFile) RenameAt(oldname string, newdir File, newname string) error
|
||||
|
||||
// UnlinkAt implements File.UnlinkAt.
|
||||
func (c *clientFile) UnlinkAt(name string, flags uint32) error {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return unix.EBADF
|
||||
}
|
||||
|
||||
@@ -764,7 +764,7 @@ func (c *clientFile) UnlinkAt(name string, flags uint32) error {
|
||||
|
||||
// Readdir implements File.Readdir.
|
||||
func (c *clientFile) Readdir(offset uint64, count uint32) ([]Dirent, error) {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return nil, unix.EBADF
|
||||
}
|
||||
|
||||
@@ -778,7 +778,7 @@ func (c *clientFile) Readdir(offset uint64, count uint32) ([]Dirent, error) {
|
||||
|
||||
// Readlink implements File.Readlink.
|
||||
func (c *clientFile) Readlink() (string, error) {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return "", unix.EBADF
|
||||
}
|
||||
|
||||
@@ -792,7 +792,7 @@ func (c *clientFile) Readlink() (string, error) {
|
||||
|
||||
// Flush implements File.Flush.
|
||||
func (c *clientFile) Flush() error {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
if c.closed.Load() != 0 {
|
||||
return unix.EBADF
|
||||
}
|
||||
|
||||
|
||||
+3
-4
@@ -21,7 +21,6 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
"gvisor.dev/gvisor/pkg/atomicbitops"
|
||||
@@ -127,7 +126,7 @@ func (t *Tversion) handle(cs *connState) message {
|
||||
if t.MSize > maximumLength {
|
||||
return newErr(unix.EINVAL)
|
||||
}
|
||||
atomic.StoreUint32(&cs.messageSize, t.MSize)
|
||||
cs.messageSize.Store(t.MSize)
|
||||
requested, ok := parseVersion(t.Version)
|
||||
if !ok {
|
||||
return newErr(unix.EINVAL)
|
||||
@@ -139,7 +138,7 @@ func (t *Tversion) handle(cs *connState) message {
|
||||
}
|
||||
// From Tversion(9P): "The server may respond with the client’s version
|
||||
// string, or a version string identifying an earlier defined protocol version".
|
||||
atomic.StoreUint32(&cs.version, requested)
|
||||
cs.version.Store(requested)
|
||||
return &Rversion{
|
||||
MSize: t.MSize,
|
||||
Version: t.Version,
|
||||
@@ -1583,7 +1582,7 @@ func (t *Tmultigetattr) handle(cs *connState) message {
|
||||
}
|
||||
|
||||
parentNode.opMu.RLock()
|
||||
if atomic.LoadUint32(&parentNode.deleted) != 0 {
|
||||
if parentNode.deleted.Load() != 0 {
|
||||
parentNode.opMu.RUnlock()
|
||||
break
|
||||
}
|
||||
|
||||
+2
-1
@@ -17,6 +17,7 @@ package p9
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/atomicbitops"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
)
|
||||
|
||||
@@ -40,7 +41,7 @@ type pathNode struct {
|
||||
// already been unlinked. deleted is protected by opMu. However, it may be
|
||||
// changed without opMu if this node is deleted as part of an entire subtree
|
||||
// on unlink. So deleted must only be accessed/mutated using atomics.
|
||||
deleted uint32
|
||||
deleted atomicbitops.Uint32
|
||||
|
||||
// childMu protects the fields below.
|
||||
childMu sync.RWMutex
|
||||
|
||||
+10
-12
@@ -17,7 +17,6 @@ package p9
|
||||
import (
|
||||
"io"
|
||||
"runtime/debug"
|
||||
"sync/atomic"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
"gvisor.dev/gvisor/pkg/atomicbitops"
|
||||
@@ -84,11 +83,11 @@ type connState struct {
|
||||
|
||||
// messageSize is the maximum message size. The server does not
|
||||
// do automatic splitting of messages.
|
||||
messageSize uint32
|
||||
messageSize atomicbitops.Uint32
|
||||
|
||||
// version is the agreed upon version X of 9P2000.L.Google.X.
|
||||
// version 0 implies 9P2000.L.
|
||||
version uint32
|
||||
version atomicbitops.Uint32
|
||||
|
||||
// reqGate counts requests that are still being handled.
|
||||
reqGate sync.Gate
|
||||
@@ -99,9 +98,8 @@ type connState struct {
|
||||
recvMu sync.Mutex
|
||||
|
||||
// recvIdle is the number of goroutines in handleRequests() attempting to
|
||||
// lock recvMu so that they can receive from conn. recvIdle is accessed
|
||||
// using atomic memory operations.
|
||||
recvIdle int32
|
||||
// lock recvMu so that they can receive from conn.
|
||||
recvIdle atomicbitops.Int32
|
||||
|
||||
// If recvShutdown is true, at least one goroutine has observed a
|
||||
// connection error while receiving from conn, and all goroutines in
|
||||
@@ -225,7 +223,7 @@ func (f *fidRef) TryIncRef() bool {
|
||||
// Precondition: this must be called via safelyRead, safelyWrite or
|
||||
// safelyGlobal.
|
||||
func (f *fidRef) isDeleted() bool {
|
||||
return atomic.LoadUint32(&f.pathNode.deleted) != 0
|
||||
return f.pathNode.deleted.Load() != 0
|
||||
}
|
||||
|
||||
// isRoot indicates whether this is a root fid.
|
||||
@@ -245,7 +243,7 @@ func (f *fidRef) maybeParent() *fidRef {
|
||||
//
|
||||
// Precondition: this must be called via safelyWrite or safelyGlobal.
|
||||
func notifyDelete(pn *pathNode) {
|
||||
atomic.StoreUint32(&pn.deleted, 1)
|
||||
pn.deleted.Store(1)
|
||||
|
||||
// Call on all subtrees.
|
||||
pn.forEachChildNode(func(pn *pathNode) {
|
||||
@@ -537,9 +535,9 @@ func (cs *connState) handle(m message) (r message) {
|
||||
// continue handling requests and false if it should terminate.
|
||||
func (cs *connState) handleRequest() bool {
|
||||
// Obtain the right to receive a message from cs.conn.
|
||||
atomic.AddInt32(&cs.recvIdle, 1)
|
||||
cs.recvIdle.Add(1)
|
||||
cs.recvMu.Lock()
|
||||
atomic.AddInt32(&cs.recvIdle, -1)
|
||||
cs.recvIdle.Add(-1)
|
||||
|
||||
if cs.recvShutdown {
|
||||
// Another goroutine already detected a connection problem; exit
|
||||
@@ -548,7 +546,7 @@ func (cs *connState) handleRequest() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
messageSize := atomic.LoadUint32(&cs.messageSize)
|
||||
messageSize := cs.messageSize.Load()
|
||||
if messageSize == 0 {
|
||||
// Default or not yet negotiated.
|
||||
messageSize = maximumLength
|
||||
@@ -565,7 +563,7 @@ func (cs *connState) handleRequest() bool {
|
||||
}
|
||||
|
||||
// Ensure that another goroutine is available to receive from cs.conn.
|
||||
if atomic.LoadInt32(&cs.recvIdle) == 0 {
|
||||
if cs.recvIdle.Load() == 0 {
|
||||
go cs.handleRequests() // S/R-SAFE: Irrelevant.
|
||||
}
|
||||
cs.recvMu.Unlock()
|
||||
|
||||
@@ -289,16 +289,16 @@ func (l LeakMode) String() string {
|
||||
// Values must be one of the LeakMode values.
|
||||
//
|
||||
// leakMode must be accessed atomically.
|
||||
var leakMode uint32
|
||||
var leakMode atomicbitops.Uint32
|
||||
|
||||
// SetLeakMode configures the reference leak checker.
|
||||
func SetLeakMode(mode LeakMode) {
|
||||
atomic.StoreUint32(&leakMode, uint32(mode))
|
||||
leakMode.Store(uint32(mode))
|
||||
}
|
||||
|
||||
// GetLeakMode returns the current leak mode.
|
||||
func GetLeakMode() LeakMode {
|
||||
return LeakMode(atomic.LoadUint32(&leakMode))
|
||||
return LeakMode(leakMode.Load())
|
||||
}
|
||||
|
||||
const maxStackFrames = 40
|
||||
@@ -375,7 +375,7 @@ func FormatStack(pcs []uintptr) string {
|
||||
|
||||
func (r *AtomicRefCount) finalize() {
|
||||
var note string
|
||||
switch LeakMode(atomic.LoadUint32(&leakMode)) {
|
||||
switch LeakMode(leakMode.Load()) {
|
||||
case NoLeakChecking:
|
||||
return
|
||||
case UninitializedLeakChecking:
|
||||
@@ -405,7 +405,7 @@ func (r *AtomicRefCount) EnableLeakCheck(name string) {
|
||||
if name == "" {
|
||||
panic("invalid name")
|
||||
}
|
||||
switch LeakMode(atomic.LoadUint32(&leakMode)) {
|
||||
switch LeakMode(leakMode.Load()) {
|
||||
case NoLeakChecking:
|
||||
return
|
||||
case LeaksLogTraces:
|
||||
@@ -533,7 +533,7 @@ func (r *AtomicRefCount) DecRef(ctx context.Context) {
|
||||
// finalizer will run before exiting, but this at least ensures that they will
|
||||
// be discovered/enqueued by GC.
|
||||
func OnExit() {
|
||||
if LeakMode(atomic.LoadUint32(&leakMode)) != NoLeakChecking {
|
||||
if LeakMode(leakMode.Load()) != NoLeakChecking {
|
||||
runtime.GC()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ package contexttest
|
||||
|
||||
import (
|
||||
"os"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -88,8 +87,8 @@ func (*globalUniqueIDProvider) UniqueID() uint64 {
|
||||
}
|
||||
|
||||
// lastInotifyCookie is a monotonically increasing counter for generating unique
|
||||
// inotify cookies. Must be accessed using atomic ops.
|
||||
var lastInotifyCookie uint32
|
||||
// inotify cookies.
|
||||
var lastInotifyCookie atomicbitops.Uint32
|
||||
|
||||
// hostClock implements ktime.Clock.
|
||||
type hostClock struct {
|
||||
@@ -126,7 +125,7 @@ func (t *TestContext) Value(key interface{}) interface{} {
|
||||
case uniqueid.CtxGlobalUniqueIDProvider:
|
||||
return &globalUniqueIDProvider{}
|
||||
case uniqueid.CtxInotifyCookie:
|
||||
return atomic.AddUint32(&lastInotifyCookie, 1)
|
||||
return lastInotifyCookie.Add(1)
|
||||
case ktime.CtxRealtimeClock:
|
||||
return &hostClock{}
|
||||
default:
|
||||
|
||||
@@ -17,10 +17,10 @@ package fs
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"sync/atomic"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/atomicbitops"
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/errors/linuxerr"
|
||||
"gvisor.dev/gvisor/pkg/refs"
|
||||
@@ -118,7 +118,7 @@ type Dirent struct {
|
||||
parent *Dirent
|
||||
|
||||
// deleted may be set atomically when removed.
|
||||
deleted int32
|
||||
deleted atomicbitops.Int32
|
||||
|
||||
// mounted is true if Dirent is a mount point, similar to include/linux/dcache.h:DCACHE_MOUNTED.
|
||||
mounted bool
|
||||
@@ -373,7 +373,7 @@ func (d *Dirent) fullName(root *Dirent) (string, bool) {
|
||||
d.parent.mu.Unlock()
|
||||
parentName, reachable := d.parent.fullName(root)
|
||||
s := path.Join(parentName, name)
|
||||
if atomic.LoadInt32(&d.deleted) != 0 {
|
||||
if d.deleted.Load() != 0 {
|
||||
return s + " (deleted)", reachable
|
||||
}
|
||||
return s, reachable
|
||||
@@ -961,7 +961,7 @@ func (d *Dirent) isMountPointLocked() bool {
|
||||
// Precondition: must be called with mm.withMountLocked held on `d`.
|
||||
func (d *Dirent) mount(ctx context.Context, inode *Inode) (newChild *Dirent, err error) {
|
||||
// Did we race with deletion?
|
||||
if atomic.LoadInt32(&d.deleted) != 0 {
|
||||
if d.deleted.Load() != 0 {
|
||||
return nil, linuxerr.ENOENT
|
||||
}
|
||||
|
||||
@@ -996,7 +996,7 @@ func (d *Dirent) mount(ctx context.Context, inode *Inode) (newChild *Dirent, err
|
||||
// Precondition: must be called with mm.withMountLocked held on `d`.
|
||||
func (d *Dirent) unmount(ctx context.Context, replacement *Dirent) error {
|
||||
// Did we race with deletion?
|
||||
if atomic.LoadInt32(&d.deleted) != 0 {
|
||||
if d.deleted.Load() != 0 {
|
||||
return linuxerr.ENOENT
|
||||
}
|
||||
|
||||
@@ -1058,7 +1058,7 @@ func (d *Dirent) Remove(ctx context.Context, root *Dirent, name string, dirPath
|
||||
child.Inode.Watches.Notify("", linux.IN_ATTRIB, 0)
|
||||
|
||||
// Mark name as deleted and remove from children.
|
||||
atomic.StoreInt32(&child.deleted, 1)
|
||||
child.deleted.Store(1)
|
||||
if w, ok := d.children[name]; ok {
|
||||
delete(d.children, name)
|
||||
w.Drop(ctx)
|
||||
@@ -1124,7 +1124,7 @@ func (d *Dirent) RemoveDirectory(ctx context.Context, root *Dirent, name string)
|
||||
}
|
||||
|
||||
// Mark name as deleted and remove from children.
|
||||
atomic.StoreInt32(&child.deleted, 1)
|
||||
child.deleted.Store(1)
|
||||
if w, ok := d.children[name]; ok {
|
||||
delete(d.children, name)
|
||||
w.Drop(ctx)
|
||||
|
||||
@@ -16,7 +16,6 @@ package fs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/refs"
|
||||
@@ -37,7 +36,7 @@ func (d *Dirent) beforeSave() {
|
||||
// perfectly OK to save---we are simply disallowing it here to prevent
|
||||
// generating non-restorable state dumps. As the program continues its
|
||||
// execution, it may become allowed to save again.
|
||||
if !d.Inode.IsVirtual() && atomic.LoadInt32(&d.deleted) != 0 {
|
||||
if !d.Inode.IsVirtual() && d.deleted.Load() != 0 {
|
||||
n, _ := d.FullName(nil /* root */)
|
||||
panic(ErrSaveRejection{fmt.Errorf("deleted file %q still has open fds", n)})
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@ package fs
|
||||
|
||||
import (
|
||||
"io"
|
||||
"sync/atomic"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/atomicbitops"
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/errors/linuxerr"
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
@@ -258,7 +258,7 @@ func (i *Inotify) newWatchLocked(target *Dirent, mask uint32) *Watch {
|
||||
watch := &Watch{
|
||||
owner: i,
|
||||
wd: wd,
|
||||
mask: mask,
|
||||
mask: atomicbitops.FromUint32(mask),
|
||||
target: target.Inode,
|
||||
pins: make(map[*Dirent]bool),
|
||||
}
|
||||
@@ -307,9 +307,9 @@ func (i *Inotify) AddWatch(target *Dirent, mask uint32) int32 {
|
||||
if mergeMask := mask&linux.IN_MASK_ADD != 0; mergeMask {
|
||||
// "Add (OR) events to watch mask for this pathname if it already
|
||||
// exists (instead of replacing mask)." -- inotify(7)
|
||||
newmask |= atomic.LoadUint32(&existing.mask)
|
||||
newmask |= existing.mask.Load()
|
||||
}
|
||||
atomic.StoreUint32(&existing.mask, newmask)
|
||||
existing.mask.Store(newmask)
|
||||
return existing.wd
|
||||
}
|
||||
|
||||
|
||||
@@ -15,9 +15,8 @@
|
||||
package fs
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/atomicbitops"
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
)
|
||||
@@ -51,7 +50,7 @@ type Watch struct {
|
||||
|
||||
// Events being monitored via this watch. Must be accessed atomically,
|
||||
// writes are protected by mu.
|
||||
mask uint32
|
||||
mask atomicbitops.Uint32
|
||||
|
||||
// pins is the set of dirents this watch is currently pinning in memory by
|
||||
// holding a reference to them. See Pin()/Unpin().
|
||||
@@ -67,7 +66,7 @@ func (w *Watch) ID() uint64 {
|
||||
// should continue to be be notified of events after the target has been
|
||||
// unlinked.
|
||||
func (w *Watch) NotifyParentAfterUnlink() bool {
|
||||
return atomic.LoadUint32(&w.mask)&linux.IN_EXCL_UNLINK == 0
|
||||
return w.mask.Load()&linux.IN_EXCL_UNLINK == 0
|
||||
}
|
||||
|
||||
// isRenameEvent returns true if eventMask describes a rename event.
|
||||
@@ -77,7 +76,7 @@ func isRenameEvent(eventMask uint32) bool {
|
||||
|
||||
// Notify queues a new event on this watch.
|
||||
func (w *Watch) Notify(name string, events uint32, cookie uint32) {
|
||||
mask := atomic.LoadUint32(&w.mask)
|
||||
mask := w.mask.Load()
|
||||
if mask&events == 0 {
|
||||
// We weren't watching for this event.
|
||||
return
|
||||
|
||||
@@ -16,7 +16,6 @@ package mm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
@@ -27,7 +26,7 @@ import (
|
||||
//
|
||||
// Preconditions: The caller must have called mm.Activate().
|
||||
func (mm *MemoryManager) AddressSpace() platform.AddressSpace {
|
||||
if atomic.LoadInt32(&mm.active) == 0 {
|
||||
if mm.active.Load() == 0 {
|
||||
panic("trying to use inactive address space?")
|
||||
}
|
||||
return mm.as
|
||||
@@ -43,12 +42,12 @@ func (mm *MemoryManager) Activate(ctx context.Context) error {
|
||||
// Fast path: the MemoryManager already has an active
|
||||
// platform.AddressSpace, and we just need to indicate that we need it too.
|
||||
for {
|
||||
active := atomic.LoadInt32(&mm.active)
|
||||
active := mm.active.Load()
|
||||
if active == 0 {
|
||||
// Fall back to the slow path.
|
||||
break
|
||||
}
|
||||
if atomic.CompareAndSwapInt32(&mm.active, active, active+1) {
|
||||
if mm.active.CompareAndSwap(active, active+1) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -61,10 +60,10 @@ func (mm *MemoryManager) Activate(ctx context.Context) error {
|
||||
// method is commonly in the hot-path.
|
||||
|
||||
// Check if we raced with another goroutine performing activation.
|
||||
if atomic.LoadInt32(&mm.active) > 0 {
|
||||
if mm.active.Load() > 0 {
|
||||
// This can't race; Deactivate can't decrease mm.active from 1 to 0
|
||||
// without holding activeMu.
|
||||
atomic.AddInt32(&mm.active, 1)
|
||||
mm.active.Add(1)
|
||||
mm.activeMu.Unlock()
|
||||
return nil
|
||||
}
|
||||
@@ -72,7 +71,7 @@ func (mm *MemoryManager) Activate(ctx context.Context) error {
|
||||
// Do we have a context? If so, then we never unmapped it. This can
|
||||
// only be the case if !mm.p.CooperativelySchedulesAddressSpace().
|
||||
if mm.as != nil {
|
||||
atomic.StoreInt32(&mm.active, 1)
|
||||
mm.active.Store(1)
|
||||
mm.activeMu.Unlock()
|
||||
return nil
|
||||
}
|
||||
@@ -118,7 +117,7 @@ func (mm *MemoryManager) Activate(ctx context.Context) error {
|
||||
|
||||
// Now that m.as has been assigned, we can set m.active to a non-zero value
|
||||
// to enable the fast path.
|
||||
atomic.StoreInt32(&mm.active, 1)
|
||||
mm.active.Store(1)
|
||||
|
||||
mm.activeMu.Unlock()
|
||||
return nil
|
||||
@@ -130,12 +129,12 @@ func (mm *MemoryManager) Deactivate() {
|
||||
// Fast path: this is not the last goroutine to deactivate the
|
||||
// MemoryManager.
|
||||
for {
|
||||
active := atomic.LoadInt32(&mm.active)
|
||||
active := mm.active.Load()
|
||||
if active == 1 {
|
||||
// Fall back to the slow path.
|
||||
break
|
||||
}
|
||||
if atomic.CompareAndSwapInt32(&mm.active, active, active-1) {
|
||||
if mm.active.CompareAndSwap(active, active-1) {
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -144,7 +143,7 @@ func (mm *MemoryManager) Deactivate() {
|
||||
// Same as Activate.
|
||||
|
||||
// Still active?
|
||||
if atomic.AddInt32(&mm.active, -1) > 0 {
|
||||
if mm.active.Add(-1) > 0 {
|
||||
mm.activeMu.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@ package mm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/atomicbitops"
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
"gvisor.dev/gvisor/pkg/sentry/arch"
|
||||
@@ -34,7 +34,7 @@ func NewMemoryManager(p platform.Platform, mfp pgalloc.MemoryFileProvider, sleep
|
||||
mfp: mfp,
|
||||
haveASIO: p.SupportsAddressSpaceIO(),
|
||||
privateRefs: &privateRefs{},
|
||||
users: 1,
|
||||
users: atomicbitops.FromInt32(1),
|
||||
auxv: arch.Auxv{},
|
||||
dumpability: UserDumpable,
|
||||
aioManager: aioManager{contexts: make(map[uint64]*AIOContext)},
|
||||
@@ -78,7 +78,7 @@ func (mm *MemoryManager) Fork(ctx context.Context) (*MemoryManager, error) {
|
||||
haveASIO: mm.haveASIO,
|
||||
layout: mm.layout,
|
||||
privateRefs: mm.privateRefs,
|
||||
users: 1,
|
||||
users: atomicbitops.FromInt32(1),
|
||||
brk: mm.brk,
|
||||
usageAS: mm.usageAS,
|
||||
dataAS: mm.dataAS,
|
||||
@@ -243,11 +243,11 @@ func (mm *MemoryManager) Fork(ctx context.Context) (*MemoryManager, error) {
|
||||
// already 0, IncUsers does nothing and returns false.
|
||||
func (mm *MemoryManager) IncUsers() bool {
|
||||
for {
|
||||
users := atomic.LoadInt32(&mm.users)
|
||||
users := mm.users.Load()
|
||||
if users == 0 {
|
||||
return false
|
||||
}
|
||||
if atomic.CompareAndSwapInt32(&mm.users, users, users+1) {
|
||||
if mm.users.CompareAndSwap(users, users+1) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -256,7 +256,7 @@ func (mm *MemoryManager) IncUsers() bool {
|
||||
// DecUsers decrements mm's user count. If the user count reaches 0, all
|
||||
// mappings in mm are unmapped.
|
||||
func (mm *MemoryManager) DecUsers(ctx context.Context) {
|
||||
if users := atomic.AddInt32(&mm.users, -1); users > 0 {
|
||||
if users := mm.users.Add(-1); users > 0 {
|
||||
return
|
||||
} else if users < 0 {
|
||||
panic(fmt.Sprintf("Invalid MemoryManager.users: %d", users))
|
||||
@@ -274,7 +274,7 @@ func (mm *MemoryManager) DecUsers(ctx context.Context) {
|
||||
|
||||
mm.activeMu.Lock()
|
||||
// Sanity check.
|
||||
if atomic.LoadInt32(&mm.active) != 0 {
|
||||
if mm.active.Load() != 0 {
|
||||
panic("active address space lost?")
|
||||
}
|
||||
// Make sure the AddressSpace is returned.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user