Skip to content

Instantly share code, notes, and snippets.

@toshi0383
Created July 13, 2017 23:57
Show Gist options
  • Save toshi0383/cfffd466e95fefb2349f8c62362e1ad0 to your computer and use it in GitHub Desktop.
Save toshi0383/cfffd466e95fefb2349f8c62362e1ad0 to your computer and use it in GitHub Desktop.
//: Playground - noun: a place where people can play
import Foundation
let sleepMilliSecond = 1
var initialSleepSec: UInt32? = 1000
func _sleep() {
if let s = initialSleepSec {
initialSleepSec = nil
sleep(s)
} else {
let ms: UInt32 = 1000
usleep(UInt32(sleepMilliSecond) * ms)
}
}
class Object: NSObject {
private(set) var value: [Int] = []
private func objc_locked(_ block: (() -> ())) {
objc_sync_enter(self); defer { objc_sync_exit(self) }
block(); _sleep()
}
private let lock = NSLock()
private func nslocked(_ block: (() -> ())) {
lock.lock(); defer { lock.unlock() }
block(); _sleep()
}
private let queue = DispatchQueue(label: "jp.toshi0383.CuncurrencyPlayground.SerialQueue")
private func serial_queue_locked(_ block: (() -> ())) {
queue.sync {
block(); _sleep()
}
}
func mutateValue(_ number: Int) {
// nslocked {
serial_queue_locked {
// objc_locked {
self.value.append(number)
}
}
}
let object = Object()
let max = 100
for i in (1...max) {
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + 0.1 * Double(i)) {
object.mutateValue(i % 2 != 0 ? 1 : -1)
}
}
let waitSecond = Double(max) * Double(sleepMilliSecond) / 10 + 1 + 1
print("waiting for \(waitSecond) seconds...")
RunLoop.main.run(until: Date(timeIntervalSince1970: Date().timeIntervalSince1970 + waitSecond))
let result = object.value.map { $0.description }.joined()
let expected = (0...max/2).map { $0 > 0 && $0 < max/2 ? 11 : 1 }.map { $0.description }.joined(separator: "-")
print("result: \(result)")
print("expected: \(expected)")
print(result == expected)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment