• 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 import kotlin.reflect.KProperty
15 import kotlinx.atomicfu.TraceBase.None
16 
atomicnull17 public actual fun <T> atomic(initial: T, trace: TraceBase): AtomicRef<T> = AtomicRef<T>(KAtomicRef(initial))
18 public actual fun <T> atomic(initial: T): AtomicRef<T> = atomic(initial, None)
19 public actual fun atomic(initial: Int, trace: TraceBase): AtomicInt = AtomicInt(KAtomicInt(initial))
20 public actual fun atomic(initial: Int): AtomicInt = atomic(initial, None)
21 public actual fun atomic(initial: Long, trace: TraceBase): AtomicLong = AtomicLong(KAtomicLong(initial))
22 public actual fun atomic(initial: Long): AtomicLong = atomic(initial, None)
23 public actual fun atomic(initial: Boolean, trace: TraceBase): AtomicBoolean = AtomicBoolean(KAtomicInt(if (initial) 1 else 0))
24 public actual fun atomic(initial: Boolean): AtomicBoolean = atomic(initial, None)
25 
26 // ==================================== AtomicRef ====================================
27 
28 @Suppress("ACTUAL_WITHOUT_EXPECT", "EXPERIMENTAL_FEATURE_WARNING", "NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS")
29 public actual inline class AtomicRef<T> internal constructor(@PublishedApi internal val a: KAtomicRef<T>) {
30     public actual inline var value: T
31         get() = a.value
32         set(value) {
33             if (a.isFrozen) value.freeze()
34             a.value = value
35         }
36 
37     public actual inline operator fun getValue(thisRef: Any?, property: KProperty<*>): T = value
38 
39     public actual inline operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { this.value = value }
40 
41     public actual inline fun lazySet(value: T) {
42         if (a.isFrozen) value.freeze()
43         a.value = value
44     }
45 
46     public actual inline fun compareAndSet(expect: T, update: T): Boolean {
47         if (a.isFrozen) update.freeze()
48         return a.compareAndSet(expect, update)
49     }
50 
51     public actual fun getAndSet(value: T): T {
52         if (a.isFrozen) value.freeze()
53         while (true) {
54             val cur = a.value
55             if (cur === value) return cur
56             if (a.compareAndSwap(cur, value) === cur) return cur
57         }
58     }
59 
60     override fun toString(): String = value.toString()
61 }
62 
63 // ==================================== AtomicBoolean ====================================
64 
65 @Suppress("ACTUAL_WITHOUT_EXPECT", "EXPERIMENTAL_FEATURE_WARNING", "NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS")
66 public actual inline class AtomicBoolean internal constructor(@PublishedApi internal val a: KAtomicInt) {
67     public actual inline var value: Boolean
68         get() = a.value != 0
69         set(value) { a.value = if (value) 1 else 0 }
70 
getValuenull71     public actual inline operator fun getValue(thisRef: Any?, property: KProperty<*>): Boolean = value
72 
73     public actual inline operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Boolean) { this.value = value }
74 
lazySetnull75     public actual inline fun lazySet(value: Boolean) { this.value = value }
76 
compareAndSetnull77     public actual fun compareAndSet(expect: Boolean, update: Boolean): Boolean {
78         val iExpect = if (expect) 1 else 0
79         val iUpdate = if (update) 1 else 0
80         return a.compareAndSet(iExpect, iUpdate)
81     }
82 
getAndSetnull83     public actual fun getAndSet(value: Boolean): Boolean {
84         val iValue = if (value) 1 else 0
85         while (true) {
86             val cur = a.value
87             if (cur == iValue) return value
88             if (a.compareAndSet(cur, iValue)) return cur != 0
89         }
90     }
91 
toStringnull92     override fun toString(): String = value.toString()
93 }
94 
95 // ==================================== AtomicInt ====================================
96 
97 @Suppress("ACTUAL_WITHOUT_EXPECT", "EXPERIMENTAL_FEATURE_WARNING", "NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS")
98 public actual inline class AtomicInt internal constructor(@PublishedApi internal val a: KAtomicInt) {
99     public actual inline var value: Int
100         get() = a.value
101         set(value) { a.value = value }
102 
103     actual inline operator fun getValue(thisRef: Any?, property: KProperty<*>): Int = value
104 
105     public actual inline operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Int) { this.value = value }
106 
107     public actual inline fun lazySet(value: Int) { a.value = value }
108 
109     public actual inline fun compareAndSet(expect: Int, update: Int): Boolean =
110         a.compareAndSet(expect, update)
111 
112     public actual fun getAndSet(value: Int): Int {
113         while (true) {
114             val cur = a.value
115             if (cur == value) return cur
116             if (a.compareAndSet(cur, value)) return cur
117         }
118     }
119 
120     public actual inline fun getAndIncrement(): Int = a.addAndGet(1) - 1
121     public actual inline fun getAndDecrement(): Int = a.addAndGet(-1) + 1
122     public actual inline fun getAndAdd(delta: Int): Int = a.addAndGet(delta) - delta
123     public actual inline fun addAndGet(delta: Int): Int = a.addAndGet(delta)
124     public actual inline fun incrementAndGet(): Int = a.addAndGet(1)
125     public actual inline fun decrementAndGet(): Int = a.addAndGet(-1)
126 
127     public actual inline operator fun plusAssign(delta: Int) { getAndAdd(delta) }
128     public actual inline operator fun minusAssign(delta: Int) { getAndAdd(-delta) }
129 
130     override fun toString(): String = value.toString()
131 }
132 
133 // ==================================== AtomicLong ====================================
134 
135 @Suppress("ACTUAL_WITHOUT_EXPECT", "EXPERIMENTAL_FEATURE_WARNING", "NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS")
136 public actual inline class AtomicLong internal constructor(@PublishedApi internal val a: KAtomicLong) {
137     public actual inline var value: Long
138         get() = a.value
139         set(value) { a.value = value }
140 
getValuenull141     public actual inline operator fun getValue(thisRef: Any?, property: KProperty<*>): Long = value
142 
143     public actual inline operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Long) { this.value = value }
144 
lazySetnull145     public actual inline fun lazySet(value: Long) { a.value = value }
146 
compareAndSetnull147     public actual inline fun compareAndSet(expect: Long, update: Long): Boolean =
148         a.compareAndSet(expect, update)
149 
150     public actual fun getAndSet(value: Long): Long {
151         while (true) {
152             val cur = a.value
153             if (cur == value) return cur
154             if (a.compareAndSet(cur, value)) return cur
155         }
156     }
157 
getAndIncrementnull158     public actual inline fun getAndIncrement(): Long = a.addAndGet(1) - 1
159     public actual inline fun getAndDecrement(): Long = a.addAndGet(-1) + 1
160     public actual inline fun getAndAdd(delta: Long): Long = a.addAndGet(delta) - delta
161     public actual inline fun addAndGet(delta: Long): Long = a.addAndGet(delta)
162     public actual inline fun incrementAndGet(): Long = a.addAndGet(1)
163     public actual inline fun decrementAndGet(): Long = a.addAndGet(-1)
164 
165     public actual inline operator fun plusAssign(delta: Long) { getAndAdd(delta) }
minusAssignnull166     public actual inline operator fun minusAssign(delta: Long) { getAndAdd(-delta) }
167 
toStringnull168     override fun toString(): String = value.toString()
169 }
170 
171