• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3  */
4 
5 @file:Suppress("NOTHING_TO_INLINE", "RedundantVisibilityModifier", "CanBePrimaryConstructorProperty")
6 
7 package kotlinx.atomicfu
8 
9 import kotlin.native.concurrent.AtomicInt as KAtomicInt
10 import kotlin.native.concurrent.AtomicLong as KAtomicLong
11 import kotlin.native.concurrent.FreezableAtomicReference as KAtomicRef
12 import kotlin.native.concurrent.isFrozen
13 import kotlin.native.concurrent.freeze
14 
atomicnull15 public actual fun <T> atomic(initial: T): AtomicRef<T> = AtomicRef<T>(KAtomicRef(initial))
16 public actual fun atomic(initial: Int): AtomicInt = AtomicInt(KAtomicInt(initial))
17 public actual fun atomic(initial: Long): AtomicLong = AtomicLong(KAtomicLong(initial))
18 public actual fun atomic(initial: Boolean): AtomicBoolean = AtomicBoolean(KAtomicInt(if (initial) 1 else 0))
19 
20 // ==================================== AtomicRef ====================================
21 
22 @Suppress("ACTUAL_WITHOUT_EXPECT", "EXPERIMENTAL_FEATURE_WARNING", "NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS")
23 public actual inline class AtomicRef<T> internal constructor(@PublishedApi internal val a: KAtomicRef<T>) {
24     public actual inline var value: T
25         get() = a.value
26         set(value) {
27             if (a.isFrozen) value.freeze()
28             a.value = value
29         }
30 
31     public actual inline fun lazySet(value: T) {
32         if (a.isFrozen) value.freeze()
33         a.value = value
34     }
35 
36     public actual inline fun compareAndSet(expect: T, update: T): Boolean {
37         if (a.isFrozen) update.freeze()
38         return a.compareAndSet(expect, update)
39     }
40 
41     public actual fun getAndSet(value: T): T {
42         if (a.isFrozen) value.freeze()
43         while (true) {
44             val cur = a.value
45             if (cur === value) return cur
46             if (a.compareAndSwap(cur, value) === cur) return cur
47         }
48     }
49 
50     override fun toString(): String = value.toString()
51 }
52 
53 // ==================================== AtomicBoolean ====================================
54 
55 @Suppress("ACTUAL_WITHOUT_EXPECT", "EXPERIMENTAL_FEATURE_WARNING", "NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS")
56 public actual inline class AtomicBoolean internal constructor(@PublishedApi internal val a: KAtomicInt) {
57     public actual inline var value: Boolean
58         get() = a.value != 0
59         set(value) { a.value = if (value) 1 else 0 }
60 
lazySetnull61     public actual inline fun lazySet(value: Boolean) { this.value = value }
62 
compareAndSetnull63     public actual fun compareAndSet(expect: Boolean, update: Boolean): Boolean {
64         val iExpect = if (expect) 1 else 0
65         val iUpdate = if (update) 1 else 0
66         return a.compareAndSet(iExpect, iUpdate)
67     }
68 
getAndSetnull69     public actual fun getAndSet(value: Boolean): Boolean {
70         val iValue = if (value) 1 else 0
71         while (true) {
72             val cur = a.value
73             if (cur == iValue) return value
74             if (a.compareAndSet(cur, iValue)) return cur != 0
75         }
76     }
77 
toStringnull78     override fun toString(): String = value.toString()
79 }
80 
81 // ==================================== AtomicInt ====================================
82 
83 @Suppress("ACTUAL_WITHOUT_EXPECT", "EXPERIMENTAL_FEATURE_WARNING", "NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS")
84 public actual inline class AtomicInt internal constructor(@PublishedApi internal val a: KAtomicInt) {
85     public actual inline var value: Int
86         get() = a.value
87         set(value) { a.value = value }
88 
89     public actual inline fun lazySet(value: Int) { a.value = value }
90 
91     public actual inline fun compareAndSet(expect: Int, update: Int): Boolean =
92         a.compareAndSet(expect, update)
93 
94     public actual fun getAndSet(value: Int): Int {
95         while (true) {
96             val cur = a.value
97             if (cur == value) return cur
98             if (a.compareAndSet(cur, value)) return cur
99         }
100     }
101 
102     public actual inline fun getAndIncrement(): Int = a.addAndGet(1) - 1
103     public actual inline fun getAndDecrement(): Int = a.addAndGet(-1) + 1
104     public actual inline fun getAndAdd(delta: Int): Int = a.addAndGet(delta) - delta
105     public actual inline fun addAndGet(delta: Int): Int = a.addAndGet(delta)
106     public actual inline fun incrementAndGet(): Int = a.addAndGet(1)
107     public actual inline fun decrementAndGet(): Int = a.addAndGet(-1)
108 
109     public actual inline operator fun plusAssign(delta: Int) { getAndAdd(delta) }
110     public actual inline operator fun minusAssign(delta: Int) { getAndAdd(-delta) }
111 
112     override fun toString(): String = value.toString()
113 }
114 
115 // ==================================== AtomicLong ====================================
116 
117 @Suppress("ACTUAL_WITHOUT_EXPECT", "EXPERIMENTAL_FEATURE_WARNING", "NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS")
118 public actual inline class AtomicLong internal constructor(@PublishedApi internal val a: KAtomicLong) {
119     public actual inline var value: Long
120         get() = a.value
121         set(value) { a.value = value }
122 
lazySetnull123     public actual inline fun lazySet(value: Long) { a.value = value }
124 
compareAndSetnull125     public actual inline fun compareAndSet(expect: Long, update: Long): Boolean =
126         a.compareAndSet(expect, update)
127 
128     public actual fun getAndSet(value: Long): Long {
129         while (true) {
130             val cur = a.value
131             if (cur == value) return cur
132             if (a.compareAndSet(cur, value)) return cur
133         }
134     }
135 
getAndIncrementnull136     public actual inline fun getAndIncrement(): Long = a.addAndGet(1) - 1
137     public actual inline fun getAndDecrement(): Long = a.addAndGet(-1) + 1
138     public actual inline fun getAndAdd(delta: Long): Long = a.addAndGet(delta) - delta
139     public actual inline fun addAndGet(delta: Long): Long = a.addAndGet(delta)
140     public actual inline fun incrementAndGet(): Long = a.addAndGet(1)
141     public actual inline fun decrementAndGet(): Long = a.addAndGet(-1)
142 
143     public actual inline operator fun plusAssign(delta: Long) { getAndAdd(delta) }
minusAssignnull144     public actual inline operator fun minusAssign(delta: Long) { getAndAdd(-delta) }
145 
toStringnull146     override fun toString(): String = value.toString()
147 }
148 
149