mirror of
https://github.com/qvacua/vimr.git
synced 2024-11-28 11:35:35 +03:00
GH-264 Use OSSpinLock
This commit is contained in:
parent
122b14f2a2
commit
673e8677e3
@ -11,8 +11,6 @@
|
||||
1929B10DD8CD7EE0B8BE529F /* Scorer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B9D510177918080BE39B /* Scorer.swift */; };
|
||||
1929B165820D7177743B537A /* Component.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B39DA7AC4A9B62D7CD39 /* Component.swift */; };
|
||||
1929B1E05C116514C1D3A384 /* CocoaCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = 1929B5C3F2F1CA4113DABFFD /* CocoaCategories.m */; };
|
||||
1929B2ADD407219BADBD5A70 /* CwlUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B0DD7AE34C049D26DA8C /* CwlUtils.swift */; };
|
||||
1929B2B6F571129EB8D231C5 /* CwlUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B0DD7AE34C049D26DA8C /* CwlUtils.swift */; };
|
||||
1929B2E1A64297B8E05BB64A /* FileUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BA8AC40B901B20F20B71 /* FileUtils.swift */; };
|
||||
1929B3BF1DB87B57559DC27D /* Matcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BEEB33113B0E33C3830F /* Matcher.swift */; };
|
||||
1929B3F5743967125F357C9F /* Matcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BEEB33113B0E33C3830F /* Matcher.swift */; };
|
||||
@ -204,7 +202,6 @@
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
1929B0DD7AE34C049D26DA8C /* CwlUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CwlUtils.swift; sourceTree = "<group>"; };
|
||||
1929B15B7EDC9B0F40E5E95C /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Logging.h; sourceTree = "<group>"; };
|
||||
1929B1A51F076E088EF4CCA4 /* server_globals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = server_globals.h; sourceTree = "<group>"; };
|
||||
1929B39DA7AC4A9B62D7CD39 /* Component.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Component.swift; sourceTree = "<group>"; };
|
||||
@ -499,7 +496,6 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4B6A70931D60E04200E12030 /* AppKitCommons.swift */,
|
||||
1929B0DD7AE34C049D26DA8C /* CwlUtils.swift */,
|
||||
1929BA8AC40B901B20F20B71 /* FileUtils.swift */,
|
||||
1929B9AF20D7BD6E5C975128 /* FoundationCommons.swift */,
|
||||
1929BEEB33113B0E33C3830F /* Matcher.swift */,
|
||||
@ -869,7 +865,6 @@
|
||||
1929B165820D7177743B537A /* Component.swift in Sources */,
|
||||
1929B93DBAD09835E428F610 /* PrefPane.swift in Sources */,
|
||||
4BDF501B1D77596500D8FBC3 /* OpenQuicklyWindowManager.swift in Sources */,
|
||||
1929B2ADD407219BADBD5A70 /* CwlUtils.swift in Sources */,
|
||||
1929B462CD4935AFF6D69457 /* FileItem.swift in Sources */,
|
||||
1929B6388EAF16C190B82955 /* FileItemIgnorePattern.swift in Sources */,
|
||||
1929B73E5EC0B108B83F82EB /* FileItemService.swift in Sources */,
|
||||
@ -886,7 +881,6 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
1929B2B6F571129EB8D231C5 /* CwlUtils.swift in Sources */,
|
||||
1929B43FBA7A31F39D294CD0 /* FileItem.swift in Sources */,
|
||||
1929B741C4E58EEDAF901353 /* FileItemIgnorePattern.swift in Sources */,
|
||||
1929B7C981A0EFCC8D631E3F /* FileItemService.swift in Sources */,
|
||||
|
@ -57,11 +57,6 @@ By:
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/eonil/FileSystemEvents"}}{\fldrslt https://github.com/eonil/FileSystemEvents}}\
|
||||
\
|
||||
|
||||
\b CwlUtils
|
||||
\b0 \
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/mattgallagher/CwlUtils"}}{\fldrslt https://github.com/mattgallagher/CwlUtils}}\
|
||||
\
|
||||
|
||||
\b Nimble
|
||||
\b0 \
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/Quick/Nimble"}}{\fldrslt https://github.com/Quick/Nimble}}\
|
||||
|
@ -1,124 +0,0 @@
|
||||
//
|
||||
// CwlMutex.swift
|
||||
// CwlUtils
|
||||
//
|
||||
// Created by Matt Gallagher on 2015/02/03.
|
||||
// Copyright © 2015 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
//
|
||||
|
||||
// Slightly modified by Tae Won Ha
|
||||
|
||||
import Foundation
|
||||
|
||||
/// A basic wrapper around the "NORMAL" and "RECURSIVE" pthread mutex types. This type is a "class" type to take advantage of the "deinit" method.
|
||||
final class PThreadMutex {
|
||||
// Non-recursive "PTHREAD_MUTEX_NORMAL" and recursive "PTHREAD_MUTEX_RECURSIVE" mutex types.
|
||||
enum PThreadMutexType {
|
||||
case Normal
|
||||
case Recursive
|
||||
}
|
||||
|
||||
/// Exposed as an "unsafe" public property so non-scoped patterns can be implemented, if required.
|
||||
private(set) var unsafeMutex = pthread_mutex_t()
|
||||
|
||||
/// Default constructs as ".Normal" or ".Recursive" on request.
|
||||
init(type: PThreadMutexType = .Normal) {
|
||||
var attr = pthread_mutexattr_t()
|
||||
guard pthread_mutexattr_init(&attr) == 0 else {
|
||||
preconditionFailure()
|
||||
}
|
||||
switch type {
|
||||
case .Normal:
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL)
|
||||
case .Recursive:
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)
|
||||
}
|
||||
guard pthread_mutex_init(&unsafeMutex, &attr) == 0 else {
|
||||
preconditionFailure()
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
pthread_mutex_destroy(&unsafeMutex)
|
||||
}
|
||||
|
||||
/* RECOMMENDATION: Don't use the `slowsync` function if you care about performance. Instead, copy this extension into your file and call it:
|
||||
|
||||
extension PThreadMutex {
|
||||
private func sync<R>(@noescape f: () throws -> R) rethrows -> R {
|
||||
pthread_mutex_lock(&unsafeMutex)
|
||||
defer { pthread_mutex_unlock(&unsafeMutex) }
|
||||
return try f()
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
func sync<R>(@noescape f: () throws -> R) rethrows -> R {
|
||||
pthread_mutex_lock(&unsafeMutex)
|
||||
defer { pthread_mutex_unlock(&unsafeMutex) }
|
||||
return try f()
|
||||
}
|
||||
|
||||
/* RECOMMENDATION: Don't use the `trySlowsync` function if you care about performance. Instead, copy this extension into your file and call it:
|
||||
|
||||
extension PThreadMutex {
|
||||
private func trySync<R>(@noescape f: () throws -> R) rethrows -> R? {
|
||||
guard pthread_mutex_trylock(&unsafeMutex) == 0 else { return nil }
|
||||
defer { pthread_mutex_unlock(&unsafeMutex) }
|
||||
return try f()
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
func trySlowsync<R>(@noescape f: () throws -> R) rethrows -> R? {
|
||||
guard pthread_mutex_trylock(&unsafeMutex) == 0 else { return nil }
|
||||
defer { pthread_mutex_unlock(&unsafeMutex) }
|
||||
return try f()
|
||||
}
|
||||
}
|
||||
|
||||
#if PERFORMANCE_TESTS
|
||||
|
||||
/// A basic scoped mutex wrapper around a `dispatch_semaphore_t`.
|
||||
/// For maximum performance, it is recommended that you copy this entire type into the same compilation unit as your code that uses it to ensure inlining.
|
||||
public struct DispatchSemaphore {
|
||||
let s = dispatch_semaphore_create(1)
|
||||
public init() {}
|
||||
public func sync<R>(@noescape f: () throws -> R) rethrows -> R {
|
||||
_ = dispatch_semaphore_wait(s, DISPATCH_TIME_FOREVER)
|
||||
defer { _ = dispatch_semaphore_signal(s) }
|
||||
return try f()
|
||||
}
|
||||
}
|
||||
|
||||
extension PThreadMutex {
|
||||
public func sync_2<T>(inout param: T, @noescape f: (inout T) throws -> Void) rethrows -> Void {
|
||||
pthread_mutex_lock(&unsafeMutex)
|
||||
defer { pthread_mutex_unlock(&unsafeMutex) }
|
||||
try f(¶m)
|
||||
}
|
||||
public func sync_3<T, R>(inout param: T, @noescape f: (inout T) throws -> R) rethrows -> R {
|
||||
pthread_mutex_lock(&unsafeMutex)
|
||||
defer { pthread_mutex_unlock(&unsafeMutex) }
|
||||
return try f(¶m)
|
||||
}
|
||||
public func sync_4<T, U>(inout param1: T, inout _ param2: U, @noescape f: (inout T, inout U) throws -> Void) rethrows -> Void {
|
||||
pthread_mutex_lock(&unsafeMutex)
|
||||
defer { pthread_mutex_unlock(&unsafeMutex) }
|
||||
return try f(¶m1, ¶m2)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -7,8 +7,6 @@ import Foundation
|
||||
|
||||
class FileItem : CustomStringConvertible {
|
||||
|
||||
let mutex = PThreadMutex()
|
||||
|
||||
let url: NSURL
|
||||
let dir: Bool
|
||||
let hidden: Bool
|
||||
|
@ -37,6 +37,8 @@ class FileItemService {
|
||||
|
||||
private let workspace = NSWorkspace.sharedWorkspace()
|
||||
private let iconsCache = NSCache()
|
||||
|
||||
private var spinLock = OS_SPINLOCK_INIT
|
||||
|
||||
init() {
|
||||
self.iconsCache.countLimit = 2000
|
||||
@ -208,7 +210,8 @@ class FileItemService {
|
||||
}
|
||||
|
||||
let child = FileItem(childUrl)
|
||||
parent.mutex.sync { parent.children.append(child) }
|
||||
self.syncAddChildren { parent.children.append(child) }
|
||||
|
||||
return child
|
||||
}
|
||||
|
||||
@ -216,8 +219,16 @@ class FileItemService {
|
||||
}
|
||||
|
||||
private func scanChildren(item: FileItem) {
|
||||
item.mutex.sync { item.children = FileUtils.directDescendants(item.url).map(FileItem.init) }
|
||||
let children = FileUtils.directDescendants(item.url).map(FileItem.init)
|
||||
self.syncAddChildren { item.children = children }
|
||||
|
||||
item.childrenScanned = true
|
||||
item.needsScanChildren = false
|
||||
}
|
||||
|
||||
private func syncAddChildren(@noescape fn: () -> Void) {
|
||||
OSSpinLockLock(&self.spinLock)
|
||||
fn()
|
||||
OSSpinLockUnlock(&self.spinLock)
|
||||
}
|
||||
}
|
||||
|
@ -60,14 +60,17 @@ extension Array {
|
||||
let chunkedCount = Int(ceil(Float(count) / Float(chunk)))
|
||||
var result: [[R]] = []
|
||||
|
||||
let mutex = PThreadMutex()
|
||||
|
||||
var spinLock = OS_SPINLOCK_INIT
|
||||
|
||||
dispatch_apply(chunkedCount, queue) { idx in
|
||||
let startIndex = min(idx * chunk, count)
|
||||
let endIndex = min(startIndex + chunk, count)
|
||||
|
||||
let mappedChunk = self[startIndex..<endIndex].map(transform)
|
||||
mutex.sync { result.append(mappedChunk) }
|
||||
|
||||
OSSpinLockLock(&spinLock)
|
||||
result.append(mappedChunk)
|
||||
OSSpinLockUnlock(&spinLock)
|
||||
}
|
||||
|
||||
return result.flatMap { $0 }
|
||||
|
@ -15,8 +15,6 @@ class OpenQuicklyFilterOperation: NSOperation {
|
||||
private let flatFileItems: [FileItem]
|
||||
private let cwd: NSURL
|
||||
|
||||
private var spinLock: OSSpinLock = OS_SPINLOCK_INIT
|
||||
|
||||
init(forOpenQuicklyWindow openQuicklyWindow: OpenQuicklyWindowComponent) {
|
||||
self.openQuicklyWindow = openQuicklyWindow
|
||||
self.pattern = openQuicklyWindow.pattern
|
||||
@ -53,6 +51,7 @@ class OpenQuicklyFilterOperation: NSOperation {
|
||||
let cwdPath = self.cwd.path! + "/"
|
||||
|
||||
var result = [ScoredFileItem]()
|
||||
var spinLock = OS_SPINLOCK_INIT
|
||||
dispatch_apply(chunksCount, dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)) { [unowned self] idx in
|
||||
if self.cancelled {
|
||||
return
|
||||
@ -78,9 +77,9 @@ class OpenQuicklyFilterOperation: NSOperation {
|
||||
return
|
||||
}
|
||||
|
||||
OSSpinLockLock(&self.spinLock)
|
||||
OSSpinLockLock(&spinLock)
|
||||
result.appendContentsOf(chunkedResult)
|
||||
OSSpinLockUnlock(&self.spinLock)
|
||||
OSSpinLockUnlock(&spinLock)
|
||||
}
|
||||
|
||||
if self.cancelled {
|
||||
|
Loading…
Reference in New Issue
Block a user