locking debug/performance tweaks

This commit is contained in:
Richard Frith-Macdonald 2018-03-26 15:05:01 +01:00
parent 2d3039694f
commit 43673452a5
5 changed files with 62 additions and 36 deletions

View file

@ -1,3 +1,14 @@
2018-03-26 Richard Frith-Macdonald <rfm@gnu.org>
Source/NSBundle.m:
Source/NSOperation.m:
Give locks names to ease debugging
Source/NSObject.m:
Source/NSZone.m:
Updates to use pthread mutexes directly rather than NSLock objects
in key places for performance.
2018-03-26 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSPThread.h:

View file

@ -1145,12 +1145,14 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory)
NSNonOwnedPointerMapValueCallBacks, 0);
pathCacheLock = [NSLock new];
[pathCacheLock setName: @"pathCacheLock"];
pathCache = [NSMutableDictionary new];
/* Need to make this recursive since both mainBundle and
* initWithPath: want to lock the thread.
*/
load_lock = [NSRecursiveLock new];
[load_lock setName: @"load_lock"];
env = [[NSProcessInfo processInfo] environment];
/* These variables are used when we are running non-flattened.

View file

@ -53,6 +53,8 @@
#include <locale.h>
#endif
#import "GSPThread.h"
#if defined(HAVE_SYS_SIGNAL_H)
# include <sys/signal.h>
#elif defined(HAVE_SIGNAL_H)
@ -127,7 +129,7 @@ GS_ROOT_CLASS @interface NSZombie
/* allocationLock is needed when for protecting the map table of zombie
* information and if atomic operations are not available.
*/
static NSLock *allocationLock = nil;
static pthread_mutex_t allocationLock = PTHREAD_MUTEX_INITIALIZER;
BOOL NSZombieEnabled = NO;
BOOL NSDeallocateZombies = NO;
@ -142,9 +144,9 @@ static void GSMakeZombie(NSObject *o, Class c)
object_setClass(o, zombieClass);
if (0 != zombieMap)
{
[allocationLock lock];
pthread_mutex_lock(&allocationLock);
NSMapInsert(zombieMap, (void*)o, (void*)c);
[allocationLock unlock];
pthread_mutex_unlock(&allocationLock);
}
}
#endif
@ -155,9 +157,9 @@ static void GSLogZombie(id o, SEL sel)
if (0 != zombieMap)
{
[allocationLock lock];
pthread_mutex_lock(&allocationLock);
c = NSMapGet(zombieMap, (void*)o);
[allocationLock unlock];
pthread_mutex_unlock(&allocationLock);
}
if (c == 0)
{
@ -402,12 +404,12 @@ typedef int gsrefcount_t; // No atomics, use a simple integer
#define LOCKMASK (LOCKCOUNT-1)
#define ALIGNBITS 3
static NSLock *allocationLocks[LOCKCOUNT] = { 0 };
static pthread_mutex_t allocationLocks[LOCKCOUNT];
static inline NSLock *GSAllocationLockForObject(id p)
static inline pthread_mutex_t *GSAllocationLockForObject(id p)
{
NSUInteger i = ((((NSUInteger)(uintptr_t)p) >> ALIGNBITS) & LOCKMASK);
return allocationLocks[i];
return &allocationLocks[i];
}
#endif
@ -512,21 +514,21 @@ static BOOL objc_release_fast_no_destroy_internal(id anObject)
return YES;
}
#else /* GSATOMICREAD */
NSLock *theLock = GSAllocationLockForObject(anObject);
pthread_mutex_t *theLock = GSAllocationLockForObject(anObject);
[theLock lock];
pthread_mutex_lock(theLock);
if (((obj)anObject)[-1].retained == 0)
{
# ifdef OBJC_CAP_ARC
objc_delete_weak_refs(anObject);
# endif
[theLock unlock];
pthread_mutex_unlock(theLock);
return YES;
}
else
{
((obj)anObject)[-1].retained--;
[theLock unlock];
pthread_mutex_unlock(theLock);
return NO;
}
#endif /* GSATOMICREAD */
@ -633,9 +635,9 @@ static id objc_retain_fast_np_internal(id anObject)
tooFar = YES;
}
#else /* GSATOMICREAD */
NSLock *theLock = GSAllocationLockForObject(anObject);
pthread_mutex_t *theLock = GSAllocationLockForObject(anObject);
[theLock lock];
pthread_mutex_lock(theLock);
if (((obj)anObject)[-1].retained > 0xfffffe)
{
tooFar = YES;
@ -644,7 +646,7 @@ static id objc_retain_fast_np_internal(id anObject)
{
((obj)anObject)[-1].retained++;
}
[theLock unlock];
pthread_mutex_unlock(theLock);
#endif /* GSATOMICREAD */
if (YES == tooFar)
{
@ -831,9 +833,9 @@ NSDeallocateObject(id anObject)
#ifdef OBJC_CAP_ARC
if (0 != zombieMap)
{
[allocationLock lock];
pthread_mutex_lock(&allocationLock);
NSMapInsert(zombieMap, (void*)anObject, (void*)aClass);
[allocationLock unlock];
pthread_mutex_unlock(&allocationLock);
}
if (NSDeallocateZombies == YES)
{
@ -1033,17 +1035,16 @@ static id gs_weak_load(id obj)
# endif
#endif
/* Create the lock for NSZombie and for allocation when atomic
/* Initialize the locks for allocation when atomic
* operations are not available.
*/
allocationLock = [NSLock new];
#if !defined(GSATOMICREAD)
{
NSUInteger i;
for (i = 0; i < LOCKCOUNT; i++)
{
allocationLocks[i] = [NSLock new];
allocationLocks[i] = PTHREAD_MUTEX_INITIALIZER;
}
}
#endif
@ -1054,6 +1055,7 @@ static id gs_weak_load(id obj)
* any use of the autorelease system.
*/
gnustep_global_lock = [NSRecursiveLock new];
[gnustep_global_lock setName: @"gnustep_global_lock"];
/* Behavior debugging ... enable with environment variable if needed.
*/
@ -2497,9 +2499,10 @@ static id gs_weak_load(id obj)
{
return nil;
}
[allocationLock lock];
pthread_mutex_lock(&allocationLock);
c = zombieMap ? NSMapGet(zombieMap, (void*)self) : Nil;
[allocationLock unlock];
pthread_mutex_unlock(&allocationLock);
return [c instanceMethodSignatureForSelector: aSelector];
}
@end

View file

@ -246,7 +246,11 @@ static NSArray *empty = nil;
internal->threadPriority = 0.5;
internal->ready = YES;
internal->lock = [NSRecursiveLock new];
[internal->lock setName:
[NSString stringWithFormat: @"lock-for-opqueue-%p", self]];
internal->cond = [[NSConditionLock alloc] initWithCondition: 0];
[internal->cond setName:
[NSString stringWithFormat: @"cond-for-opqueue-%p", self]];
[self addObserver: self
forKeyPath: @"isFinished"
options: NSKeyValueObservingOptionNew
@ -751,7 +755,11 @@ static NSOperationQueue *mainQueue = nil;
internal->starting = [NSMutableArray new];
internal->waiting = [NSMutableArray new];
internal->lock = [NSRecursiveLock new];
[internal->lock setName:
[NSString stringWithFormat: @"lock-for-op-%p", self]];
internal->cond = [[NSConditionLock alloc] initWithCondition: 0];
[internal->cond setName:
[NSString stringWithFormat: @"cond-for-op-%p", self]];
}
return self;
}

View file

@ -93,6 +93,8 @@
#import "GSPrivate.h"
#import "GSPThread.h"
static pthread_mutex_t zoneLock = PTHREAD_MUTEX_INITIALIZER;
/**
* Try to get more memory - the normal process has failed.
* If we can't do anything, just return a null pointer.
@ -203,12 +205,12 @@ NSSetZoneName (NSZone *zone, NSString *name)
{
if (!zone)
zone = NSDefaultMallocZone();
[gnustep_global_lock lock];
pthread_mutex_lock(&zoneLock);
name = [name copy];
if (zone->name != nil)
[zone->name release];
zone->name = name;
[gnustep_global_lock unlock];
pthread_mutex_unlock(&zoneLock);
}
NSString*
@ -758,7 +760,7 @@ frecycle1(NSZone *zone)
static void
frecycle (NSZone *zone)
{
[gnustep_global_lock lock];
pthread_mutex_lock(&zoneLock);
if (zone->name != nil)
{
NSString *name = zone->name;
@ -774,17 +776,17 @@ frecycle (NSZone *zone)
zone->free = rffree;
zone->recycle = rrecycle;
}
[gnustep_global_lock unlock];
pthread_mutex_unlock(&zoneLock);
}
static void
rffree (NSZone *zone, void *ptr)
{
ffree(zone, ptr);
[gnustep_global_lock lock];
pthread_mutex_lock(&zoneLock);
if (frecycle1(zone))
destroy_zone(zone);
[gnustep_global_lock unlock];
pthread_mutex_unlock(&zoneLock);
}
@ -1380,7 +1382,7 @@ nrecycle1 (NSZone *zone)
static void
nrecycle (NSZone *zone)
{
[gnustep_global_lock lock];
pthread_mutex_lock(&zoneLock);
if (zone->name != nil)
{
NSString *name = zone->name;
@ -1396,7 +1398,7 @@ nrecycle (NSZone *zone)
zone->free = rnfree;
zone->recycle = rrecycle;
}
[gnustep_global_lock unlock];
pthread_mutex_unlock(&zoneLock);
}
static void*
@ -1456,10 +1458,10 @@ rnfree (NSZone *zone, void *ptr)
nfree(zone, ptr);
if (zptr->use == 0)
{
[gnustep_global_lock lock];
pthread_mutex_lock(&zoneLock);
nrecycle1(zone);
destroy_zone(zone);
[gnustep_global_lock unlock];
pthread_mutex_unlock(&zoneLock);
}
}
@ -1583,7 +1585,7 @@ NSZoneFromPointer(void *ptr)
/*
* See if we can find the zone in our list of all zones.
*/
[gnustep_global_lock lock];
pthread_mutex_lock(&zoneLock);
for (zone = zone_list; zone != 0; zone = zone->next)
{
if ((zone->lookup)(zone, ptr) == YES)
@ -1591,7 +1593,7 @@ NSZoneFromPointer(void *ptr)
break;
}
}
[gnustep_global_lock unlock];
pthread_mutex_unlock(&zoneLock);
return (zone == 0) ? &default_zone : zone;
}
@ -1702,10 +1704,10 @@ NSCreateZone (NSUInteger start, NSUInteger gran, BOOL canFree)
newZone = (NSZone*)zone;
}
[gnustep_global_lock lock];
pthread_mutex_lock(&zoneLock);
newZone->next = zone_list;
zone_list = newZone;
[gnustep_global_lock unlock];
pthread_mutex_unlock(&zoneLock);
return newZone;
}