Hello all, attached is a small patch that replaces all objc_mutexes in gnustep-base with pthread_mutexes (save for the runtime mutex, of course). NSLock and friends already use pthreads and I don't think there is anything to be gained by sticking to the old runtime-threading layer in other places (the new runtime doesn't even export objc_mutex_(de)allocate() anymore). This also has the added benefit that (slightly faster) non-recursive mutexes can be used in a few places, where they're just protecting simple lookup or update operations on some table. As a downside, the GSAllocateMutexAt() function from GSObjCRuntime.h had to go (but, apart from the fact that using objc_mutexes shouldn't really be encouraged, nobody seems to be using it). I verified that the testsuite still passes for -base after the change and I didn't notice any problems in day-to-day usage. Still, I'd really appreciate somebody taking a closer look.
I'd also like to ask about whom to contact regarding copyright assignment. I know that this is a rather insignificiant (and repetitive) contribution, so it might not be strictly needed, but just in case⦠kind regards, Niels
Index: Source/GSFFCallInvocation.m
===================================================================
--- Source/GSFFCallInvocation.m (revision 29331)
+++ Source/GSFFCallInvocation.m (working copy)
@@ -32,6 +32,8 @@
#import <callback.h>
#import "callframe.h"
+#include <pthread.h>
+
#import "GSInvocation.h"
#ifndef INLINE
@@ -136,7 +138,7 @@
/* Lock that protects the ff_callback_map */
-static objc_mutex_t ff_callback_map_lock = NULL;
+static pthread_mutex_t ff_callback_map_lock = PTHREAD_MUTEX_INITIALIZER;
/* Static pre-computed return type info */
@@ -477,7 +479,7 @@
GSIMapNode node;
// Lock
- objc_mutex_lock (ff_callback_map_lock);
+ pthread_mutex_lock (&ff_callback_map_lock);
node = GSIMapNodeForKey (&ff_callback_map,
(GSIMapKey) ((void *) &returnInfo));
@@ -503,7 +505,7 @@
(GSIMapVal) forwarding_callback);
}
// Unlock
- objc_mutex_unlock (ff_callback_map_lock);
+ pthread_mutex_unlock (&ff_callback_map_lock);
}
return forwarding_callback;
}
@@ -512,8 +514,6 @@
{
int index;
- ff_callback_map_lock = objc_mutex_allocate ();
-
for (index = 0; index < STATIC_CALLBACK_LIST_SIZE; ++index)
{
returnTypeInfo[index].type = index;
Index: Source/GSPThread.h
===================================================================
--- Source/GSPThread.h (revision 0)
+++ Source/GSPThread.h (revision 0)
@@ -0,0 +1,58 @@
+/* GSPThread.h
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ Written by: Niels Grewe <[email protected]>
+
+ This file is part of the GNUstep Base Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02111 USA.
+*/
+#ifndef _GSPThread_h_
+#define _GSPThread_h_
+
+/*
+ * Since glibc does not enable Unix98 extensions by default, we need to tell it
+ * to do so explicitly. Whether that support is switched on by _XOPEN_SOURCE or
+ * by __USE_UNIX98 depends on whether <features.h> has already been included or
+ * will be included by pthread.h. Hence both flags need to be set here. This
+ * shouldn't be be a problem with other libcs.
+ */
+#define _XOPEN_SOURCE 500
+#define __USE_UNIX98
+#include <pthread.h>
+
+/*
+ * Macro to initialize recursive mutexes in a portable way. Adopted from
+ * libobjc2 (lock.h).
+ */
+# ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
+# define GS_INIT_RECURSIVE_MUTEX(x) x = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
+# elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
+# define GS_INIT_RECURSIVE_MUTEX(x) x = PTHREAD_RECURSIVE_MUTEX_INITIALIZER
+# else
+# define GS_INIT_RECURSIVE_MUTEX(x) GSPThreadInitRecursiveMutex(&(x))
+
+static inline void GSPThreadInitRecursiveMutex(pthread_mutex_t *x)
+{
+ pthread_mutexattr_t recursiveAttributes;
+ pthread_mutexattr_init(&recursiveAttributes);
+ pthread_mutexattr_settype(&recursiveAttributes, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(x, &recursiveAttributes);
+ pthread_mutexattr_destroy(&recursiveAttributes);
+}
+# endif // PTHREAD_RECURSIVE_MUTEX_INITIALIZER(_NP)
+
+#endif // _GSPThread_h_
Index: Source/NSZone.m
===================================================================
--- Source/NSZone.m (revision 29331)
+++ Source/NSZone.m (working copy)
@@ -96,6 +96,7 @@
#include "Foundation/NSZone.h"
#include "Foundation/NSLock.h"
#include "GSPrivate.h"
+#include "GSPThread.h"
/**
* Try to get more memory - the normal process has failed.
@@ -555,7 +556,7 @@
struct _ffree_zone_struct
{
NSZone common;
- objc_mutex_t lock;
+ pthread_mutex_t lock;
ff_block *blocks; // Linked list of blocks
ff_link *segheadlist[MAX_SEG]; // Segregated list, holds heads
ff_link *segtaillist[MAX_SEG]; // Segregated list, holds tails
@@ -710,7 +711,7 @@
struct _nfree_zone_struct
{
NSZone common;
- objc_mutex_t lock;
+ pthread_mutex_t lock;
/* Linked list of blocks in decreasing order of free space,
except maybe for the first block. */
nf_block *blocks;
@@ -791,7 +792,7 @@
ff_block *chunkhead;
void *result;
- objc_mutex_lock(zptr->lock);
+ pthread_mutex_lock(&(zptr->lock));
bufsize = zptr->bufsize;
while ((i < bufsize) && (chunksize > size_buf[i]))
i++;
@@ -830,7 +831,7 @@
chunkhead = get_chunk(zptr, chunksize);
if (chunkhead == NULL)
{
- objc_mutex_unlock(zptr->lock);
+ pthread_mutex_unlock(&(zptr->lock));
if (zone->name != nil)
[NSException raise: NSMallocException
format: @"Zone %@ has run out of memory", zone->name];
@@ -849,7 +850,7 @@
*((char*)chunkhead->next) = (char)42;
chunkSetLive(chunkhead);
result = chunkToPointer(chunkhead);
- objc_mutex_unlock(zptr->lock);
+ pthread_mutex_unlock(&(zptr->lock));
return result;
}
@@ -873,7 +874,7 @@
if (ptr == NULL)
return fmalloc(zone, size);
chunkhead = pointerToChunk(ptr);
- objc_mutex_lock(zptr->lock);
+ pthread_mutex_lock(&(zptr->lock));
realsize = chunkSize(chunkhead);
NSAssert(chunkIsInUse(chunkhead), NSInternalInconsistencyException);
@@ -929,7 +930,7 @@
newchunk = get_chunk(zptr, chunksize);
if (newchunk == NULL)
{
- objc_mutex_unlock(zptr->lock);
+ pthread_mutex_unlock(&(zptr->lock));
if (zone->name != nil)
[NSException raise: NSMallocException
format: @"Zone %@ has run out of memory",
@@ -947,7 +948,7 @@
*((char*)chunkhead->next) = (char)42;
chunkSetLive(chunkhead);
result = chunkToPointer(chunkhead);
- objc_mutex_unlock(zptr->lock);
+ pthread_mutex_unlock(&(zptr->lock));
return result;
}
@@ -957,14 +958,14 @@
{
ff_block *chunk;
NSAssert(NSZoneFromPointer(ptr) == zone, NSInternalInconsistencyException);
- objc_mutex_lock(((ffree_zone*)zone)->lock);
+ pthread_mutex_lock(&(((ffree_zone*)zone)->lock));
chunk = pointerToChunk(ptr);
if (chunkIsLive(chunk) == 0)
[NSException raise: NSMallocException
format: @"Attempt to free freed memory"];
NSAssert(*((char*)chunk->next) == (char)42, NSInternalInconsistencyException);
add_buf((ffree_zone*)zone, chunk);
- objc_mutex_unlock(((ffree_zone*)zone)->lock);
+ pthread_mutex_unlock(&(((ffree_zone*)zone)->lock));
}
static BOOL
@@ -974,7 +975,7 @@
ff_block *block;
ff_block *nextblock;
- objc_mutex_lock(zptr->lock);
+ pthread_mutex_lock(&(zptr->lock));
flush_buf(zptr);
block = zptr->blocks;
while (block != NULL)
@@ -996,10 +997,10 @@
}
block = nextblock;
}
- objc_mutex_unlock(zptr->lock);
+ pthread_mutex_unlock(&(zptr->lock));
if (zptr->blocks == 0)
{
- objc_mutex_deallocate(zptr->lock);
+ pthread_mutex_destroy(&(zptr->lock));
return YES;
}
return NO;
@@ -1048,7 +1049,7 @@
ffree_zone *zptr = (ffree_zone*)zone;
ff_block *block;
- objc_mutex_lock(zptr->lock);
+ pthread_mutex_lock(&(zptr->lock));
/* Check integrity of each block the zone owns. */
block = zptr->blocks;
while (block != NULL)
@@ -1141,11 +1142,11 @@
if ((zptr->size_buf[i] != chunkSize(chunk)) || !chunkIsInUse(chunk))
goto inconsistent;
}
- objc_mutex_unlock(zptr->lock);
+ pthread_mutex_unlock(&(zptr->lock));
return YES;
inconsistent: // Jump here if an inconsistency was found.
- objc_mutex_unlock(zptr->lock);
+ pthread_mutex_unlock(&(zptr->lock));
return NO;
}
@@ -1156,7 +1157,7 @@
ff_block *block;
BOOL found = NO;
- objc_mutex_lock(zptr->lock);
+ pthread_mutex_lock(&(zptr->lock));
for (block = zptr->blocks; block != NULL; block = block->next)
{
if (ptr >= (void*)block && ptr < (void*)chunkNext(block))
@@ -1165,7 +1166,7 @@
break;
}
}
- objc_mutex_unlock(zptr->lock);
+ pthread_mutex_unlock(&(zptr->lock));
return found;
}
@@ -1184,7 +1185,7 @@
stats.bytes_used = 0;
stats.chunks_free = 0;
stats.bytes_free = 0;
- objc_mutex_lock(zptr->lock);
+ pthread_mutex_lock(&(zptr->lock));
block = zptr->blocks;
/* Go through each block. */
while (block != NULL)
@@ -1219,7 +1220,7 @@
stats.bytes_used -= zptr->size_buf[i];
stats.bytes_free += zptr->size_buf[i];
}
- objc_mutex_unlock(zptr->lock);
+ pthread_mutex_unlock(&(zptr->lock));
/* Remove overhead. */
stats.bytes_used -= FBSZ*stats.chunks_used;
return stats;
@@ -1540,7 +1541,7 @@
nf_block *block;
size_t top;
- objc_mutex_lock(zptr->lock);
+ pthread_mutex_lock(&(zptr->lock));
block = zptr->blocks;
top = block->top;
freesize = block->size-top;
@@ -1575,7 +1576,7 @@
block = objc_malloc(blocksize);
if (block == NULL)
{
- objc_mutex_unlock(zptr->lock);
+ pthread_mutex_unlock(&(zptr->lock));
if (zone->name != nil)
[NSException raise: NSMallocException
format: @"Zone %@ has run out of memory",
@@ -1593,7 +1594,7 @@
block->top += chunksize;
}
zptr->use++;
- objc_mutex_unlock(zptr->lock);
+ pthread_mutex_unlock(&(zptr->lock));
return chunkhead;
}
@@ -1604,7 +1605,7 @@
{
nfree_zone *zptr = (nfree_zone*)zone;
- objc_mutex_lock(zptr->lock);
+ pthread_mutex_lock(&(zptr->lock));
if (zptr->use == 0)
{
nf_block *nextblock;
@@ -1618,10 +1619,10 @@
}
zptr->blocks = 0;
}
- objc_mutex_unlock(zptr->lock);
+ pthread_mutex_unlock(&(zptr->lock));
if (zptr->blocks == 0)
{
- objc_mutex_deallocate(zptr->lock);
+ pthread_mutex_destroy(&(zptr->lock));
return YES;
}
return NO;
@@ -1658,7 +1659,7 @@
if (ptr != 0)
{
- objc_mutex_lock(zptr->lock);
+ pthread_mutex_lock(&(zptr->lock));
if (tmp)
{
nf_block *block;
@@ -1678,7 +1679,7 @@
}
}
zptr->use--;
- objc_mutex_unlock(zptr->lock);
+ pthread_mutex_unlock(&(zptr->lock));
}
return tmp;
}
@@ -1694,9 +1695,9 @@
{
nfree_zone *zptr = (nfree_zone*)zone;
- objc_mutex_lock(zptr->lock);
+ pthread_mutex_lock(&(zptr->lock));
zptr->use--;
- objc_mutex_unlock(zptr->lock);
+ pthread_mutex_unlock(&(zptr->lock));
}
static void
@@ -1722,19 +1723,19 @@
nfree_zone *zptr = (nfree_zone*)zone;
nf_block *block;
- objc_mutex_lock(zptr->lock);
+ pthread_mutex_lock(&(zptr->lock));
block = zptr->blocks;
while (block != NULL)
{
if (block->size < block->top)
{
- objc_mutex_unlock(zptr->lock);
+ pthread_mutex_unlock(&(zptr->lock));
return NO;
}
block = block->next;
}
/* FIXME: Do more checking? */
- objc_mutex_unlock(zptr->lock);
+ pthread_mutex_unlock(&(zptr->lock));
return YES;
}
@@ -1745,7 +1746,7 @@
nf_block *block;
BOOL found = NO;
- objc_mutex_lock(zptr->lock);
+ pthread_mutex_lock(&(zptr->lock));
for (block = zptr->blocks; block != NULL; block = block->next)
{
if (ptr >= (void*)block && ptr < ((void*)block)+block->size)
@@ -1754,7 +1755,7 @@
break;
}
}
- objc_mutex_unlock(zptr->lock);
+ pthread_mutex_unlock(&(zptr->lock));
return found;
}
@@ -1772,7 +1773,7 @@
stats.bytes_used = 0;
stats.chunks_free = 0;
stats.bytes_free = 0;
- objc_mutex_lock(zptr->lock);
+ pthread_mutex_lock(&(zptr->lock));
block = zptr->blocks;
while (block != NULL)
{
@@ -1793,7 +1794,7 @@
}
block = block->next;
}
- objc_mutex_unlock(zptr->lock);
+ pthread_mutex_unlock(&(zptr->lock));
return stats;
}
@@ -1880,7 +1881,7 @@
zone->common.stats = fstats;
zone->common.gran = granularity;
zone->common.name = nil;
- zone->lock = objc_mutex_allocate();
+ GS_INIT_RECURSIVE_MUTEX(zone->lock);
for (i = 0; i < MAX_SEG; i++)
{
zone->segheadlist[i] = NULL;
@@ -1890,7 +1891,7 @@
zone->blocks = objc_malloc(startsize + 2*FBSZ);
if (zone->blocks == NULL)
{
- objc_mutex_deallocate(zone->lock);
+ pthread_mutex_destroy(&(zone->lock));
objc_free(zone);
[NSException raise: NSMallocException
format: @"No memory to create zone"];
@@ -1935,12 +1936,12 @@
zone->common.stats = nstats;
zone->common.gran = granularity;
zone->common.name = nil;
- zone->lock = objc_mutex_allocate();
+ GS_INIT_RECURSIVE_MUTEX(zone->lock);
zone->blocks = objc_malloc(startsize);
zone->use = 0;
if (zone->blocks == NULL)
{
- objc_mutex_deallocate(zone->lock);
+ pthread_mutex_destroy(&(zone->lock));
objc_free(zone);
[NSException raise: NSMallocException
format: @"No memory to create zone"];
Index: Source/Additions/GSObjCRuntime.m
===================================================================
--- Source/Additions/GSObjCRuntime.m (revision 29331)
+++ Source/Additions/GSObjCRuntime.m (working copy)
@@ -58,6 +58,10 @@
#include <string.h>
+#ifndef NeXT_RUNTIME
+#include <pthread.h>
+#endif
+
#ifdef NeXT_Foundation_LIBRARY
@interface NSObject (MissingFromMacOSX)
+ (IMP) methodForSelector: (SEL)aSelector;
@@ -67,59 +71,6 @@
#define BDBGPrintf(format, args...) \
do { if (behavior_debug) { fprintf(stderr, (format) , ## args); } } while (0)
-static objc_mutex_t local_lock = NULL;
-
-/* This class it intended soley for thread safe / +load safe
- initialization of the local lock.
- It's a root class so it won't trigger the initialization
- of any other class. */
-...@interface _GSObjCRuntimeInitializer /* Root Class */
-{
- Class isa;
-}
-+ (Class)class;
-...@end
-...@implementation _GSObjCRuntimeInitializer
-+ (void)initialize
-{
- if (local_lock == NULL)
- {
- local_lock = objc_mutex_allocate();
- }
-}
-+ (Class)class
-{
- return self;
-}
-...@end
-
-void
-GSAllocateMutexAt(objc_mutex_t *request)
-{
- if (request == NULL)
- {
- /* This could be called very early in process
- initialization so many things may not have
- been setup correctly yet. */
- fprintf(stderr,
- "Error: GSAllocateMutexAt() called with NULL pointer.\n");
- abort();
- }
-
- if (local_lock == NULL)
- {
- /* Initialize in a thread safe way. */
- [_GSObjCRuntimeInitializer class];
- }
-
- objc_mutex_lock(local_lock);
- if (*request == NULL)
- {
- *request = objc_mutex_allocate();
- }
- objc_mutex_unlock(local_lock);
-}
-
/**
* This function is used to locate information about the instance
* variable of obj called name. It returns YES if the variable
@@ -310,16 +261,11 @@
#else
static Class *cache = 0;
static unsigned cacheClassCount = 0;
- static volatile objc_mutex_t cache_lock = NULL;
+ static pthread_mutex_t cache_lock = PTHREAD_MUTEX_INITIALIZER;
unsigned int num;
- if (cache_lock == NULL)
- {
- GSAllocateMutexAt((void*)&cache_lock);
- }
+ pthread_mutex_lock(&cache_lock);
- objc_mutex_lock(cache_lock);
-
if (clearCache)
{
if (cache)
@@ -369,7 +315,7 @@
num = (max > cacheClassCount) ? 0 : (cacheClassCount - max);
}
- objc_mutex_unlock(cache_lock);
+ pthread_mutex_unlock(&cache_lock);
#endif
@@ -1267,26 +1213,22 @@
static GSIMapTable_t protocol_by_name;
static BOOL protocol_by_name_init = NO;
-static volatile objc_mutex_t protocol_by_name_lock = NULL;
+static pthread_mutex_t protocol_by_name_lock = PTHREAD_MUTEX_INITIALIZER;
/* Not sure about the semantics of inlining
functions with static variables. */
static void
gs_init_protocol_lock(void)
{
- if (protocol_by_name_lock == NULL)
- {
- GSAllocateMutexAt((void *)&protocol_by_name_lock);
- objc_mutex_lock(protocol_by_name_lock);
- if (protocol_by_name_init == NO)
- {
+ pthread_mutex_lock(&protocol_by_name_lock);
+ if (protocol_by_name_init == NO)
+ {
GSIMapInitWithZoneAndCapacity (&protocol_by_name,
NSDefaultMallocZone(),
128);
protocol_by_name_init = YES;
}
- objc_mutex_unlock(protocol_by_name_lock);
- }
+ pthread_mutex_unlock(&protocol_by_name_lock);
}
void
@@ -1303,7 +1245,7 @@
pcl p;
p = (pcl)proto;
- objc_mutex_lock(protocol_by_name_lock);
+ pthread_mutex_lock(&protocol_by_name_lock);
node = GSIMapNodeForKey(&protocol_by_name,
(GSIMapKey) p->protocol_name);
if (node == 0)
@@ -1312,7 +1254,7 @@
(GSIMapKey) (void *) p->protocol_name,
(GSIMapVal) (void *) p);
}
- objc_mutex_unlock(protocol_by_name_lock);
+ pthread_mutex_unlock(&protocol_by_name_lock);
}
}
@@ -1334,7 +1276,7 @@
}
else
{
- objc_mutex_lock(protocol_by_name_lock);
+ pthread_mutex_lock(&protocol_by_name_lock);
node = GSIMapNodeForKey(&protocol_by_name, (GSIMapKey) name);
if (node)
@@ -1353,7 +1295,7 @@
(GSIMapVal) (void *) p);
}
}
- objc_mutex_unlock(protocol_by_name_lock);
+ pthread_mutex_unlock(&protocol_by_name_lock);
}
Index: Source/Additions/GCObject.m
===================================================================
--- Source/Additions/GCObject.m (revision 29331)
+++ Source/Additions/GCObject.m (working copy)
@@ -40,6 +40,7 @@
#include "GNUstepBase/GCObject.h"
#include "GNUstepBase/GSCategories.h"
+#include <pthread.h>
/*
* The head of a linked list of all garbage collecting objects is a
@@ -70,18 +71,25 @@
#ifdef NeXT_RUNTIME
static void *allocationLock = NULL;
-#define objc_mutex_allocate() NULL
-#define objc_mutex_lock(lock)
-#define objc_mutex_unlock(lock)
+#define pthread_mutex_lock(lock)
+#define pthread_mutex_unlock(lock)
#else
-static objc_mutex_t allocationLock = NULL;
+static pthread_mutex_t *allocationLock = NULL;
#endif
+ (void) _becomeMultiThreaded: (NSNotification *)aNotification
{
- if (allocationLock == 0)
+ if (allocationLock == NULL)
{
- allocationLock = objc_mutex_allocate();
+# ifndef NeXT_RUNTIME
+ allocationLock = malloc(sizeof(pthread_mutex_t));
+ if (allocationLock == NULL)
+ {
+ abort();
+ }
+
+ pthread_mutex_init(allocationLock, NULL);
+# endif
}
}
@@ -95,7 +103,7 @@
if (allocationLock != 0)
{
- objc_mutex_lock(allocationLock);
+ pthread_mutex_lock(allocationLock);
}
o->gc.next = allObjects;
o->gc.previous = allObjects->gc.previous;
@@ -104,7 +112,7 @@
o->gc.flags.refCount = 1;
if (allocationLock != 0)
{
- objc_mutex_unlock(allocationLock);
+ pthread_mutex_unlock(allocationLock);
}
return o;
@@ -145,13 +153,13 @@
if (allocationLock != 0)
{
- objc_mutex_lock(allocationLock);
+ pthread_mutex_lock(allocationLock);
}
if (isCollecting == YES)
{
if (allocationLock != 0)
{
- objc_mutex_unlock(allocationLock);
+ pthread_mutex_unlock(allocationLock);
}
return; // Don't allow recursion.
}
@@ -211,7 +219,7 @@
isCollecting = NO;
if (allocationLock != 0)
{
- objc_mutex_unlock(allocationLock);
+ pthread_mutex_unlock(allocationLock);
}
}
@@ -261,7 +269,7 @@
if (allocationLock != 0)
{
- objc_mutex_lock(allocationLock);
+ pthread_mutex_lock(allocationLock);
}
// p = anObject->gc.previous;
// n = anObject->gc.next;
@@ -273,7 +281,7 @@
[n gcSetPreviousObject: p];
if (allocationLock != 0)
{
- objc_mutex_unlock(allocationLock);
+ pthread_mutex_unlock(allocationLock);
}
}
@@ -288,7 +296,7 @@
if (allocationLock != 0)
{
- objc_mutex_lock(allocationLock);
+ pthread_mutex_lock(allocationLock);
}
o->gc.next = allObjects;
o->gc.previous = allObjects->gc.previous;
@@ -297,7 +305,7 @@
o->gc.flags.refCount = 1;
if (allocationLock != 0)
{
- objc_mutex_unlock(allocationLock);
+ pthread_mutex_unlock(allocationLock);
}
return o;
}
@@ -315,7 +323,7 @@
if (allocationLock != 0)
{
- objc_mutex_lock(allocationLock);
+ pthread_mutex_lock(allocationLock);
}
// p = anObject->gc.previous;
// n = anObject->gc.next;
@@ -327,7 +335,7 @@
[n gcSetPreviousObject: p];
if (allocationLock != 0)
{
- objc_mutex_unlock(allocationLock);
+ pthread_mutex_unlock(allocationLock);
}
[super dealloc];
}
@@ -410,7 +418,7 @@
{
if (allocationLock != 0)
{
- objc_mutex_lock(allocationLock);
+ pthread_mutex_lock(allocationLock);
}
if (gc.flags.refCount > 0 && gc.flags.refCount-- == 1)
{
@@ -419,7 +427,7 @@
}
if (allocationLock != 0)
{
- objc_mutex_unlock(allocationLock);
+ pthread_mutex_unlock(allocationLock);
}
}
@@ -430,12 +438,12 @@
{
if (allocationLock != 0)
{
- objc_mutex_lock(allocationLock);
+ pthread_mutex_lock(allocationLock);
}
gc.flags.refCount++;
if (allocationLock != 0)
{
- objc_mutex_unlock(allocationLock);
+ pthread_mutex_unlock(allocationLock);
}
return self;
}
Index: Source/synchronization.m
===================================================================
--- Source/synchronization.m (revision 29331)
+++ Source/synchronization.m (working copy)
@@ -22,17 +22,18 @@
Boston, MA 02111 USA.
*/
+
#include <stdlib.h>
#include "objc/objc.h"
#include "objc/objc-api.h"
-#include "objc/thr.h"
+#include "GSPThread.h"
/*
* Node structure...
*/
typedef struct lock_node {
id obj;
- objc_mutex_t lock;
+ pthread_mutex_t lock;
struct lock_node *next;
struct lock_node *prev;
} lock_node_t;
@@ -48,21 +49,9 @@
} sync_return_t;
static lock_node_t *lock_list = NULL;
-static objc_mutex_t table_lock = NULL;
+static pthread_mutex_t table_lock = PTHREAD_MUTEX_INITIALIZER;
/**
- * Initialize the table lock.
- */
-static void
-sync_lock_init()
-{
- if (table_lock == NULL)
- {
- table_lock = objc_mutex_allocate();
- }
-}
-
-/**
* Find the node in the list.
*/
static lock_node_t*
@@ -97,9 +86,6 @@
{
lock_node_t *current = NULL;
- // get the lock...
- sync_lock_init();
-
// if the list hasn't been initialized, initialize it.
if (lock_list == NULL)
{
@@ -143,7 +129,7 @@
{
// add the object and it's lock
current->obj = obj;
- current->lock = objc_mutex_allocate();
+ GS_INIT_RECURSIVE_MUTEX(current->lock);
}
return current;
@@ -163,9 +149,7 @@
lock_node_t *node = NULL;
int status = 0;
- // lock access to the table until we're done....
- sync_lock_init();
- objc_mutex_lock(table_lock);
+ pthread_mutex_lock(&table_lock);
node = sync_find_node(obj);
if (node == NULL)
@@ -174,15 +158,15 @@
if (node == NULL)
{
// unlock the table....
- objc_mutex_unlock(table_lock);
+ pthread_mutex_unlock(&table_lock);
return OBJC_SYNC_NOT_INITIALIZED;
}
}
// unlock the table....
- objc_mutex_unlock(table_lock);
+ pthread_mutex_unlock(&table_lock);
- status = objc_mutex_lock(node->lock);
+ status = pthread_mutex_lock(&(node->lock));
// if the status is more than one, then another thread
// has this section locked, so we abort. A status of -1
@@ -209,22 +193,20 @@
lock_node_t *node = NULL;
int status = 0;
- // lock access to the table until we're done....
- sync_lock_init();
- objc_mutex_lock(table_lock);
+ pthread_mutex_lock(&table_lock);
node = sync_find_node(obj);
if (node == NULL)
{
// unlock the table....
- objc_mutex_unlock(table_lock);
+ pthread_mutex_unlock(&table_lock);
return OBJC_SYNC_NOT_INITIALIZED;
}
- status = objc_mutex_unlock(node->lock);
+ status = pthread_mutex_unlock(&(node->lock));
// unlock the table....
- objc_mutex_unlock(table_lock);
+ pthread_mutex_unlock(&table_lock);
// if the status is not zero, then we are not the sole
// owner of this node. Also if -1 is returned, this indicates and error
Index: Headers/Additions/GNUstepBase/GSObjCRuntime.h
===================================================================
--- Headers/Additions/GNUstepBase/GSObjCRuntime.h (revision 29331)
+++ Headers/Additions/GNUstepBase/GSObjCRuntime.h (working copy)
@@ -657,31 +657,6 @@
GSAutoreleasedBuffer(unsigned size);
/**
- * Allocate a new objc_mutex_t and store it in the location
- * pointed to by request. A mutex is only created if the value
- * pointed to by request is NULL. This function is thread safe
- * in the sense that multiple threads my call this function with the same
- * value of request and only one will actually set the mutex.
- * It is the users responsibility that no one else attempts to set
- * the mutex pointed to. This function should be
- * used with objc_mutex_t variables which were statically initialized
- * to NULL like:
- * <example>
- * void function (void)
- * {
- * static objc_mutex_t my_lock = NULL;
- * if (my_lock == NULL)
- * GSAllocateMutexAt(&my_lock);
- * objc_mutex_lock(my_lock);
- * do_work ();
- * objc_mutex_unlock(my_lock);
- * }
- * </example>
- */
-GS_EXPORT void
-GSAllocateMutexAt(objc_mutex_t *request);
-
-/**
* <p>Prints a message to fptr using the format string provided and any
* additional arguments. The format string is interpreted as by
* the NSString formatted initialisers, and understands the '%@' syntax
signature.asc
Description: Digital signature
_______________________________________________ Gnustep-dev mailing list [email protected] http://lists.gnu.org/mailman/listinfo/gnustep-dev
