switch remaining sync/atomic to atomicbitops for 32 bit values

PiperOrigin-RevId: 443571047
This commit is contained in:
Kevin Krakauer
2022-04-21 22:27:05 -07:00
committed by gVisor bot
parent 9050184c20
commit 39790bd3a1
47 changed files with 264 additions and 261 deletions
+3
View File
@@ -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 (
+1
View File
@@ -15,6 +15,7 @@ go_library(
visibility = ["//visibility:public"],
deps = [
"//pkg/abi/linux",
"//pkg/atomicbitops",
"//pkg/log",
"//pkg/memutil",
"//pkg/sync",
+12 -12
View File
@@ -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)
+9 -10
View File
@@ -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
+5 -4
View File
@@ -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.
+3 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 clients 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
View File
@@ -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
View File
@@ -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()
+6 -6
View File
@@ -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()
}
}
+3 -4
View File
@@ -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:
+7 -7
View File
@@ -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)
+1 -2
View File
@@ -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)})
}
+4 -4
View File
@@ -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
}
+4 -5
View File
@@ -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
+10 -11
View File
@@ -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
}
+7 -7
View File
@@ -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