github.com/XiaoMi/Gaea@v1.2.5/util/sync2/atomic.go (about)

     1  /*
     2  Copyright 2017 Google Inc.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package sync2
    18  
    19  import (
    20  	"sync"
    21  	"sync/atomic"
    22  	"time"
    23  )
    24  
    25  // AtomicInt32 is a wrapper with a simpler interface around atomic.(Add|Store|Load|CompareAndSwap)Int32 functions.
    26  type AtomicInt32 struct {
    27  	int32
    28  }
    29  
    30  // NewAtomicInt32 initializes a new AtomicInt32 with a given value.
    31  func NewAtomicInt32(n int32) AtomicInt32 {
    32  	return AtomicInt32{n}
    33  }
    34  
    35  // Add atomically adds n to the value.
    36  func (i *AtomicInt32) Add(n int32) int32 {
    37  	return atomic.AddInt32(&i.int32, n)
    38  }
    39  
    40  // Set atomically sets n as new value.
    41  func (i *AtomicInt32) Set(n int32) {
    42  	atomic.StoreInt32(&i.int32, n)
    43  }
    44  
    45  // Get atomically returns the current value.
    46  func (i *AtomicInt32) Get() int32 {
    47  	return atomic.LoadInt32(&i.int32)
    48  }
    49  
    50  // CompareAndSwap atomatically swaps the old with the new value.
    51  func (i *AtomicInt32) CompareAndSwap(oldval, newval int32) (swapped bool) {
    52  	return atomic.CompareAndSwapInt32(&i.int32, oldval, newval)
    53  }
    54  
    55  // AtomicInt64 is a wrapper with a simpler interface around atomic.(Add|Store|Load|CompareAndSwap)Int64 functions.
    56  type AtomicInt64 struct {
    57  	int64
    58  }
    59  
    60  // NewAtomicInt64 initializes a new AtomicInt64 with a given value.
    61  func NewAtomicInt64(n int64) AtomicInt64 {
    62  	return AtomicInt64{n}
    63  }
    64  
    65  // Add atomically adds n to the value.
    66  func (i *AtomicInt64) Add(n int64) int64 {
    67  	return atomic.AddInt64(&i.int64, n)
    68  }
    69  
    70  // Set atomically sets n as new value.
    71  func (i *AtomicInt64) Set(n int64) {
    72  	atomic.StoreInt64(&i.int64, n)
    73  }
    74  
    75  // Get atomically returns the current value.
    76  func (i *AtomicInt64) Get() int64 {
    77  	return atomic.LoadInt64(&i.int64)
    78  }
    79  
    80  // CompareAndSwap atomatically swaps the old with the new value.
    81  func (i *AtomicInt64) CompareAndSwap(oldval, newval int64) (swapped bool) {
    82  	return atomic.CompareAndSwapInt64(&i.int64, oldval, newval)
    83  }
    84  
    85  // AtomicDuration is a wrapper with a simpler interface around atomic.(Add|Store|Load|CompareAndSwap)Int64 functions.
    86  type AtomicDuration struct {
    87  	int64
    88  }
    89  
    90  // NewAtomicDuration initializes a new AtomicDuration with a given value.
    91  func NewAtomicDuration(duration time.Duration) AtomicDuration {
    92  	return AtomicDuration{int64(duration)}
    93  }
    94  
    95  // Add atomically adds duration to the value.
    96  func (d *AtomicDuration) Add(duration time.Duration) time.Duration {
    97  	return time.Duration(atomic.AddInt64(&d.int64, int64(duration)))
    98  }
    99  
   100  // Set atomically sets duration as new value.
   101  func (d *AtomicDuration) Set(duration time.Duration) {
   102  	atomic.StoreInt64(&d.int64, int64(duration))
   103  }
   104  
   105  // Get atomically returns the current value.
   106  func (d *AtomicDuration) Get() time.Duration {
   107  	return time.Duration(atomic.LoadInt64(&d.int64))
   108  }
   109  
   110  // CompareAndSwap atomatically swaps the old with the new value.
   111  func (d *AtomicDuration) CompareAndSwap(oldval, newval time.Duration) (swapped bool) {
   112  	return atomic.CompareAndSwapInt64(&d.int64, int64(oldval), int64(newval))
   113  }
   114  
   115  // AtomicBool gives an atomic boolean variable.
   116  type AtomicBool struct {
   117  	int32
   118  }
   119  
   120  // NewAtomicBool initializes a new AtomicBool with a given value.
   121  func NewAtomicBool(n bool) AtomicBool {
   122  	if n {
   123  		return AtomicBool{1}
   124  	}
   125  	return AtomicBool{0}
   126  }
   127  
   128  // Set atomically sets n as new value.
   129  func (i *AtomicBool) Set(n bool) {
   130  	if n {
   131  		atomic.StoreInt32(&i.int32, 1)
   132  	} else {
   133  		atomic.StoreInt32(&i.int32, 0)
   134  	}
   135  }
   136  
   137  // Get atomically returns the current value.
   138  func (i *AtomicBool) Get() bool {
   139  	return atomic.LoadInt32(&i.int32) != 0
   140  }
   141  
   142  // CompareAndSwap atomatically swaps the old with the new value.
   143  func (i *AtomicBool) CompareAndSwap(o, n bool) bool {
   144  	var old, new int32
   145  	if o {
   146  		old = 1
   147  	}
   148  	if n {
   149  		new = 1
   150  	}
   151  	return atomic.CompareAndSwapInt32(&i.int32, old, new)
   152  }
   153  
   154  // AtomicString gives you atomic-style APIs for string, but
   155  // it's only a convenience wrapper that uses a mutex. So, it's
   156  // not as efficient as the rest of the atomic types.
   157  type AtomicString struct {
   158  	mu  sync.Mutex
   159  	str string
   160  }
   161  
   162  // Set atomically sets str as new value.
   163  func (s *AtomicString) Set(str string) {
   164  	s.mu.Lock()
   165  	s.str = str
   166  	s.mu.Unlock()
   167  }
   168  
   169  // Get atomically returns the current value.
   170  func (s *AtomicString) Get() string {
   171  	s.mu.Lock()
   172  	str := s.str
   173  	s.mu.Unlock()
   174  	return str
   175  }
   176  
   177  // CompareAndSwap atomatically swaps the old with the new value.
   178  func (s *AtomicString) CompareAndSwap(oldval, newval string) (swqpped bool) {
   179  	s.mu.Lock()
   180  	defer s.mu.Unlock()
   181  	if s.str == oldval {
   182  		s.str = newval
   183  		return true
   184  	}
   185  	return false
   186  }