From ab789455fc96440b46c61e8ac9c7722981eb98f8 Mon Sep 17 00:00:00 2001 From: zhongwuzw Date: Wed, 18 Apr 2018 18:25:34 +0800 Subject: [PATCH] Optimize trylock using runLoop to replace usleep `usleep` function would block the thread, in `RunLoop` way, which can handle input sources in 10 ms. --- YYCache/YYMemoryCache.m | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/YYCache/YYMemoryCache.m b/YYCache/YYMemoryCache.m index 9042d9b..5e96ba3 100644 --- a/YYCache/YYMemoryCache.m +++ b/YYCache/YYMemoryCache.m @@ -176,6 +176,7 @@ @implementation YYMemoryCache { pthread_mutex_t _lock; _YYLinkedMap *_lru; dispatch_queue_t _queue; + CFRunLoopSourceRef _noSpinSource; } - (void)_trimRecursively { @@ -208,6 +209,8 @@ - (void)_trimToCost:(NSUInteger)costLimit { pthread_mutex_unlock(&_lock); if (finish) return; + CFRunLoopAddSource(CFRunLoopGetCurrent(), _noSpinSource, kCFRunLoopDefaultMode); + NSMutableArray *holder = [NSMutableArray new]; while (!finish) { if (pthread_mutex_trylock(&_lock) == 0) { @@ -219,7 +222,7 @@ - (void)_trimToCost:(NSUInteger)costLimit { } pthread_mutex_unlock(&_lock); } else { - usleep(10 * 1000); //10 ms + CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.01, NO); // Give RunLoop 10ms to handle input sources. } } if (holder.count) { @@ -242,6 +245,8 @@ - (void)_trimToCount:(NSUInteger)countLimit { pthread_mutex_unlock(&_lock); if (finish) return; + CFRunLoopAddSource(CFRunLoopGetCurrent(), _noSpinSource, kCFRunLoopDefaultMode); + NSMutableArray *holder = [NSMutableArray new]; while (!finish) { if (pthread_mutex_trylock(&_lock) == 0) { @@ -253,7 +258,7 @@ - (void)_trimToCount:(NSUInteger)countLimit { } pthread_mutex_unlock(&_lock); } else { - usleep(10 * 1000); //10 ms + CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.01, NO); // Give RunLoop 10ms to handle input sources. } } if (holder.count) { @@ -277,6 +282,8 @@ - (void)_trimToAge:(NSTimeInterval)ageLimit { pthread_mutex_unlock(&_lock); if (finish) return; + CFRunLoopAddSource(CFRunLoopGetCurrent(), _noSpinSource, kCFRunLoopDefaultMode); + NSMutableArray *holder = [NSMutableArray new]; while (!finish) { if (pthread_mutex_trylock(&_lock) == 0) { @@ -288,7 +295,7 @@ - (void)_trimToAge:(NSTimeInterval)ageLimit { } pthread_mutex_unlock(&_lock); } else { - usleep(10 * 1000); //10 ms + CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.01, NO); // Give RunLoop 10ms to handle input sources. } } if (holder.count) { @@ -331,6 +338,8 @@ - (instancetype)init { _autoTrimInterval = 5.0; _shouldRemoveAllObjectsOnMemoryWarning = YES; _shouldRemoveAllObjectsWhenEnteringBackground = YES; + CFRunLoopSourceContext noSpinCtx = {0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; + _noSpinSource = CFRunLoopSourceCreate(NULL, 0, &noSpinCtx); [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_appDidReceiveMemoryWarningNotification) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_appDidEnterBackgroundNotification) name:UIApplicationDidEnterBackgroundNotification object:nil]; @@ -344,6 +353,7 @@ - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil]; [_lru removeAll]; pthread_mutex_destroy(&_lock); + CFRelease(_noSpinSource); } - (NSUInteger)totalCount {