github.com/ttpreport/gvisor-ligolo@v0.0.0-20240123134145-a858404967ba/pkg/atomicbitops/32b_32bit.go (about)

     1  // Copyright 2022 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  //go:build arm || mips || mipsle || 386
    16  // +build arm mips mipsle 386
    17  
    18  package atomicbitops
    19  
    20  import (
    21  	"sync/atomic"
    22  
    23  	"github.com/ttpreport/gvisor-ligolo/pkg/sync"
    24  )
    25  
    26  // Note that this file is *identical* to 32b_64bit.go, as go_stateify gets
    27  // confused about build tags if these are not separated.
    28  
    29  // LINT.IfChange
    30  
    31  // Int32 is an atomic int32.
    32  //
    33  // The default value is zero.
    34  //
    35  // Don't add fields to this struct. It is important that it remain the same
    36  // size as its builtin analogue.
    37  //
    38  // +stateify savable
    39  type Int32 struct {
    40  	_     sync.NoCopy
    41  	value int32
    42  }
    43  
    44  // FromInt32 returns an Int32 initialized to value v.
    45  //
    46  //go:nosplit
    47  func FromInt32(v int32) Int32 {
    48  	return Int32{value: v}
    49  }
    50  
    51  // Load is analogous to atomic.LoadInt32.
    52  //
    53  //go:nosplit
    54  func (i *Int32) Load() int32 {
    55  	return atomic.LoadInt32(&i.value)
    56  }
    57  
    58  // RacyLoad is analogous to reading an atomic value without using
    59  // synchronization.
    60  //
    61  // It may be helpful to document why a racy operation is permitted.
    62  //
    63  //go:nosplit
    64  func (i *Int32) RacyLoad() int32 {
    65  	return i.value
    66  }
    67  
    68  // Store is analogous to atomic.StoreInt32.
    69  //
    70  //go:nosplit
    71  func (i *Int32) Store(v int32) {
    72  	atomic.StoreInt32(&i.value, v)
    73  }
    74  
    75  // RacyStore is analogous to setting an atomic value without using
    76  // synchronization.
    77  //
    78  // It may be helpful to document why a racy operation is permitted.
    79  //
    80  // Don't add fields to this struct. It is important that it remain the same
    81  // size as its builtin analogue.
    82  //
    83  //go:nosplit
    84  func (i *Int32) RacyStore(v int32) {
    85  	i.value = v
    86  }
    87  
    88  // Add is analogous to atomic.AddInt32.
    89  //
    90  //go:nosplit
    91  func (i *Int32) Add(v int32) int32 {
    92  	return atomic.AddInt32(&i.value, v)
    93  }
    94  
    95  // RacyAdd is analogous to adding to an atomic value without using
    96  // synchronization.
    97  //
    98  // It may be helpful to document why a racy operation is permitted.
    99  //
   100  //go:nosplit
   101  func (i *Int32) RacyAdd(v int32) int32 {
   102  	i.value += v
   103  	return i.value
   104  }
   105  
   106  // Swap is analogous to atomic.SwapInt32.
   107  //
   108  //go:nosplit
   109  func (i *Int32) Swap(v int32) int32 {
   110  	return atomic.SwapInt32(&i.value, v)
   111  }
   112  
   113  // CompareAndSwap is analogous to atomic.CompareAndSwapInt32.
   114  //
   115  //go:nosplit
   116  func (i *Int32) CompareAndSwap(oldVal, newVal int32) bool {
   117  	return atomic.CompareAndSwapInt32(&i.value, oldVal, newVal)
   118  }
   119  
   120  //go:nosplit
   121  func (i *Int32) ptr() *int32 {
   122  	return &i.value
   123  }
   124  
   125  // Uint32 is an atomic uint32.
   126  //
   127  // See aligned_unsafe.go in this directory for justification.
   128  //
   129  // +stateify savable
   130  type Uint32 struct {
   131  	_     sync.NoCopy
   132  	value uint32
   133  }
   134  
   135  // FromUint32 returns an Uint32 initialized to value v.
   136  //
   137  //go:nosplit
   138  func FromUint32(v uint32) Uint32 {
   139  	return Uint32{value: v}
   140  }
   141  
   142  // Load is analogous to atomic.LoadUint32.
   143  //
   144  //go:nosplit
   145  func (u *Uint32) Load() uint32 {
   146  	return atomic.LoadUint32(&u.value)
   147  }
   148  
   149  // RacyLoad is analogous to reading an atomic value without using
   150  // synchronization.
   151  //
   152  // It may be helpful to document why a racy operation is permitted.
   153  //
   154  //go:nosplit
   155  func (u *Uint32) RacyLoad() uint32 {
   156  	return u.value
   157  }
   158  
   159  // Store is analogous to atomic.StoreUint32.
   160  //
   161  //go:nosplit
   162  func (u *Uint32) Store(v uint32) {
   163  	atomic.StoreUint32(&u.value, v)
   164  }
   165  
   166  // RacyStore is analogous to setting an atomic value without using
   167  // synchronization.
   168  //
   169  // It may be helpful to document why a racy operation is permitted.
   170  //
   171  //go:nosplit
   172  func (u *Uint32) RacyStore(v uint32) {
   173  	u.value = v
   174  }
   175  
   176  // Add is analogous to atomic.AddUint32.
   177  //
   178  //go:nosplit
   179  func (u *Uint32) Add(v uint32) uint32 {
   180  	return atomic.AddUint32(&u.value, v)
   181  }
   182  
   183  // RacyAdd is analogous to adding to an atomic value without using
   184  // synchronization.
   185  //
   186  // It may be helpful to document why a racy operation is permitted.
   187  //
   188  //go:nosplit
   189  func (u *Uint32) RacyAdd(v uint32) uint32 {
   190  	u.value += v
   191  	return u.value
   192  }
   193  
   194  // Swap is analogous to atomic.SwapUint32.
   195  //
   196  //go:nosplit
   197  func (u *Uint32) Swap(v uint32) uint32 {
   198  	return atomic.SwapUint32(&u.value, v)
   199  }
   200  
   201  // CompareAndSwap is analogous to atomic.CompareAndSwapUint32.
   202  //
   203  //go:nosplit
   204  func (u *Uint32) CompareAndSwap(oldVal, newVal uint32) bool {
   205  	return atomic.CompareAndSwapUint32(&u.value, oldVal, newVal)
   206  }
   207  
   208  //go:nosplit
   209  func (u *Uint32) ptr() *uint32 {
   210  	return &u.value
   211  }
   212  
   213  // LINT.ThenChange(32b_64bit.go)