This repository has been archived by the owner on Aug 10, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 564
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
303 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package runtime.workers.atomic0 | ||
|
||
import kotlin.test.* | ||
|
||
import konan.worker.* | ||
|
||
fun test1(workers: Array<Worker>) { | ||
val atomic = AtomicInt(15) | ||
val futures = Array(workers.size, { workerIndex -> | ||
workers[workerIndex].schedule(TransferMode.CHECKED, { atomic }) { | ||
input -> input.increment() | ||
} | ||
}) | ||
futures.forEach { | ||
it.result() | ||
} | ||
println(atomic.get()) | ||
} | ||
|
||
fun test2(workers: Array<Worker>) { | ||
val atomic = AtomicInt(0) | ||
val futures = Array(workers.size, { workerIndex -> | ||
workers[workerIndex].schedule(TransferMode.CHECKED, { atomic to workerIndex }) { | ||
(place, index) -> | ||
while (place.compareAndSwap(index, index + 1) != index) {} | ||
println(index) | ||
} | ||
}) | ||
futures.forEach { | ||
it.result() | ||
} | ||
println(atomic.get()) | ||
} | ||
|
||
@Test fun runTest() { | ||
val COUNT = 20 | ||
val workers = Array(COUNT, { _ -> startWorker()}) | ||
|
||
test1(workers) | ||
test2(workers) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* | ||
* Copyright 2010-2018 JetBrains s.r.o. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#include "Atomic.h" | ||
#include "Types.h" | ||
|
||
namespace { | ||
|
||
template <typename T> T addAndGetImpl(KRef thiz, T delta) { | ||
volatile T* location = reinterpret_cast<volatile T*>(thiz + 1); | ||
return atomicAdd(location, delta); | ||
} | ||
|
||
template <typename T> T compareAndSwapImpl(KRef thiz, T expectedValue, T newValue) { | ||
volatile T* location = reinterpret_cast<volatile T*>(thiz + 1); | ||
return compareAndSwap(location, expectedValue, newValue); | ||
} | ||
|
||
} // namespace | ||
|
||
extern "C" { | ||
|
||
KInt Kotlin_AtomicInt_addAndGet(KRef thiz, KInt delta) { | ||
return addAndGetImpl(thiz, delta); | ||
} | ||
|
||
KInt Kotlin_AtomicInt_compareAndSwap(KRef thiz, KInt expectedValue, KInt newValue) { | ||
return compareAndSwapImpl(thiz, expectedValue, newValue); | ||
} | ||
|
||
KLong Kotlin_AtomicLong_addAndGet(KRef thiz, KLong delta) { | ||
return addAndGetImpl(thiz, delta); | ||
} | ||
|
||
KLong Kotlin_AtomicLong_compareAndSwap(KRef thiz, KLong expectedValue, KLong newValue) { | ||
return compareAndSwapImpl(thiz, expectedValue, newValue); | ||
} | ||
|
||
KNativePtr Kotlin_AtomicNativePtr_compareAndSwap(KRef thiz, KNativePtr expectedValue, KNativePtr newValue) { | ||
return compareAndSwapImpl(thiz, expectedValue, newValue); | ||
} | ||
|
||
} // extern "C" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
/* | ||
* Copyright 2010-2018 JetBrains s.r.o. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package konan.worker | ||
|
||
import konan.internal.Immutable | ||
import konan.SymbolName | ||
import kotlinx.cinterop.NativePtr | ||
|
||
@Immutable | ||
class AtomicInt(private var value: Int = 0) : Number() { | ||
/* Atomic operations. */ | ||
|
||
/** | ||
* Increments the value by [delta] and returns the new value. | ||
*/ | ||
@SymbolName("Kotlin_AtomicInt_addAndGet") | ||
external fun addAndGet(delta: Int): Int | ||
|
||
/** | ||
* Compares value with [expected] and replaces it with [new] value if values matches. | ||
* Returns the old value. | ||
*/ | ||
@SymbolName("Kotlin_AtomicInt_compareAndSwap") | ||
external fun compareAndSwap(expected: Int, new: Int): Int | ||
|
||
/** | ||
* Increments value by one. | ||
*/ | ||
fun increment(): Int = addAndGet(1) | ||
|
||
/** | ||
* Decrements value by one. | ||
*/ | ||
fun decrement(): Int = addAndGet(-1) | ||
|
||
/** | ||
* Returns the current value. | ||
*/ | ||
fun get(): Int = value | ||
|
||
/* Operations from Number. */ | ||
|
||
/** | ||
* Returns the value of this number as a [Double], which may involve rounding. | ||
*/ | ||
public override fun toDouble(): Double = value.toDouble() | ||
|
||
/** | ||
* Returns the value of this number as a [Float], which may involve rounding. | ||
*/ | ||
public override fun toFloat(): Float = value.toFloat() | ||
|
||
/** | ||
* Returns the value of this number as a [Long], which may involve rounding or truncation. | ||
*/ | ||
public override fun toLong(): Long = value.toLong() | ||
|
||
/** | ||
* Returns the value of this number as an [Int], which may involve rounding or truncation. | ||
*/ | ||
public override fun toInt(): Int = value.toInt() | ||
|
||
/** | ||
* Returns the [Char] with the numeric value equal to this number, truncated to 16 bits if appropriate. | ||
*/ | ||
public override fun toChar(): Char = value.toChar() | ||
|
||
/** | ||
* Returns the value of this number as a [Short], which may involve rounding or truncation. | ||
*/ | ||
public override fun toShort(): Short = value.toShort() | ||
|
||
/** | ||
* Returns the value of this number as a [Byte], which may involve rounding or truncation. | ||
*/ | ||
public override fun toByte(): Byte = value.toByte() | ||
} | ||
|
||
@Immutable | ||
class AtomicLong(private var value: Long = 0) : Number() { | ||
/* Atomic operations. */ | ||
|
||
/** | ||
* Increments the value by [delta] and returns the new value. | ||
*/ | ||
@SymbolName("Kotlin_AtomicLong_addAndGet") | ||
external fun addAndGet(delta: Long): Long | ||
|
||
/** | ||
* Increments the value by [delta] and returns the new value. | ||
*/ | ||
fun addAndGet(delta: Int): Long = addAndGet(delta.toLong()) | ||
|
||
/** | ||
* Compares value with [expected] and replaces it with [new] value if values matches. | ||
* Returns the old value. | ||
*/ | ||
@SymbolName("Kotlin_AtomicLong_compareAndSwap") | ||
external fun compareAndSwap(expected: Long, new: Long): Long | ||
|
||
/** | ||
* Increments value by one. | ||
*/ | ||
fun increment(): Long = addAndGet(1L) | ||
|
||
/** | ||
* Decrements value by one. | ||
*/ | ||
fun decrement(): Long = addAndGet(-1L) | ||
|
||
/** | ||
* Returns the current value. | ||
*/ | ||
fun get(): Long = value | ||
|
||
/* Operations from Number. */ | ||
|
||
/** | ||
* Returns the value of this number as a [Double], which may involve rounding. | ||
*/ | ||
public override fun toDouble(): Double = value.toDouble() | ||
|
||
/** | ||
* Returns the value of this number as a [Float], which may involve rounding. | ||
*/ | ||
public override fun toFloat(): Float = value.toFloat() | ||
|
||
/** | ||
* Returns the value of this number as a [Long], which may involve rounding or truncation. | ||
*/ | ||
public override fun toLong(): Long = value.toLong() | ||
|
||
/** | ||
* Returns the value of this number as an [Int], which may involve rounding or truncation. | ||
*/ | ||
public override fun toInt(): Int = value.toInt() | ||
|
||
/** | ||
* Returns the [Char] with the numeric value equal to this number, truncated to 16 bits if appropriate. | ||
*/ | ||
public override fun toChar(): Char = value.toChar() | ||
|
||
/** | ||
* Returns the value of this number as a [Short], which may involve rounding or truncation. | ||
*/ | ||
public override fun toShort(): Short = value.toShort() | ||
|
||
/** | ||
* Returns the value of this number as a [Byte], which may involve rounding or truncation. | ||
*/ | ||
public override fun toByte(): Byte = value.toByte() | ||
} | ||
|
||
@Immutable | ||
class AtomicNativePtr(private var value: NativePtr) { | ||
/** | ||
* Compares value with [expected] and replaces it with [new] value if values matches. | ||
* Returns the old value. | ||
*/ | ||
@SymbolName("Kotlin_AtomicNativePtr_compareAndSwap") | ||
external fun compareAndSwap(expected: NativePtr, new: NativePtr): NativePtr | ||
|
||
/** | ||
* Returns the current value. | ||
*/ | ||
fun get(): NativePtr = value | ||
} |