From 71f24ca3827adc1d3dc38283ee18b2936ba951d4 Mon Sep 17 00:00:00 2001 From: Richard Frith-Macdonald Date: Wed, 6 Jul 2022 15:05:36 +0100 Subject: [PATCH] Add support for thread naming --- ChangeLog | 9 +++++++-- GSIOThreadPool.h | 4 +++- GSIOThreadPool.m | 33 +++++++++++++++++++++++++++++++++ GSThreadPool.h | 10 ++++++++++ GSThreadPool.m | 38 ++++++++++++++++++++++++++++++++++++-- 5 files changed, 89 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2656c57..164250a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,12 @@ +2022-07-06 Richard Frith-Macdonald 2019-08-08 Richard Frith-Macdonald - * GSUniqued.m: - Add special case code for handling objcts which can't be copied. + * GSThreadPool.h: + * GSIOThreadPool.h: + * GSThreadPool.m: + * GSIOThreadPool.m: + Add support for naming the pools, with threads named sequentially (as + they are created) based on the pool name. 2019-04-16 Richard Frith-Macdonald diff --git a/GSIOThreadPool.h b/GSIOThreadPool.h index 6503fea..a035d29 100644 --- a/GSIOThreadPool.h +++ b/GSIOThreadPool.h @@ -80,6 +80,8 @@ typedef unsigned int NSUInteger; NSTimeInterval timeout; NSUInteger maxThreads; Class threadClass; + NSString *poolName; + unsigned created; } /** Returns an instance intended for sharing between sections of code which @@ -138,7 +140,7 @@ typedef unsigned int NSUInteger; /** Releases a thread previously selected from the pool. This decreases the * acquire count for the thread. If a thread has a zero acquire count, it is - * a candidatre for termination and removal from the pool if/when the pool + * a candidate for termination and removal from the pool if/when the pool * has its size changed. */ - (void) unacquireThread: (NSThread*)aThread; diff --git a/GSIOThreadPool.m b/GSIOThreadPool.m index 98cb323..d0a09bd 100644 --- a/GSIOThreadPool.m +++ b/GSIOThreadPool.m @@ -257,7 +257,15 @@ best(NSMutableArray *a) t = best(threads); if (nil == t || ((c = [t _count]) > 0 && [threads count] < maxThreads)) { + NSString *n; + t = [threadClass new]; + if (nil == (n = poolName)) + { + n = @"GSIOThreadPool"; + } + n = [NSString stringWithFormat: @"%@-%u", n, ++created]; + [t setName: n]; [threads addObject: t]; [t release]; [t start]; @@ -299,6 +307,7 @@ best(NSMutableArray *a) [threads release]; [classLock unlock]; #endif + DESTROY(poolName); [super dealloc]; } @@ -323,6 +332,30 @@ best(NSMutableArray *a) return maxThreads; } +- (NSString*) poolName +{ + NSString *n; + + [classLock lock]; + n = RETAIN(poolName); + [classLock unlock]; + return AUTORELEASE(n); +} + +- (void) setPoolName: (NSString*)aName +{ + NSString *s = nil; + + if (aName) + { + s = AUTORELEASE([aName copy]); + NSAssert([s isKindOfClass: [NSString class]], NSInvalidArgumentException); + } + [classLock lock]; + ASSIGN(poolName, s); + [classLock unlock]; +} + - (void) setThreads: (NSUInteger)max { maxThreads = max; diff --git a/GSThreadPool.h b/GSThreadPool.h index ee3c54d..b5c45c1 100644 --- a/GSThreadPool.h +++ b/GSThreadPool.h @@ -38,6 +38,8 @@ @interface GSThreadPool : NSObject { NSRecursiveLock *poolLock; + NSString *poolName; + unsigned created; BOOL shutdown; BOOL suspended; NSUInteger maxThreads; @@ -88,6 +90,10 @@ */ - (NSUInteger) maxThreads; +/** Returns the name of the pool as set using the -setPoolName: method. + */ +- (NSString*) poolName; + /** Reverses the effect of -suspend. */ - (void) resume; @@ -112,6 +118,10 @@ */ - (void) setOperations: (NSUInteger)max; +/** Sets the pool name, used as a prefix for thread names. + */ +- (void) setPoolName: (NSString*)aName; + /** Specify the maximum number of threads in the pool (the actual number * used may be lower than this value).
* Default is 2.
diff --git a/GSThreadPool.m b/GSThreadPool.m index eb96ba8..c71c21a 100644 --- a/GSThreadPool.m +++ b/GSThreadPool.m @@ -114,6 +114,7 @@ static GSThreadPool *shared = nil; [live release]; live = nil; } + [poolName release]; [poolLock unlock]; [poolLock release]; [super dealloc]; @@ -125,10 +126,10 @@ static GSThreadPool *shared = nil; [poolLock lock]; result = [NSString stringWithFormat: - @"%@ queue: %"PRIuPTR"(%"PRIuPTR")" + @"%@ %@ queue: %"PRIuPTR"(%"PRIuPTR")" @" threads: %"PRIuPTR"(%"PRIuPTR")" @" active: %"PRIuPTR" processed: %"PRIuPTR"", - [super description], operations->count, maxOperations, + [super description], poolName, operations->count, maxOperations, idle->count + live->count, maxThreads, live->count, processed]; [poolLock unlock]; return result; @@ -170,6 +171,7 @@ static GSThreadPool *shared = nil; if ((self = [super init]) != nil) { poolLock = [NSRecursiveLock new]; + poolName = @"GSThreadPool"; idle = [GSLinkedList new]; live = [GSLinkedList new]; operations = [GSLinkedList new]; @@ -205,6 +207,16 @@ static GSThreadPool *shared = nil; return maxThreads; } +- (NSString*) poolName +{ + NSString *n; + + [poolLock lock]; + n = RETAIN(poolName); + [poolLock unlock]; + return AUTORELEASE(n); +} + - (void) resume { [poolLock lock]; @@ -284,6 +296,20 @@ static GSThreadPool *shared = nil; maxOperations = max; } +- (void) setPoolName: (NSString*)aName +{ + NSString *s = nil; + + if (aName) + { + s = AUTORELEASE([aName copy]); + NSAssert([s isKindOfClass: [NSString class]], NSInvalidArgumentException); + } + [poolLock lock]; + ASSIGN(poolName, s); + [poolLock unlock]; +} + - (void) setThreads: (NSUInteger)max { [poolLock lock]; @@ -344,6 +370,7 @@ static GSThreadPool *shared = nil; if (maxThreads > idle->count + live->count) { NSThread *thread; + NSString *name; /* Create a new link, add it to the idle list, and start the * thread which will work with it. @@ -378,6 +405,13 @@ static GSThreadPool *shared = nil; thread = [[NSThread alloc] initWithTarget: self selector: @selector(_run:) object: link]; + if (nil == (name = poolName)) + { + name = @"GSThreadPool"; + } + name = [NSString stringWithFormat: @"%@-%u", + name, ++created]; + [thread setName: name]; [link setItem: thread]; [thread start]; [thread release]; // Retained by link