Forked from RomanTruba/Synchronization_test_iOS_SDK10
Last active
August 29, 2023 08:47
-
-
Save steipete/36350a8a60693d440954b95ea6cbbafc to your computer and use it in GitHub Desktop.
Updated for Xcode 8, Swift 3; added os_unfair_lock
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
// | |
// SpinlockTestTests.swift | |
// SpinlockTestTests | |
// | |
// Created by Peter Steinberger on 04/10/2016. | |
// Copyright © 2016 PSPDFKit GmbH. All rights reserved. | |
// | |
import XCTest | |
final class LockingTests: XCTestCase { | |
func testSpinLock() { | |
var spinLock = OS_SPINLOCK_INIT | |
executeLockTest { (block) in | |
OSSpinLockLock(&spinLock) | |
block() | |
OSSpinLockUnlock(&spinLock) | |
} | |
} | |
func testUnfairLock() { | |
var unfairLock = os_unfair_lock_s() | |
executeLockTest { (block) in | |
os_unfair_lock_lock(&unfairLock) | |
block() | |
os_unfair_lock_unlock(&unfairLock) | |
} | |
} | |
func testDispatchSemaphore() { | |
let sem = DispatchSemaphore(value: 1) | |
executeLockTest { (block) in | |
_ = sem.wait(timeout: DispatchTime.distantFuture) | |
block() | |
sem.signal() | |
} | |
} | |
func testNSLock() { | |
let lock = NSLock() | |
executeLockTest { (block) in | |
lock.lock() | |
block() | |
lock.unlock() | |
} | |
} | |
func testPthreadMutex() { | |
var mutex = pthread_mutex_t() | |
pthread_mutex_init(&mutex, nil) | |
executeLockTest{ (block) in | |
pthread_mutex_lock(&mutex) | |
block() | |
pthread_mutex_unlock(&mutex) | |
} | |
pthread_mutex_destroy(&mutex); | |
} | |
func testSyncronized() { | |
let obj = NSObject() | |
executeLockTest{ (block) in | |
objc_sync_enter(obj) | |
block() | |
objc_sync_exit(obj) | |
} | |
} | |
func testQueue() { | |
let lockQueue = DispatchQueue.init(label: "com.test.LockQueue") | |
executeLockTest{ (block) in | |
lockQueue.sync() { | |
block() | |
} | |
} | |
} | |
func disabled_testNoLock() { | |
executeLockTest { (block) in | |
block() | |
} | |
} | |
private func executeLockTest(performBlock:@escaping (_ block:() -> Void) -> Void) { | |
let dispatchBlockCount = 16 | |
let iterationCountPerBlock = 100_000 | |
// This is an example of a performance test case. | |
let queues = [ | |
DispatchQueue.global(qos: DispatchQoS.QoSClass.userInteractive), | |
DispatchQueue.global(qos: DispatchQoS.QoSClass.default), | |
DispatchQueue.global(qos: DispatchQoS.QoSClass.utility), | |
] | |
var value = 0 | |
self.measure { | |
let group = DispatchGroup.init() | |
for block in 0..<dispatchBlockCount { | |
group.enter() | |
let queue = queues[block % queues.count] | |
queue.async(execute: { | |
for _ in 0..<iterationCountPerBlock { | |
performBlock({ | |
value = value + 2 | |
value = value - 1 | |
}) | |
} | |
group.leave() | |
}) | |
} | |
_ = group.wait(timeout: DispatchTime.distantFuture) | |
} | |
} | |
} |
I won't recommend to use os_unfair_lock_s as in this code, PLEASE, read this before http://www.russbishop.net/the-law.
In short, in swift you must use
var unfairLock: UnsafeMutablePointer<os_unfair_lock>
...
init
unfairLock = UnsafeMutablePointer<os_unfair_lock>.allocate(capacity: 1)
unfairLock.initialize(to: os_unfair_lock())
deinit
unfairLock.deallocate()
instead of
var unfairLock = os_unfair_lock_s()
...
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Don't really understand any of this. Anyway to break it down in sinple was? Been trying to figure it out for months now but still I am lost. Thanks for your help.