mirror of
https://github.com/gnustep/libs-base.git
synced 2025-06-02 17:41:05 +00:00
Use native threading and locking APIs on Windows
Removes dependency on pthread library and uses fast Slim Reader/Writer (SRW) locks for NSLock/NSRecursiveLock/NSCondition/NSConditionLock as well as all internal locks. Adds GS_MUTEX_*() macros in GSPThread.h, that are being used for all internal locking instead of pthread APIs. Also adds support for thread priorities on Windows, fixes method signature of +[NSThread setThreadPriority:] to match Apple platforms, and adds error handling in same method.
This commit is contained in:
parent
3b8bbb00ba
commit
abfe4e2a04
29 changed files with 1611 additions and 640 deletions
39
ChangeLog
39
ChangeLog
|
@ -21,6 +21,45 @@
|
||||||
Changes to add support for 64bit transitions used by v2+ of the
|
Changes to add support for 64bit transitions used by v2+ of the
|
||||||
timezone format.
|
timezone format.
|
||||||
|
|
||||||
|
2021-07-14 Frederik Seiffert <frederik@algoriddim.com>
|
||||||
|
|
||||||
|
* Headers/Foundation/NSLock.h:
|
||||||
|
* Headers/Foundation/NSThread.h:
|
||||||
|
* Headers/GNUstepBase/GSConfig.h.in:
|
||||||
|
* Headers/GNUstepBase/config.h.in:
|
||||||
|
* Source/Additions/GCObject.m:
|
||||||
|
* Source/Additions/GSObjCRuntime.m:
|
||||||
|
* Source/Additions/Unicode.m:
|
||||||
|
* Source/GSAtomic.h:
|
||||||
|
* Source/GSFFCallInvocation.m:
|
||||||
|
* Source/GSFFIInvocation.m:
|
||||||
|
* Source/GSPThread.h:
|
||||||
|
* Source/NSArray.m:
|
||||||
|
* Source/NSCharacterSet.m:
|
||||||
|
* Source/NSDebug.m:
|
||||||
|
* Source/NSException.m:
|
||||||
|
* Source/NSLock.m:
|
||||||
|
* Source/NSObject.m:
|
||||||
|
* Source/NSScanner.m:
|
||||||
|
* Source/NSString.m:
|
||||||
|
* Source/NSThread.m:
|
||||||
|
* Source/NSTimeZone.m:
|
||||||
|
* Source/NSZone.m:
|
||||||
|
* Tests/base/NSThread/GNUmakefile.preamble:
|
||||||
|
* Tests/base/NSThread/late_unregister.m:
|
||||||
|
* Tests/base/NSThread/lazy_thread.m:
|
||||||
|
* config/config.initialize.m:
|
||||||
|
* configure:
|
||||||
|
* configure.ac:
|
||||||
|
Use native threading and locking APIs on Windows, removing dependency
|
||||||
|
on pthread library and using fast Slim Reader/Writer (SRW) locks for
|
||||||
|
NSLock/NSRecursiveLock/NSCondition/NSConditionLock as well as all
|
||||||
|
internal locks. Adds GS_MUTEX_*() macros in GSPThread.h, that are being
|
||||||
|
used for all internal locking instead of pthread APIs.
|
||||||
|
Also adds support for thread priorities on Windows, fixes method
|
||||||
|
signature of +[NSThread setThreadPriority:] to match Apple platforms,
|
||||||
|
and adds error handling in same method.
|
||||||
|
|
||||||
2021-07-16 Frederik Seiffert <frederik@algoriddim.com>
|
2021-07-16 Frederik Seiffert <frederik@algoriddim.com>
|
||||||
|
|
||||||
* Source/GSICUString.h:
|
* Source/GSICUString.h:
|
||||||
|
|
|
@ -74,7 +74,7 @@ GS_EXPORT_CLASS
|
||||||
{
|
{
|
||||||
#if GS_EXPOSE(NSLock)
|
#if GS_EXPOSE(NSLock)
|
||||||
@protected
|
@protected
|
||||||
gs_mutex_t _mutex;
|
gs_mutex_public_t _mutex;
|
||||||
NSString *_name;
|
NSString *_name;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -126,8 +126,8 @@ GS_EXPORT_CLASS
|
||||||
{
|
{
|
||||||
#if GS_EXPOSE(NSCondition)
|
#if GS_EXPOSE(NSCondition)
|
||||||
@protected
|
@protected
|
||||||
gs_cond_t _condition;
|
gs_cond_public_t _condition;
|
||||||
gs_mutex_t _mutex;
|
gs_mutex_public_t _mutex;
|
||||||
NSString *_name;
|
NSString *_name;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -278,7 +278,7 @@ GS_EXPORT_CLASS
|
||||||
{
|
{
|
||||||
#if GS_EXPOSE(NSRecursiveLock)
|
#if GS_EXPOSE(NSRecursiveLock)
|
||||||
@protected
|
@protected
|
||||||
gs_mutex_t _mutex;
|
gs_mutex_public_t _mutex;
|
||||||
NSString *_name;
|
NSString *_name;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,7 +134,7 @@ GS_EXPORT_CLASS
|
||||||
|
|
||||||
#if OS_API_VERSION(MAC_OS_X_VERSION_10_2,GS_API_LATEST) \
|
#if OS_API_VERSION(MAC_OS_X_VERSION_10_2,GS_API_LATEST) \
|
||||||
&& GS_API_VERSION( 10200,GS_API_LATEST)
|
&& GS_API_VERSION( 10200,GS_API_LATEST)
|
||||||
+ (void) setThreadPriority: (double)pri;
|
+ (BOOL) setThreadPriority: (double)pri;
|
||||||
+ (double) threadPriority;
|
+ (double) threadPriority;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -254,10 +254,13 @@ typedef gsuaddr gsaddr;
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t dummy[@GS_SIZEOF_COND_T@];
|
uint8_t dummy[@GS_SIZEOF_COND_T@];
|
||||||
} gs_cond_t __attribute__((aligned (@GS_ALIGNOF_COND_T@)));
|
} gs_cond_public_t __attribute__((aligned (@GS_ALIGNOF_COND_T@)));
|
||||||
|
typedef struct {
|
||||||
|
uint8_t dummy[@GS_SIZEOF_COND_MUTEX_T@];
|
||||||
|
} gs_cond_mutex_public_t __attribute__((aligned (@GS_ALIGNOF_COND_MUTEX_T@)));
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t dummy[@GS_SIZEOF_MUTEX_T@];
|
uint8_t dummy[@GS_SIZEOF_MUTEX_T@];
|
||||||
} gs_mutex_t __attribute__((aligned (@GS_ALIGNOF_MUTEX_T@)));
|
} gs_mutex_public_t __attribute__((aligned (@GS_ALIGNOF_MUTEX_T@)));
|
||||||
|
|
||||||
#define OBJC2RUNTIME @OBJC2RUNTIME@
|
#define OBJC2RUNTIME @OBJC2RUNTIME@
|
||||||
#define BASE_NATIVE_OBJC_EXCEPTIONS @BASE_NATIVE_OBJC_EXCEPTIONS@
|
#define BASE_NATIVE_OBJC_EXCEPTIONS @BASE_NATIVE_OBJC_EXCEPTIONS@
|
||||||
|
@ -272,6 +275,7 @@ typedef struct {
|
||||||
#define GS_USE_LIBDISPATCH_RUNLOOP @HAVE_LIBDISPATCH_RUNLOOP@
|
#define GS_USE_LIBDISPATCH_RUNLOOP @HAVE_LIBDISPATCH_RUNLOOP@
|
||||||
#define GS_HAVE_NSURLSESSION @GS_HAVE_NSURLSESSION@
|
#define GS_HAVE_NSURLSESSION @GS_HAVE_NSURLSESSION@
|
||||||
#define GS_HAVE_OBJC_ROOT_CLASS_ATTR @GS_HAVE_OBJC_ROOT_CLASS_ATTR@
|
#define GS_HAVE_OBJC_ROOT_CLASS_ATTR @GS_HAVE_OBJC_ROOT_CLASS_ATTR@
|
||||||
|
#define GS_USE_WIN32_THREADS_AND_LOCKS @HAVE_WIN32_THREADS_AND_LOCKS@
|
||||||
|
|
||||||
#ifndef __has_include
|
#ifndef __has_include
|
||||||
# define __has_include(x) 0
|
# define __has_include(x) 0
|
||||||
|
|
|
@ -3,12 +3,21 @@
|
||||||
/* Define if building universal (internal helper macro) */
|
/* Define if building universal (internal helper macro) */
|
||||||
#undef AC_APPLE_UNIVERSAL_BUILD
|
#undef AC_APPLE_UNIVERSAL_BUILD
|
||||||
|
|
||||||
|
/* The normal alignment of `CONDITION_VARIABLE', in bytes. */
|
||||||
|
#undef ALIGNOF_CONDITION_VARIABLE
|
||||||
|
|
||||||
|
/* The normal alignment of `gs_mutex_t', in bytes. */
|
||||||
|
#undef ALIGNOF_GS_MUTEX_T
|
||||||
|
|
||||||
/* The normal alignment of `pthread_cond_t', in bytes. */
|
/* The normal alignment of `pthread_cond_t', in bytes. */
|
||||||
#undef ALIGNOF_PTHREAD_COND_T
|
#undef ALIGNOF_PTHREAD_COND_T
|
||||||
|
|
||||||
/* The normal alignment of `pthread_mutex_t', in bytes. */
|
/* The normal alignment of `pthread_mutex_t', in bytes. */
|
||||||
#undef ALIGNOF_PTHREAD_MUTEX_T
|
#undef ALIGNOF_PTHREAD_MUTEX_T
|
||||||
|
|
||||||
|
/* The normal alignment of `SRWLOCK', in bytes. */
|
||||||
|
#undef ALIGNOF_SRWLOCK
|
||||||
|
|
||||||
/* Define if SO_REUSEADDR is broken on this system */
|
/* Define if SO_REUSEADDR is broken on this system */
|
||||||
#undef BROKEN_SO_REUSEADDR
|
#undef BROKEN_SO_REUSEADDR
|
||||||
|
|
||||||
|
@ -858,12 +867,18 @@
|
||||||
/* Define to 1 if the `setpgrp' function takes no argument. */
|
/* Define to 1 if the `setpgrp' function takes no argument. */
|
||||||
#undef SETPGRP_VOID
|
#undef SETPGRP_VOID
|
||||||
|
|
||||||
|
/* The size of `CONDITION_VARIABLE', as computed by sizeof. */
|
||||||
|
#undef SIZEOF_CONDITION_VARIABLE
|
||||||
|
|
||||||
/* The size of `double', as computed by sizeof. */
|
/* The size of `double', as computed by sizeof. */
|
||||||
#undef SIZEOF_DOUBLE
|
#undef SIZEOF_DOUBLE
|
||||||
|
|
||||||
/* The size of `float', as computed by sizeof. */
|
/* The size of `float', as computed by sizeof. */
|
||||||
#undef SIZEOF_FLOAT
|
#undef SIZEOF_FLOAT
|
||||||
|
|
||||||
|
/* The size of `gs_mutex_t', as computed by sizeof. */
|
||||||
|
#undef SIZEOF_GS_MUTEX_T
|
||||||
|
|
||||||
/* The size of `int', as computed by sizeof. */
|
/* The size of `int', as computed by sizeof. */
|
||||||
#undef SIZEOF_INT
|
#undef SIZEOF_INT
|
||||||
|
|
||||||
|
@ -882,6 +897,9 @@
|
||||||
/* The size of `short', as computed by sizeof. */
|
/* The size of `short', as computed by sizeof. */
|
||||||
#undef SIZEOF_SHORT
|
#undef SIZEOF_SHORT
|
||||||
|
|
||||||
|
/* The size of `SRWLOCK', as computed by sizeof. */
|
||||||
|
#undef SIZEOF_SRWLOCK
|
||||||
|
|
||||||
/* The size of `void*', as computed by sizeof. */
|
/* The size of `void*', as computed by sizeof. */
|
||||||
#undef SIZEOF_VOIDP
|
#undef SIZEOF_VOIDP
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
#import "GNUstepBase/GCObject.h"
|
#import "GNUstepBase/GCObject.h"
|
||||||
|
|
||||||
#include <pthread.h>
|
#import "../GSPThread.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The head of a linked list of all garbage collecting objects is a
|
* The head of a linked list of all garbage collecting objects is a
|
||||||
|
@ -65,27 +65,20 @@
|
||||||
|
|
||||||
static GCObject *allObjects = nil;
|
static GCObject *allObjects = nil;
|
||||||
static BOOL isCollecting = NO;
|
static BOOL isCollecting = NO;
|
||||||
|
static gs_mutex_t *allocationLock = NULL;
|
||||||
#ifdef NeXT_RUNTIME
|
|
||||||
static void *allocationLock = NULL;
|
|
||||||
#define pthread_mutex_lock(lock)
|
|
||||||
#define pthread_mutex_unlock(lock)
|
|
||||||
#else
|
|
||||||
static pthread_mutex_t *allocationLock = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+ (void) _becomeMultiThreaded: (NSNotification *)aNotification
|
+ (void) _becomeMultiThreaded: (NSNotification *)aNotification
|
||||||
{
|
{
|
||||||
if (allocationLock == NULL)
|
if (allocationLock == NULL)
|
||||||
{
|
{
|
||||||
# ifndef NeXT_RUNTIME
|
# ifndef NeXT_RUNTIME
|
||||||
allocationLock = malloc(sizeof(pthread_mutex_t));
|
allocationLock = malloc(sizeof(gs_mutex_t));
|
||||||
if (allocationLock == NULL)
|
if (allocationLock == NULL)
|
||||||
{
|
{
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_init(allocationLock, NULL);
|
GS_MUTEX_INIT(*allocationLock);
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,7 +93,7 @@ static pthread_mutex_t *allocationLock = NULL;
|
||||||
|
|
||||||
if (allocationLock != 0)
|
if (allocationLock != 0)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(allocationLock);
|
GS_MUTEX_LOCK(*allocationLock);
|
||||||
}
|
}
|
||||||
o->gc.next = allObjects;
|
o->gc.next = allObjects;
|
||||||
o->gc.previous = allObjects->gc.previous;
|
o->gc.previous = allObjects->gc.previous;
|
||||||
|
@ -109,7 +102,7 @@ static pthread_mutex_t *allocationLock = NULL;
|
||||||
o->gc.flags.refCount = 1;
|
o->gc.flags.refCount = 1;
|
||||||
if (allocationLock != 0)
|
if (allocationLock != 0)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(allocationLock);
|
GS_MUTEX_UNLOCK(*allocationLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
return o;
|
return o;
|
||||||
|
@ -150,13 +143,13 @@ static pthread_mutex_t *allocationLock = NULL;
|
||||||
|
|
||||||
if (allocationLock != 0)
|
if (allocationLock != 0)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(allocationLock);
|
GS_MUTEX_LOCK(*allocationLock);
|
||||||
}
|
}
|
||||||
if (isCollecting == YES)
|
if (isCollecting == YES)
|
||||||
{
|
{
|
||||||
if (allocationLock != 0)
|
if (allocationLock != 0)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(allocationLock);
|
GS_MUTEX_UNLOCK(*allocationLock);
|
||||||
}
|
}
|
||||||
return; // Don't allow recursion.
|
return; // Don't allow recursion.
|
||||||
}
|
}
|
||||||
|
@ -216,7 +209,7 @@ static pthread_mutex_t *allocationLock = NULL;
|
||||||
isCollecting = NO;
|
isCollecting = NO;
|
||||||
if (allocationLock != 0)
|
if (allocationLock != 0)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(allocationLock);
|
GS_MUTEX_UNLOCK(*allocationLock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,7 +260,7 @@ static pthread_mutex_t *allocationLock = NULL;
|
||||||
|
|
||||||
if (allocationLock != 0)
|
if (allocationLock != 0)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(allocationLock);
|
GS_MUTEX_LOCK(*allocationLock);
|
||||||
}
|
}
|
||||||
// p = anObject->gc.previous;
|
// p = anObject->gc.previous;
|
||||||
// n = anObject->gc.next;
|
// n = anObject->gc.next;
|
||||||
|
@ -279,7 +272,7 @@ static pthread_mutex_t *allocationLock = NULL;
|
||||||
[n gcSetPreviousObject: p];
|
[n gcSetPreviousObject: p];
|
||||||
if (allocationLock != 0)
|
if (allocationLock != 0)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(allocationLock);
|
GS_MUTEX_UNLOCK(*allocationLock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,7 +287,7 @@ static pthread_mutex_t *allocationLock = NULL;
|
||||||
|
|
||||||
if (allocationLock != 0)
|
if (allocationLock != 0)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(allocationLock);
|
GS_MUTEX_LOCK(*allocationLock);
|
||||||
}
|
}
|
||||||
o->gc.next = allObjects;
|
o->gc.next = allObjects;
|
||||||
o->gc.previous = allObjects->gc.previous;
|
o->gc.previous = allObjects->gc.previous;
|
||||||
|
@ -303,7 +296,7 @@ static pthread_mutex_t *allocationLock = NULL;
|
||||||
o->gc.flags.refCount = 1;
|
o->gc.flags.refCount = 1;
|
||||||
if (allocationLock != 0)
|
if (allocationLock != 0)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(allocationLock);
|
GS_MUTEX_UNLOCK(*allocationLock);
|
||||||
}
|
}
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
@ -321,7 +314,7 @@ static pthread_mutex_t *allocationLock = NULL;
|
||||||
|
|
||||||
if (allocationLock != 0)
|
if (allocationLock != 0)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(allocationLock);
|
GS_MUTEX_LOCK(*allocationLock);
|
||||||
}
|
}
|
||||||
// p = anObject->gc.previous;
|
// p = anObject->gc.previous;
|
||||||
// n = anObject->gc.next;
|
// n = anObject->gc.next;
|
||||||
|
@ -333,7 +326,7 @@ static pthread_mutex_t *allocationLock = NULL;
|
||||||
[n gcSetPreviousObject: p];
|
[n gcSetPreviousObject: p];
|
||||||
if (allocationLock != 0)
|
if (allocationLock != 0)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(allocationLock);
|
GS_MUTEX_UNLOCK(*allocationLock);
|
||||||
}
|
}
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
@ -416,7 +409,7 @@ static pthread_mutex_t *allocationLock = NULL;
|
||||||
{
|
{
|
||||||
if (allocationLock != 0)
|
if (allocationLock != 0)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(allocationLock);
|
GS_MUTEX_LOCK(*allocationLock);
|
||||||
}
|
}
|
||||||
if (gc.flags.refCount > 0 && gc.flags.refCount-- == 1)
|
if (gc.flags.refCount > 0 && gc.flags.refCount-- == 1)
|
||||||
{
|
{
|
||||||
|
@ -425,7 +418,7 @@ static pthread_mutex_t *allocationLock = NULL;
|
||||||
}
|
}
|
||||||
if (allocationLock != 0)
|
if (allocationLock != 0)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(allocationLock);
|
GS_MUTEX_UNLOCK(*allocationLock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,12 +429,12 @@ static pthread_mutex_t *allocationLock = NULL;
|
||||||
{
|
{
|
||||||
if (allocationLock != 0)
|
if (allocationLock != 0)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(allocationLock);
|
GS_MUTEX_LOCK(*allocationLock);
|
||||||
}
|
}
|
||||||
gc.flags.refCount++;
|
gc.flags.refCount++;
|
||||||
if (allocationLock != 0)
|
if (allocationLock != 0)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(allocationLock);
|
GS_MUTEX_UNLOCK(*allocationLock);
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,16 +48,15 @@
|
||||||
#import "GNUstepBase/NSObject+GNUstepBase.h"
|
#import "GNUstepBase/NSObject+GNUstepBase.h"
|
||||||
|
|
||||||
#import "../GSPrivate.h"
|
#import "../GSPrivate.h"
|
||||||
|
#import "../GSPThread.h"
|
||||||
|
|
||||||
#include <objc/Protocol.h>
|
#include <objc/Protocol.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#ifndef NeXT_RUNTIME
|
|
||||||
#include <pthread.h>
|
|
||||||
#endif
|
|
||||||
#ifdef __GNUSTEP_RUNTIME__
|
#ifdef __GNUSTEP_RUNTIME__
|
||||||
|
GS_IMPORT
|
||||||
extern struct objc_slot *objc_get_slot(Class, SEL);
|
extern struct objc_slot *objc_get_slot(Class, SEL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -728,18 +727,17 @@ gs_string_hash(const char *s)
|
||||||
#define GSI_MAP_VTYPES GSUNION_PTR
|
#define GSI_MAP_VTYPES GSUNION_PTR
|
||||||
|
|
||||||
#include "GNUstepBase/GSIMap.h"
|
#include "GNUstepBase/GSIMap.h"
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
static GSIMapTable_t protocol_by_name;
|
static GSIMapTable_t protocol_by_name;
|
||||||
static BOOL protocol_by_name_init = NO;
|
static BOOL protocol_by_name_init = NO;
|
||||||
static pthread_mutex_t protocol_by_name_lock = PTHREAD_MUTEX_INITIALIZER;
|
static gs_mutex_t protocol_by_name_lock = GS_MUTEX_INIT_STATIC;
|
||||||
|
|
||||||
/* Not sure about the semantics of inlining
|
/* Not sure about the semantics of inlining
|
||||||
functions with static variables. */
|
functions with static variables. */
|
||||||
static void
|
static void
|
||||||
gs_init_protocol_lock(void)
|
gs_init_protocol_lock(void)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&protocol_by_name_lock);
|
GS_MUTEX_LOCK(protocol_by_name_lock);
|
||||||
if (protocol_by_name_init == NO)
|
if (protocol_by_name_init == NO)
|
||||||
{
|
{
|
||||||
GSIMapInitWithZoneAndCapacity (&protocol_by_name,
|
GSIMapInitWithZoneAndCapacity (&protocol_by_name,
|
||||||
|
@ -747,7 +745,7 @@ gs_init_protocol_lock(void)
|
||||||
128);
|
128);
|
||||||
protocol_by_name_init = YES;
|
protocol_by_name_init = YES;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&protocol_by_name_lock);
|
GS_MUTEX_UNLOCK(protocol_by_name_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -762,7 +760,7 @@ GSRegisterProtocol(Protocol *proto)
|
||||||
{
|
{
|
||||||
GSIMapNode node;
|
GSIMapNode node;
|
||||||
|
|
||||||
pthread_mutex_lock(&protocol_by_name_lock);
|
GS_MUTEX_LOCK(protocol_by_name_lock);
|
||||||
node = GSIMapNodeForKey(&protocol_by_name,
|
node = GSIMapNodeForKey(&protocol_by_name,
|
||||||
(GSIMapKey)protocol_getName(proto));
|
(GSIMapKey)protocol_getName(proto));
|
||||||
if (node == 0)
|
if (node == 0)
|
||||||
|
@ -771,7 +769,7 @@ GSRegisterProtocol(Protocol *proto)
|
||||||
(GSIMapKey)(void*)protocol_getName(proto),
|
(GSIMapKey)(void*)protocol_getName(proto),
|
||||||
(GSIMapVal)(void*)proto);
|
(GSIMapVal)(void*)proto);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&protocol_by_name_lock);
|
GS_MUTEX_UNLOCK(protocol_by_name_lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -793,7 +791,7 @@ GSProtocolFromName(const char *name)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&protocol_by_name_lock);
|
GS_MUTEX_LOCK(protocol_by_name_lock);
|
||||||
node = GSIMapNodeForKey(&protocol_by_name, (GSIMapKey) name);
|
node = GSIMapNodeForKey(&protocol_by_name, (GSIMapKey) name);
|
||||||
|
|
||||||
if (node)
|
if (node)
|
||||||
|
@ -812,7 +810,7 @@ GSProtocolFromName(const char *name)
|
||||||
(GSIMapVal)(void*)p);
|
(GSIMapVal)(void*)p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&protocol_by_name_lock);
|
GS_MUTEX_UNLOCK(protocol_by_name_lock);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,7 +137,7 @@ internal_unicode_enc(void)
|
||||||
#define UNICODE_UTF32 ""
|
#define UNICODE_UTF32 ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static pthread_mutex_t local_lock = PTHREAD_MUTEX_INITIALIZER;
|
static gs_mutex_t local_lock = GS_MUTEX_INIT_STATIC;
|
||||||
|
|
||||||
typedef unsigned char unc;
|
typedef unsigned char unc;
|
||||||
static NSStringEncoding defEnc = GSUndefinedEncoding;
|
static NSStringEncoding defEnc = GSUndefinedEncoding;
|
||||||
|
@ -279,7 +279,7 @@ static void GSSetupEncodingTable(void)
|
||||||
{
|
{
|
||||||
if (encodingTable == 0)
|
if (encodingTable == 0)
|
||||||
{
|
{
|
||||||
(void)pthread_mutex_lock(&local_lock);
|
GS_MUTEX_LOCK(local_lock);
|
||||||
if (encodingTable == 0)
|
if (encodingTable == 0)
|
||||||
{
|
{
|
||||||
static struct _strenc_ **encTable = 0;
|
static struct _strenc_ **encTable = 0;
|
||||||
|
@ -355,7 +355,7 @@ static void GSSetupEncodingTable(void)
|
||||||
}
|
}
|
||||||
encodingTable = encTable;
|
encodingTable = encTable;
|
||||||
}
|
}
|
||||||
(void)pthread_mutex_unlock(&local_lock);
|
GS_MUTEX_UNLOCK(local_lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2735,7 +2735,7 @@ GSPrivateAvailableEncodings()
|
||||||
if (_availableEncodings == 0)
|
if (_availableEncodings == 0)
|
||||||
{
|
{
|
||||||
GSSetupEncodingTable();
|
GSSetupEncodingTable();
|
||||||
(void)pthread_mutex_lock(&local_lock);
|
GS_MUTEX_LOCK(local_lock);
|
||||||
if (_availableEncodings == 0)
|
if (_availableEncodings == 0)
|
||||||
{
|
{
|
||||||
NSStringEncoding *encodings;
|
NSStringEncoding *encodings;
|
||||||
|
@ -2761,7 +2761,7 @@ GSPrivateAvailableEncodings()
|
||||||
encodings[pos] = 0;
|
encodings[pos] = 0;
|
||||||
_availableEncodings = encodings;
|
_availableEncodings = encodings;
|
||||||
}
|
}
|
||||||
(void)pthread_mutex_unlock(&local_lock);
|
GS_MUTEX_UNLOCK(local_lock);
|
||||||
}
|
}
|
||||||
return _availableEncodings;
|
return _availableEncodings;
|
||||||
}
|
}
|
||||||
|
@ -2903,10 +2903,10 @@ GSPrivateDefaultCStringEncoding()
|
||||||
|
|
||||||
GSSetupEncodingTable();
|
GSSetupEncodingTable();
|
||||||
|
|
||||||
(void)pthread_mutex_lock(&local_lock);
|
GS_MUTEX_LOCK(local_lock);
|
||||||
if (defEnc != GSUndefinedEncoding)
|
if (defEnc != GSUndefinedEncoding)
|
||||||
{
|
{
|
||||||
(void)pthread_mutex_unlock(&local_lock);
|
GS_MUTEX_UNLOCK(local_lock);
|
||||||
return defEnc;
|
return defEnc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2950,7 +2950,7 @@ GSPrivateDefaultCStringEncoding()
|
||||||
defEnc = NSISOLatin1StringEncoding;
|
defEnc = NSISOLatin1StringEncoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)pthread_mutex_unlock(&local_lock);
|
GS_MUTEX_UNLOCK(local_lock);
|
||||||
}
|
}
|
||||||
return defEnc;
|
return defEnc;
|
||||||
}
|
}
|
||||||
|
|
72
Source/GSAtomic.h
Normal file
72
Source/GSAtomic.h
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* Provides atomic load and store functions using either native C11 atomic
|
||||||
|
* types and operations if available, or otherwise using fallback
|
||||||
|
* implementations (e.g. with GCC where stdatomic.h is not useable from
|
||||||
|
* Objective-C).
|
||||||
|
*
|
||||||
|
* Adopted from FreeBSD's stdatomic.h.
|
||||||
|
*/
|
||||||
|
#ifndef _GSAtomic_h_
|
||||||
|
#define _GSAtomic_h_
|
||||||
|
|
||||||
|
#ifndef __has_extension
|
||||||
|
#define __has_extension(x) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __has_extension(c_atomic) || __has_extension(cxx_atomic)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use native C11 atomic operations. _Atomic() should be defined by the
|
||||||
|
* compiler.
|
||||||
|
*/
|
||||||
|
#define atomic_load_explicit(object, order) \
|
||||||
|
__c11_atomic_load(object, order)
|
||||||
|
#define atomic_store_explicit(object, desired, order) \
|
||||||
|
__c11_atomic_store(object, desired, order)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No native support for _Atomic(). Place object in structure to prevent
|
||||||
|
* most forms of direct non-atomic access.
|
||||||
|
*/
|
||||||
|
#define _Atomic(T) struct { T volatile __val; }
|
||||||
|
#if __has_builtin(__sync_swap)
|
||||||
|
/* Clang provides a full-barrier atomic exchange - use it if available. */
|
||||||
|
#define atomic_exchange_explicit(object, desired, order) \
|
||||||
|
((void)(order), __sync_swap(&(object)->__val, desired))
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* __sync_lock_test_and_set() is only an acquire barrier in theory (although in
|
||||||
|
* practice it is usually a full barrier) so we need an explicit barrier before
|
||||||
|
* it.
|
||||||
|
*/
|
||||||
|
#define atomic_exchange_explicit(object, desired, order) \
|
||||||
|
__extension__ ({ \
|
||||||
|
__typeof__(object) __o = (object); \
|
||||||
|
__typeof__(desired) __d = (desired); \
|
||||||
|
(void)(order); \
|
||||||
|
__sync_synchronize(); \
|
||||||
|
__sync_lock_test_and_set(&(__o)->__val, __d); \
|
||||||
|
})
|
||||||
|
#endif
|
||||||
|
#define atomic_load_explicit(object, order) \
|
||||||
|
((void)(order), __sync_fetch_and_add(&(object)->__val, 0))
|
||||||
|
#define atomic_store_explicit(object, desired, order) \
|
||||||
|
((void)atomic_exchange_explicit(object, desired, order))
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __ATOMIC_SEQ_CST
|
||||||
|
#define __ATOMIC_SEQ_CST 5
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convenience functions.
|
||||||
|
*/
|
||||||
|
#define atomic_load(object) \
|
||||||
|
atomic_load_explicit(object, __ATOMIC_SEQ_CST)
|
||||||
|
#define atomic_store(object, desired) \
|
||||||
|
atomic_store_explicit(object, desired, __ATOMIC_SEQ_CST)
|
||||||
|
|
||||||
|
#endif // _GSAtomic_h_
|
|
@ -26,6 +26,7 @@
|
||||||
#import "Foundation/NSCoder.h"
|
#import "Foundation/NSCoder.h"
|
||||||
#import "Foundation/NSDistantObject.h"
|
#import "Foundation/NSDistantObject.h"
|
||||||
#import "GSInvocation.h"
|
#import "GSInvocation.h"
|
||||||
|
#import "GSPThread.h"
|
||||||
#import <avcall.h>
|
#import <avcall.h>
|
||||||
#import <callback.h>
|
#import <callback.h>
|
||||||
#import "callframe.h"
|
#import "callframe.h"
|
||||||
|
@ -34,10 +35,6 @@
|
||||||
# include <objc/encoding.h>
|
# include <objc/encoding.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
#import "GSInvocation.h"
|
|
||||||
|
|
||||||
#ifndef GS_STATIC_INLINE
|
#ifndef GS_STATIC_INLINE
|
||||||
#define GS_STATIC_INLINE static inline
|
#define GS_STATIC_INLINE static inline
|
||||||
#endif
|
#endif
|
||||||
|
@ -140,7 +137,7 @@ static GSIMapTable_t ff_callback_map;
|
||||||
|
|
||||||
/* Lock that protects the ff_callback_map */
|
/* Lock that protects the ff_callback_map */
|
||||||
|
|
||||||
static pthread_mutex_t ff_callback_map_lock = PTHREAD_MUTEX_INITIALIZER;
|
static gs_mutex_t ff_callback_map_lock = GS_MUTEX_INIT_STATIC;
|
||||||
|
|
||||||
/* Static pre-computed return type info */
|
/* Static pre-computed return type info */
|
||||||
|
|
||||||
|
@ -486,7 +483,7 @@ static IMP gs_objc_msg_forward (SEL sel)
|
||||||
GSIMapNode node;
|
GSIMapNode node;
|
||||||
|
|
||||||
// Lock
|
// Lock
|
||||||
pthread_mutex_lock (&ff_callback_map_lock);
|
GS_MUTEX_LOCK(ff_callback_map_lock);
|
||||||
|
|
||||||
node = GSIMapNodeForKey (&ff_callback_map,
|
node = GSIMapNodeForKey (&ff_callback_map,
|
||||||
(GSIMapKey) ((void *) &returnInfo));
|
(GSIMapKey) ((void *) &returnInfo));
|
||||||
|
@ -512,7 +509,7 @@ static IMP gs_objc_msg_forward (SEL sel)
|
||||||
(GSIMapVal) forwarding_callback);
|
(GSIMapVal) forwarding_callback);
|
||||||
}
|
}
|
||||||
// Unlock
|
// Unlock
|
||||||
pthread_mutex_unlock (&ff_callback_map_lock);
|
GS_MUTEX_UNLOCK(ff_callback_map_lock);
|
||||||
}
|
}
|
||||||
return forwarding_callback;
|
return forwarding_callback;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,8 @@
|
||||||
#import "Foundation/NSDistantObject.h"
|
#import "Foundation/NSDistantObject.h"
|
||||||
#import "Foundation/NSData.h"
|
#import "Foundation/NSData.h"
|
||||||
#import "GSInvocation.h"
|
#import "GSInvocation.h"
|
||||||
|
#import "GSPThread.h"
|
||||||
#import "GNUstepBase/GSObjCRuntime.h"
|
#import "GNUstepBase/GSObjCRuntime.h"
|
||||||
#import <pthread.h>
|
|
||||||
#import "cifframe.h"
|
#import "cifframe.h"
|
||||||
#import "GSPrivate.h"
|
#import "GSPrivate.h"
|
||||||
|
|
||||||
|
@ -190,18 +190,18 @@ IMP gs_objc_msg_forward (SEL sel)
|
||||||
return gs_objc_msg_forward2 (nil, sel);
|
return gs_objc_msg_forward2 (nil, sel);
|
||||||
}
|
}
|
||||||
#ifdef __GNUSTEP_RUNTIME__
|
#ifdef __GNUSTEP_RUNTIME__
|
||||||
pthread_key_t thread_slot_key;
|
gs_thread_key_t thread_slot_key;
|
||||||
static struct objc_slot *
|
static struct objc_slot *
|
||||||
gs_objc_msg_forward3(id receiver, SEL op)
|
gs_objc_msg_forward3(id receiver, SEL op)
|
||||||
{
|
{
|
||||||
/* The slot has its version set to 0, so it can not be cached. This makes it
|
/* The slot has its version set to 0, so it can not be cached. This makes it
|
||||||
* safe to free it when the thread exits. */
|
* safe to free it when the thread exits. */
|
||||||
struct objc_slot *slot = pthread_getspecific(thread_slot_key);
|
struct objc_slot *slot = GS_THREAD_KEY_GET(thread_slot_key);
|
||||||
|
|
||||||
if (NULL == slot)
|
if (NULL == slot)
|
||||||
{
|
{
|
||||||
slot = calloc(sizeof(struct objc_slot), 1);
|
slot = calloc(sizeof(struct objc_slot), 1);
|
||||||
pthread_setspecific(thread_slot_key, slot);
|
GS_THREAD_KEY_SET(thread_slot_key, slot);
|
||||||
}
|
}
|
||||||
slot->method = gs_objc_msg_forward2(receiver, op);
|
slot->method = gs_objc_msg_forward2(receiver, op);
|
||||||
return slot;
|
return slot;
|
||||||
|
@ -259,7 +259,7 @@ static id gs_objc_proxy_lookup(id receiver, SEL op)
|
||||||
+ (void) load
|
+ (void) load
|
||||||
{
|
{
|
||||||
#ifdef __GNUSTEP_RUNTIME__
|
#ifdef __GNUSTEP_RUNTIME__
|
||||||
pthread_key_create(&thread_slot_key, free);
|
GS_THREAD_KEY_INIT(thread_slot_key, free);
|
||||||
__objc_msg_forward3 = gs_objc_msg_forward3;
|
__objc_msg_forward3 = gs_objc_msg_forward3;
|
||||||
__objc_msg_forward2 = gs_objc_msg_forward2;
|
__objc_msg_forward2 = gs_objc_msg_forward2;
|
||||||
objc_proxy_lookup = gs_objc_proxy_lookup;
|
objc_proxy_lookup = gs_objc_proxy_lookup;
|
||||||
|
|
|
@ -23,26 +23,97 @@
|
||||||
#ifndef _GSPThread_h_
|
#ifndef _GSPThread_h_
|
||||||
#define _GSPThread_h_
|
#define _GSPThread_h_
|
||||||
|
|
||||||
|
#if GS_USE_WIN32_THREADS_AND_LOCKS
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <process.h>
|
||||||
|
#include "GSAtomic.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
gs_mutex_attr_normal = 0,
|
||||||
|
gs_mutex_attr_errorcheck = 1,
|
||||||
|
gs_mutex_attr_recursive = 2
|
||||||
|
} gs_mutex_attr_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SRWLOCK lock;
|
||||||
|
_Atomic(DWORD) owner;
|
||||||
|
DWORD depth;
|
||||||
|
gs_mutex_attr_t attr;
|
||||||
|
} gs_mutex_t;
|
||||||
|
|
||||||
|
typedef SRWLOCK gs_cond_mutex_t;
|
||||||
|
typedef CONDITION_VARIABLE gs_cond_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Locking primitives.
|
||||||
|
*/
|
||||||
|
#define GS_MUTEX_INIT_STATIC {.lock = SRWLOCK_INIT, .attr = gs_mutex_attr_normal}
|
||||||
|
#define GS_MUTEX_INIT(x) gs_mutex_init(&(x), gs_mutex_attr_normal)
|
||||||
|
#define GS_MUTEX_INIT_RECURSIVE(x) gs_mutex_init(&(x), gs_mutex_attr_recursive)
|
||||||
|
|
||||||
|
#define GS_MUTEX_LOCK(x) gs_mutex_lock(&(x))
|
||||||
|
#define GS_MUTEX_TRYLOCK(x) gs_mutex_trylock(&(x))
|
||||||
|
#define GS_MUTEX_UNLOCK(x) gs_mutex_unlock(&(x))
|
||||||
|
#define GS_MUTEX_DESTROY(x)
|
||||||
|
|
||||||
|
#define GS_COND_WAIT(cond, mutex) gs_cond_wait(cond, mutex)
|
||||||
|
#define GS_COND_SIGNAL(cond) WakeConditionVariable(&(cond))
|
||||||
|
#define GS_COND_BROADCAST(cond) WakeAllConditionVariable(&(cond))
|
||||||
|
|
||||||
|
/* Pthread-like locking primitives defined in NSLock.m */
|
||||||
|
void gs_mutex_init(gs_mutex_t *l, gs_mutex_attr_t attr);
|
||||||
|
int gs_mutex_lock(gs_mutex_t *l);
|
||||||
|
int gs_mutex_trylock(gs_mutex_t *l);
|
||||||
|
int gs_mutex_unlock(gs_mutex_t *l);
|
||||||
|
int gs_cond_wait(gs_cond_t *cond, gs_mutex_t *mutex);
|
||||||
|
int gs_cond_timedwait(gs_cond_t *cond, gs_mutex_t *mutex, DWORD millisecs);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Threading primitives.
|
||||||
|
*
|
||||||
|
* Use Fiber Local Storage (FLS), as in contrast to Thread Local Storage (TLS)
|
||||||
|
* they provide a destructor callback and will just manipulate the FLS
|
||||||
|
* associated with the current thread if fibers are not being used.
|
||||||
|
*/
|
||||||
|
#define GS_THREAD_KEY_INIT(key, dtor) \
|
||||||
|
((key = FlsAlloc(dtor)) != FLS_OUT_OF_INDEXES)
|
||||||
|
#define GS_THREAD_KEY_GET(key) FlsGetValue(key)
|
||||||
|
#define GS_THREAD_KEY_SET(key, val) FlsSetValue(key, val)
|
||||||
|
|
||||||
|
#define GS_THREAD_ID_SELF() GetCurrentThreadId()
|
||||||
|
|
||||||
|
#define GS_YIELD() Sleep(0)
|
||||||
|
|
||||||
|
typedef DWORD gs_thread_key_t;
|
||||||
|
typedef DWORD gs_thread_id_t;
|
||||||
|
|
||||||
|
#else /* GS_USE_WIN32_THREADS_AND_LOCKS */
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#import "Foundation/NSLock.h"
|
typedef pthread_mutex_t gs_mutex_t;
|
||||||
|
typedef pthread_mutex_t gs_cond_mutex_t;
|
||||||
|
typedef pthread_cond_t gs_cond_t;
|
||||||
|
|
||||||
@class GSStackTrace;
|
/*
|
||||||
@class NSArray;
|
* Locking primitives
|
||||||
@class NSMapTable;
|
*/
|
||||||
|
#define GS_MUTEX_INIT_STATIC PTHREAD_MUTEX_INITIALIZER
|
||||||
|
#define GS_MUTEX_INIT(x) pthread_mutex_init(&(x), NULL)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Macro to initialize recursive mutexes in a portable way. Adopted from
|
* Macro to initialize recursive mutexes in a portable way. Adopted from
|
||||||
* libobjc2 (lock.h).
|
* libobjc2 (lock.h).
|
||||||
*/
|
*/
|
||||||
# ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
|
# ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
|
||||||
# define GS_INIT_RECURSIVE_MUTEX(x) \
|
# define GS_MUTEX_INIT_RECURSIVE(x) \
|
||||||
x = (pthread_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
|
x = (pthread_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
|
||||||
# elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
|
# elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
|
||||||
# define GS_INIT_RECURSIVE_MUTEX(x) \
|
# define GS_MUTEX_INIT_RECURSIVE(x) \
|
||||||
x = (pthread_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER
|
x = (pthread_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER
|
||||||
# else
|
# else
|
||||||
# define GS_INIT_RECURSIVE_MUTEX(x) GSPThreadInitRecursiveMutex(&(x))
|
# define GS_MUTEX_INIT_RECURSIVE(x) GSPThreadInitRecursiveMutex(&(x))
|
||||||
|
|
||||||
static inline void GSPThreadInitRecursiveMutex(pthread_mutex_t *x)
|
static inline void GSPThreadInitRecursiveMutex(pthread_mutex_t *x)
|
||||||
{
|
{
|
||||||
|
@ -54,6 +125,39 @@ static inline void GSPThreadInitRecursiveMutex(pthread_mutex_t *x)
|
||||||
}
|
}
|
||||||
# endif // PTHREAD_RECURSIVE_MUTEX_INITIALIZER(_NP)
|
# endif // PTHREAD_RECURSIVE_MUTEX_INITIALIZER(_NP)
|
||||||
|
|
||||||
|
#define GS_MUTEX_LOCK(x) pthread_mutex_lock(&(x))
|
||||||
|
#define GS_MUTEX_TRYLOCK(x) pthread_mutex_trylock(&(x))
|
||||||
|
#define GS_MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
|
||||||
|
#define GS_MUTEX_DESTROY(x) pthread_mutex_destroy(&(x))
|
||||||
|
|
||||||
|
#define GS_COND_WAIT(cond, mutex) pthread_cond_wait(cond, mutex)
|
||||||
|
#define GS_COND_SIGNAL(cond) pthread_cond_signal(&(cond))
|
||||||
|
#define GS_COND_BROADCAST(cond) pthread_cond_broadcast(&(cond))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Threading primitives.
|
||||||
|
*/
|
||||||
|
#define GS_THREAD_KEY_INIT(key, dtor) (pthread_key_create(&(key), dtor) == 0)
|
||||||
|
#define GS_THREAD_KEY_GET(key) pthread_getspecific(key)
|
||||||
|
#define GS_THREAD_KEY_SET(key, val) pthread_setspecific(key, val)
|
||||||
|
|
||||||
|
#define GS_THREAD_ID_SELF() pthread_self()
|
||||||
|
|
||||||
|
#define GS_YIELD() sched_yield()
|
||||||
|
|
||||||
|
typedef pthread_key_t gs_thread_key_t;
|
||||||
|
typedef pthread_t gs_thread_id_t;
|
||||||
|
|
||||||
|
#endif /* GS_USE_WIN32_THREADS_AND_LOCKS */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __OBJC__ /* Enables including file in autoconf check */
|
||||||
|
|
||||||
|
#import "Foundation/NSLock.h"
|
||||||
|
|
||||||
|
@class GSStackTrace;
|
||||||
|
@class NSArray;
|
||||||
|
@class NSMapTable;
|
||||||
|
|
||||||
/* Class to obtain/encapsulate a stack trace for exception reporting and/or
|
/* Class to obtain/encapsulate a stack trace for exception reporting and/or
|
||||||
* lock tracing.
|
* lock tracing.
|
||||||
|
@ -109,4 +213,6 @@ static inline void GSPThreadInitRecursiveMutex(pthread_mutex_t *x)
|
||||||
- (GSStackTrace*) stack;
|
- (GSStackTrace*) stack;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
#endif // __OBJC__
|
||||||
|
|
||||||
#endif // _GSPThread_h_
|
#endif // _GSPThread_h_
|
||||||
|
|
|
@ -86,7 +86,7 @@ static Class GSPlaceholderArrayClass;
|
||||||
|
|
||||||
static GSPlaceholderArray *defaultPlaceholderArray;
|
static GSPlaceholderArray *defaultPlaceholderArray;
|
||||||
static NSMapTable *placeholderMap;
|
static NSMapTable *placeholderMap;
|
||||||
static pthread_mutex_t placeholderLock = PTHREAD_MUTEX_INITIALIZER;
|
static gs_mutex_t placeholderLock = GS_MUTEX_INIT_STATIC;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -167,7 +167,7 @@ static SEL rlSel;
|
||||||
* locate the correct placeholder in the (lock protected)
|
* locate the correct placeholder in the (lock protected)
|
||||||
* table of placeholders.
|
* table of placeholders.
|
||||||
*/
|
*/
|
||||||
(void)pthread_mutex_lock(&placeholderLock);
|
GS_MUTEX_LOCK(placeholderLock);
|
||||||
obj = (id)NSMapGet(placeholderMap, (void*)z);
|
obj = (id)NSMapGet(placeholderMap, (void*)z);
|
||||||
if (obj == nil)
|
if (obj == nil)
|
||||||
{
|
{
|
||||||
|
@ -178,7 +178,7 @@ static SEL rlSel;
|
||||||
obj = (id)NSAllocateObject(GSPlaceholderArrayClass, 0, z);
|
obj = (id)NSAllocateObject(GSPlaceholderArrayClass, 0, z);
|
||||||
NSMapInsert(placeholderMap, (void*)z, (void*)obj);
|
NSMapInsert(placeholderMap, (void*)z, (void*)obj);
|
||||||
}
|
}
|
||||||
(void)pthread_mutex_unlock(&placeholderLock);
|
GS_MUTEX_UNLOCK(placeholderLock);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -736,9 +736,9 @@ static Class concreteMutableClass = nil;
|
||||||
length: (unsigned)length
|
length: (unsigned)length
|
||||||
number: (int)number
|
number: (int)number
|
||||||
{
|
{
|
||||||
static pthread_mutex_t cache_lock = PTHREAD_MUTEX_INITIALIZER;
|
static gs_mutex_t cache_lock = GS_MUTEX_INIT_STATIC;
|
||||||
|
|
||||||
pthread_mutex_lock(&cache_lock);
|
GS_MUTEX_LOCK(cache_lock);
|
||||||
if (cache_set[number] == nil && bytes != 0)
|
if (cache_set[number] == nil && bytes != 0)
|
||||||
{
|
{
|
||||||
NSData *bitmap;
|
NSData *bitmap;
|
||||||
|
@ -751,7 +751,7 @@ static Class concreteMutableClass = nil;
|
||||||
[[NSObject leakAt: &cache_set[number]] release];
|
[[NSObject leakAt: &cache_set[number]] release];
|
||||||
RELEASE(bitmap);
|
RELEASE(bitmap);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&cache_lock);
|
GS_MUTEX_UNLOCK(cache_lock);
|
||||||
return cache_set[number];
|
return cache_set[number];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ static table_entry* the_table = 0;
|
||||||
static BOOL debug_allocation = NO;
|
static BOOL debug_allocation = NO;
|
||||||
static BOOL debug_byte_size = NO;
|
static BOOL debug_byte_size = NO;
|
||||||
|
|
||||||
static pthread_mutex_t uniqueLock;
|
static gs_mutex_t uniqueLock;
|
||||||
|
|
||||||
static void _GSDebugAllocationFetch(list_entry *items, BOOL difference);
|
static void _GSDebugAllocationFetch(list_entry *items, BOOL difference);
|
||||||
static void _GSDebugAllocationFetchAll(list_entry *items);
|
static void _GSDebugAllocationFetchAll(list_entry *items);
|
||||||
|
@ -106,8 +106,8 @@ static void (*_GSDebugAllocationAddFunc)(Class c, id o)
|
||||||
static void (*_GSDebugAllocationRemoveFunc)(Class c, id o)
|
static void (*_GSDebugAllocationRemoveFunc)(Class c, id o)
|
||||||
= _GSDebugAllocationRemove;
|
= _GSDebugAllocationRemove;
|
||||||
|
|
||||||
#define doLock() pthread_mutex_lock(&uniqueLock)
|
#define doLock() GS_MUTEX_LOCK(uniqueLock)
|
||||||
#define unLock() pthread_mutex_unlock(&uniqueLock)
|
#define unLock() GS_MUTEX_UNLOCK(uniqueLock)
|
||||||
|
|
||||||
@interface GSDebugAlloc : NSObject
|
@interface GSDebugAlloc : NSObject
|
||||||
+ (void) initialize;
|
+ (void) initialize;
|
||||||
|
@ -116,7 +116,7 @@ static void (*_GSDebugAllocationRemoveFunc)(Class c, id o)
|
||||||
@implementation GSDebugAlloc
|
@implementation GSDebugAlloc
|
||||||
+ (void) initialize
|
+ (void) initialize
|
||||||
{
|
{
|
||||||
GS_INIT_RECURSIVE_MUTEX(uniqueLock);
|
GS_MUTEX_INIT_RECURSIVE(uniqueLock);
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -491,7 +491,7 @@ static void find_address (bfd *abfd, asection *section,
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
static pthread_mutex_t modLock;
|
static gs_mutex_t modLock;
|
||||||
static NSMutableDictionary *stackModules = nil;
|
static NSMutableDictionary *stackModules = nil;
|
||||||
|
|
||||||
// initialize stack trace info
|
// initialize stack trace info
|
||||||
|
@ -500,7 +500,7 @@ GSLoadModule(NSString *fileName)
|
||||||
{
|
{
|
||||||
GSBinaryFileInfo *module = nil;
|
GSBinaryFileInfo *module = nil;
|
||||||
|
|
||||||
(void)pthread_mutex_lock(&modLock);
|
GS_MUTEX_LOCK(modLock);
|
||||||
|
|
||||||
if (stackModules == nil)
|
if (stackModules == nil)
|
||||||
{
|
{
|
||||||
|
@ -549,7 +549,7 @@ GSLoadModule(NSString *fileName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(void)pthread_mutex_unlock(&modLock);
|
GS_MUTEX_UNLOCK(modLock);
|
||||||
|
|
||||||
if (module == (id)[NSNull null])
|
if (module == (id)[NSNull null])
|
||||||
{
|
{
|
||||||
|
@ -564,9 +564,9 @@ GSListModules()
|
||||||
NSArray *result;
|
NSArray *result;
|
||||||
|
|
||||||
GSLoadModule(nil); // initialise
|
GSLoadModule(nil); // initialise
|
||||||
(void)pthread_mutex_lock(&modLock);
|
GS_MUTEX_LOCK(modLock);
|
||||||
result = [stackModules allValues];
|
result = [stackModules allValues];
|
||||||
(void)pthread_mutex_unlock(&modLock);
|
GS_MUTEX_UNLOCK(modLock);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -615,7 +615,7 @@ static SymInitializeType initSym = 0;
|
||||||
static SymSetOptionsType optSym = 0;
|
static SymSetOptionsType optSym = 0;
|
||||||
static SymFromAddrType fromSym = 0;
|
static SymFromAddrType fromSym = 0;
|
||||||
static HANDLE hProcess = 0;
|
static HANDLE hProcess = 0;
|
||||||
static pthread_mutex_t traceLock;
|
static gs_mutex_t traceLock;
|
||||||
#define MAXFRAMES 62 /* Limitation of windows-xp */
|
#define MAXFRAMES 62 /* Limitation of windows-xp */
|
||||||
#else
|
#else
|
||||||
#define MAXFRAMES 128 /* 1KB buffer on 64bit machine */
|
#define MAXFRAMES 128 /* 1KB buffer on 64bit machine */
|
||||||
|
@ -902,7 +902,7 @@ GSPrivateReturnAddresses(NSUInteger **returns)
|
||||||
#if defined(_WIN32) && !defined(USE_BFD)
|
#if defined(_WIN32) && !defined(USE_BFD)
|
||||||
NSUInteger addr[MAXFRAMES];
|
NSUInteger addr[MAXFRAMES];
|
||||||
|
|
||||||
(void)pthread_mutex_lock(&traceLock);
|
GS_MUTEX_LOCK(traceLock);
|
||||||
if (0 == hProcess)
|
if (0 == hProcess)
|
||||||
{
|
{
|
||||||
hProcess = GetCurrentProcess();
|
hProcess = GetCurrentProcess();
|
||||||
|
@ -916,7 +916,7 @@ GSPrivateReturnAddresses(NSUInteger **returns)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to load kernel32.dll with error: %d\n",
|
fprintf(stderr, "Failed to load kernel32.dll with error: %d\n",
|
||||||
(int)GetLastError());
|
(int)GetLastError());
|
||||||
(void)pthread_mutex_unlock(&traceLock);
|
GS_MUTEX_UNLOCK(traceLock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
capture = (CaptureStackBackTraceType)GetProcAddress(
|
capture = (CaptureStackBackTraceType)GetProcAddress(
|
||||||
|
@ -925,7 +925,7 @@ GSPrivateReturnAddresses(NSUInteger **returns)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to find RtlCaptureStackBackTrace: %d\n",
|
fprintf(stderr, "Failed to find RtlCaptureStackBackTrace: %d\n",
|
||||||
(int)GetLastError());
|
(int)GetLastError());
|
||||||
(void)pthread_mutex_unlock(&traceLock);
|
GS_MUTEX_UNLOCK(traceLock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
hModule = LoadLibrary("dbghelp.dll");
|
hModule = LoadLibrary("dbghelp.dll");
|
||||||
|
@ -933,7 +933,7 @@ GSPrivateReturnAddresses(NSUInteger **returns)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to load dbghelp.dll with error: %d\n",
|
fprintf(stderr, "Failed to load dbghelp.dll with error: %d\n",
|
||||||
(int)GetLastError());
|
(int)GetLastError());
|
||||||
(void)pthread_mutex_unlock(&traceLock);
|
GS_MUTEX_UNLOCK(traceLock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
optSym = (SymSetOptionsType)GetProcAddress(
|
optSym = (SymSetOptionsType)GetProcAddress(
|
||||||
|
@ -942,7 +942,7 @@ GSPrivateReturnAddresses(NSUInteger **returns)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to find SymSetOptions: %d\n",
|
fprintf(stderr, "Failed to find SymSetOptions: %d\n",
|
||||||
(int)GetLastError());
|
(int)GetLastError());
|
||||||
(void)pthread_mutex_unlock(&traceLock);
|
GS_MUTEX_UNLOCK(traceLock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
initSym = (SymInitializeType)GetProcAddress(
|
initSym = (SymInitializeType)GetProcAddress(
|
||||||
|
@ -951,7 +951,7 @@ GSPrivateReturnAddresses(NSUInteger **returns)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to find SymInitialize: %d\n",
|
fprintf(stderr, "Failed to find SymInitialize: %d\n",
|
||||||
(int)GetLastError());
|
(int)GetLastError());
|
||||||
(void)pthread_mutex_unlock(&traceLock);
|
GS_MUTEX_UNLOCK(traceLock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
fromSym = (SymFromAddrType)GetProcAddress(
|
fromSym = (SymFromAddrType)GetProcAddress(
|
||||||
|
@ -960,7 +960,7 @@ GSPrivateReturnAddresses(NSUInteger **returns)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to find SymFromAddr: %d\n",
|
fprintf(stderr, "Failed to find SymFromAddr: %d\n",
|
||||||
(int)GetLastError());
|
(int)GetLastError());
|
||||||
(void)pthread_mutex_unlock(&traceLock);
|
GS_MUTEX_UNLOCK(traceLock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -972,13 +972,13 @@ GSPrivateReturnAddresses(NSUInteger **returns)
|
||||||
fprintf(stderr, "SymInitialize failed with error: %d\n",
|
fprintf(stderr, "SymInitialize failed with error: %d\n",
|
||||||
(int)GetLastError());
|
(int)GetLastError());
|
||||||
fromSym = 0;
|
fromSym = 0;
|
||||||
(void)pthread_mutex_unlock(&traceLock);
|
GS_MUTEX_UNLOCK(traceLock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (0 == capture)
|
if (0 == capture)
|
||||||
{
|
{
|
||||||
(void)pthread_mutex_unlock(&traceLock);
|
GS_MUTEX_UNLOCK(traceLock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -989,7 +989,7 @@ GSPrivateReturnAddresses(NSUInteger **returns)
|
||||||
memcpy(*returns, addr, numReturns * sizeof(void*));
|
memcpy(*returns, addr, numReturns * sizeof(void*));
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)pthread_mutex_unlock(&traceLock);
|
GS_MUTEX_UNLOCK(traceLock);
|
||||||
|
|
||||||
#elif defined(HAVE_BACKTRACE)
|
#elif defined(HAVE_BACKTRACE)
|
||||||
void *addr[MAXFRAMES*sizeof(void*)];
|
void *addr[MAXFRAMES*sizeof(void*)];
|
||||||
|
@ -1112,10 +1112,10 @@ GSPrivateReturnAddresses(NSUInteger **returns)
|
||||||
+ (void) initialize
|
+ (void) initialize
|
||||||
{
|
{
|
||||||
#if defined(_WIN32) && !defined(USE_BFD)
|
#if defined(_WIN32) && !defined(USE_BFD)
|
||||||
GS_INIT_RECURSIVE_MUTEX(traceLock);
|
GS_MUTEX_INIT_RECURSIVE(traceLock);
|
||||||
#endif
|
#endif
|
||||||
#if defined(USE_BFD)
|
#if defined(USE_BFD)
|
||||||
GS_INIT_RECURSIVE_MUTEX(modLock);
|
GS_MUTEX_INIT_RECURSIVE(modLock);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1257,7 +1257,7 @@ GSPrivateReturnAddresses(NSUInteger **returns)
|
||||||
symbol->MaxNameLen = 1024;
|
symbol->MaxNameLen = 1024;
|
||||||
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||||
|
|
||||||
(void)pthread_mutex_lock(&traceLock);
|
GS_MUTEX_LOCK(traceLock);
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
NSUInteger addr = (NSUInteger)*ptrs++;
|
NSUInteger addr = (NSUInteger)*ptrs++;
|
||||||
|
@ -1273,7 +1273,7 @@ GSPrivateReturnAddresses(NSUInteger **returns)
|
||||||
@"unknown - %p", symbol->Name, addr];
|
@"unknown - %p", symbol->Name, addr];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(void)pthread_mutex_unlock(&traceLock);
|
GS_MUTEX_UNLOCK(traceLock);
|
||||||
free(symbol);
|
free(symbol);
|
||||||
|
|
||||||
symbols = [[NSArray alloc] initWithObjects: syms count: count];
|
symbols = [[NSArray alloc] initWithObjects: syms count: count];
|
||||||
|
|
321
Source/NSLock.m
321
Source/NSLock.m
|
@ -24,25 +24,25 @@
|
||||||
|
|
||||||
#import "common.h"
|
#import "common.h"
|
||||||
|
|
||||||
#include <pthread.h>
|
|
||||||
#import "GSPrivate.h"
|
|
||||||
#define gs_cond_t pthread_cond_t
|
|
||||||
#define gs_mutex_t pthread_mutex_t
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#define EXPOSE_NSLock_IVARS 1
|
#define EXPOSE_NSLock_IVARS 1
|
||||||
#define EXPOSE_NSRecursiveLock_IVARS 1
|
#define EXPOSE_NSRecursiveLock_IVARS 1
|
||||||
#define EXPOSE_NSCondition_IVARS 1
|
#define EXPOSE_NSCondition_IVARS 1
|
||||||
#define EXPOSE_NSConditionLock_IVARS 1
|
#define EXPOSE_NSConditionLock_IVARS 1
|
||||||
|
|
||||||
|
#define gs_cond_public_t gs_cond_t
|
||||||
|
#define gs_cond_mutex_public_t gs_cond_mutex_t
|
||||||
|
#define gs_mutex_public_t gs_mutex_t
|
||||||
|
|
||||||
|
#import "GSPrivate.h"
|
||||||
|
#import "GSPThread.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#import "common.h"
|
#import "common.h"
|
||||||
|
|
||||||
#import "Foundation/NSLock.h"
|
#import "Foundation/NSLock.h"
|
||||||
#import "Foundation/NSException.h"
|
#import "Foundation/NSException.h"
|
||||||
#import "Foundation/NSThread.h"
|
#import "Foundation/NSThread.h"
|
||||||
|
|
||||||
#import "GSPThread.h"
|
|
||||||
|
|
||||||
#define class_createInstance(C,E) NSAllocateObject(C,E,NSDefaultMallocZone())
|
#define class_createInstance(C,E) NSAllocateObject(C,E,NSDefaultMallocZone())
|
||||||
|
|
||||||
static Class baseConditionClass = Nil;
|
static Class baseConditionClass = Nil;
|
||||||
|
@ -178,13 +178,13 @@ static BOOL traceLocks = NO;
|
||||||
#define MFINALIZE \
|
#define MFINALIZE \
|
||||||
- (void) finalize\
|
- (void) finalize\
|
||||||
{\
|
{\
|
||||||
pthread_mutex_destroy(&_mutex);\
|
GS_MUTEX_DESTROY(_mutex);\
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MLOCK \
|
#define MLOCK \
|
||||||
- (void) lock\
|
- (void) lock\
|
||||||
{\
|
{\
|
||||||
int err = pthread_mutex_lock(&_mutex);\
|
int err = GS_MUTEX_LOCK(_mutex);\
|
||||||
if (EDEADLK == err)\
|
if (EDEADLK == err)\
|
||||||
{\
|
{\
|
||||||
(*_NSLock_error_handler)(self, _cmd, YES, @"deadlock");\
|
(*_NSLock_error_handler)(self, _cmd, YES, @"deadlock");\
|
||||||
|
@ -200,13 +200,13 @@ static BOOL traceLocks = NO;
|
||||||
{\
|
{\
|
||||||
do\
|
do\
|
||||||
{\
|
{\
|
||||||
int err = pthread_mutex_trylock(&_mutex);\
|
int err = GS_MUTEX_TRYLOCK(_mutex);\
|
||||||
if (0 == err)\
|
if (0 == err)\
|
||||||
{\
|
{\
|
||||||
CHK(Hold) \
|
CHK(Hold) \
|
||||||
return YES;\
|
return YES;\
|
||||||
}\
|
}\
|
||||||
sched_yield();\
|
GS_YIELD();\
|
||||||
} while ([limit timeIntervalSinceNow] > 0);\
|
} while ([limit timeIntervalSinceNow] > 0);\
|
||||||
return NO;\
|
return NO;\
|
||||||
}
|
}
|
||||||
|
@ -230,7 +230,7 @@ static BOOL traceLocks = NO;
|
||||||
#define MTRYLOCK \
|
#define MTRYLOCK \
|
||||||
- (BOOL) tryLock\
|
- (BOOL) tryLock\
|
||||||
{\
|
{\
|
||||||
int err = pthread_mutex_trylock(&_mutex);\
|
int err = GS_MUTEX_TRYLOCK(_mutex);\
|
||||||
if (0 == err) \
|
if (0 == err) \
|
||||||
{ \
|
{ \
|
||||||
CHK(Hold) \
|
CHK(Hold) \
|
||||||
|
@ -245,7 +245,7 @@ static BOOL traceLocks = NO;
|
||||||
#define MUNLOCK \
|
#define MUNLOCK \
|
||||||
- (void) unlock\
|
- (void) unlock\
|
||||||
{\
|
{\
|
||||||
if (0 != pthread_mutex_unlock(&_mutex))\
|
if (0 != GS_MUTEX_UNLOCK(_mutex))\
|
||||||
{\
|
{\
|
||||||
[NSException raise: NSLockException\
|
[NSException raise: NSLockException\
|
||||||
format: @"failed to unlock mutex"];\
|
format: @"failed to unlock mutex"];\
|
||||||
|
@ -253,10 +253,12 @@ static BOOL traceLocks = NO;
|
||||||
CHK(Drop) \
|
CHK(Drop) \
|
||||||
}
|
}
|
||||||
|
|
||||||
static pthread_mutex_t deadlock;
|
static gs_mutex_t deadlock;
|
||||||
|
#if !GS_USE_WIN32_THREADS_AND_LOCKS
|
||||||
static pthread_mutexattr_t attr_normal;
|
static pthread_mutexattr_t attr_normal;
|
||||||
static pthread_mutexattr_t attr_reporting;
|
static pthread_mutexattr_t attr_reporting;
|
||||||
static pthread_mutexattr_t attr_recursive;
|
static pthread_mutexattr_t attr_recursive;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OS X 10.5 compatibility function to allow debugging deadlock conditions.
|
* OS X 10.5 compatibility function to allow debugging deadlock conditions.
|
||||||
|
@ -267,7 +269,7 @@ void _NSLockError(id obj, SEL _cmd, BOOL stop, NSString *msg)
|
||||||
msg, obj);
|
msg, obj);
|
||||||
NSLog(@"*** Break on _NSLockError() to debug.");
|
NSLog(@"*** Break on _NSLockError() to debug.");
|
||||||
if (YES == stop)
|
if (YES == stop)
|
||||||
pthread_mutex_lock(&deadlock);
|
GS_MUTEX_LOCK(deadlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
NSLock_error_handler *_NSLock_error_handler = _NSLockError;
|
NSLock_error_handler *_NSLock_error_handler = _NSLockError;
|
||||||
|
@ -295,6 +297,7 @@ NSString *NSLockException = @"NSLockException";
|
||||||
{
|
{
|
||||||
beenHere = YES;
|
beenHere = YES;
|
||||||
|
|
||||||
|
#if !GS_USE_WIN32_THREADS_AND_LOCKS
|
||||||
/* Initialise attributes for the different types of mutex.
|
/* Initialise attributes for the different types of mutex.
|
||||||
* We do it once, since attributes can be shared between multiple
|
* We do it once, since attributes can be shared between multiple
|
||||||
* mutexes.
|
* mutexes.
|
||||||
|
@ -312,14 +315,19 @@ NSString *NSLockException = @"NSLockException";
|
||||||
pthread_mutexattr_settype(&attr_reporting, PTHREAD_MUTEX_ERRORCHECK);
|
pthread_mutexattr_settype(&attr_reporting, PTHREAD_MUTEX_ERRORCHECK);
|
||||||
pthread_mutexattr_init(&attr_recursive);
|
pthread_mutexattr_init(&attr_recursive);
|
||||||
pthread_mutexattr_settype(&attr_recursive, PTHREAD_MUTEX_RECURSIVE);
|
pthread_mutexattr_settype(&attr_recursive, PTHREAD_MUTEX_RECURSIVE);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* To emulate OSX behavior, we need to be able both to detect deadlocks
|
/* To emulate OSX behavior, we need to be able both to detect deadlocks
|
||||||
* (so we can log them), and also hang the thread when one occurs.
|
* (so we can log them), and also hang the thread when one occurs.
|
||||||
* the simple way to do that is to set up a locked mutex we can
|
* the simple way to do that is to set up a locked mutex we can
|
||||||
* force a deadlock on.
|
* force a deadlock on.
|
||||||
*/
|
*/
|
||||||
|
#if GS_USE_WIN32_THREADS_AND_LOCKS
|
||||||
|
gs_mutex_init(&deadlock, gs_mutex_attr_normal);
|
||||||
|
#else
|
||||||
pthread_mutex_init(&deadlock, &attr_normal);
|
pthread_mutex_init(&deadlock, &attr_normal);
|
||||||
pthread_mutex_lock(&deadlock);
|
#endif
|
||||||
|
GS_MUTEX_LOCK(deadlock);
|
||||||
|
|
||||||
baseConditionClass = [NSCondition class];
|
baseConditionClass = [NSCondition class];
|
||||||
baseConditionLockClass = [NSConditionLock class];
|
baseConditionLockClass = [NSConditionLock class];
|
||||||
|
@ -349,10 +357,14 @@ MFINALIZE
|
||||||
{
|
{
|
||||||
if (nil != (self = [super init]))
|
if (nil != (self = [super init]))
|
||||||
{
|
{
|
||||||
|
#if GS_USE_WIN32_THREADS_AND_LOCKS
|
||||||
|
gs_mutex_init(&_mutex, gs_mutex_attr_errorcheck);
|
||||||
|
#else
|
||||||
if (0 != pthread_mutex_init(&_mutex, &attr_reporting))
|
if (0 != pthread_mutex_init(&_mutex, &attr_reporting))
|
||||||
{
|
{
|
||||||
DESTROY(self);
|
DESTROY(self);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -364,17 +376,17 @@ MLOCK
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
int err = pthread_mutex_trylock(&_mutex);
|
int err = GS_MUTEX_TRYLOCK(_mutex);
|
||||||
if (0 == err)
|
if (0 == err)
|
||||||
{
|
{
|
||||||
CHK(Hold)
|
CHK(Hold)
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
if (EDEADLK == err)
|
if (EDEADLK == err)
|
||||||
{
|
{
|
||||||
(*_NSLock_error_handler)(self, _cmd, NO, @"deadlock");
|
(*_NSLock_error_handler)(self, _cmd, NO, @"deadlock");
|
||||||
}
|
}
|
||||||
sched_yield();
|
GS_YIELD();
|
||||||
} while ([limit timeIntervalSinceNow] > 0);
|
} while ([limit timeIntervalSinceNow] > 0);
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
@ -410,10 +422,14 @@ MFINALIZE
|
||||||
{
|
{
|
||||||
if (nil != (self = [super init]))
|
if (nil != (self = [super init]))
|
||||||
{
|
{
|
||||||
|
#if GS_USE_WIN32_THREADS_AND_LOCKS
|
||||||
|
gs_mutex_init(&_mutex, gs_mutex_attr_recursive);
|
||||||
|
#else
|
||||||
if (0 != pthread_mutex_init(&_mutex, &attr_recursive))
|
if (0 != pthread_mutex_init(&_mutex, &attr_recursive))
|
||||||
{
|
{
|
||||||
DESTROY(self);
|
DESTROY(self);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -445,7 +461,7 @@ MUNLOCK
|
||||||
|
|
||||||
- (void) broadcast
|
- (void) broadcast
|
||||||
{
|
{
|
||||||
pthread_cond_broadcast(&_condition);
|
GS_COND_BROADCAST(_condition);
|
||||||
}
|
}
|
||||||
|
|
||||||
MDEALLOC
|
MDEALLOC
|
||||||
|
@ -453,23 +469,30 @@ MDESCRIPTION
|
||||||
|
|
||||||
- (void) finalize
|
- (void) finalize
|
||||||
{
|
{
|
||||||
|
#if !GS_USE_WIN32_THREADS_AND_LOCKS
|
||||||
pthread_cond_destroy(&_condition);
|
pthread_cond_destroy(&_condition);
|
||||||
pthread_mutex_destroy(&_mutex);
|
#endif
|
||||||
|
GS_MUTEX_DESTROY(_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) init
|
- (id) init
|
||||||
{
|
{
|
||||||
if (nil != (self = [super init]))
|
if (nil != (self = [super init]))
|
||||||
{
|
{
|
||||||
|
#if GS_USE_WIN32_THREADS_AND_LOCKS
|
||||||
|
InitializeConditionVariable(&_condition);
|
||||||
|
gs_mutex_init(&_mutex, gs_mutex_attr_errorcheck);
|
||||||
|
#else
|
||||||
if (0 != pthread_cond_init(&_condition, NULL))
|
if (0 != pthread_cond_init(&_condition, NULL))
|
||||||
{
|
{
|
||||||
DESTROY(self);
|
DESTROY(self);
|
||||||
}
|
}
|
||||||
else if (0 != pthread_mutex_init(&_mutex, &attr_reporting))
|
else if (0 != pthread_mutex_init(&_mutex, &attr_reporting))
|
||||||
{
|
{
|
||||||
pthread_cond_destroy(&_condition);
|
pthread_cond_destroy(&_condition);
|
||||||
DESTROY(self);
|
DESTROY(self);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -481,7 +504,7 @@ MNAME
|
||||||
|
|
||||||
- (void) signal
|
- (void) signal
|
||||||
{
|
{
|
||||||
pthread_cond_signal(&_condition);
|
GS_COND_SIGNAL(_condition);
|
||||||
}
|
}
|
||||||
|
|
||||||
MSTACK
|
MSTACK
|
||||||
|
@ -490,15 +513,25 @@ MUNLOCK
|
||||||
|
|
||||||
- (void) wait
|
- (void) wait
|
||||||
{
|
{
|
||||||
pthread_cond_wait(&_condition, &_mutex);
|
GS_COND_WAIT(&_condition, &_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) waitUntilDate: (NSDate*)limit
|
- (BOOL) waitUntilDate: (NSDate*)limit
|
||||||
{
|
{
|
||||||
|
int retVal = 0;
|
||||||
|
|
||||||
|
#if GS_USE_WIN32_THREADS_AND_LOCKS
|
||||||
|
NSTimeInterval ti = [limit timeIntervalSinceNow];
|
||||||
|
if (ti < 0) {
|
||||||
|
ti = 0.0; // handle timeout in the past
|
||||||
|
}
|
||||||
|
|
||||||
|
retVal = gs_cond_timedwait(&_condition, &_mutex, ti * 1000.0);
|
||||||
|
#else
|
||||||
NSTimeInterval ti = [limit timeIntervalSince1970];
|
NSTimeInterval ti = [limit timeIntervalSince1970];
|
||||||
|
|
||||||
double secs, subsecs;
|
double secs, subsecs;
|
||||||
struct timespec timeout;
|
struct timespec timeout;
|
||||||
int retVal = 0;
|
|
||||||
|
|
||||||
// Split the float into seconds and fractions of a second
|
// Split the float into seconds and fractions of a second
|
||||||
subsecs = modf(ti, &secs);
|
subsecs = modf(ti, &secs);
|
||||||
|
@ -510,6 +543,8 @@ MUNLOCK
|
||||||
*/
|
*/
|
||||||
|
|
||||||
retVal = pthread_cond_timedwait(&_condition, &_mutex, &timeout);
|
retVal = pthread_cond_timedwait(&_condition, &_mutex, &timeout);
|
||||||
|
#endif /* GS_USE_WIN32_THREADS_AND_LOCKS */
|
||||||
|
|
||||||
if (retVal == 0)
|
if (retVal == 0)
|
||||||
{
|
{
|
||||||
return YES;
|
return YES;
|
||||||
|
@ -518,10 +553,8 @@ MUNLOCK
|
||||||
{
|
{
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
if (retVal == EINVAL)
|
|
||||||
{
|
NSLog(@"Error calling pthread_cond_timedwait: %d", retVal);
|
||||||
NSLog(@"Invalid arguments to pthread_cond_timedwait");
|
|
||||||
}
|
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -694,7 +727,7 @@ MSTACK
|
||||||
NSThread *t = GSCurrentThread(); \
|
NSThread *t = GSCurrentThread(); \
|
||||||
int err; \
|
int err; \
|
||||||
CHKT(t,Wait) \
|
CHKT(t,Wait) \
|
||||||
err = pthread_mutex_lock(&_mutex);\
|
err = GS_MUTEX_LOCK(_mutex);\
|
||||||
if (EDEADLK == err)\
|
if (EDEADLK == err)\
|
||||||
{\
|
{\
|
||||||
CHKT(t,Drop) \
|
CHKT(t,Drop) \
|
||||||
|
@ -735,17 +768,28 @@ MTRYLOCK
|
||||||
NSThread *t = GSCurrentThread();
|
NSThread *t = GSCurrentThread();
|
||||||
CHKT(t,Drop)
|
CHKT(t,Drop)
|
||||||
CHKT(t,Wait)
|
CHKT(t,Wait)
|
||||||
pthread_cond_wait(&_condition, &_mutex);
|
GS_COND_WAIT(&_condition, &_mutex);
|
||||||
CHKT(t,Hold)
|
CHKT(t,Hold)
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) waitUntilDate: (NSDate*)limit
|
- (BOOL) waitUntilDate: (NSDate*)limit
|
||||||
{
|
{
|
||||||
|
int retVal = 0;
|
||||||
|
NSThread *t = GSCurrentThread();
|
||||||
|
|
||||||
|
#if GS_USE_WIN32_THREADS_AND_LOCKS
|
||||||
|
NSTimeInterval ti = [limit timeIntervalSinceNow];
|
||||||
|
if (ti < 0) {
|
||||||
|
ti = 0.0; // handle timeout in the past
|
||||||
|
}
|
||||||
|
|
||||||
|
CHKT(t,Drop)
|
||||||
|
retVal = gs_cond_timedwait(&_condition, &_mutex, ti * 1000.0);
|
||||||
|
#else
|
||||||
NSTimeInterval ti = [limit timeIntervalSince1970];
|
NSTimeInterval ti = [limit timeIntervalSince1970];
|
||||||
NSThread *t = GSCurrentThread();
|
|
||||||
double secs, subsecs;
|
double secs, subsecs;
|
||||||
struct timespec timeout;
|
struct timespec timeout;
|
||||||
int retVal = 0;
|
|
||||||
|
|
||||||
// Split the float into seconds and fractions of a second
|
// Split the float into seconds and fractions of a second
|
||||||
subsecs = modf(ti, &secs);
|
subsecs = modf(ti, &secs);
|
||||||
|
@ -758,6 +802,8 @@ MTRYLOCK
|
||||||
|
|
||||||
CHKT(t,Drop)
|
CHKT(t,Drop)
|
||||||
retVal = pthread_cond_timedwait(&_condition, &_mutex, &timeout);
|
retVal = pthread_cond_timedwait(&_condition, &_mutex, &timeout);
|
||||||
|
#endif /* GS_USE_WIN32_THREADS_AND_LOCKS */
|
||||||
|
|
||||||
if (retVal == 0)
|
if (retVal == 0)
|
||||||
{
|
{
|
||||||
CHKT(t,Hold)
|
CHKT(t,Hold)
|
||||||
|
@ -769,10 +815,7 @@ MTRYLOCK
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retVal == EINVAL)
|
NSLog(@"Error calling pthread_cond_timedwait: %d", retVal);
|
||||||
{
|
|
||||||
NSLog(@"Invalid arguments to pthread_cond_timedwait");
|
|
||||||
}
|
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -854,3 +897,165 @@ MUNLOCK
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pthread-like locking primitives using Windows SRWLock. Provides
|
||||||
|
* normal, recursive, and error-checked locks.
|
||||||
|
*/
|
||||||
|
#if GS_USE_WIN32_THREADS_AND_LOCKS
|
||||||
|
|
||||||
|
void
|
||||||
|
gs_mutex_init(gs_mutex_t *mutex, gs_mutex_attr_t attr)
|
||||||
|
{
|
||||||
|
memset(mutex, 0, sizeof(gs_mutex_t));
|
||||||
|
InitializeSRWLock(&mutex->lock);
|
||||||
|
mutex->attr = attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
gs_mutex_lock(gs_mutex_t *mutex)
|
||||||
|
{
|
||||||
|
DWORD thisThread = GetCurrentThreadId();
|
||||||
|
DWORD ownerThread;
|
||||||
|
|
||||||
|
// fast path if lock is not taken
|
||||||
|
if (TryAcquireSRWLockExclusive(&mutex->lock))
|
||||||
|
{
|
||||||
|
assert(mutex->depth == 0);
|
||||||
|
mutex->depth = 1;
|
||||||
|
atomic_store(&mutex->owner, thisThread);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// needs to be atomic because another thread can concurrently set it
|
||||||
|
ownerThread = atomic_load(&mutex->owner);
|
||||||
|
if (ownerThread == thisThread)
|
||||||
|
{
|
||||||
|
// this thread already owns this lock
|
||||||
|
switch (mutex->attr)
|
||||||
|
{
|
||||||
|
case gs_mutex_attr_normal:
|
||||||
|
// deadlock
|
||||||
|
assert(mutex->depth == 1);
|
||||||
|
AcquireSRWLockExclusive(&mutex->lock);
|
||||||
|
assert(false); // not reached
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case gs_mutex_attr_errorcheck:
|
||||||
|
// return deadlock error
|
||||||
|
assert(mutex->depth == 1);
|
||||||
|
return EDEADLK;
|
||||||
|
|
||||||
|
case gs_mutex_attr_recursive:
|
||||||
|
// recursive lock
|
||||||
|
mutex->depth++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for another thread to release the lock
|
||||||
|
AcquireSRWLockExclusive(&mutex->lock);
|
||||||
|
assert(mutex->depth == 0);
|
||||||
|
mutex->depth = 1;
|
||||||
|
atomic_store(&mutex->owner, thisThread);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
gs_mutex_trylock(gs_mutex_t *mutex)
|
||||||
|
{
|
||||||
|
DWORD thisThread = GetCurrentThreadId();
|
||||||
|
DWORD ownerThread;
|
||||||
|
|
||||||
|
if (TryAcquireSRWLockExclusive(&mutex->lock))
|
||||||
|
{
|
||||||
|
assert(mutex->depth == 0);
|
||||||
|
mutex->depth = 1;
|
||||||
|
atomic_store(&mutex->owner, thisThread);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// needs to be atomic because another thread can concurrently set it
|
||||||
|
ownerThread = atomic_load(&mutex->owner);
|
||||||
|
if (ownerThread == thisThread && mutex->attr == gs_mutex_attr_recursive)
|
||||||
|
{
|
||||||
|
// this thread already owns this lock and it's recursive
|
||||||
|
assert(mutex->depth > 0);
|
||||||
|
mutex->depth++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// lock is taken
|
||||||
|
return EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
gs_mutex_unlock(gs_mutex_t *mutex)
|
||||||
|
{
|
||||||
|
switch (mutex->attr)
|
||||||
|
{
|
||||||
|
case gs_mutex_attr_normal:
|
||||||
|
break;
|
||||||
|
case gs_mutex_attr_errorcheck:
|
||||||
|
case gs_mutex_attr_recursive: {
|
||||||
|
// return error if lock is not held by this thread
|
||||||
|
DWORD thisThread = GetCurrentThreadId();
|
||||||
|
DWORD ownerThread = atomic_load(&mutex->owner);
|
||||||
|
if (ownerThread != thisThread) {
|
||||||
|
return EPERM;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mutex->attr == gs_mutex_attr_recursive && mutex->depth > 1)
|
||||||
|
{
|
||||||
|
// recursive lock releasing inner lock
|
||||||
|
mutex->depth--;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(mutex->depth == 1);
|
||||||
|
mutex->depth = 0;
|
||||||
|
atomic_store(&mutex->owner, 0);
|
||||||
|
ReleaseSRWLockExclusive(&mutex->lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NB: timeout specified in milliseconds relative to now
|
||||||
|
int
|
||||||
|
gs_cond_timedwait(gs_cond_t *cond, gs_mutex_t *mutex, DWORD millisecs)
|
||||||
|
{
|
||||||
|
int retVal = 0;
|
||||||
|
|
||||||
|
assert(mutex->depth == 1);
|
||||||
|
mutex->depth = 0;
|
||||||
|
atomic_store(&mutex->owner, 0);
|
||||||
|
|
||||||
|
if (!SleepConditionVariableSRW(cond, &mutex->lock, millisecs, 0))
|
||||||
|
{
|
||||||
|
DWORD lastError = GetLastError();
|
||||||
|
if (lastError == ERROR_TIMEOUT) {
|
||||||
|
retVal = ETIMEDOUT;
|
||||||
|
} else {
|
||||||
|
retVal = lastError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(mutex->depth == 0);
|
||||||
|
mutex->depth = 1;
|
||||||
|
atomic_store(&mutex->owner, GetCurrentThreadId());
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int
|
||||||
|
gs_cond_wait(gs_cond_t *cond, gs_mutex_t *mutex)
|
||||||
|
{
|
||||||
|
return gs_cond_timedwait(cond, mutex, INFINITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* GS_USE_WIN32_THREADS_AND_LOCKS */
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,7 @@ GS_ROOT_CLASS @interface NSZombie
|
||||||
/* allocationLock is needed when for protecting the map table of zombie
|
/* allocationLock is needed when for protecting the map table of zombie
|
||||||
* information and if atomic operations are not available.
|
* information and if atomic operations are not available.
|
||||||
*/
|
*/
|
||||||
static pthread_mutex_t allocationLock = PTHREAD_MUTEX_INITIALIZER;
|
static gs_mutex_t allocationLock = GS_MUTEX_INIT_STATIC;
|
||||||
|
|
||||||
BOOL NSZombieEnabled = NO;
|
BOOL NSZombieEnabled = NO;
|
||||||
BOOL NSDeallocateZombies = NO;
|
BOOL NSDeallocateZombies = NO;
|
||||||
|
@ -146,12 +146,12 @@ static void GSMakeZombie(NSObject *o, Class c)
|
||||||
object_setClass(o, zombieClass);
|
object_setClass(o, zombieClass);
|
||||||
if (0 != zombieMap)
|
if (0 != zombieMap)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&allocationLock);
|
GS_MUTEX_LOCK(allocationLock);
|
||||||
if (0 != zombieMap)
|
if (0 != zombieMap)
|
||||||
{
|
{
|
||||||
NSMapInsert(zombieMap, (void*)o, (void*)c);
|
NSMapInsert(zombieMap, (void*)o, (void*)c);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&allocationLock);
|
GS_MUTEX_UNLOCK(allocationLock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -162,12 +162,12 @@ static void GSLogZombie(id o, SEL sel)
|
||||||
|
|
||||||
if (0 != zombieMap)
|
if (0 != zombieMap)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&allocationLock);
|
GS_MUTEX_LOCK(allocationLock);
|
||||||
if (0 != zombieMap)
|
if (0 != zombieMap)
|
||||||
{
|
{
|
||||||
c = NSMapGet(zombieMap, (void*)o);
|
c = NSMapGet(zombieMap, (void*)o);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&allocationLock);
|
GS_MUTEX_UNLOCK(allocationLock);
|
||||||
}
|
}
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
{
|
{
|
||||||
|
@ -395,6 +395,8 @@ GSAtomicDecrement(gsatomic_t X)
|
||||||
|
|
||||||
#if !defined(GSATOMICREAD)
|
#if !defined(GSATOMICREAD)
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
typedef int gsrefcount_t; // No atomics, use a simple integer
|
typedef int gsrefcount_t; // No atomics, use a simple integer
|
||||||
|
|
||||||
/* Having just one allocationLock for all leads to lock contention
|
/* Having just one allocationLock for all leads to lock contention
|
||||||
|
@ -841,12 +843,12 @@ NSDeallocateObject(id anObject)
|
||||||
#ifdef OBJC_CAP_ARC
|
#ifdef OBJC_CAP_ARC
|
||||||
if (0 != zombieMap)
|
if (0 != zombieMap)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&allocationLock);
|
GS_MUTEX_LOCK(allocationLock);
|
||||||
if (0 != zombieMap)
|
if (0 != zombieMap)
|
||||||
{
|
{
|
||||||
NSMapInsert(zombieMap, (void*)anObject, (void*)aClass);
|
NSMapInsert(zombieMap, (void*)anObject, (void*)aClass);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&allocationLock);
|
GS_MUTEX_UNLOCK(allocationLock);
|
||||||
}
|
}
|
||||||
if (NSDeallocateZombies == YES)
|
if (NSDeallocateZombies == YES)
|
||||||
{
|
{
|
||||||
|
@ -1117,10 +1119,10 @@ static id gs_weak_load(id obj)
|
||||||
+ (void) _atExit
|
+ (void) _atExit
|
||||||
{
|
{
|
||||||
NSMapTable *m = nil;
|
NSMapTable *m = nil;
|
||||||
pthread_mutex_lock(&allocationLock);
|
GS_MUTEX_LOCK(allocationLock);
|
||||||
m = zombieMap;
|
m = zombieMap;
|
||||||
zombieMap = nil;
|
zombieMap = nil;
|
||||||
pthread_mutex_unlock(&allocationLock);
|
GS_MUTEX_UNLOCK(allocationLock);
|
||||||
DESTROY(m);
|
DESTROY(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2500,12 +2502,12 @@ static id gs_weak_load(id obj)
|
||||||
|
|
||||||
if (0 != zombieMap)
|
if (0 != zombieMap)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&allocationLock);
|
GS_MUTEX_LOCK(allocationLock);
|
||||||
if (0 != zombieMap)
|
if (0 != zombieMap)
|
||||||
{
|
{
|
||||||
c = NSMapGet(zombieMap, (void*)self);
|
c = NSMapGet(zombieMap, (void*)self);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&allocationLock);
|
GS_MUTEX_UNLOCK(allocationLock);
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
@ -2527,9 +2529,9 @@ static id gs_weak_load(id obj)
|
||||||
{
|
{
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
pthread_mutex_lock(&allocationLock);
|
GS_MUTEX_LOCK(allocationLock);
|
||||||
c = zombieMap ? NSMapGet(zombieMap, (void*)self) : Nil;
|
c = zombieMap ? NSMapGet(zombieMap, (void*)self) : Nil;
|
||||||
pthread_mutex_unlock(&allocationLock);
|
GS_MUTEX_UNLOCK(allocationLock);
|
||||||
|
|
||||||
return [c instanceMethodSignatureForSelector: aSelector];
|
return [c instanceMethodSignatureForSelector: aSelector];
|
||||||
}
|
}
|
||||||
|
|
|
@ -246,11 +246,11 @@ typedef GSString *ivars;
|
||||||
*/
|
*/
|
||||||
+ (BOOL) _scanDouble: (double*)value from: (NSString*)str
|
+ (BOOL) _scanDouble: (double*)value from: (NSString*)str
|
||||||
{
|
{
|
||||||
static pthread_mutex_t myLock = PTHREAD_MUTEX_INITIALIZER;
|
static gs_mutex_t myLock = GS_MUTEX_INIT_STATIC;
|
||||||
static NSScanner *doubleScanner = nil;
|
static NSScanner *doubleScanner = nil;
|
||||||
BOOL ok = NO;
|
BOOL ok = NO;
|
||||||
|
|
||||||
pthread_mutex_lock(&myLock);
|
GS_MUTEX_LOCK(myLock);
|
||||||
if (nil == doubleScanner)
|
if (nil == doubleScanner)
|
||||||
{
|
{
|
||||||
doubleScanner = [[self alloc] initWithString: _empty];
|
doubleScanner = [[self alloc] initWithString: _empty];
|
||||||
|
@ -258,7 +258,7 @@ typedef GSString *ivars;
|
||||||
[doubleScanner _setString: str];
|
[doubleScanner _setString: str];
|
||||||
ok = [doubleScanner scanDouble: value];
|
ok = [doubleScanner scanDouble: value];
|
||||||
[doubleScanner _setString: _empty]; // Release scanned string
|
[doubleScanner _setString: _empty]; // Release scanned string
|
||||||
pthread_mutex_unlock(&myLock);
|
GS_MUTEX_UNLOCK(myLock);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -153,7 +153,7 @@ static Class GSPlaceholderStringClass;
|
||||||
|
|
||||||
static GSPlaceholderString *defaultPlaceholderString;
|
static GSPlaceholderString *defaultPlaceholderString;
|
||||||
static NSMapTable *placeholderMap;
|
static NSMapTable *placeholderMap;
|
||||||
static pthread_mutex_t placeholderLock = PTHREAD_MUTEX_INITIALIZER;
|
static gs_mutex_t placeholderLock = GS_MUTEX_INIT_STATIC;
|
||||||
|
|
||||||
|
|
||||||
static SEL cMemberSel = 0;
|
static SEL cMemberSel = 0;
|
||||||
|
@ -305,14 +305,14 @@ pathSeps(void)
|
||||||
{
|
{
|
||||||
if (rPathSeps == nil)
|
if (rPathSeps == nil)
|
||||||
{
|
{
|
||||||
(void)pthread_mutex_lock(&placeholderLock);
|
GS_MUTEX_LOCK(placeholderLock);
|
||||||
if (rPathSeps == nil)
|
if (rPathSeps == nil)
|
||||||
{
|
{
|
||||||
rPathSeps
|
rPathSeps
|
||||||
= [NSCharacterSet characterSetWithCharactersInString: @"/\\"];
|
= [NSCharacterSet characterSetWithCharactersInString: @"/\\"];
|
||||||
rPathSeps = [NSObject leakAt: &rPathSeps];
|
rPathSeps = [NSObject leakAt: &rPathSeps];
|
||||||
}
|
}
|
||||||
(void)pthread_mutex_unlock(&placeholderLock);
|
GS_MUTEX_UNLOCK(placeholderLock);
|
||||||
}
|
}
|
||||||
return rPathSeps;
|
return rPathSeps;
|
||||||
}
|
}
|
||||||
|
@ -320,14 +320,14 @@ pathSeps(void)
|
||||||
{
|
{
|
||||||
if (uPathSeps == nil)
|
if (uPathSeps == nil)
|
||||||
{
|
{
|
||||||
(void)pthread_mutex_lock(&placeholderLock);
|
GS_MUTEX_LOCK(placeholderLock);
|
||||||
if (uPathSeps == nil)
|
if (uPathSeps == nil)
|
||||||
{
|
{
|
||||||
uPathSeps
|
uPathSeps
|
||||||
= [NSCharacterSet characterSetWithCharactersInString: @"/"];
|
= [NSCharacterSet characterSetWithCharactersInString: @"/"];
|
||||||
uPathSeps = [NSObject leakAt: &uPathSeps];
|
uPathSeps = [NSObject leakAt: &uPathSeps];
|
||||||
}
|
}
|
||||||
(void)pthread_mutex_unlock(&placeholderLock);
|
GS_MUTEX_UNLOCK(placeholderLock);
|
||||||
}
|
}
|
||||||
return uPathSeps;
|
return uPathSeps;
|
||||||
}
|
}
|
||||||
|
@ -335,14 +335,14 @@ pathSeps(void)
|
||||||
{
|
{
|
||||||
if (wPathSeps == nil)
|
if (wPathSeps == nil)
|
||||||
{
|
{
|
||||||
(void)pthread_mutex_lock(&placeholderLock);
|
GS_MUTEX_LOCK(placeholderLock);
|
||||||
if (wPathSeps == nil)
|
if (wPathSeps == nil)
|
||||||
{
|
{
|
||||||
wPathSeps
|
wPathSeps
|
||||||
= [NSCharacterSet characterSetWithCharactersInString: @"\\"];
|
= [NSCharacterSet characterSetWithCharactersInString: @"\\"];
|
||||||
wPathSeps = [NSObject leakAt: &wPathSeps];
|
wPathSeps = [NSObject leakAt: &wPathSeps];
|
||||||
}
|
}
|
||||||
(void)pthread_mutex_unlock(&placeholderLock);
|
GS_MUTEX_UNLOCK(placeholderLock);
|
||||||
}
|
}
|
||||||
return wPathSeps;
|
return wPathSeps;
|
||||||
}
|
}
|
||||||
|
@ -897,7 +897,7 @@ GSICUCollatorOpen(NSStringCompareOptions mask, NSLocale *locale)
|
||||||
* locate the correct placeholder in the (lock protected)
|
* locate the correct placeholder in the (lock protected)
|
||||||
* table of placeholders.
|
* table of placeholders.
|
||||||
*/
|
*/
|
||||||
(void)pthread_mutex_lock(&placeholderLock);
|
GS_MUTEX_LOCK(placeholderLock);
|
||||||
obj = (id)NSMapGet(placeholderMap, (void*)z);
|
obj = (id)NSMapGet(placeholderMap, (void*)z);
|
||||||
if (obj == nil)
|
if (obj == nil)
|
||||||
{
|
{
|
||||||
|
@ -908,7 +908,7 @@ GSICUCollatorOpen(NSStringCompareOptions mask, NSLocale *locale)
|
||||||
obj = (id)[GSPlaceholderStringClass allocWithZone: z];
|
obj = (id)[GSPlaceholderStringClass allocWithZone: z];
|
||||||
NSMapInsert(placeholderMap, (void*)z, (void*)obj);
|
NSMapInsert(placeholderMap, (void*)z, (void*)obj);
|
||||||
}
|
}
|
||||||
(void)pthread_mutex_unlock(&placeholderLock);
|
GS_MUTEX_UNLOCK(placeholderLock);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
// Dummy implementatation
|
// Dummy implementatation
|
||||||
// cleaner than IFDEF'ing the code everywhere
|
// cleaner than IFDEF'ing the code everywhere
|
||||||
#if !(HAVE_PTHREAD_SPIN_LOCK)
|
#ifndef HAVE_PTHREAD_SPIN_LOCK
|
||||||
typedef volatile int pthread_spinlock_t;
|
typedef volatile int pthread_spinlock_t;
|
||||||
int pthread_spin_init(pthread_spinlock_t *lock, int pshared)
|
int pthread_spin_init(pthread_spinlock_t *lock, int pshared)
|
||||||
{
|
{
|
||||||
|
@ -58,7 +58,11 @@ int pthread_spin_lock(pthread_spinlock_t *lock)
|
||||||
{
|
{
|
||||||
// If it is already 1, let another thread play with the CPU for a
|
// If it is already 1, let another thread play with the CPU for a
|
||||||
// bit then try again.
|
// bit then try again.
|
||||||
|
#if defined(_WIN32)
|
||||||
|
Sleep(0);
|
||||||
|
#else
|
||||||
sleep(0);
|
sleep(0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -78,7 +82,7 @@ int pthread_spin_destroy(pthread_spinlock_t *lock)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* HAVE_PTHREAD_SPIN_LOCK */
|
||||||
|
|
||||||
/** Structure for holding lock information for a thread.
|
/** Structure for holding lock information for a thread.
|
||||||
*/
|
*/
|
||||||
|
@ -90,7 +94,7 @@ typedef struct {
|
||||||
|
|
||||||
#define EXPOSE_NSThread_IVARS 1
|
#define EXPOSE_NSThread_IVARS 1
|
||||||
#define GS_NSThread_IVARS \
|
#define GS_NSThread_IVARS \
|
||||||
pthread_t _pthreadID; \
|
gs_thread_id_t _pthreadID; \
|
||||||
NSUInteger _threadID; \
|
NSUInteger _threadID; \
|
||||||
GSLockInfo _lockInfo
|
GSLockInfo _lockInfo
|
||||||
|
|
||||||
|
@ -326,7 +330,7 @@ GSSleepUntilIntervalSinceReferenceDate(NSTimeInterval when)
|
||||||
/* We don't need to wait, but since we are willing to wait at this
|
/* We don't need to wait, but since we are willing to wait at this
|
||||||
* point, we should let other threads have preference over this one.
|
* point, we should let other threads have preference over this one.
|
||||||
*/
|
*/
|
||||||
sched_yield();
|
GS_YIELD();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -458,12 +462,12 @@ static BOOL entered_multi_threaded_state = NO;
|
||||||
static NSThread *defaultThread;
|
static NSThread *defaultThread;
|
||||||
|
|
||||||
static BOOL keyInitialized = NO;
|
static BOOL keyInitialized = NO;
|
||||||
static pthread_key_t thread_object_key;
|
static gs_thread_key_t thread_object_key;
|
||||||
|
|
||||||
|
|
||||||
static NSHashTable *_activeBlocked = nil;
|
static NSHashTable *_activeBlocked = nil;
|
||||||
static NSHashTable *_activeThreads = nil;
|
static NSHashTable *_activeThreads = nil;
|
||||||
static pthread_mutex_t _activeLock = PTHREAD_MUTEX_INITIALIZER;
|
static gs_mutex_t _activeLock = GS_MUTEX_INIT_STATIC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pthread_t is an opaque type. It might be a scalar type or
|
* pthread_t is an opaque type. It might be a scalar type or
|
||||||
|
@ -473,10 +477,10 @@ static pthread_mutex_t _activeLock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
* This follows the CoreFoundation 'create rule' and returns an object with
|
* This follows the CoreFoundation 'create rule' and returns an object with
|
||||||
* a reference count of 1.
|
* a reference count of 1.
|
||||||
*/
|
*/
|
||||||
static inline NSValue* NSValueCreateFromPthread(pthread_t thread)
|
static inline NSValue* NSValueCreateFromPthread(gs_thread_id_t thread)
|
||||||
{
|
{
|
||||||
return [[NSValue alloc] initWithBytes: &thread
|
return [[NSValue alloc] initWithBytes: &thread
|
||||||
objCType: @encode(pthread_t)];
|
objCType: @encode(gs_thread_id_t)];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -484,14 +488,14 @@ static inline NSValue* NSValueCreateFromPthread(pthread_t thread)
|
||||||
* from an NSValue.
|
* from an NSValue.
|
||||||
*/
|
*/
|
||||||
static inline void
|
static inline void
|
||||||
_getPthreadFromNSValue(const void *value, pthread_t *thread_ptr)
|
_getPthreadFromNSValue(const void *value, gs_thread_id_t *thread_ptr)
|
||||||
{
|
{
|
||||||
const char *enc;
|
const char *enc;
|
||||||
|
|
||||||
NSCAssert(thread_ptr, @"No storage for thread reference");
|
NSCAssert(thread_ptr, @"No storage for thread reference");
|
||||||
# ifndef NS_BLOCK_ASSERTIONS
|
# ifndef NS_BLOCK_ASSERTIONS
|
||||||
enc = [(NSValue*)value objCType];
|
enc = [(NSValue*)value objCType];
|
||||||
NSCAssert(enc != NULL && (0 == strcmp(@encode(pthread_t),enc)),
|
NSCAssert(enc != NULL && (0 == strcmp(@encode(gs_thread_id_t),enc)),
|
||||||
@"Invalid NSValue container for thread reference");
|
@"Invalid NSValue container for thread reference");
|
||||||
# endif
|
# endif
|
||||||
[(NSValue*)value getValue: (void*)thread_ptr];
|
[(NSValue*)value getValue: (void*)thread_ptr];
|
||||||
|
@ -506,12 +510,17 @@ _boxedPthreadIsEqual(NSMapTable *t,
|
||||||
const void *boxed,
|
const void *boxed,
|
||||||
const void *boxedOther)
|
const void *boxedOther)
|
||||||
{
|
{
|
||||||
pthread_t thread;
|
gs_thread_id_t thread;
|
||||||
pthread_t otherThread;
|
gs_thread_id_t otherThread;
|
||||||
|
|
||||||
_getPthreadFromNSValue(boxed, &thread);
|
_getPthreadFromNSValue(boxed, &thread);
|
||||||
_getPthreadFromNSValue(boxedOther, &otherThread);
|
_getPthreadFromNSValue(boxedOther, &otherThread);
|
||||||
|
|
||||||
|
#if GS_USE_WIN32_THREADS_AND_LOCKS
|
||||||
|
return thread == otherThread;
|
||||||
|
#else
|
||||||
return pthread_equal(thread, otherThread);
|
return pthread_equal(thread, otherThread);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -576,7 +585,7 @@ static const NSMapTableKeyCallBacks _boxedPthreadKeyCallBacks =
|
||||||
* thred if called from within the late-cleanup function.
|
* thred if called from within the late-cleanup function.
|
||||||
*/
|
*/
|
||||||
static NSMapTable *_exitingThreads = nil;
|
static NSMapTable *_exitingThreads = nil;
|
||||||
static pthread_mutex_t _exitingThreadsLock = PTHREAD_MUTEX_INITIALIZER;
|
static gs_mutex_t _exitingThreadsLock = GS_MUTEX_INIT_STATIC;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -588,7 +597,7 @@ static pthread_mutex_t _exitingThreadsLock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
static inline void _willLateUnregisterThread(NSValue *boxedThread,
|
static inline void _willLateUnregisterThread(NSValue *boxedThread,
|
||||||
NSThread *specific)
|
NSThread *specific)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&_exitingThreadsLock);
|
GS_MUTEX_LOCK(_exitingThreadsLock);
|
||||||
/* The map table is created lazily/late so that the NSThread
|
/* The map table is created lazily/late so that the NSThread
|
||||||
* +initialize method can be called without causing other
|
* +initialize method can be called without causing other
|
||||||
* classes to be initialized.
|
* classes to be initialized.
|
||||||
|
@ -603,7 +612,7 @@ static inline void _willLateUnregisterThread(NSValue *boxedThread,
|
||||||
}
|
}
|
||||||
NSMapInsert(_exitingThreads, (const void*)boxedThread,
|
NSMapInsert(_exitingThreads, (const void*)boxedThread,
|
||||||
(const void*)specific);
|
(const void*)specific);
|
||||||
pthread_mutex_unlock(&_exitingThreadsLock);
|
GS_MUTEX_UNLOCK(_exitingThreadsLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -617,12 +626,12 @@ static inline void _didLateUnregisterCurrentThread(NSValue *boxedThread)
|
||||||
* because the exception handler stores information in the current
|
* because the exception handler stores information in the current
|
||||||
* thread variables ... which causes recursion.
|
* thread variables ... which causes recursion.
|
||||||
*/
|
*/
|
||||||
pthread_mutex_lock(&_exitingThreadsLock);
|
GS_MUTEX_LOCK(_exitingThreadsLock);
|
||||||
if (nil != _exitingThreads)
|
if (nil != _exitingThreads)
|
||||||
{
|
{
|
||||||
NSMapRemove(_exitingThreads, (const void*)boxedThread);
|
NSMapRemove(_exitingThreads, (const void*)boxedThread);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&_exitingThreadsLock);
|
GS_MUTEX_UNLOCK(_exitingThreadsLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -654,14 +663,14 @@ static void exitedThread(void *thread)
|
||||||
/* On some systems this is called with a null thread pointer,
|
/* On some systems this is called with a null thread pointer,
|
||||||
* so try to get the NSThread object for the current thread.
|
* so try to get the NSThread object for the current thread.
|
||||||
*/
|
*/
|
||||||
thread = pthread_getspecific(thread_object_key);
|
thread = GS_THREAD_KEY_GET(thread_object_key);
|
||||||
if (0 == thread)
|
if (0 == thread)
|
||||||
{
|
{
|
||||||
return; // no thread info
|
return; // no thread info
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RETAIN((NSThread*)thread);
|
RETAIN((NSThread*)thread);
|
||||||
ref = NSValueCreateFromPthread(pthread_self());
|
ref = NSValueCreateFromPthread(GS_THREAD_ID_SELF());
|
||||||
_willLateUnregisterThread(ref, (NSThread*)thread);
|
_willLateUnregisterThread(ref, (NSThread*)thread);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -701,17 +710,17 @@ GSCurrentThread(void)
|
||||||
|
|
||||||
if (NO == keyInitialized)
|
if (NO == keyInitialized)
|
||||||
{
|
{
|
||||||
if (pthread_key_create(&thread_object_key, exitedThread))
|
if (!GS_THREAD_KEY_INIT(thread_object_key, exitedThread))
|
||||||
{
|
{
|
||||||
[NSException raise: NSInternalInconsistencyException
|
[NSException raise: NSInternalInconsistencyException
|
||||||
format: @"Unable to create thread key!"];
|
format: @"Unable to create thread key!"];
|
||||||
}
|
}
|
||||||
keyInitialized = YES;
|
keyInitialized = YES;
|
||||||
}
|
}
|
||||||
thr = pthread_getspecific(thread_object_key);
|
thr = GS_THREAD_KEY_GET(thread_object_key);
|
||||||
if (nil == thr)
|
if (nil == thr)
|
||||||
{
|
{
|
||||||
NSValue *selfThread = NSValueCreateFromPthread(pthread_self());
|
NSValue *selfThread = NSValueCreateFromPthread(GS_THREAD_ID_SELF());
|
||||||
|
|
||||||
/* NB this locked section cannot be protected by an exception handler
|
/* NB this locked section cannot be protected by an exception handler
|
||||||
* because the exception handler stores information in the current
|
* because the exception handler stores information in the current
|
||||||
|
@ -719,15 +728,15 @@ GSCurrentThread(void)
|
||||||
*/
|
*/
|
||||||
if (nil != _exitingThreads)
|
if (nil != _exitingThreads)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&_exitingThreadsLock);
|
GS_MUTEX_LOCK(_exitingThreadsLock);
|
||||||
thr = NSMapGet(_exitingThreads, (const void*)selfThread);
|
thr = NSMapGet(_exitingThreads, (const void*)selfThread);
|
||||||
pthread_mutex_unlock(&_exitingThreadsLock);
|
GS_MUTEX_UNLOCK(_exitingThreadsLock);
|
||||||
}
|
}
|
||||||
DESTROY(selfThread);
|
DESTROY(selfThread);
|
||||||
if (nil == thr)
|
if (nil == thr)
|
||||||
{
|
{
|
||||||
GSRegisterCurrentThread();
|
GSRegisterCurrentThread();
|
||||||
thr = pthread_getspecific(thread_object_key);
|
thr = GS_THREAD_KEY_GET(thread_object_key);
|
||||||
if ((nil == defaultThread) && IS_MAIN_PTHREAD)
|
if ((nil == defaultThread) && IS_MAIN_PTHREAD)
|
||||||
{
|
{
|
||||||
defaultThread = RETAIN(thr);
|
defaultThread = RETAIN(thr);
|
||||||
|
@ -763,7 +772,7 @@ GSCurrentThreadDictionary(void)
|
||||||
static void
|
static void
|
||||||
gnustep_base_thread_callback(void)
|
gnustep_base_thread_callback(void)
|
||||||
{
|
{
|
||||||
static pthread_mutex_t threadLock = PTHREAD_MUTEX_INITIALIZER;
|
static gs_mutex_t threadLock = GS_MUTEX_INIT_STATIC;
|
||||||
/*
|
/*
|
||||||
* Protect this function with locking ... to avoid any possibility
|
* Protect this function with locking ... to avoid any possibility
|
||||||
* of multiple threads registering with the system simultaneously,
|
* of multiple threads registering with the system simultaneously,
|
||||||
|
@ -772,7 +781,7 @@ gnustep_base_thread_callback(void)
|
||||||
*/
|
*/
|
||||||
if (entered_multi_threaded_state == NO)
|
if (entered_multi_threaded_state == NO)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&threadLock);
|
GS_MUTEX_LOCK(threadLock);
|
||||||
if (entered_multi_threaded_state == NO)
|
if (entered_multi_threaded_state == NO)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -823,7 +832,7 @@ gnustep_base_thread_callback(void)
|
||||||
NS_ENDHANDLER
|
NS_ENDHANDLER
|
||||||
LEAVE_POOL
|
LEAVE_POOL
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&threadLock);
|
GS_MUTEX_UNLOCK(threadLock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -834,9 +843,9 @@ gnustep_base_thread_callback(void)
|
||||||
* pthread specific memory before we do anything which might need to
|
* pthread specific memory before we do anything which might need to
|
||||||
* check what the current thread is (like getting the ID)!
|
* check what the current thread is (like getting the ID)!
|
||||||
*/
|
*/
|
||||||
pthread_setspecific(thread_object_key, self);
|
GS_THREAD_KEY_SET(thread_object_key, self);
|
||||||
threadID = GSPrivateThreadID();
|
threadID = GSPrivateThreadID();
|
||||||
pthread_mutex_lock(&_activeLock);
|
GS_MUTEX_LOCK(_activeLock);
|
||||||
/* The hash table is created lazily/late so that the NSThread
|
/* The hash table is created lazily/late so that the NSThread
|
||||||
* +initialize method can be called without causing other
|
* +initialize method can be called without causing other
|
||||||
* classes to be initialized.
|
* classes to be initialized.
|
||||||
|
@ -850,7 +859,7 @@ gnustep_base_thread_callback(void)
|
||||||
NSNonRetainedObjectHashCallBacks, 100);
|
NSNonRetainedObjectHashCallBacks, 100);
|
||||||
}
|
}
|
||||||
NSHashInsert(_activeThreads, (const void*)self);
|
NSHashInsert(_activeThreads, (const void*)self);
|
||||||
pthread_mutex_unlock(&_activeLock);
|
GS_MUTEX_UNLOCK(_activeLock);
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -888,7 +897,7 @@ unregisterActiveThread(NSThread *thread)
|
||||||
[(GSRunLoopThreadInfo*)thread->_runLoopInfo invalidate];
|
[(GSRunLoopThreadInfo*)thread->_runLoopInfo invalidate];
|
||||||
LEAVE_POOL
|
LEAVE_POOL
|
||||||
RELEASE(thread);
|
RELEASE(thread);
|
||||||
pthread_setspecific(thread_object_key, nil);
|
GS_THREAD_KEY_SET(thread_object_key, nil);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -906,7 +915,7 @@ unregisterActiveThread(NSThread *thread)
|
||||||
|
|
||||||
+ (BOOL) _createThreadForCurrentPthread
|
+ (BOOL) _createThreadForCurrentPthread
|
||||||
{
|
{
|
||||||
NSThread *t = pthread_getspecific(thread_object_key);
|
NSThread *t = GS_THREAD_KEY_GET(thread_object_key);
|
||||||
|
|
||||||
if (t == nil)
|
if (t == nil)
|
||||||
{
|
{
|
||||||
|
@ -962,7 +971,11 @@ unregisterActiveThread(NSThread *thread)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#if GS_USE_WIN32_THREADS_AND_LOCKS
|
||||||
|
_endthread();
|
||||||
|
#else
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -976,7 +989,7 @@ unregisterActiveThread(NSThread *thread)
|
||||||
{
|
{
|
||||||
if (NO == keyInitialized)
|
if (NO == keyInitialized)
|
||||||
{
|
{
|
||||||
if (pthread_key_create(&thread_object_key, exitedThread))
|
if (!GS_THREAD_KEY_INIT(thread_object_key, exitedThread))
|
||||||
{
|
{
|
||||||
[NSException raise: NSInternalInconsistencyException
|
[NSException raise: NSInternalInconsistencyException
|
||||||
format: @"Unable to create thread key!"];
|
format: @"Unable to create thread key!"];
|
||||||
|
@ -1014,9 +1027,34 @@ unregisterActiveThread(NSThread *thread)
|
||||||
* range 0.0 (lowest) to 1.0 (highest) which is mapped to the underlying
|
* range 0.0 (lowest) to 1.0 (highest) which is mapped to the underlying
|
||||||
* system priorities.
|
* system priorities.
|
||||||
*/
|
*/
|
||||||
+ (void) setThreadPriority: (double)pri
|
+ (BOOL) setThreadPriority: (double)pri
|
||||||
{
|
{
|
||||||
#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING > 0)
|
#if GS_USE_WIN32_THREADS_AND_LOCKS
|
||||||
|
// convert [0.0,1.0] priority to Windows defines
|
||||||
|
int winPri;
|
||||||
|
if (pri <= 0.0) {
|
||||||
|
winPri = THREAD_PRIORITY_IDLE;
|
||||||
|
} else if (pri <= 0.25) {
|
||||||
|
winPri = THREAD_PRIORITY_LOWEST;
|
||||||
|
} else if (pri < 0.5) {
|
||||||
|
winPri = THREAD_PRIORITY_BELOW_NORMAL;
|
||||||
|
} else if (pri >= 1.0) {
|
||||||
|
winPri = THREAD_PRIORITY_TIME_CRITICAL;
|
||||||
|
} else if (pri >= 0.75) {
|
||||||
|
winPri = THREAD_PRIORITY_HIGHEST;
|
||||||
|
} else if (pri > 0.5) {
|
||||||
|
winPri = THREAD_PRIORITY_ABOVE_NORMAL;
|
||||||
|
} else {
|
||||||
|
winPri = THREAD_PRIORITY_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SetThreadPriority(GetCurrentThread(), winPri)) {
|
||||||
|
NSLog(@"Failed to set thread priority %d: %@", winPri, [NSError _last]);
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
return YES;
|
||||||
|
#elif defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING > 0)
|
||||||
|
int res;
|
||||||
int policy;
|
int policy;
|
||||||
struct sched_param param;
|
struct sched_param param;
|
||||||
|
|
||||||
|
@ -1028,9 +1066,18 @@ unregisterActiveThread(NSThread *thread)
|
||||||
pri *= (PTHREAD_MAX_PRIORITY - PTHREAD_MIN_PRIORITY);
|
pri *= (PTHREAD_MAX_PRIORITY - PTHREAD_MIN_PRIORITY);
|
||||||
pri += PTHREAD_MIN_PRIORITY;
|
pri += PTHREAD_MIN_PRIORITY;
|
||||||
|
|
||||||
pthread_getschedparam(pthread_self(), &policy, ¶m);
|
res = pthread_getschedparam(pthread_self(), &policy, ¶m);
|
||||||
param.sched_priority = pri;
|
if (res == 0) {
|
||||||
pthread_setschedparam(pthread_self(), policy, ¶m);
|
param.sched_priority = pri;
|
||||||
|
res = pthread_setschedparam(pthread_self(), policy, ¶m);
|
||||||
|
}
|
||||||
|
if (res != 0) {
|
||||||
|
NSLog(@"Failed to set thread priority %f: %d", pri, res);
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
return YES;
|
||||||
|
#else
|
||||||
|
return NO;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1054,21 +1101,61 @@ unregisterActiveThread(NSThread *thread)
|
||||||
+ (double) threadPriority
|
+ (double) threadPriority
|
||||||
{
|
{
|
||||||
double pri = 0;
|
double pri = 0;
|
||||||
#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING > 0)
|
|
||||||
|
#if GS_USE_WIN32_THREADS_AND_LOCKS
|
||||||
|
// convert [0.0,1.0] priority to Windows defines
|
||||||
|
int winPri = GetThreadPriority(GetCurrentThread());
|
||||||
|
if (winPri == THREAD_PRIORITY_ERROR_RETURN) {
|
||||||
|
NSLog(@"Failed to get thread priority: %@", [NSError _last]);
|
||||||
|
return pri;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (winPri)
|
||||||
|
{
|
||||||
|
case THREAD_PRIORITY_IDLE:
|
||||||
|
pri = 0.0;
|
||||||
|
break;
|
||||||
|
case THREAD_PRIORITY_LOWEST:
|
||||||
|
pri = 0.2;
|
||||||
|
break;
|
||||||
|
case THREAD_PRIORITY_BELOW_NORMAL:
|
||||||
|
pri = 0.4;
|
||||||
|
break;
|
||||||
|
case THREAD_PRIORITY_TIME_CRITICAL:
|
||||||
|
pri = 1.0;
|
||||||
|
break;
|
||||||
|
case THREAD_PRIORITY_HIGHEST:
|
||||||
|
pri = 0.8;
|
||||||
|
break;
|
||||||
|
case THREAD_PRIORITY_ABOVE_NORMAL:
|
||||||
|
pri = 0.6;
|
||||||
|
break;
|
||||||
|
case THREAD_PRIORITY_NORMAL:
|
||||||
|
pri = 0.5;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
NSLog(@"Unknown thread priority: %d", winPri);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#elif defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING > 0)
|
||||||
|
int res;
|
||||||
int policy;
|
int policy;
|
||||||
struct sched_param param;
|
struct sched_param param;
|
||||||
|
|
||||||
pthread_getschedparam(pthread_self(), &policy, ¶m);
|
res = pthread_getschedparam(pthread_self(), &policy, ¶m);
|
||||||
pri = param.sched_priority;
|
if (res == 0) {
|
||||||
// Scale pri based on the range of the host system.
|
pri = param.sched_priority;
|
||||||
pri -= PTHREAD_MIN_PRIORITY;
|
// Scale pri based on the range of the host system.
|
||||||
pri /= (PTHREAD_MAX_PRIORITY - PTHREAD_MIN_PRIORITY);
|
pri -= PTHREAD_MIN_PRIORITY;
|
||||||
|
pri /= (PTHREAD_MAX_PRIORITY - PTHREAD_MIN_PRIORITY);
|
||||||
|
} else {
|
||||||
|
NSLog(@"Failed to get thread priority: %d", res);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
#warning Your pthread implementation does not support thread priorities
|
#warning Your pthread implementation does not support thread priorities
|
||||||
#endif
|
#endif
|
||||||
return pri;
|
|
||||||
|
|
||||||
|
return pri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1132,9 +1219,9 @@ unregisterActiveThread(NSThread *thread)
|
||||||
DESTROY(_gcontext);
|
DESTROY(_gcontext);
|
||||||
if (_activeThreads)
|
if (_activeThreads)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&_activeLock);
|
GS_MUTEX_LOCK(_activeLock);
|
||||||
NSHashRemove(_activeThreads, self);
|
NSHashRemove(_activeThreads, self);
|
||||||
pthread_mutex_unlock(&_activeLock);
|
GS_MUTEX_UNLOCK(_activeLock);
|
||||||
}
|
}
|
||||||
if (GS_EXISTS_INTERNAL)
|
if (GS_EXISTS_INTERNAL)
|
||||||
{
|
{
|
||||||
|
@ -1311,7 +1398,12 @@ unregisterActiveThread(NSThread *thread)
|
||||||
/**
|
/**
|
||||||
* Trampoline function called to launch the thread
|
* Trampoline function called to launch the thread
|
||||||
*/
|
*/
|
||||||
static void *
|
static
|
||||||
|
#if GS_USE_WIN32_THREADS_AND_LOCKS
|
||||||
|
void __cdecl
|
||||||
|
#else
|
||||||
|
void *
|
||||||
|
#endif
|
||||||
nsthreadLauncher(void *thread)
|
nsthreadLauncher(void *thread)
|
||||||
{
|
{
|
||||||
NSThread *t = (NSThread*)thread;
|
NSThread *t = (NSThread*)thread;
|
||||||
|
@ -1335,12 +1427,16 @@ nsthreadLauncher(void *thread)
|
||||||
|
|
||||||
[NSThread exit];
|
[NSThread exit];
|
||||||
// Not reached
|
// Not reached
|
||||||
|
#if !GS_USE_WIN32_THREADS_AND_LOCKS
|
||||||
return NULL;
|
return NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) start
|
- (void) start
|
||||||
{
|
{
|
||||||
|
#if !GS_USE_WIN32_THREADS_AND_LOCKS
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (_active == YES)
|
if (_active == YES)
|
||||||
{
|
{
|
||||||
|
@ -1377,6 +1473,16 @@ nsthreadLauncher(void *thread)
|
||||||
_active = YES;
|
_active = YES;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
|
#if GS_USE_WIN32_THREADS_AND_LOCKS
|
||||||
|
if (_beginthread(nsthreadLauncher, _stackSize, self) == -1)
|
||||||
|
{
|
||||||
|
DESTROY(self);
|
||||||
|
[NSException raise: NSInternalInconsistencyException
|
||||||
|
format: @"Unable to detach thread (last error %d)",
|
||||||
|
errno];
|
||||||
|
}
|
||||||
|
#else
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
/* Create this thread detached, because we never use the return state from
|
/* Create this thread detached, because we never use the return state from
|
||||||
* threads.
|
* threads.
|
||||||
|
@ -1396,6 +1502,7 @@ nsthreadLauncher(void *thread)
|
||||||
format: @"Unable to detach thread (last error %@)",
|
format: @"Unable to detach thread (last error %@)",
|
||||||
[NSError _last]];
|
[NSError _last]];
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1563,7 +1670,7 @@ lockInfoErr(NSString *str)
|
||||||
* This also ensures that no more than one thread can be checking for
|
* This also ensures that no more than one thread can be checking for
|
||||||
* deadlocks at a time (no interference between checks).
|
* deadlocks at a time (no interference between checks).
|
||||||
*/
|
*/
|
||||||
pthread_mutex_lock(&_activeLock);
|
GS_MUTEX_LOCK(_activeLock);
|
||||||
|
|
||||||
/* As we isolate dependencies (a thread holding the lock another thread
|
/* As we isolate dependencies (a thread holding the lock another thread
|
||||||
* is waiting for) we disable locking in each thread and record the
|
* is waiting for) we disable locking in each thread and record the
|
||||||
|
@ -1695,7 +1802,7 @@ lockInfoErr(NSString *str)
|
||||||
|
|
||||||
/* Finished check ... re-enable thread activity changes.
|
/* Finished check ... re-enable thread activity changes.
|
||||||
*/
|
*/
|
||||||
pthread_mutex_unlock(&_activeLock);
|
GS_MUTEX_UNLOCK(_activeLock);
|
||||||
|
|
||||||
|
|
||||||
if (nil != dependencies)
|
if (nil != dependencies)
|
||||||
|
|
|
@ -289,7 +289,7 @@ static NSMutableDictionary *abbreviationDictionary = nil;
|
||||||
static NSMutableDictionary *abbreviationMap = nil;
|
static NSMutableDictionary *abbreviationMap = nil;
|
||||||
|
|
||||||
/* Lock for creating time zones. */
|
/* Lock for creating time zones. */
|
||||||
static pthread_mutex_t zone_mutex;
|
static gs_mutex_t zone_mutex;
|
||||||
|
|
||||||
static Class NSTimeZoneClass;
|
static Class NSTimeZoneClass;
|
||||||
static Class GSPlaceholderTimeZoneClass;
|
static Class GSPlaceholderTimeZoneClass;
|
||||||
|
@ -387,14 +387,14 @@ static NSString *_time_zone_path(NSString *subpath, NSString *type)
|
||||||
* Return a cached time zone if possible.
|
* Return a cached time zone if possible.
|
||||||
* NB. if data of cached zone does not match new data ... don't use cache
|
* NB. if data of cached zone does not match new data ... don't use cache
|
||||||
*/
|
*/
|
||||||
pthread_mutex_lock(&zone_mutex);
|
GS_MUTEX_LOCK(zone_mutex);
|
||||||
zone = [zoneDictionary objectForKey: name];
|
zone = [zoneDictionary objectForKey: name];
|
||||||
if (data != nil && [data isEqual: [zone data]] == NO)
|
if (data != nil && [data isEqual: [zone data]] == NO)
|
||||||
{
|
{
|
||||||
zone = nil;
|
zone = nil;
|
||||||
}
|
}
|
||||||
IF_NO_GC(RETAIN(zone));
|
IF_NO_GC(RETAIN(zone));
|
||||||
pthread_mutex_unlock(&zone_mutex);
|
GS_MUTEX_UNLOCK(zone_mutex);
|
||||||
|
|
||||||
if (zone == nil)
|
if (zone == nil)
|
||||||
{
|
{
|
||||||
|
@ -657,9 +657,9 @@ static NSMapTable *absolutes = 0;
|
||||||
{
|
{
|
||||||
if (offset != uninitialisedOffset)
|
if (offset != uninitialisedOffset)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&zone_mutex);
|
GS_MUTEX_LOCK(zone_mutex);
|
||||||
NSMapRemove(absolutes, (void*)(uintptr_t)offset);
|
NSMapRemove(absolutes, (void*)(uintptr_t)offset);
|
||||||
pthread_mutex_unlock(&zone_mutex);
|
GS_MUTEX_UNLOCK(zone_mutex);
|
||||||
}
|
}
|
||||||
RELEASE(name);
|
RELEASE(name);
|
||||||
RELEASE(detail);
|
RELEASE(detail);
|
||||||
|
@ -715,7 +715,7 @@ static NSMapTable *absolutes = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&zone_mutex);
|
GS_MUTEX_LOCK(zone_mutex);
|
||||||
z = (GSAbsTimeZone*)NSMapGet(absolutes, (void*)(uintptr_t)anOffset);
|
z = (GSAbsTimeZone*)NSMapGet(absolutes, (void*)(uintptr_t)anOffset);
|
||||||
if (z != nil)
|
if (z != nil)
|
||||||
{
|
{
|
||||||
|
@ -766,7 +766,7 @@ static NSMapTable *absolutes = 0;
|
||||||
commonAbsolutes[index] = RETAIN(self);
|
commonAbsolutes[index] = RETAIN(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&zone_mutex);
|
GS_MUTEX_UNLOCK(zone_mutex);
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -986,7 +986,7 @@ static NSMapTable *absolutes = 0;
|
||||||
{
|
{
|
||||||
return abbreviationDictionary;
|
return abbreviationDictionary;
|
||||||
}
|
}
|
||||||
pthread_mutex_lock(&zone_mutex);
|
GS_MUTEX_LOCK(zone_mutex);
|
||||||
if (abbreviationDictionary == nil)
|
if (abbreviationDictionary == nil)
|
||||||
{
|
{
|
||||||
NSAutoreleasePool *pool = [NSAutoreleasePool new];
|
NSAutoreleasePool *pool = [NSAutoreleasePool new];
|
||||||
|
@ -1043,7 +1043,7 @@ static NSMapTable *absolutes = 0;
|
||||||
}
|
}
|
||||||
[pool drain];
|
[pool drain];
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&zone_mutex);
|
GS_MUTEX_UNLOCK(zone_mutex);
|
||||||
return abbreviationDictionary;
|
return abbreviationDictionary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1061,7 +1061,7 @@ static NSMapTable *absolutes = 0;
|
||||||
{
|
{
|
||||||
return abbreviationMap;
|
return abbreviationMap;
|
||||||
}
|
}
|
||||||
pthread_mutex_lock(&zone_mutex);
|
GS_MUTEX_LOCK(zone_mutex);
|
||||||
if (abbreviationMap == nil)
|
if (abbreviationMap == nil)
|
||||||
{
|
{
|
||||||
NSAutoreleasePool *pool = [NSAutoreleasePool new];
|
NSAutoreleasePool *pool = [NSAutoreleasePool new];
|
||||||
|
@ -1095,7 +1095,7 @@ static NSMapTable *absolutes = 0;
|
||||||
#endif
|
#endif
|
||||||
if (file == NULL)
|
if (file == NULL)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(&zone_mutex);
|
GS_MUTEX_UNLOCK(zone_mutex);
|
||||||
[NSException
|
[NSException
|
||||||
raise: NSInternalInconsistencyException
|
raise: NSInternalInconsistencyException
|
||||||
format: @"Failed to open time zone abbreviation map."];
|
format: @"Failed to open time zone abbreviation map."];
|
||||||
|
@ -1186,7 +1186,7 @@ static NSMapTable *absolutes = 0;
|
||||||
}
|
}
|
||||||
[pool drain];
|
[pool drain];
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&zone_mutex);
|
GS_MUTEX_UNLOCK(zone_mutex);
|
||||||
|
|
||||||
return abbreviationMap;
|
return abbreviationMap;
|
||||||
}
|
}
|
||||||
|
@ -1204,7 +1204,7 @@ static NSMapTable *absolutes = 0;
|
||||||
return namesArray;
|
return namesArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&zone_mutex);
|
GS_MUTEX_LOCK(zone_mutex);
|
||||||
if (namesArray == nil)
|
if (namesArray == nil)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
@ -1230,7 +1230,7 @@ static NSMapTable *absolutes = 0;
|
||||||
RELEASE(ma);
|
RELEASE(ma);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&zone_mutex);
|
GS_MUTEX_UNLOCK(zone_mutex);
|
||||||
return namesArray;
|
return namesArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1260,7 +1260,7 @@ static NSMapTable *absolutes = 0;
|
||||||
* locate the correct placeholder in the (lock protected)
|
* locate the correct placeholder in the (lock protected)
|
||||||
* table of placeholders.
|
* table of placeholders.
|
||||||
*/
|
*/
|
||||||
pthread_mutex_lock(&zone_mutex);
|
GS_MUTEX_LOCK(zone_mutex);
|
||||||
obj = (id)NSMapGet(placeholderMap, (void*)z);
|
obj = (id)NSMapGet(placeholderMap, (void*)z);
|
||||||
if (obj == nil)
|
if (obj == nil)
|
||||||
{
|
{
|
||||||
|
@ -1271,7 +1271,7 @@ static NSMapTable *absolutes = 0;
|
||||||
obj = (id)NSAllocateObject(GSPlaceholderTimeZoneClass, 0, z);
|
obj = (id)NSAllocateObject(GSPlaceholderTimeZoneClass, 0, z);
|
||||||
NSMapInsert(placeholderMap, (void*)z, (void*)obj);
|
NSMapInsert(placeholderMap, (void*)z, (void*)obj);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&zone_mutex);
|
GS_MUTEX_UNLOCK(zone_mutex);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1288,7 +1288,7 @@ static NSMapTable *absolutes = 0;
|
||||||
{
|
{
|
||||||
NSTimeZone *zone;
|
NSTimeZone *zone;
|
||||||
|
|
||||||
pthread_mutex_lock(&zone_mutex);
|
GS_MUTEX_LOCK(zone_mutex);
|
||||||
if (defaultTimeZone == nil)
|
if (defaultTimeZone == nil)
|
||||||
{
|
{
|
||||||
zone = [self systemTimeZone];
|
zone = [self systemTimeZone];
|
||||||
|
@ -1297,7 +1297,7 @@ static NSMapTable *absolutes = 0;
|
||||||
{
|
{
|
||||||
zone = AUTORELEASE(RETAIN(defaultTimeZone));
|
zone = AUTORELEASE(RETAIN(defaultTimeZone));
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&zone_mutex);
|
GS_MUTEX_UNLOCK(zone_mutex);
|
||||||
return zone;
|
return zone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1306,7 +1306,7 @@ static NSMapTable *absolutes = 0;
|
||||||
if (self == [NSTimeZone class])
|
if (self == [NSTimeZone class])
|
||||||
{
|
{
|
||||||
NSTimeZoneClass = self;
|
NSTimeZoneClass = self;
|
||||||
GS_INIT_RECURSIVE_MUTEX(zone_mutex);
|
GS_MUTEX_INIT_RECURSIVE(zone_mutex);
|
||||||
GSPlaceholderTimeZoneClass = [GSPlaceholderTimeZone class];
|
GSPlaceholderTimeZoneClass = [GSPlaceholderTimeZone class];
|
||||||
zoneDictionary = [[NSMutableDictionary alloc] init];
|
zoneDictionary = [[NSMutableDictionary alloc] init];
|
||||||
[[NSObject leakAt: &zoneDictionary] release];
|
[[NSObject leakAt: &zoneDictionary] release];
|
||||||
|
@ -1351,9 +1351,9 @@ static NSMapTable *absolutes = 0;
|
||||||
*/
|
*/
|
||||||
+ (void) resetSystemTimeZone
|
+ (void) resetSystemTimeZone
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&zone_mutex);
|
GS_MUTEX_LOCK(zone_mutex);
|
||||||
DESTROY(systemTimeZone);
|
DESTROY(systemTimeZone);
|
||||||
pthread_mutex_unlock(&zone_mutex);
|
GS_MUTEX_UNLOCK(zone_mutex);
|
||||||
[[NSNotificationCenter defaultCenter]
|
[[NSNotificationCenter defaultCenter]
|
||||||
postNotificationName: NSSystemTimeZoneDidChangeNotification
|
postNotificationName: NSSystemTimeZoneDidChangeNotification
|
||||||
object: nil];
|
object: nil];
|
||||||
|
@ -1374,9 +1374,9 @@ static NSMapTable *absolutes = 0;
|
||||||
{
|
{
|
||||||
aTimeZone = [self systemTimeZone];
|
aTimeZone = [self systemTimeZone];
|
||||||
}
|
}
|
||||||
pthread_mutex_lock(&zone_mutex);
|
GS_MUTEX_LOCK(zone_mutex);
|
||||||
ASSIGN(defaultTimeZone, aTimeZone);
|
ASSIGN(defaultTimeZone, aTimeZone);
|
||||||
pthread_mutex_unlock(&zone_mutex);
|
GS_MUTEX_UNLOCK(zone_mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1387,7 +1387,7 @@ static NSMapTable *absolutes = 0;
|
||||||
{
|
{
|
||||||
NSTimeZone *zone = nil;
|
NSTimeZone *zone = nil;
|
||||||
|
|
||||||
pthread_mutex_lock(&zone_mutex);
|
GS_MUTEX_LOCK(zone_mutex);
|
||||||
if (systemTimeZone == nil)
|
if (systemTimeZone == nil)
|
||||||
{
|
{
|
||||||
NSFileManager *dflt = [NSFileManager defaultManager];
|
NSFileManager *dflt = [NSFileManager defaultManager];
|
||||||
|
@ -1727,7 +1727,7 @@ localZoneString, [zone name], sign, s/3600, (s/60)%60);
|
||||||
ASSIGN(systemTimeZone, zone);
|
ASSIGN(systemTimeZone, zone);
|
||||||
}
|
}
|
||||||
zone = AUTORELEASE(RETAIN(systemTimeZone));
|
zone = AUTORELEASE(RETAIN(systemTimeZone));
|
||||||
pthread_mutex_unlock(&zone_mutex);
|
GS_MUTEX_UNLOCK(zone_mutex);
|
||||||
return zone;
|
return zone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1746,7 +1746,7 @@ localZoneString, [zone name], sign, s/3600, (s/60)%60);
|
||||||
{
|
{
|
||||||
return regionsArray;
|
return regionsArray;
|
||||||
}
|
}
|
||||||
pthread_mutex_lock(&zone_mutex);
|
GS_MUTEX_LOCK(zone_mutex);
|
||||||
if (regionsArray == nil)
|
if (regionsArray == nil)
|
||||||
{
|
{
|
||||||
NSAutoreleasePool *pool = [NSAutoreleasePool new];
|
NSAutoreleasePool *pool = [NSAutoreleasePool new];
|
||||||
|
@ -1778,7 +1778,7 @@ localZoneString, [zone name], sign, s/3600, (s/60)%60);
|
||||||
#endif
|
#endif
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(&zone_mutex);
|
GS_MUTEX_UNLOCK(zone_mutex);
|
||||||
[NSException
|
[NSException
|
||||||
raise: NSInternalInconsistencyException
|
raise: NSInternalInconsistencyException
|
||||||
format: @"Failed to open time zone regions array file."];
|
format: @"Failed to open time zone regions array file."];
|
||||||
|
@ -1878,7 +1878,7 @@ localZoneString, [zone name], sign, s/3600, (s/60)%60);
|
||||||
regionsArray = [[NSArray alloc] initWithObjects: temp_array count: 24];
|
regionsArray = [[NSArray alloc] initWithObjects: temp_array count: 24];
|
||||||
[pool drain];
|
[pool drain];
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&zone_mutex);
|
GS_MUTEX_UNLOCK(zone_mutex);
|
||||||
return regionsArray;
|
return regionsArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1921,9 +1921,9 @@ localZoneString, [zone name], sign, s/3600, (s/60)%60);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&zone_mutex);
|
GS_MUTEX_LOCK(zone_mutex);
|
||||||
zone = (NSTimeZone*)NSMapGet(absolutes, (void*)(uintptr_t)seconds);
|
zone = (NSTimeZone*)NSMapGet(absolutes, (void*)(uintptr_t)seconds);
|
||||||
pthread_mutex_unlock(&zone_mutex);
|
GS_MUTEX_UNLOCK(zone_mutex);
|
||||||
}
|
}
|
||||||
if (nil == zone)
|
if (nil == zone)
|
||||||
{
|
{
|
||||||
|
@ -2403,7 +2403,7 @@ static NSString *zoneDirs[] = {
|
||||||
|
|
||||||
if (beenHere == NO && tzdir == nil)
|
if (beenHere == NO && tzdir == nil)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&zone_mutex);
|
GS_MUTEX_LOCK(zone_mutex);
|
||||||
if (beenHere == NO && tzdir == nil)
|
if (beenHere == NO && tzdir == nil)
|
||||||
{
|
{
|
||||||
NSFileManager *mgr = [NSFileManager defaultManager];
|
NSFileManager *mgr = [NSFileManager defaultManager];
|
||||||
|
@ -2424,7 +2424,7 @@ static NSString *zoneDirs[] = {
|
||||||
}
|
}
|
||||||
beenHere = YES;
|
beenHere = YES;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&zone_mutex);
|
GS_MUTEX_UNLOCK(zone_mutex);
|
||||||
}
|
}
|
||||||
/* Use the system zone info if possible, otherwise, use our installed
|
/* Use the system zone info if possible, otherwise, use our installed
|
||||||
info. */
|
info. */
|
||||||
|
@ -3198,9 +3198,9 @@ newDetailInZoneForType(GSTimeZone *zone, TypeInfo *type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&zone_mutex);
|
GS_MUTEX_LOCK(zone_mutex);
|
||||||
[zoneDictionary setObject: self forKey: timeZoneName];
|
[zoneDictionary setObject: self forKey: timeZoneName];
|
||||||
pthread_mutex_unlock(&zone_mutex);
|
GS_MUTEX_UNLOCK(zone_mutex);
|
||||||
}
|
}
|
||||||
NS_HANDLER
|
NS_HANDLER
|
||||||
{
|
{
|
||||||
|
|
112
Source/NSZone.m
112
Source/NSZone.m
|
@ -93,7 +93,7 @@
|
||||||
#import "GSPrivate.h"
|
#import "GSPrivate.h"
|
||||||
#import "GSPThread.h"
|
#import "GSPThread.h"
|
||||||
|
|
||||||
static pthread_mutex_t zoneLock = PTHREAD_MUTEX_INITIALIZER;
|
static gs_mutex_t zoneLock = GS_MUTEX_INIT_STATIC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to get more memory - the normal process has failed.
|
* Try to get more memory - the normal process has failed.
|
||||||
|
@ -205,12 +205,12 @@ NSSetZoneName (NSZone *zone, NSString *name)
|
||||||
{
|
{
|
||||||
if (!zone)
|
if (!zone)
|
||||||
zone = NSDefaultMallocZone();
|
zone = NSDefaultMallocZone();
|
||||||
pthread_mutex_lock(&zoneLock);
|
GS_MUTEX_LOCK(zoneLock);
|
||||||
name = [name copy];
|
name = [name copy];
|
||||||
if (zone->name != nil)
|
if (zone->name != nil)
|
||||||
[zone->name release];
|
[zone->name release];
|
||||||
zone->name = name;
|
zone->name = name;
|
||||||
pthread_mutex_unlock(&zoneLock);
|
GS_MUTEX_UNLOCK(zoneLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
GS_DECLARE NSString*
|
GS_DECLARE NSString*
|
||||||
|
@ -303,7 +303,7 @@ struct _ffree_free_link
|
||||||
struct _ffree_zone_struct
|
struct _ffree_zone_struct
|
||||||
{
|
{
|
||||||
NSZone common;
|
NSZone common;
|
||||||
pthread_mutex_t lock;
|
gs_mutex_t lock;
|
||||||
ff_block *blocks; // Linked list of blocks
|
ff_block *blocks; // Linked list of blocks
|
||||||
ff_link *segheadlist[MAX_SEG]; // Segregated list, holds heads
|
ff_link *segheadlist[MAX_SEG]; // Segregated list, holds heads
|
||||||
ff_link *segtaillist[MAX_SEG]; // Segregated list, holds tails
|
ff_link *segtaillist[MAX_SEG]; // Segregated list, holds tails
|
||||||
|
@ -452,7 +452,7 @@ chunkPrev(ff_block *ptr)
|
||||||
struct _nfree_zone_struct
|
struct _nfree_zone_struct
|
||||||
{
|
{
|
||||||
NSZone common;
|
NSZone common;
|
||||||
pthread_mutex_t lock;
|
gs_mutex_t lock;
|
||||||
/* Linked list of blocks in decreasing order of free space,
|
/* Linked list of blocks in decreasing order of free space,
|
||||||
except maybe for the first block. */
|
except maybe for the first block. */
|
||||||
nf_block *blocks;
|
nf_block *blocks;
|
||||||
|
@ -542,7 +542,7 @@ fmalloc (NSZone *zone, size_t size)
|
||||||
ff_block *chunkhead;
|
ff_block *chunkhead;
|
||||||
void *result;
|
void *result;
|
||||||
|
|
||||||
pthread_mutex_lock(&(zptr->lock));
|
GS_MUTEX_LOCK(zptr->lock);
|
||||||
bufsize = zptr->bufsize;
|
bufsize = zptr->bufsize;
|
||||||
while ((i < bufsize) && (chunksize > size_buf[i]))
|
while ((i < bufsize) && (chunksize > size_buf[i]))
|
||||||
i++;
|
i++;
|
||||||
|
@ -581,7 +581,7 @@ fmalloc (NSZone *zone, size_t size)
|
||||||
chunkhead = get_chunk(zptr, chunksize);
|
chunkhead = get_chunk(zptr, chunksize);
|
||||||
if (chunkhead == NULL)
|
if (chunkhead == NULL)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(&(zptr->lock));
|
GS_MUTEX_UNLOCK(zptr->lock);
|
||||||
if (zone->name != nil)
|
if (zone->name != nil)
|
||||||
[NSException raise: NSMallocException
|
[NSException raise: NSMallocException
|
||||||
format: @"Zone %@ has run out of memory", zone->name];
|
format: @"Zone %@ has run out of memory", zone->name];
|
||||||
|
@ -600,7 +600,7 @@ fmalloc (NSZone *zone, size_t size)
|
||||||
*((char*)chunkhead->next) = (char)42;
|
*((char*)chunkhead->next) = (char)42;
|
||||||
chunkSetLive(chunkhead);
|
chunkSetLive(chunkhead);
|
||||||
result = chunkToPointer(chunkhead);
|
result = chunkToPointer(chunkhead);
|
||||||
pthread_mutex_unlock(&(zptr->lock));
|
GS_MUTEX_UNLOCK(zptr->lock);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -624,7 +624,7 @@ frealloc (NSZone *zone, void *ptr, size_t size)
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
return fmalloc(zone, size);
|
return fmalloc(zone, size);
|
||||||
chunkhead = pointerToChunk(ptr);
|
chunkhead = pointerToChunk(ptr);
|
||||||
pthread_mutex_lock(&(zptr->lock));
|
GS_MUTEX_LOCK(zptr->lock);
|
||||||
realsize = chunkSize(chunkhead);
|
realsize = chunkSize(chunkhead);
|
||||||
|
|
||||||
NSAssert(chunkIsInUse(chunkhead), NSInternalInconsistencyException);
|
NSAssert(chunkIsInUse(chunkhead), NSInternalInconsistencyException);
|
||||||
|
@ -680,7 +680,7 @@ frealloc (NSZone *zone, void *ptr, size_t size)
|
||||||
newchunk = get_chunk(zptr, chunksize);
|
newchunk = get_chunk(zptr, chunksize);
|
||||||
if (newchunk == NULL)
|
if (newchunk == NULL)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(&(zptr->lock));
|
GS_MUTEX_UNLOCK(zptr->lock);
|
||||||
if (zone->name != nil)
|
if (zone->name != nil)
|
||||||
[NSException raise: NSMallocException
|
[NSException raise: NSMallocException
|
||||||
format: @"Zone %@ has run out of memory",
|
format: @"Zone %@ has run out of memory",
|
||||||
|
@ -698,7 +698,7 @@ frealloc (NSZone *zone, void *ptr, size_t size)
|
||||||
*((char*)chunkhead->next) = (char)42;
|
*((char*)chunkhead->next) = (char)42;
|
||||||
chunkSetLive(chunkhead);
|
chunkSetLive(chunkhead);
|
||||||
result = chunkToPointer(chunkhead);
|
result = chunkToPointer(chunkhead);
|
||||||
pthread_mutex_unlock(&(zptr->lock));
|
GS_MUTEX_UNLOCK(zptr->lock);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -708,14 +708,14 @@ ffree (NSZone *zone, void *ptr)
|
||||||
{
|
{
|
||||||
ff_block *chunk;
|
ff_block *chunk;
|
||||||
NSAssert(NSZoneFromPointer(ptr) == zone, NSInternalInconsistencyException);
|
NSAssert(NSZoneFromPointer(ptr) == zone, NSInternalInconsistencyException);
|
||||||
pthread_mutex_lock(&(((ffree_zone*)zone)->lock));
|
GS_MUTEX_LOCK(((ffree_zone*)zone)->lock);
|
||||||
chunk = pointerToChunk(ptr);
|
chunk = pointerToChunk(ptr);
|
||||||
if (chunkIsLive(chunk) == 0)
|
if (chunkIsLive(chunk) == 0)
|
||||||
[NSException raise: NSMallocException
|
[NSException raise: NSMallocException
|
||||||
format: @"Attempt to free freed memory"];
|
format: @"Attempt to free freed memory"];
|
||||||
NSAssert(*((char*)chunk->next) == (char)42, NSInternalInconsistencyException);
|
NSAssert(*((char*)chunk->next) == (char)42, NSInternalInconsistencyException);
|
||||||
add_buf((ffree_zone*)zone, chunk);
|
add_buf((ffree_zone*)zone, chunk);
|
||||||
pthread_mutex_unlock(&(((ffree_zone*)zone)->lock));
|
GS_MUTEX_UNLOCK(((ffree_zone*)zone)->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL
|
static BOOL
|
||||||
|
@ -725,7 +725,7 @@ frecycle1(NSZone *zone)
|
||||||
ff_block *block;
|
ff_block *block;
|
||||||
ff_block *nextblock;
|
ff_block *nextblock;
|
||||||
|
|
||||||
pthread_mutex_lock(&(zptr->lock));
|
GS_MUTEX_LOCK(zptr->lock);
|
||||||
flush_buf(zptr);
|
flush_buf(zptr);
|
||||||
block = zptr->blocks;
|
block = zptr->blocks;
|
||||||
while (block != NULL)
|
while (block != NULL)
|
||||||
|
@ -747,10 +747,10 @@ frecycle1(NSZone *zone)
|
||||||
}
|
}
|
||||||
block = nextblock;
|
block = nextblock;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&(zptr->lock));
|
GS_MUTEX_UNLOCK(zptr->lock);
|
||||||
if (zptr->blocks == 0)
|
if (zptr->blocks == 0)
|
||||||
{
|
{
|
||||||
pthread_mutex_destroy(&(zptr->lock));
|
GS_MUTEX_DESTROY(zptr->lock);
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
return NO;
|
return NO;
|
||||||
|
@ -760,7 +760,7 @@ frecycle1(NSZone *zone)
|
||||||
static void
|
static void
|
||||||
frecycle (NSZone *zone)
|
frecycle (NSZone *zone)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&zoneLock);
|
GS_MUTEX_LOCK(zoneLock);
|
||||||
if (zone->name != nil)
|
if (zone->name != nil)
|
||||||
{
|
{
|
||||||
NSString *name = zone->name;
|
NSString *name = zone->name;
|
||||||
|
@ -776,17 +776,17 @@ frecycle (NSZone *zone)
|
||||||
zone->free = rffree;
|
zone->free = rffree;
|
||||||
zone->recycle = rrecycle;
|
zone->recycle = rrecycle;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&zoneLock);
|
GS_MUTEX_UNLOCK(zoneLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rffree (NSZone *zone, void *ptr)
|
rffree (NSZone *zone, void *ptr)
|
||||||
{
|
{
|
||||||
ffree(zone, ptr);
|
ffree(zone, ptr);
|
||||||
pthread_mutex_lock(&zoneLock);
|
GS_MUTEX_LOCK(zoneLock);
|
||||||
if (frecycle1(zone))
|
if (frecycle1(zone))
|
||||||
destroy_zone(zone);
|
destroy_zone(zone);
|
||||||
pthread_mutex_unlock(&zoneLock);
|
GS_MUTEX_UNLOCK(zoneLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -799,7 +799,7 @@ fcheck (NSZone *zone)
|
||||||
ffree_zone *zptr = (ffree_zone*)zone;
|
ffree_zone *zptr = (ffree_zone*)zone;
|
||||||
ff_block *block;
|
ff_block *block;
|
||||||
|
|
||||||
pthread_mutex_lock(&(zptr->lock));
|
GS_MUTEX_LOCK(zptr->lock);
|
||||||
/* Check integrity of each block the zone owns. */
|
/* Check integrity of each block the zone owns. */
|
||||||
block = zptr->blocks;
|
block = zptr->blocks;
|
||||||
while (block != NULL)
|
while (block != NULL)
|
||||||
|
@ -892,11 +892,11 @@ fcheck (NSZone *zone)
|
||||||
if ((zptr->size_buf[i] != chunkSize(chunk)) || !chunkIsInUse(chunk))
|
if ((zptr->size_buf[i] != chunkSize(chunk)) || !chunkIsInUse(chunk))
|
||||||
goto inconsistent;
|
goto inconsistent;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&(zptr->lock));
|
GS_MUTEX_UNLOCK(zptr->lock);
|
||||||
return YES;
|
return YES;
|
||||||
|
|
||||||
inconsistent: // Jump here if an inconsistency was found.
|
inconsistent: // Jump here if an inconsistency was found.
|
||||||
pthread_mutex_unlock(&(zptr->lock));
|
GS_MUTEX_UNLOCK(zptr->lock);
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -907,7 +907,7 @@ flookup (NSZone *zone, void *ptr)
|
||||||
ff_block *block;
|
ff_block *block;
|
||||||
BOOL found = NO;
|
BOOL found = NO;
|
||||||
|
|
||||||
pthread_mutex_lock(&(zptr->lock));
|
GS_MUTEX_LOCK(zptr->lock);
|
||||||
for (block = zptr->blocks; block != NULL; block = block->next)
|
for (block = zptr->blocks; block != NULL; block = block->next)
|
||||||
{
|
{
|
||||||
if (ptr >= (void*)block && ptr < (void*)chunkNext(block))
|
if (ptr >= (void*)block && ptr < (void*)chunkNext(block))
|
||||||
|
@ -916,7 +916,7 @@ flookup (NSZone *zone, void *ptr)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&(zptr->lock));
|
GS_MUTEX_UNLOCK(zptr->lock);
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -935,7 +935,7 @@ fstats (NSZone *zone)
|
||||||
stats.bytes_used = 0;
|
stats.bytes_used = 0;
|
||||||
stats.chunks_free = 0;
|
stats.chunks_free = 0;
|
||||||
stats.bytes_free = 0;
|
stats.bytes_free = 0;
|
||||||
pthread_mutex_lock(&(zptr->lock));
|
GS_MUTEX_LOCK(zptr->lock);
|
||||||
block = zptr->blocks;
|
block = zptr->blocks;
|
||||||
/* Go through each block. */
|
/* Go through each block. */
|
||||||
while (block != NULL)
|
while (block != NULL)
|
||||||
|
@ -970,7 +970,7 @@ fstats (NSZone *zone)
|
||||||
stats.bytes_used -= zptr->size_buf[i];
|
stats.bytes_used -= zptr->size_buf[i];
|
||||||
stats.bytes_free += zptr->size_buf[i];
|
stats.bytes_free += zptr->size_buf[i];
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&(zptr->lock));
|
GS_MUTEX_UNLOCK(zptr->lock);
|
||||||
/* Remove overhead. */
|
/* Remove overhead. */
|
||||||
stats.bytes_used -= FBSZ*stats.chunks_used;
|
stats.bytes_used -= FBSZ*stats.chunks_used;
|
||||||
return stats;
|
return stats;
|
||||||
|
@ -1291,7 +1291,7 @@ nmalloc (NSZone *zone, size_t size)
|
||||||
nf_block *block;
|
nf_block *block;
|
||||||
size_t top;
|
size_t top;
|
||||||
|
|
||||||
pthread_mutex_lock(&(zptr->lock));
|
GS_MUTEX_LOCK(zptr->lock);
|
||||||
block = zptr->blocks;
|
block = zptr->blocks;
|
||||||
top = block->top;
|
top = block->top;
|
||||||
freesize = block->size-top;
|
freesize = block->size-top;
|
||||||
|
@ -1326,7 +1326,7 @@ nmalloc (NSZone *zone, size_t size)
|
||||||
block = malloc(blocksize);
|
block = malloc(blocksize);
|
||||||
if (block == NULL)
|
if (block == NULL)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(&(zptr->lock));
|
GS_MUTEX_UNLOCK(zptr->lock);
|
||||||
if (zone->name != nil)
|
if (zone->name != nil)
|
||||||
[NSException raise: NSMallocException
|
[NSException raise: NSMallocException
|
||||||
format: @"Zone %@ has run out of memory",
|
format: @"Zone %@ has run out of memory",
|
||||||
|
@ -1344,7 +1344,7 @@ nmalloc (NSZone *zone, size_t size)
|
||||||
block->top += chunksize;
|
block->top += chunksize;
|
||||||
}
|
}
|
||||||
zptr->use++;
|
zptr->use++;
|
||||||
pthread_mutex_unlock(&(zptr->lock));
|
GS_MUTEX_UNLOCK(zptr->lock);
|
||||||
return chunkhead;
|
return chunkhead;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1355,7 +1355,7 @@ nrecycle1 (NSZone *zone)
|
||||||
{
|
{
|
||||||
nfree_zone *zptr = (nfree_zone*)zone;
|
nfree_zone *zptr = (nfree_zone*)zone;
|
||||||
|
|
||||||
pthread_mutex_lock(&(zptr->lock));
|
GS_MUTEX_LOCK(zptr->lock);
|
||||||
if (zptr->use == 0)
|
if (zptr->use == 0)
|
||||||
{
|
{
|
||||||
nf_block *nextblock;
|
nf_block *nextblock;
|
||||||
|
@ -1369,10 +1369,10 @@ nrecycle1 (NSZone *zone)
|
||||||
}
|
}
|
||||||
zptr->blocks = 0;
|
zptr->blocks = 0;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&(zptr->lock));
|
GS_MUTEX_UNLOCK(zptr->lock);
|
||||||
if (zptr->blocks == 0)
|
if (zptr->blocks == 0)
|
||||||
{
|
{
|
||||||
pthread_mutex_destroy(&(zptr->lock));
|
GS_MUTEX_DESTROY(zptr->lock);
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
return NO;
|
return NO;
|
||||||
|
@ -1382,7 +1382,7 @@ nrecycle1 (NSZone *zone)
|
||||||
static void
|
static void
|
||||||
nrecycle (NSZone *zone)
|
nrecycle (NSZone *zone)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&zoneLock);
|
GS_MUTEX_LOCK(zoneLock);
|
||||||
if (zone->name != nil)
|
if (zone->name != nil)
|
||||||
{
|
{
|
||||||
NSString *name = zone->name;
|
NSString *name = zone->name;
|
||||||
|
@ -1398,7 +1398,7 @@ nrecycle (NSZone *zone)
|
||||||
zone->free = rnfree;
|
zone->free = rnfree;
|
||||||
zone->recycle = rrecycle;
|
zone->recycle = rrecycle;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&zoneLock);
|
GS_MUTEX_UNLOCK(zoneLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void*
|
static void*
|
||||||
|
@ -1409,7 +1409,7 @@ nrealloc (NSZone *zone, void *ptr, size_t size)
|
||||||
|
|
||||||
if (ptr != 0)
|
if (ptr != 0)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&(zptr->lock));
|
GS_MUTEX_LOCK(zptr->lock);
|
||||||
if (tmp)
|
if (tmp)
|
||||||
{
|
{
|
||||||
nf_block *block;
|
nf_block *block;
|
||||||
|
@ -1429,7 +1429,7 @@ nrealloc (NSZone *zone, void *ptr, size_t size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
zptr->use--;
|
zptr->use--;
|
||||||
pthread_mutex_unlock(&(zptr->lock));
|
GS_MUTEX_UNLOCK(zptr->lock);
|
||||||
}
|
}
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
@ -1445,9 +1445,9 @@ nfree (NSZone *zone, void *ptr)
|
||||||
{
|
{
|
||||||
nfree_zone *zptr = (nfree_zone*)zone;
|
nfree_zone *zptr = (nfree_zone*)zone;
|
||||||
|
|
||||||
pthread_mutex_lock(&(zptr->lock));
|
GS_MUTEX_LOCK(zptr->lock);
|
||||||
zptr->use--;
|
zptr->use--;
|
||||||
pthread_mutex_unlock(&(zptr->lock));
|
GS_MUTEX_UNLOCK(zptr->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1458,10 +1458,10 @@ rnfree (NSZone *zone, void *ptr)
|
||||||
nfree(zone, ptr);
|
nfree(zone, ptr);
|
||||||
if (zptr->use == 0)
|
if (zptr->use == 0)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&zoneLock);
|
GS_MUTEX_LOCK(zoneLock);
|
||||||
nrecycle1(zone);
|
nrecycle1(zone);
|
||||||
destroy_zone(zone);
|
destroy_zone(zone);
|
||||||
pthread_mutex_unlock(&zoneLock);
|
GS_MUTEX_UNLOCK(zoneLock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1473,19 +1473,19 @@ ncheck (NSZone *zone)
|
||||||
nfree_zone *zptr = (nfree_zone*)zone;
|
nfree_zone *zptr = (nfree_zone*)zone;
|
||||||
nf_block *block;
|
nf_block *block;
|
||||||
|
|
||||||
pthread_mutex_lock(&(zptr->lock));
|
GS_MUTEX_LOCK(zptr->lock);
|
||||||
block = zptr->blocks;
|
block = zptr->blocks;
|
||||||
while (block != NULL)
|
while (block != NULL)
|
||||||
{
|
{
|
||||||
if (block->size < block->top)
|
if (block->size < block->top)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(&(zptr->lock));
|
GS_MUTEX_UNLOCK(zptr->lock);
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
block = block->next;
|
block = block->next;
|
||||||
}
|
}
|
||||||
/* FIXME: Do more checking? */
|
/* FIXME: Do more checking? */
|
||||||
pthread_mutex_unlock(&(zptr->lock));
|
GS_MUTEX_UNLOCK(zptr->lock);
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1496,7 +1496,7 @@ nlookup (NSZone *zone, void *ptr)
|
||||||
nf_block *block;
|
nf_block *block;
|
||||||
BOOL found = NO;
|
BOOL found = NO;
|
||||||
|
|
||||||
pthread_mutex_lock(&(zptr->lock));
|
GS_MUTEX_LOCK(zptr->lock);
|
||||||
for (block = zptr->blocks; block != NULL; block = block->next)
|
for (block = zptr->blocks; block != NULL; block = block->next)
|
||||||
{
|
{
|
||||||
if (ptr >= (void*)block && ptr < ((void*)block)+block->size)
|
if (ptr >= (void*)block && ptr < ((void*)block)+block->size)
|
||||||
|
@ -1505,7 +1505,7 @@ nlookup (NSZone *zone, void *ptr)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&(zptr->lock));
|
GS_MUTEX_UNLOCK(zptr->lock);
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1523,7 +1523,7 @@ nstats (NSZone *zone)
|
||||||
stats.bytes_used = 0;
|
stats.bytes_used = 0;
|
||||||
stats.chunks_free = 0;
|
stats.chunks_free = 0;
|
||||||
stats.bytes_free = 0;
|
stats.bytes_free = 0;
|
||||||
pthread_mutex_lock(&(zptr->lock));
|
GS_MUTEX_LOCK(zptr->lock);
|
||||||
block = zptr->blocks;
|
block = zptr->blocks;
|
||||||
while (block != NULL)
|
while (block != NULL)
|
||||||
{
|
{
|
||||||
|
@ -1544,7 +1544,7 @@ nstats (NSZone *zone)
|
||||||
}
|
}
|
||||||
block = block->next;
|
block = block->next;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&(zptr->lock));
|
GS_MUTEX_UNLOCK(zptr->lock);
|
||||||
return stats;
|
return stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1585,7 +1585,7 @@ NSZoneFromPointer(void *ptr)
|
||||||
/*
|
/*
|
||||||
* See if we can find the zone in our list of all zones.
|
* See if we can find the zone in our list of all zones.
|
||||||
*/
|
*/
|
||||||
pthread_mutex_lock(&zoneLock);
|
GS_MUTEX_LOCK(zoneLock);
|
||||||
for (zone = zone_list; zone != 0; zone = zone->next)
|
for (zone = zone_list; zone != 0; zone = zone->next)
|
||||||
{
|
{
|
||||||
if ((zone->lookup)(zone, ptr) == YES)
|
if ((zone->lookup)(zone, ptr) == YES)
|
||||||
|
@ -1593,7 +1593,7 @@ NSZoneFromPointer(void *ptr)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&zoneLock);
|
GS_MUTEX_UNLOCK(zoneLock);
|
||||||
return (zone == 0) ? &default_zone : zone;
|
return (zone == 0) ? &default_zone : zone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1631,7 +1631,7 @@ NSCreateZone (NSUInteger start, NSUInteger gran, BOOL canFree)
|
||||||
zone->common.stats = fstats;
|
zone->common.stats = fstats;
|
||||||
zone->common.gran = granularity;
|
zone->common.gran = granularity;
|
||||||
zone->common.name = nil;
|
zone->common.name = nil;
|
||||||
GS_INIT_RECURSIVE_MUTEX(zone->lock);
|
GS_MUTEX_INIT_RECURSIVE(zone->lock);
|
||||||
for (i = 0; i < MAX_SEG; i++)
|
for (i = 0; i < MAX_SEG; i++)
|
||||||
{
|
{
|
||||||
zone->segheadlist[i] = NULL;
|
zone->segheadlist[i] = NULL;
|
||||||
|
@ -1641,7 +1641,7 @@ NSCreateZone (NSUInteger start, NSUInteger gran, BOOL canFree)
|
||||||
zone->blocks = malloc(startsize + 2*FBSZ);
|
zone->blocks = malloc(startsize + 2*FBSZ);
|
||||||
if (zone->blocks == NULL)
|
if (zone->blocks == NULL)
|
||||||
{
|
{
|
||||||
pthread_mutex_destroy(&(zone->lock));
|
GS_MUTEX_DESTROY(zone->lock);
|
||||||
free(zone);
|
free(zone);
|
||||||
[NSException raise: NSMallocException
|
[NSException raise: NSMallocException
|
||||||
format: @"No memory to create zone"];
|
format: @"No memory to create zone"];
|
||||||
|
@ -1686,12 +1686,12 @@ NSCreateZone (NSUInteger start, NSUInteger gran, BOOL canFree)
|
||||||
zone->common.stats = nstats;
|
zone->common.stats = nstats;
|
||||||
zone->common.gran = granularity;
|
zone->common.gran = granularity;
|
||||||
zone->common.name = nil;
|
zone->common.name = nil;
|
||||||
GS_INIT_RECURSIVE_MUTEX(zone->lock);
|
GS_MUTEX_INIT_RECURSIVE(zone->lock);
|
||||||
zone->blocks = malloc(startsize);
|
zone->blocks = malloc(startsize);
|
||||||
zone->use = 0;
|
zone->use = 0;
|
||||||
if (zone->blocks == NULL)
|
if (zone->blocks == NULL)
|
||||||
{
|
{
|
||||||
pthread_mutex_destroy(&(zone->lock));
|
GS_MUTEX_DESTROY(zone->lock);
|
||||||
free(zone);
|
free(zone);
|
||||||
[NSException raise: NSMallocException
|
[NSException raise: NSMallocException
|
||||||
format: @"No memory to create zone"];
|
format: @"No memory to create zone"];
|
||||||
|
@ -1704,10 +1704,10 @@ NSCreateZone (NSUInteger start, NSUInteger gran, BOOL canFree)
|
||||||
newZone = (NSZone*)zone;
|
newZone = (NSZone*)zone;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&zoneLock);
|
GS_MUTEX_LOCK(zoneLock);
|
||||||
newZone->next = zone_list;
|
newZone->next = zone_list;
|
||||||
zone_list = newZone;
|
zone_list = newZone;
|
||||||
pthread_mutex_unlock(&zoneLock);
|
GS_MUTEX_UNLOCK(zoneLock);
|
||||||
|
|
||||||
return newZone;
|
return newZone;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1,8 @@
|
||||||
ADDITIONAL_TOOL_LIBS += -lpthread
|
|
||||||
|
ifneq ($(GNUSTEP_TARGET_OS), mingw32)
|
||||||
|
ifneq ($(GNUSTEP_TARGET_OS), mingw64)
|
||||||
|
ifneq ($(GNUSTEP_TARGET_OS), windows)
|
||||||
|
ADDITIONAL_TOOL_LIBS += -lpthread
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
|
@ -2,10 +2,12 @@
|
||||||
#import <Foundation/NSThread.h>
|
#import <Foundation/NSThread.h>
|
||||||
#import <Foundation/NSLock.h>
|
#import <Foundation/NSLock.h>
|
||||||
#import <Foundation/NSNotification.h>
|
#import <Foundation/NSNotification.h>
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#include <process.h>
|
||||||
|
#else
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@interface ThreadExpectation : NSObject <NSLocking>
|
@interface ThreadExpectation : NSObject <NSLocking>
|
||||||
{
|
{
|
||||||
|
@ -98,10 +100,17 @@
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
void *thread(void *expectation)
|
#if defined(_WIN32)
|
||||||
|
void __cdecl
|
||||||
|
#else
|
||||||
|
void *
|
||||||
|
#endif
|
||||||
|
thread(void *expectation)
|
||||||
{
|
{
|
||||||
[(ThreadExpectation*)expectation inThread: [NSThread currentThread]];
|
[(ThreadExpectation*)expectation inThread: [NSThread currentThread]];
|
||||||
return nil;
|
#if !defined(_WIN32)
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -116,13 +125,18 @@ void *thread(void *expectation)
|
||||||
*/
|
*/
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
NSAutoreleasePool *arp = [NSAutoreleasePool new];
|
||||||
|
ThreadExpectation *expectation = [ThreadExpectation new];
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
_beginthread(thread, 0, expectation);
|
||||||
|
#else
|
||||||
pthread_t thr;
|
pthread_t thr;
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||||
NSAutoreleasePool *arp = [NSAutoreleasePool new];
|
|
||||||
ThreadExpectation *expectation = [ThreadExpectation new];
|
|
||||||
pthread_create(&thr, &attr, thread, expectation);
|
pthread_create(&thr, &attr, thread, expectation);
|
||||||
|
#endif
|
||||||
|
|
||||||
NSDate *start = [NSDate date];
|
NSDate *start = [NSDate date];
|
||||||
[expectation lock];
|
[expectation lock];
|
||||||
|
|
|
@ -1,27 +1,54 @@
|
||||||
#import "ObjectTesting.h"
|
#import "ObjectTesting.h"
|
||||||
#import <Foundation/NSThread.h>
|
#import <Foundation/NSThread.h>
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
void *thread(void *ignored)
|
#if defined(_WIN32)
|
||||||
|
#include <process.h>
|
||||||
|
#else
|
||||||
|
#include <pthread.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static NSThread *threadResult = nil;
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
unsigned int __stdcall
|
||||||
|
#else
|
||||||
|
void *
|
||||||
|
#endif
|
||||||
|
thread(void *ignored)
|
||||||
{
|
{
|
||||||
return [NSThread currentThread];
|
threadResult = [NSThread currentThread];
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
NSAutoreleasePool *arp = [NSAutoreleasePool new];
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
HANDLE thr;
|
||||||
|
thr = (HANDLE)_beginthreadex(NULL, 0, thread, NULL, 0, NULL);
|
||||||
|
WaitForSingleObject(thr, INFINITE);
|
||||||
|
CloseHandle(thr);
|
||||||
|
#else
|
||||||
pthread_t thr;
|
pthread_t thr;
|
||||||
void *ret;
|
|
||||||
|
|
||||||
pthread_create(&thr, NULL, thread, NULL);
|
pthread_create(&thr, NULL, thread, NULL);
|
||||||
pthread_join(thr, &ret);
|
pthread_join(thr, NULL);
|
||||||
PASS(ret != 0, "NSThread lazily created from POSIX thread");
|
#endif
|
||||||
|
PASS(threadResult != 0, "NSThread lazily created from native thread");
|
||||||
testHopeful = YES;
|
testHopeful = YES;
|
||||||
PASS((ret != 0) && (ret != [NSThread mainThread]),
|
PASS((threadResult != 0) && (threadResult != [NSThread mainThread]),
|
||||||
"Spawned thread is not main thread");
|
"Spawned thread is not main thread");
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
thr = (HANDLE)_beginthreadex(NULL, 0, thread, NULL, 0, NULL);
|
||||||
|
WaitForSingleObject(thr, INFINITE);
|
||||||
|
CloseHandle(thr);
|
||||||
|
#else
|
||||||
pthread_create(&thr, NULL, thread, NULL);
|
pthread_create(&thr, NULL, thread, NULL);
|
||||||
pthread_join(thr, &ret);
|
pthread_join(thr, NULL);
|
||||||
PASS(ret != 0, "NSThread lazily created from POSIX thread");
|
#endif
|
||||||
PASS((ret != 0) && (ret != [NSThread mainThread]),
|
PASS(threadResult != 0, "NSThread lazily created from native thread");
|
||||||
|
PASS((threadResult != 0) && (threadResult != [NSThread mainThread]),
|
||||||
"Spawned thread is not main thread");
|
"Spawned thread is not main thread");
|
||||||
|
|
||||||
NSThread *t = [NSThread currentThread];
|
NSThread *t = [NSThread currentThread];
|
||||||
|
@ -29,7 +56,14 @@ int main(void)
|
||||||
NSLog(@"Thread description is '%@'", t);
|
NSLog(@"Thread description is '%@'", t);
|
||||||
NSRange r = [[t description] rangeOfString: @"name = xxxtestxxx"];
|
NSRange r = [[t description] rangeOfString: @"name = xxxtestxxx"];
|
||||||
PASS(r.length > 0, "thread description contains name");
|
PASS(r.length > 0, "thread description contains name");
|
||||||
|
|
||||||
|
PASS([NSThread threadPriority] == 0.5, "default thread priority is 0.5");
|
||||||
|
PASS([NSThread setThreadPriority:0.8], "change thread priority to 0.8");
|
||||||
|
PASS([NSThread threadPriority] == 0.8, "thread priority was changed to 0.8");
|
||||||
|
PASS([NSThread setThreadPriority:0.2], "change thread priority to 0.2");
|
||||||
|
PASS([NSThread threadPriority] == 0.2, "thread priority was changed to 0.2");
|
||||||
|
|
||||||
|
DESTROY(arp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,24 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "objc-common.g"
|
#include "objc-common.g"
|
||||||
#include <pthread.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
# define mySleep(X) usleep(1000*(X))
|
|
||||||
|
#include <process.h>
|
||||||
|
typedef unsigned thread_id_t;
|
||||||
|
#define CREATE_THREAD(threadId, start, arg) \
|
||||||
|
_beginthreadex(NULL, 0, start, arg, 0, &threadId) != 0
|
||||||
|
#define mySleep(X) usleep(1000*(X))
|
||||||
|
|
||||||
#else
|
#else
|
||||||
# define mySleep(X) sleep(X)
|
|
||||||
|
#include <pthread.h>
|
||||||
|
typedef pthread_t thread_id_t;
|
||||||
|
#define CREATE_THREAD(threadId, start, arg) \
|
||||||
|
pthread_create(&threadId, 0, start, arg) == 0
|
||||||
|
#define mySleep(X) sleep(X)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if _MSC_VER
|
#if _MSC_VER
|
||||||
|
@ -65,11 +76,11 @@ test(void *arg)
|
||||||
int
|
int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
pthread_t t1;
|
thread_id_t t1;
|
||||||
pthread_t t2;
|
thread_id_t t2;
|
||||||
unsigned counter;
|
unsigned counter;
|
||||||
|
|
||||||
if (0 == pthread_create(&t1, 0, test, 0))
|
if (CREATE_THREAD(t1, test, 0))
|
||||||
{
|
{
|
||||||
for (counter = 0; 0 == initialize_entered && counter < 5; counter++)
|
for (counter = 0; 0 == initialize_entered && counter < 5; counter++)
|
||||||
{
|
{
|
||||||
|
@ -82,7 +93,7 @@ main()
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 == pthread_create(&t2, 0, test, 0))
|
if (CREATE_THREAD(t2, test, 0))
|
||||||
{
|
{
|
||||||
/* Wait long enough for t2 to try calling +class
|
/* Wait long enough for t2 to try calling +class
|
||||||
*/
|
*/
|
||||||
|
|
604
configure
vendored
604
configure
vendored
|
@ -680,9 +680,12 @@ NX_CONST_STRING_CLASS
|
||||||
NX_CONST_STRING_OBJCFLAGS
|
NX_CONST_STRING_OBJCFLAGS
|
||||||
GS_HAVE_OBJC_ROOT_CLASS_ATTR
|
GS_HAVE_OBJC_ROOT_CLASS_ATTR
|
||||||
GS_ALIGNOF_COND_T
|
GS_ALIGNOF_COND_T
|
||||||
|
GS_ALIGNOF_COND_MUTEX_T
|
||||||
GS_ALIGNOF_MUTEX_T
|
GS_ALIGNOF_MUTEX_T
|
||||||
GS_SIZEOF_COND_T
|
GS_SIZEOF_COND_T
|
||||||
|
GS_SIZEOF_COND_MUTEX_T
|
||||||
GS_SIZEOF_MUTEX_T
|
GS_SIZEOF_MUTEX_T
|
||||||
|
HAVE_WIN32_THREADS_AND_LOCKS
|
||||||
DYNAMIC_LINKER
|
DYNAMIC_LINKER
|
||||||
BUGGY_PTR_LIMITS
|
BUGGY_PTR_LIMITS
|
||||||
GS_UINTPTR_MAX
|
GS_UINTPTR_MAX
|
||||||
|
@ -3008,7 +3011,7 @@ then
|
||||||
fi
|
fi
|
||||||
if test x"$GNUSTEP_TARGET_CONFIG_FILE" = x""; then
|
if test x"$GNUSTEP_TARGET_CONFIG_FILE" = x""; then
|
||||||
case "$target_os" in
|
case "$target_os" in
|
||||||
mingw*|windows*)
|
mingw*|windows)
|
||||||
GNUSTEP_TARGET_CONFIG_FILE=./GNUstep.conf ;;
|
GNUSTEP_TARGET_CONFIG_FILE=./GNUstep.conf ;;
|
||||||
*)
|
*)
|
||||||
GNUSTEP_TARGET_CONFIG_FILE="$GNUSTEP_MAKE_CONFIG" ;;
|
GNUSTEP_TARGET_CONFIG_FILE="$GNUSTEP_MAKE_CONFIG" ;;
|
||||||
|
@ -3026,7 +3029,7 @@ $as_echo "$GNUSTEP_TARGET_CONFIG_FILE" >&6; }
|
||||||
# location (used by gnustep-make when building).
|
# location (used by gnustep-make when building).
|
||||||
#-----------------------------------------------------------------
|
#-----------------------------------------------------------------
|
||||||
case "$target_os" in
|
case "$target_os" in
|
||||||
mingw*|windows*) enable_env_config=no;;
|
mingw*|windows) enable_env_config=no;;
|
||||||
*) enable_env_config=yes;;
|
*) enable_env_config=yes;;
|
||||||
esac
|
esac
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the GNUstep.conf file path can be set in the environment" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the GNUstep.conf file path can be set in the environment" >&5
|
||||||
|
@ -3306,7 +3309,7 @@ GNUSTEP_BASE_DOMAIN=$result
|
||||||
# paths (relative to libgnustep-base.dll).
|
# paths (relative to libgnustep-base.dll).
|
||||||
#
|
#
|
||||||
case "$target_os" in
|
case "$target_os" in
|
||||||
mingw*|windows*)
|
mingw*|windows)
|
||||||
# TODO: Improve this hack.
|
# TODO: Improve this hack.
|
||||||
# According to Wikipedia, this is the default for Windows 2000,
|
# According to Wikipedia, this is the default for Windows 2000,
|
||||||
# Windows XP and Windows Server 2003. For Windows Vista this will
|
# Windows XP and Windows Server 2003. For Windows Vista this will
|
||||||
|
@ -7251,10 +7254,39 @@ fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# Windows: check if we have native threading APIs and SRW locks
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
HAVE_WIN32_THREADS_AND_LOCKS=0
|
||||||
|
case "$target_os" in
|
||||||
|
mingw*|windows)
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for native Windows threads and locks" >&5
|
||||||
|
$as_echo_n "checking for native Windows threads and locks... " >&6; }
|
||||||
|
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||||
|
/* end confdefs.h. */
|
||||||
|
|
||||||
|
#define GS_USE_WIN32_THREADS_AND_LOCKS 1
|
||||||
|
#include "$srcdir/Source/GSPThread.h"
|
||||||
|
|
||||||
|
_ACEOF
|
||||||
|
if ac_fn_c_try_compile "$LINENO"; then :
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||||
|
$as_echo "yes" >&6; }
|
||||||
|
HAVE_WIN32_THREADS_AND_LOCKS=1
|
||||||
|
else
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||||
|
$as_echo "no" >&6; }
|
||||||
|
fi
|
||||||
|
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
# Check for pthread.h
|
# Check for pthread.h
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
for ac_header in pthread.h
|
if test $HAVE_WIN32_THREADS_AND_LOCKS = 0; then
|
||||||
|
for ac_header in pthread.h
|
||||||
do :
|
do :
|
||||||
ac_fn_c_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default"
|
ac_fn_c_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default"
|
||||||
if test "x$ac_cv_header_pthread_h" = xyes; then :
|
if test "x$ac_cv_header_pthread_h" = xyes; then :
|
||||||
|
@ -7266,12 +7298,12 @@ fi
|
||||||
|
|
||||||
done
|
done
|
||||||
|
|
||||||
for ac_header in pthread_np.h
|
for ac_header in pthread_np.h
|
||||||
do :
|
do :
|
||||||
ac_fn_c_check_header_compile "$LINENO" "pthread_np.h" "ac_cv_header_pthread_np_h" "$ac_includes_default
|
ac_fn_c_check_header_compile "$LINENO" "pthread_np.h" "ac_cv_header_pthread_np_h" "$ac_includes_default
|
||||||
#ifdef HAVE_PTHREAD_H
|
#ifdef HAVE_PTHREAD_H
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
"
|
"
|
||||||
if test "x$ac_cv_header_pthread_np_h" = xyes; then :
|
if test "x$ac_cv_header_pthread_np_h" = xyes; then :
|
||||||
|
@ -7283,8 +7315,8 @@ fi
|
||||||
|
|
||||||
done
|
done
|
||||||
|
|
||||||
if test $ac_cv_header_pthread_h = yes ; then
|
if test $ac_cv_header_pthread_h = yes ; then
|
||||||
# The cast to long int works around a bug in the HP C Compiler
|
# The cast to long int works around a bug in the HP C Compiler
|
||||||
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
|
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
|
||||||
# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
|
# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
|
||||||
# This bug is HP SR number 8606223364.
|
# This bug is HP SR number 8606223364.
|
||||||
|
@ -7294,7 +7326,7 @@ if ${ac_cv_sizeof_pthread_mutex_t+:} false; then :
|
||||||
$as_echo_n "(cached) " >&6
|
$as_echo_n "(cached) " >&6
|
||||||
else
|
else
|
||||||
if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (pthread_mutex_t))" "ac_cv_sizeof_pthread_mutex_t" "$ac_includes_default
|
if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (pthread_mutex_t))" "ac_cv_sizeof_pthread_mutex_t" "$ac_includes_default
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
"; then :
|
"; then :
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -7319,27 +7351,31 @@ cat >>confdefs.h <<_ACEOF
|
||||||
_ACEOF
|
_ACEOF
|
||||||
|
|
||||||
|
|
||||||
GS_SIZEOF_MUTEX_T=$ac_cv_sizeof_pthread_mutex_t
|
GS_SIZEOF_MUTEX_T=$ac_cv_sizeof_pthread_mutex_t
|
||||||
if test $ac_cv_sizeof_pthread_mutex_t = 0 ; then
|
if test $ac_cv_sizeof_pthread_mutex_t = 0 ; then
|
||||||
as_fn_error $? "Unable to find size of pthread_mutex_t (required)." "$LINENO" 5
|
as_fn_error $? "Unable to find size of pthread_mutex_t (required)." "$LINENO" 5
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# pthread_mutex_t.__data.__owner is non-standard since pthread_mutex_t is
|
GS_SIZEOF_COND_MUTEX_T=$ac_cv_sizeof_pthread_mutex_t
|
||||||
# nominally an opaque type. We must not rely on this for anything other
|
|
||||||
# than debug output!
|
|
||||||
ac_fn_c_check_member "$LINENO" "pthread_mutex_t" "__data.__owner" "ac_cv_member_pthread_mutex_t___data___owner" "$ac_includes_default
|
# pthread_mutex_t.__data.__owner is non-standard since pthread_mutex_t is
|
||||||
#include <pthread.h>
|
# nominally an opaque type. We must not rely on this for anything other
|
||||||
|
# than debug output!
|
||||||
|
ac_fn_c_check_member "$LINENO" "pthread_mutex_t" "__data.__owner" "ac_cv_member_pthread_mutex_t___data___owner" "$ac_includes_default
|
||||||
|
#include <pthread.h>
|
||||||
"
|
"
|
||||||
if test "x$ac_cv_member_pthread_mutex_t___data___owner" = xyes; then :
|
if test "x$ac_cv_member_pthread_mutex_t___data___owner" = xyes; then :
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test $ac_cv_member_pthread_mutex_t___data___owner = yes ; then
|
if test $ac_cv_member_pthread_mutex_t___data___owner = yes ; then
|
||||||
|
|
||||||
$as_echo "#define HAVE_PTHREAD_MUTEX_OWNER 1" >>confdefs.h
|
$as_echo "#define HAVE_PTHREAD_MUTEX_OWNER 1" >>confdefs.h
|
||||||
|
|
||||||
fi
|
fi
|
||||||
# The cast to long int works around a bug in the HP C Compiler
|
|
||||||
|
# The cast to long int works around a bug in the HP C Compiler
|
||||||
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
|
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
|
||||||
# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
|
# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
|
||||||
# This bug is HP SR number 8606223364.
|
# This bug is HP SR number 8606223364.
|
||||||
|
@ -7349,7 +7385,7 @@ if ${ac_cv_sizeof_pthread_cond_t+:} false; then :
|
||||||
$as_echo_n "(cached) " >&6
|
$as_echo_n "(cached) " >&6
|
||||||
else
|
else
|
||||||
if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (pthread_cond_t))" "ac_cv_sizeof_pthread_cond_t" "$ac_includes_default
|
if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (pthread_cond_t))" "ac_cv_sizeof_pthread_cond_t" "$ac_includes_default
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
"; then :
|
"; then :
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -7374,12 +7410,13 @@ cat >>confdefs.h <<_ACEOF
|
||||||
_ACEOF
|
_ACEOF
|
||||||
|
|
||||||
|
|
||||||
if test $ac_cv_sizeof_pthread_cond_t = 0 ; then
|
if test $ac_cv_sizeof_pthread_cond_t = 0 ; then
|
||||||
as_fn_error $? "Unable to find size of pthread_cond_t (required)." "$LINENO" 5
|
as_fn_error $? "Unable to find size of pthread_cond_t (required)." "$LINENO" 5
|
||||||
fi
|
fi
|
||||||
GS_SIZEOF_COND_T=$ac_cv_sizeof_pthread_cond_t
|
GS_SIZEOF_COND_T=$ac_cv_sizeof_pthread_cond_t
|
||||||
|
|
||||||
# The cast to long int works around a bug in the HP C Compiler,
|
|
||||||
|
# The cast to long int works around a bug in the HP C Compiler,
|
||||||
# see AC_CHECK_SIZEOF for more information.
|
# see AC_CHECK_SIZEOF for more information.
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of pthread_mutex_t" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of pthread_mutex_t" >&5
|
||||||
$as_echo_n "checking alignment of pthread_mutex_t... " >&6; }
|
$as_echo_n "checking alignment of pthread_mutex_t... " >&6; }
|
||||||
|
@ -7387,7 +7424,7 @@ if ${ac_cv_alignof_pthread_mutex_t+:} false; then :
|
||||||
$as_echo_n "(cached) " >&6
|
$as_echo_n "(cached) " >&6
|
||||||
else
|
else
|
||||||
if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_pthread_mutex_t" "$ac_includes_default
|
if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_pthread_mutex_t" "$ac_includes_default
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#ifndef offsetof
|
#ifndef offsetof
|
||||||
# define offsetof(type, member) ((char *) &((type *) 0)->member - (char *) 0)
|
# define offsetof(type, member) ((char *) &((type *) 0)->member - (char *) 0)
|
||||||
|
@ -7416,12 +7453,15 @@ cat >>confdefs.h <<_ACEOF
|
||||||
_ACEOF
|
_ACEOF
|
||||||
|
|
||||||
|
|
||||||
GS_ALIGNOF_MUTEX_T=$ac_cv_alignof_pthread_mutex_t
|
GS_ALIGNOF_MUTEX_T=$ac_cv_alignof_pthread_mutex_t
|
||||||
if test $ac_cv_alignof_pthread_mutex_t = 0 ; then
|
if test $ac_cv_alignof_pthread_mutex_t = 0 ; then
|
||||||
as_fn_error $? "Unable to find align of pthread_mutex_t (required)." "$LINENO" 5
|
as_fn_error $? "Unable to find align of pthread_mutex_t (required)." "$LINENO" 5
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# The cast to long int works around a bug in the HP C Compiler,
|
GS_ALIGNOF_COND_MUTEX_T=$ac_cv_alignof_pthread_mutex_t
|
||||||
|
|
||||||
|
|
||||||
|
# The cast to long int works around a bug in the HP C Compiler,
|
||||||
# see AC_CHECK_SIZEOF for more information.
|
# see AC_CHECK_SIZEOF for more information.
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of pthread_cond_t" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of pthread_cond_t" >&5
|
||||||
$as_echo_n "checking alignment of pthread_cond_t... " >&6; }
|
$as_echo_n "checking alignment of pthread_cond_t... " >&6; }
|
||||||
|
@ -7429,7 +7469,7 @@ if ${ac_cv_alignof_pthread_cond_t+:} false; then :
|
||||||
$as_echo_n "(cached) " >&6
|
$as_echo_n "(cached) " >&6
|
||||||
else
|
else
|
||||||
if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_pthread_cond_t" "$ac_includes_default
|
if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_pthread_cond_t" "$ac_includes_default
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#ifndef offsetof
|
#ifndef offsetof
|
||||||
# define offsetof(type, member) ((char *) &((type *) 0)->member - (char *) 0)
|
# define offsetof(type, member) ((char *) &((type *) 0)->member - (char *) 0)
|
||||||
|
@ -7458,15 +7498,15 @@ cat >>confdefs.h <<_ACEOF
|
||||||
_ACEOF
|
_ACEOF
|
||||||
|
|
||||||
|
|
||||||
if test $ac_cv_alignof_pthread_cond_t = 0 ; then
|
if test $ac_cv_alignof_pthread_cond_t = 0 ; then
|
||||||
as_fn_error $? "Unable to find align of pthread_cond_t (required)." "$LINENO" 5
|
as_fn_error $? "Unable to find align of pthread_cond_t (required)." "$LINENO" 5
|
||||||
fi
|
fi
|
||||||
GS_ALIGNOF_COND_T=$ac_cv_alignof_pthread_cond_t
|
GS_ALIGNOF_COND_T=$ac_cv_alignof_pthread_cond_t
|
||||||
|
|
||||||
else
|
else
|
||||||
as_fn_error $? "Unable to find pthread.h (needed for thread support)." "$LINENO" 5
|
as_fn_error $? "Unable to find pthread.h (needed for thread support)." "$LINENO" 5
|
||||||
fi
|
fi
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in -lpthread" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in -lpthread" >&5
|
||||||
$as_echo_n "checking for pthread_join in -lpthread... " >&6; }
|
$as_echo_n "checking for pthread_join in -lpthread... " >&6; }
|
||||||
if ${ac_cv_lib_pthread_pthread_join+:} false; then :
|
if ${ac_cv_lib_pthread_pthread_join+:} false; then :
|
||||||
$as_echo_n "(cached) " >&6
|
$as_echo_n "(cached) " >&6
|
||||||
|
@ -7508,20 +7548,13 @@ else
|
||||||
pthread_ok=no
|
pthread_ok=no
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ismingw=no
|
|
||||||
checkinlibc=no
|
if test $pthread_ok = yes ; then
|
||||||
case "$target_os" in
|
LIBS="$LIBS -lpthread"
|
||||||
mingw*) ismingw=yes;;
|
else
|
||||||
windows) iswindows=yes;;
|
case "$target_os" in
|
||||||
nto*) checkinlibc=yes;;
|
mingw*)
|
||||||
qnx*) checkinlibc=yes;;
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in -lpthreadGC2" >&5
|
||||||
*android*) checkinlibc=yes;;
|
|
||||||
esac
|
|
||||||
if test $pthread_ok = yes ; then
|
|
||||||
LIBS="$LIBS -lpthread"
|
|
||||||
else
|
|
||||||
if test $ismingw = yes ; then
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in -lpthreadGC2" >&5
|
|
||||||
$as_echo_n "checking for pthread_join in -lpthreadGC2... " >&6; }
|
$as_echo_n "checking for pthread_join in -lpthreadGC2... " >&6; }
|
||||||
if ${ac_cv_lib_pthreadGC2_pthread_join+:} false; then :
|
if ${ac_cv_lib_pthreadGC2_pthread_join+:} false; then :
|
||||||
$as_echo_n "(cached) " >&6
|
$as_echo_n "(cached) " >&6
|
||||||
|
@ -7563,12 +7596,12 @@ else
|
||||||
pthread_ok=no
|
pthread_ok=no
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test $pthread_ok = yes ; then
|
if test $pthread_ok = yes ; then
|
||||||
LIBS="$LIBS -lpthreadGC2"
|
LIBS="$LIBS -lpthreadGC2"
|
||||||
fi
|
fi
|
||||||
fi
|
;;
|
||||||
if test $iswindows = yes ; then
|
windows)
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in -lpthreadVC2" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in -lpthreadVC2" >&5
|
||||||
$as_echo_n "checking for pthread_join in -lpthreadVC2... " >&6; }
|
$as_echo_n "checking for pthread_join in -lpthreadVC2... " >&6; }
|
||||||
if ${ac_cv_lib_pthreadVC2_pthread_join+:} false; then :
|
if ${ac_cv_lib_pthreadVC2_pthread_join+:} false; then :
|
||||||
$as_echo_n "(cached) " >&6
|
$as_echo_n "(cached) " >&6
|
||||||
|
@ -7610,13 +7643,13 @@ else
|
||||||
pthread_ok=no
|
pthread_ok=no
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test $pthread_ok = yes ; then
|
if test $pthread_ok = yes ; then
|
||||||
LIBS="$LIBS -lpthreadVC2"
|
LIBS="$LIBS -lpthreadVC2"
|
||||||
fi
|
fi
|
||||||
fi
|
;;
|
||||||
# Android and QNX have pthread in libc instead of libpthread
|
nto*|qnx*|*android*)
|
||||||
if test $checkinlibc = yes ; then
|
# Android and QNX have pthread in libc instead of libpthread
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in -lc" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in -lc" >&5
|
||||||
$as_echo_n "checking for pthread_join in -lc... " >&6; }
|
$as_echo_n "checking for pthread_join in -lc... " >&6; }
|
||||||
if ${ac_cv_lib_c_pthread_join+:} false; then :
|
if ${ac_cv_lib_c_pthread_join+:} false; then :
|
||||||
$as_echo_n "(cached) " >&6
|
$as_echo_n "(cached) " >&6
|
||||||
|
@ -7658,17 +7691,18 @@ else
|
||||||
pthread_ok=no
|
pthread_ok=no
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test $pthread_ok = yes ; then
|
if test $pthread_ok = yes ; then
|
||||||
LIBS="$LIBS -lc"
|
LIBS="$LIBS -lc"
|
||||||
fi
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
if test $pthread_ok = no ; then
|
||||||
|
as_fn_error $? "Unable to find pthread library (needed for thread support)." "$LINENO" 5
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
if test $pthread_ok = no ; then
|
|
||||||
as_fn_error $? "Unable to find pthread library (needed for thread support)." "$LINENO" 5
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check threading extensions
|
# Check threading extensions
|
||||||
for ac_func in pthread_getthreadid_np pthread_main_np
|
for ac_func in pthread_getthreadid_np pthread_main_np
|
||||||
do :
|
do :
|
||||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||||
|
@ -7681,8 +7715,8 @@ fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
||||||
# Typically need librt on Solaris for sched_yield
|
# Typically need librt on Solaris for sched_yield
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sched_yield in -lrt" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sched_yield in -lrt" >&5
|
||||||
$as_echo_n "checking for sched_yield in -lrt... " >&6; }
|
$as_echo_n "checking for sched_yield in -lrt... " >&6; }
|
||||||
if ${ac_cv_lib_rt_sched_yield+:} false; then :
|
if ${ac_cv_lib_rt_sched_yield+:} false; then :
|
||||||
$as_echo_n "(cached) " >&6
|
$as_echo_n "(cached) " >&6
|
||||||
|
@ -7728,62 +7762,8 @@ _ACEOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Check if we can name pthreads
|
||||||
#--------------------------------------------------------------------
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_setname_np()" >&5
|
||||||
# One of these function needed by NSThread.m and objc initialize test
|
|
||||||
#--------------------------------------------------------------------
|
|
||||||
for ac_func in nanosleep usleep Sleep
|
|
||||||
do :
|
|
||||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
|
||||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
|
||||||
if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
|
|
||||||
cat >>confdefs.h <<_ACEOF
|
|
||||||
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
|
|
||||||
_ACEOF
|
|
||||||
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objc_root_class attribute support" >&5
|
|
||||||
$as_echo_n "checking for objc_root_class attribute support... " >&6; }
|
|
||||||
saved_CFLAGS="$CFLAGS"
|
|
||||||
CFLAGS="$CFLAGS -Werror $OBJCFLAGS -x objective-c"
|
|
||||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
|
||||||
/* end confdefs.h. */
|
|
||||||
|
|
||||||
__attribute__((objc_root_class)) @interface RootObject
|
|
||||||
@end
|
|
||||||
@implementation RootObject
|
|
||||||
@end
|
|
||||||
_ACEOF
|
|
||||||
if ac_fn_c_try_compile "$LINENO"; then :
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5
|
|
||||||
$as_echo "found" >&6; }
|
|
||||||
gs_objc_root_class_attr=1
|
|
||||||
else
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not present" >&5
|
|
||||||
$as_echo "not present" >&6; }
|
|
||||||
gs_objc_root_class_attr=0
|
|
||||||
|
|
||||||
fi
|
|
||||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
|
||||||
|
|
||||||
GS_HAVE_OBJC_ROOT_CLASS_ATTR=$gs_objc_root_class_attr
|
|
||||||
|
|
||||||
|
|
||||||
cat >>confdefs.h <<_ACEOF
|
|
||||||
#define HAVE_OBJC_ROOT_CLASS_ATTRIBUTE $gs_objc_root_class_attr
|
|
||||||
_ACEOF
|
|
||||||
|
|
||||||
CFLAGS=$saved_CFLAGS
|
|
||||||
|
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
|
||||||
# Check if we can name pthreads
|
|
||||||
#--------------------------------------------------------------------
|
|
||||||
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_setname_np()" >&5
|
|
||||||
$as_echo_n "checking for pthread_setname_np()... " >&6; }
|
$as_echo_n "checking for pthread_setname_np()... " >&6; }
|
||||||
if ${gs_cv_pthread_setname_np+:} false; then :
|
if ${gs_cv_pthread_setname_np+:} false; then :
|
||||||
$as_echo_n "(cached) " >&6
|
$as_echo_n "(cached) " >&6
|
||||||
|
@ -7843,28 +7823,26 @@ rm -f core conftest.err conftest.$ac_objext \
|
||||||
fi
|
fi
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gs_cv_pthread_setname_np" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gs_cv_pthread_setname_np" >&5
|
||||||
$as_echo "$gs_cv_pthread_setname_np" >&6; }
|
$as_echo "$gs_cv_pthread_setname_np" >&6; }
|
||||||
case $gs_cv_pthread_setname_np in
|
case $gs_cv_pthread_setname_np in
|
||||||
darwin)
|
darwin)
|
||||||
|
|
||||||
$as_echo "#define PTHREAD_SETNAME(a) pthread_setname_np(a)" >>confdefs.h
|
$as_echo "#define PTHREAD_SETNAME(a) pthread_setname_np(a)" >>confdefs.h
|
||||||
|
|
||||||
;;
|
;;
|
||||||
glibc)
|
glibc)
|
||||||
|
|
||||||
$as_echo "#define PTHREAD_SETNAME(a) pthread_setname_np(pthread_self(),a)" >>confdefs.h
|
$as_echo "#define PTHREAD_SETNAME(a) pthread_setname_np(pthread_self(),a)" >>confdefs.h
|
||||||
|
|
||||||
;;
|
;;
|
||||||
netbsd)
|
netbsd)
|
||||||
|
|
||||||
$as_echo "#define PTHREAD_SETNAME(a) pthread_setname_np(pthread_self(),\"%s\",a)" >>confdefs.h
|
$as_echo "#define PTHREAD_SETNAME(a) pthread_setname_np(pthread_self(),\"%s\",a)" >>confdefs.h
|
||||||
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
# Check if we have spinlock support
|
||||||
# Check if we have spinlock support
|
for ac_func in pthread_spin_lock
|
||||||
#--------------------------------------------------------------------
|
|
||||||
for ac_func in pthread_spin_lock
|
|
||||||
do :
|
do :
|
||||||
ac_fn_c_check_func "$LINENO" "pthread_spin_lock" "ac_cv_func_pthread_spin_lock"
|
ac_fn_c_check_func "$LINENO" "pthread_spin_lock" "ac_cv_func_pthread_spin_lock"
|
||||||
if test "x$ac_cv_func_pthread_spin_lock" = xyes; then :
|
if test "x$ac_cv_func_pthread_spin_lock" = xyes; then :
|
||||||
|
@ -7875,6 +7853,315 @@ _ACEOF
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# Check Win32 lock sizes
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
if test $HAVE_WIN32_THREADS_AND_LOCKS = 1; then
|
||||||
|
# The cast to long int works around a bug in the HP C Compiler
|
||||||
|
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
|
||||||
|
# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
|
||||||
|
# This bug is HP SR number 8606223364.
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of gs_mutex_t" >&5
|
||||||
|
$as_echo_n "checking size of gs_mutex_t... " >&6; }
|
||||||
|
if ${ac_cv_sizeof_gs_mutex_t+:} false; then :
|
||||||
|
$as_echo_n "(cached) " >&6
|
||||||
|
else
|
||||||
|
if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (gs_mutex_t))" "ac_cv_sizeof_gs_mutex_t" "$ac_includes_default
|
||||||
|
#define GS_USE_WIN32_THREADS_AND_LOCKS 1
|
||||||
|
#include \"Source/GSPThread.h\"
|
||||||
|
"; then :
|
||||||
|
|
||||||
|
else
|
||||||
|
if test "$ac_cv_type_gs_mutex_t" = yes; then
|
||||||
|
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
|
||||||
|
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
|
||||||
|
as_fn_error 77 "cannot compute sizeof (gs_mutex_t)
|
||||||
|
See \`config.log' for more details" "$LINENO" 5; }
|
||||||
|
else
|
||||||
|
ac_cv_sizeof_gs_mutex_t=0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_gs_mutex_t" >&5
|
||||||
|
$as_echo "$ac_cv_sizeof_gs_mutex_t" >&6; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define SIZEOF_GS_MUTEX_T $ac_cv_sizeof_gs_mutex_t
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
|
||||||
|
GS_SIZEOF_MUTEX_T=$ac_cv_sizeof_gs_mutex_t
|
||||||
|
if test $ac_cv_sizeof_gs_mutex_t = 0 ; then
|
||||||
|
as_fn_error $? "Unable to find size of gs_mutex_t (required)." "$LINENO" 5
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# The cast to long int works around a bug in the HP C Compiler,
|
||||||
|
# see AC_CHECK_SIZEOF for more information.
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of gs_mutex_t" >&5
|
||||||
|
$as_echo_n "checking alignment of gs_mutex_t... " >&6; }
|
||||||
|
if ${ac_cv_alignof_gs_mutex_t+:} false; then :
|
||||||
|
$as_echo_n "(cached) " >&6
|
||||||
|
else
|
||||||
|
if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_gs_mutex_t" "$ac_includes_default
|
||||||
|
#define GS_USE_WIN32_THREADS_AND_LOCKS 1
|
||||||
|
#include \"Source/GSPThread.h\"
|
||||||
|
|
||||||
|
#ifndef offsetof
|
||||||
|
# define offsetof(type, member) ((char *) &((type *) 0)->member - (char *) 0)
|
||||||
|
#endif
|
||||||
|
typedef struct { char x; gs_mutex_t y; } ac__type_alignof_;"; then :
|
||||||
|
|
||||||
|
else
|
||||||
|
if test "$ac_cv_type_gs_mutex_t" = yes; then
|
||||||
|
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
|
||||||
|
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
|
||||||
|
as_fn_error 77 "cannot compute alignment of gs_mutex_t
|
||||||
|
See \`config.log' for more details" "$LINENO" 5; }
|
||||||
|
else
|
||||||
|
ac_cv_alignof_gs_mutex_t=0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_gs_mutex_t" >&5
|
||||||
|
$as_echo "$ac_cv_alignof_gs_mutex_t" >&6; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define ALIGNOF_GS_MUTEX_T $ac_cv_alignof_gs_mutex_t
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
|
||||||
|
GS_ALIGNOF_MUTEX_T=$ac_cv_alignof_gs_mutex_t
|
||||||
|
if test $ac_cv_alignof_gs_mutex_t = 0 ; then
|
||||||
|
as_fn_error $? "Unable to find align of gs_mutex_t (required)." "$LINENO" 5
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# The cast to long int works around a bug in the HP C Compiler
|
||||||
|
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
|
||||||
|
# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
|
||||||
|
# This bug is HP SR number 8606223364.
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of CONDITION_VARIABLE" >&5
|
||||||
|
$as_echo_n "checking size of CONDITION_VARIABLE... " >&6; }
|
||||||
|
if ${ac_cv_sizeof_CONDITION_VARIABLE+:} false; then :
|
||||||
|
$as_echo_n "(cached) " >&6
|
||||||
|
else
|
||||||
|
if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (CONDITION_VARIABLE))" "ac_cv_sizeof_CONDITION_VARIABLE" "$ac_includes_default
|
||||||
|
#include <windows.h>
|
||||||
|
"; then :
|
||||||
|
|
||||||
|
else
|
||||||
|
if test "$ac_cv_type_CONDITION_VARIABLE" = yes; then
|
||||||
|
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
|
||||||
|
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
|
||||||
|
as_fn_error 77 "cannot compute sizeof (CONDITION_VARIABLE)
|
||||||
|
See \`config.log' for more details" "$LINENO" 5; }
|
||||||
|
else
|
||||||
|
ac_cv_sizeof_CONDITION_VARIABLE=0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_CONDITION_VARIABLE" >&5
|
||||||
|
$as_echo "$ac_cv_sizeof_CONDITION_VARIABLE" >&6; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define SIZEOF_CONDITION_VARIABLE $ac_cv_sizeof_CONDITION_VARIABLE
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
|
||||||
|
GS_SIZEOF_COND_T=$ac_cv_sizeof_CONDITION_VARIABLE
|
||||||
|
if test $ac_cv_sizeof_CONDITION_VARIABLE = 0 ; then
|
||||||
|
as_fn_error $? "Unable to find size of CONDITION_VARIABLE (required)." "$LINENO" 5
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# The cast to long int works around a bug in the HP C Compiler,
|
||||||
|
# see AC_CHECK_SIZEOF for more information.
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of CONDITION_VARIABLE" >&5
|
||||||
|
$as_echo_n "checking alignment of CONDITION_VARIABLE... " >&6; }
|
||||||
|
if ${ac_cv_alignof_CONDITION_VARIABLE+:} false; then :
|
||||||
|
$as_echo_n "(cached) " >&6
|
||||||
|
else
|
||||||
|
if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_CONDITION_VARIABLE" "$ac_includes_default
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#ifndef offsetof
|
||||||
|
# define offsetof(type, member) ((char *) &((type *) 0)->member - (char *) 0)
|
||||||
|
#endif
|
||||||
|
typedef struct { char x; CONDITION_VARIABLE y; } ac__type_alignof_;"; then :
|
||||||
|
|
||||||
|
else
|
||||||
|
if test "$ac_cv_type_CONDITION_VARIABLE" = yes; then
|
||||||
|
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
|
||||||
|
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
|
||||||
|
as_fn_error 77 "cannot compute alignment of CONDITION_VARIABLE
|
||||||
|
See \`config.log' for more details" "$LINENO" 5; }
|
||||||
|
else
|
||||||
|
ac_cv_alignof_CONDITION_VARIABLE=0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_CONDITION_VARIABLE" >&5
|
||||||
|
$as_echo "$ac_cv_alignof_CONDITION_VARIABLE" >&6; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define ALIGNOF_CONDITION_VARIABLE $ac_cv_alignof_CONDITION_VARIABLE
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
|
||||||
|
GS_ALIGNOF_COND_T=$ac_cv_alignof_CONDITION_VARIABLE
|
||||||
|
if test $ac_cv_alignof_CONDITION_VARIABLE = 0 ; then
|
||||||
|
as_fn_error $? "Unable to find align of CONDITION_VARIABLE (required)." "$LINENO" 5
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# The cast to long int works around a bug in the HP C Compiler
|
||||||
|
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
|
||||||
|
# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
|
||||||
|
# This bug is HP SR number 8606223364.
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of SRWLOCK" >&5
|
||||||
|
$as_echo_n "checking size of SRWLOCK... " >&6; }
|
||||||
|
if ${ac_cv_sizeof_SRWLOCK+:} false; then :
|
||||||
|
$as_echo_n "(cached) " >&6
|
||||||
|
else
|
||||||
|
if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (SRWLOCK))" "ac_cv_sizeof_SRWLOCK" "$ac_includes_default
|
||||||
|
#include <windows.h>
|
||||||
|
"; then :
|
||||||
|
|
||||||
|
else
|
||||||
|
if test "$ac_cv_type_SRWLOCK" = yes; then
|
||||||
|
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
|
||||||
|
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
|
||||||
|
as_fn_error 77 "cannot compute sizeof (SRWLOCK)
|
||||||
|
See \`config.log' for more details" "$LINENO" 5; }
|
||||||
|
else
|
||||||
|
ac_cv_sizeof_SRWLOCK=0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_SRWLOCK" >&5
|
||||||
|
$as_echo "$ac_cv_sizeof_SRWLOCK" >&6; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define SIZEOF_SRWLOCK $ac_cv_sizeof_SRWLOCK
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
|
||||||
|
GS_SIZEOF_COND_MUTEX_T=$ac_cv_sizeof_SRWLOCK
|
||||||
|
if test $ac_cv_sizeof_SRWLOCK = 0 ; then
|
||||||
|
as_fn_error $? "Unable to find size of SRWLOCK (required)." "$LINENO" 5
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# The cast to long int works around a bug in the HP C Compiler,
|
||||||
|
# see AC_CHECK_SIZEOF for more information.
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of SRWLOCK" >&5
|
||||||
|
$as_echo_n "checking alignment of SRWLOCK... " >&6; }
|
||||||
|
if ${ac_cv_alignof_SRWLOCK+:} false; then :
|
||||||
|
$as_echo_n "(cached) " >&6
|
||||||
|
else
|
||||||
|
if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_SRWLOCK" "$ac_includes_default
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#ifndef offsetof
|
||||||
|
# define offsetof(type, member) ((char *) &((type *) 0)->member - (char *) 0)
|
||||||
|
#endif
|
||||||
|
typedef struct { char x; SRWLOCK y; } ac__type_alignof_;"; then :
|
||||||
|
|
||||||
|
else
|
||||||
|
if test "$ac_cv_type_SRWLOCK" = yes; then
|
||||||
|
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
|
||||||
|
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
|
||||||
|
as_fn_error 77 "cannot compute alignment of SRWLOCK
|
||||||
|
See \`config.log' for more details" "$LINENO" 5; }
|
||||||
|
else
|
||||||
|
ac_cv_alignof_SRWLOCK=0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_SRWLOCK" >&5
|
||||||
|
$as_echo "$ac_cv_alignof_SRWLOCK" >&6; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define ALIGNOF_SRWLOCK $ac_cv_alignof_SRWLOCK
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
|
||||||
|
GS_ALIGNOF_COND_MUTEX_T=$ac_cv_alignof_SRWLOCK
|
||||||
|
if test $ac_cv_alignof_SRWLOCK = 0 ; then
|
||||||
|
as_fn_error $? "Unable to find align of SRWLOCK (required)." "$LINENO" 5
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# One of these function needed by NSThread.m and objc initialize test
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
for ac_func in nanosleep usleep Sleep
|
||||||
|
do :
|
||||||
|
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||||
|
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||||
|
if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objc_root_class attribute support" >&5
|
||||||
|
$as_echo_n "checking for objc_root_class attribute support... " >&6; }
|
||||||
|
saved_CFLAGS="$CFLAGS"
|
||||||
|
CFLAGS="$CFLAGS -Werror $OBJCFLAGS -x objective-c"
|
||||||
|
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||||
|
/* end confdefs.h. */
|
||||||
|
|
||||||
|
__attribute__((objc_root_class)) @interface RootObject
|
||||||
|
@end
|
||||||
|
@implementation RootObject
|
||||||
|
@end
|
||||||
|
_ACEOF
|
||||||
|
if ac_fn_c_try_compile "$LINENO"; then :
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5
|
||||||
|
$as_echo "found" >&6; }
|
||||||
|
gs_objc_root_class_attr=1
|
||||||
|
else
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not present" >&5
|
||||||
|
$as_echo "not present" >&6; }
|
||||||
|
gs_objc_root_class_attr=0
|
||||||
|
|
||||||
|
fi
|
||||||
|
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||||
|
|
||||||
|
GS_HAVE_OBJC_ROOT_CLASS_ATTR=$gs_objc_root_class_attr
|
||||||
|
|
||||||
|
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define HAVE_OBJC_ROOT_CLASS_ATTRIBUTE $gs_objc_root_class_attr
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
CFLAGS=$saved_CFLAGS
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
# Check whether we can get the system thread ID
|
# Check whether we can get the system thread ID
|
||||||
|
@ -9141,8 +9428,9 @@ $as_echo "#define HAVE_BFD_SECTION_VMA 1" >>confdefs.h
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
if test $ismingw = yes ; then
|
case "$target_os" in
|
||||||
for ac_header in dbghelp.h
|
mingw*)
|
||||||
|
for ac_header in dbghelp.h
|
||||||
do :
|
do :
|
||||||
ac_fn_c_check_header_mongrel "$LINENO" "dbghelp.h" "ac_cv_header_dbghelp_h" "$ac_includes_default"
|
ac_fn_c_check_header_mongrel "$LINENO" "dbghelp.h" "ac_cv_header_dbghelp_h" "$ac_includes_default"
|
||||||
if test "x$ac_cv_header_dbghelp_h" = xyes; then :
|
if test "x$ac_cv_header_dbghelp_h" = xyes; then :
|
||||||
|
@ -9154,8 +9442,9 @@ fi
|
||||||
|
|
||||||
done
|
done
|
||||||
|
|
||||||
else
|
;;
|
||||||
for ac_header in execinfo.h
|
*)
|
||||||
|
for ac_header in execinfo.h
|
||||||
do :
|
do :
|
||||||
ac_fn_c_check_header_mongrel "$LINENO" "execinfo.h" "ac_cv_header_execinfo_h" "$ac_includes_default"
|
ac_fn_c_check_header_mongrel "$LINENO" "execinfo.h" "ac_cv_header_execinfo_h" "$ac_includes_default"
|
||||||
if test "x$ac_cv_header_execinfo_h" = xyes; then :
|
if test "x$ac_cv_header_execinfo_h" = xyes; then :
|
||||||
|
@ -9167,7 +9456,7 @@ fi
|
||||||
|
|
||||||
done
|
done
|
||||||
|
|
||||||
for ac_func in backtrace
|
for ac_func in backtrace
|
||||||
do :
|
do :
|
||||||
ac_fn_c_check_func "$LINENO" "backtrace" "ac_cv_func_backtrace"
|
ac_fn_c_check_func "$LINENO" "backtrace" "ac_cv_func_backtrace"
|
||||||
if test "x$ac_cv_func_backtrace" = xyes; then :
|
if test "x$ac_cv_func_backtrace" = xyes; then :
|
||||||
|
@ -9178,7 +9467,8 @@ _ACEOF
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
fi
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
for ac_func in __builtin_extract_return_address
|
for ac_func in __builtin_extract_return_address
|
||||||
do :
|
do :
|
||||||
|
@ -10774,7 +11064,7 @@ $as_echo "$as_me: WARNING: Using libkvm which is known to be buggy on some syste
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
case "$target_os" in
|
case "$target_os" in
|
||||||
mingw*|windows*) enable_fake_main=no; GS_FAKE_MAIN=0;;
|
mingw*|windows) enable_fake_main=no; GS_FAKE_MAIN=0;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_fake_main" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_fake_main" >&5
|
||||||
|
|
334
configure.ac
334
configure.ac
|
@ -235,7 +235,7 @@ then
|
||||||
fi
|
fi
|
||||||
if test x"$GNUSTEP_TARGET_CONFIG_FILE" = x""; then
|
if test x"$GNUSTEP_TARGET_CONFIG_FILE" = x""; then
|
||||||
case "$target_os" in
|
case "$target_os" in
|
||||||
mingw*|windows*)
|
mingw*|windows)
|
||||||
GNUSTEP_TARGET_CONFIG_FILE=./GNUstep.conf ;;
|
GNUSTEP_TARGET_CONFIG_FILE=./GNUstep.conf ;;
|
||||||
*)
|
*)
|
||||||
GNUSTEP_TARGET_CONFIG_FILE="$GNUSTEP_MAKE_CONFIG" ;;
|
GNUSTEP_TARGET_CONFIG_FILE="$GNUSTEP_MAKE_CONFIG" ;;
|
||||||
|
@ -252,7 +252,7 @@ AC_MSG_RESULT($GNUSTEP_TARGET_CONFIG_FILE)
|
||||||
# location (used by gnustep-make when building).
|
# location (used by gnustep-make when building).
|
||||||
#-----------------------------------------------------------------
|
#-----------------------------------------------------------------
|
||||||
case "$target_os" in
|
case "$target_os" in
|
||||||
mingw*|windows*) enable_env_config=no;;
|
mingw*|windows) enable_env_config=no;;
|
||||||
*) enable_env_config=yes;;
|
*) enable_env_config=yes;;
|
||||||
esac
|
esac
|
||||||
AC_MSG_CHECKING([whether the GNUstep.conf file path can be set in the environment])
|
AC_MSG_CHECKING([whether the GNUstep.conf file path can be set in the environment])
|
||||||
|
@ -534,7 +534,7 @@ AC_SUBST(GNUSTEP_BASE_DOMAIN)
|
||||||
# paths (relative to libgnustep-base.dll).
|
# paths (relative to libgnustep-base.dll).
|
||||||
#
|
#
|
||||||
case "$target_os" in
|
case "$target_os" in
|
||||||
mingw*|windows*)
|
mingw*|windows)
|
||||||
# TODO: Improve this hack.
|
# TODO: Improve this hack.
|
||||||
# According to Wikipedia, this is the default for Windows 2000,
|
# According to Wikipedia, this is the default for Windows 2000,
|
||||||
# Windows XP and Windows Server 2003. For Windows Vista this will
|
# Windows XP and Windows Server 2003. For Windows Vista this will
|
||||||
|
@ -1702,99 +1702,209 @@ fi
|
||||||
|
|
||||||
AC_CHECK_FUNCS(getaddrinfo)
|
AC_CHECK_FUNCS(getaddrinfo)
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# Windows: check if we have native threading APIs and SRW locks
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
HAVE_WIN32_THREADS_AND_LOCKS=0
|
||||||
|
case "$target_os" in
|
||||||
|
mingw*|windows)
|
||||||
|
AC_MSG_CHECKING(for native Windows threads and locks)
|
||||||
|
AC_COMPILE_IFELSE(
|
||||||
|
[AC_LANG_SOURCE([
|
||||||
|
#define GS_USE_WIN32_THREADS_AND_LOCKS 1
|
||||||
|
#include "$srcdir/Source/GSPThread.h"
|
||||||
|
])],
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
HAVE_WIN32_THREADS_AND_LOCKS=1,
|
||||||
|
AC_MSG_RESULT([no]))
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
AC_SUBST(HAVE_WIN32_THREADS_AND_LOCKS)
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
# Check for pthread.h
|
# Check for pthread.h
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
AC_CHECK_HEADERS([pthread.h])
|
if test $HAVE_WIN32_THREADS_AND_LOCKS = 0; then
|
||||||
AC_CHECK_HEADERS([pthread_np.h],[],[],[AC_INCLUDES_DEFAULT
|
AC_CHECK_HEADERS([pthread.h])
|
||||||
#ifdef HAVE_PTHREAD_H
|
AC_CHECK_HEADERS([pthread_np.h],[],[],[AC_INCLUDES_DEFAULT
|
||||||
#include <pthread.h>
|
#ifdef HAVE_PTHREAD_H
|
||||||
#endif
|
#include <pthread.h>
|
||||||
])
|
#endif
|
||||||
if test $ac_cv_header_pthread_h = yes ; then
|
])
|
||||||
AC_CHECK_SIZEOF(pthread_mutex_t,,[AC_INCLUDES_DEFAULT
|
if test $ac_cv_header_pthread_h = yes ; then
|
||||||
#include <pthread.h>])
|
AC_CHECK_SIZEOF(pthread_mutex_t,,[AC_INCLUDES_DEFAULT
|
||||||
GS_SIZEOF_MUTEX_T=$ac_cv_sizeof_pthread_mutex_t
|
#include <pthread.h>])
|
||||||
if test $ac_cv_sizeof_pthread_mutex_t = 0 ; then
|
GS_SIZEOF_MUTEX_T=$ac_cv_sizeof_pthread_mutex_t
|
||||||
AC_MSG_ERROR([Unable to find size of pthread_mutex_t (required).])
|
if test $ac_cv_sizeof_pthread_mutex_t = 0 ; then
|
||||||
|
AC_MSG_ERROR([Unable to find size of pthread_mutex_t (required).])
|
||||||
|
fi
|
||||||
|
AC_SUBST(GS_SIZEOF_MUTEX_T)
|
||||||
|
GS_SIZEOF_COND_MUTEX_T=$ac_cv_sizeof_pthread_mutex_t
|
||||||
|
AC_SUBST(GS_SIZEOF_COND_MUTEX_T)
|
||||||
|
|
||||||
|
# pthread_mutex_t.__data.__owner is non-standard since pthread_mutex_t is
|
||||||
|
# nominally an opaque type. We must not rely on this for anything other
|
||||||
|
# than debug output!
|
||||||
|
AC_CHECK_MEMBER([pthread_mutex_t.__data.__owner],,,[AC_INCLUDES_DEFAULT
|
||||||
|
#include <pthread.h>])
|
||||||
|
if test $ac_cv_member_pthread_mutex_t___data___owner = yes ; then
|
||||||
|
AC_DEFINE(HAVE_PTHREAD_MUTEX_OWNER, 1,
|
||||||
|
[Define if you have pthread_mutex_t.__data.__owner])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_CHECK_SIZEOF(pthread_cond_t,,[AC_INCLUDES_DEFAULT
|
||||||
|
#include <pthread.h>])
|
||||||
|
if test $ac_cv_sizeof_pthread_cond_t = 0 ; then
|
||||||
|
AC_MSG_ERROR([Unable to find size of pthread_cond_t (required).])
|
||||||
|
fi
|
||||||
|
GS_SIZEOF_COND_T=$ac_cv_sizeof_pthread_cond_t
|
||||||
|
AC_SUBST(GS_SIZEOF_COND_T)
|
||||||
|
|
||||||
|
AC_CHECK_ALIGNOF(pthread_mutex_t,[AC_INCLUDES_DEFAULT
|
||||||
|
#include <pthread.h>])
|
||||||
|
GS_ALIGNOF_MUTEX_T=$ac_cv_alignof_pthread_mutex_t
|
||||||
|
if test $ac_cv_alignof_pthread_mutex_t = 0 ; then
|
||||||
|
AC_MSG_ERROR([Unable to find align of pthread_mutex_t (required).])
|
||||||
|
fi
|
||||||
|
AC_SUBST(GS_ALIGNOF_MUTEX_T)
|
||||||
|
GS_ALIGNOF_COND_MUTEX_T=$ac_cv_alignof_pthread_mutex_t
|
||||||
|
AC_SUBST(GS_ALIGNOF_COND_MUTEX_T)
|
||||||
|
|
||||||
|
AC_CHECK_ALIGNOF(pthread_cond_t,[AC_INCLUDES_DEFAULT
|
||||||
|
#include <pthread.h>])
|
||||||
|
if test $ac_cv_alignof_pthread_cond_t = 0 ; then
|
||||||
|
AC_MSG_ERROR([Unable to find align of pthread_cond_t (required).])
|
||||||
|
fi
|
||||||
|
GS_ALIGNOF_COND_T=$ac_cv_alignof_pthread_cond_t
|
||||||
|
AC_SUBST(GS_ALIGNOF_COND_T)
|
||||||
|
else
|
||||||
|
AC_MSG_ERROR([Unable to find pthread.h (needed for thread support).])
|
||||||
|
fi
|
||||||
|
AC_CHECK_LIB(pthread, pthread_join, pthread_ok=yes, pthread_ok=no)
|
||||||
|
|
||||||
|
if test $pthread_ok = yes ; then
|
||||||
|
LIBS="$LIBS -lpthread"
|
||||||
|
else
|
||||||
|
case "$target_os" in
|
||||||
|
mingw*)
|
||||||
|
AC_CHECK_LIB(pthreadGC2, pthread_join, pthread_ok=yes, pthread_ok=no)
|
||||||
|
if test $pthread_ok = yes ; then
|
||||||
|
LIBS="$LIBS -lpthreadGC2"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
windows)
|
||||||
|
AC_CHECK_LIB(pthreadVC2, pthread_join, pthread_ok=yes, pthread_ok=no)
|
||||||
|
if test $pthread_ok = yes ; then
|
||||||
|
LIBS="$LIBS -lpthreadVC2"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
nto*|qnx*|*android*)
|
||||||
|
# Android and QNX have pthread in libc instead of libpthread
|
||||||
|
AC_CHECK_LIB(c, pthread_join, pthread_ok=yes, pthread_ok=no)
|
||||||
|
if test $pthread_ok = yes ; then
|
||||||
|
LIBS="$LIBS -lc"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
if test $pthread_ok = no ; then
|
||||||
|
AC_MSG_ERROR([Unable to find pthread library (needed for thread support).])
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check threading extensions
|
||||||
|
AC_CHECK_FUNCS(pthread_getthreadid_np pthread_main_np)
|
||||||
|
|
||||||
|
# Typically need librt on Solaris for sched_yield
|
||||||
|
AC_CHECK_LIB(rt, sched_yield)
|
||||||
|
|
||||||
|
# Check if we can name pthreads
|
||||||
|
AC_CACHE_CHECK([for pthread_setname_np()], gs_cv_pthread_setname_np,
|
||||||
|
[AC_LINK_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM([#include <pthread.h>],
|
||||||
|
[pthread_setname_np("name");])],
|
||||||
|
[gs_cv_pthread_setname_np=darwin],
|
||||||
|
[AC_LINK_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM([#include <pthread.h>],
|
||||||
|
[pthread_setname_np(pthread_self(), "name");])],
|
||||||
|
[gs_cv_pthread_setname_np=glibc],
|
||||||
|
[AC_LINK_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM([#include <pthread.h>],
|
||||||
|
[pthread_setname_np(pthread_self(), "%s", "name");])],
|
||||||
|
[gs_cv_pthread_setname_np=netbsd],
|
||||||
|
[gs_cv_pthread_setname_np=none])])])])
|
||||||
|
case $gs_cv_pthread_setname_np in
|
||||||
|
darwin)
|
||||||
|
AC_DEFINE(PTHREAD_SETNAME(a), pthread_setname_np(a),
|
||||||
|
[Description: Define set name function for pthread with one arg])
|
||||||
|
;;
|
||||||
|
glibc)
|
||||||
|
AC_DEFINE(PTHREAD_SETNAME(a), pthread_setname_np(pthread_self(),a),
|
||||||
|
[Description: Define setname function for pthread with two args])
|
||||||
|
;;
|
||||||
|
netbsd)
|
||||||
|
AC_DEFINE(PTHREAD_SETNAME(a), pthread_setname_np(pthread_self(),"%s",a),
|
||||||
|
[Description: Define setname function for pthread with three args])
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Check if we have spinlock support
|
||||||
|
AC_CHECK_FUNCS(pthread_spin_lock)
|
||||||
|
fi
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# Check Win32 lock sizes
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
if test $HAVE_WIN32_THREADS_AND_LOCKS = 1; then
|
||||||
|
AC_CHECK_SIZEOF(gs_mutex_t,,[AC_INCLUDES_DEFAULT
|
||||||
|
#define GS_USE_WIN32_THREADS_AND_LOCKS 1
|
||||||
|
#include "Source/GSPThread.h"])
|
||||||
|
GS_SIZEOF_MUTEX_T=$ac_cv_sizeof_gs_mutex_t
|
||||||
|
if test $ac_cv_sizeof_gs_mutex_t = 0 ; then
|
||||||
|
AC_MSG_ERROR([Unable to find size of gs_mutex_t (required).])
|
||||||
fi
|
fi
|
||||||
AC_SUBST(GS_SIZEOF_MUTEX_T)
|
AC_SUBST(GS_SIZEOF_MUTEX_T)
|
||||||
# pthread_mutex_t.__data.__owner is non-standard since pthread_mutex_t is
|
|
||||||
# nominally an opaque type. We must not rely on this for anything other
|
AC_CHECK_ALIGNOF(gs_mutex_t,[AC_INCLUDES_DEFAULT
|
||||||
# than debug output!
|
#define GS_USE_WIN32_THREADS_AND_LOCKS 1
|
||||||
AC_CHECK_MEMBER([pthread_mutex_t.__data.__owner],,,[AC_INCLUDES_DEFAULT
|
#include "Source/GSPThread.h"])
|
||||||
#include <pthread.h>])
|
GS_ALIGNOF_MUTEX_T=$ac_cv_alignof_gs_mutex_t
|
||||||
if test $ac_cv_member_pthread_mutex_t___data___owner = yes ; then
|
if test $ac_cv_alignof_gs_mutex_t = 0 ; then
|
||||||
AC_DEFINE(HAVE_PTHREAD_MUTEX_OWNER, 1,
|
AC_MSG_ERROR([Unable to find align of gs_mutex_t (required).])
|
||||||
[Define if you have pthread_mutex_t.__data.__owner])
|
|
||||||
fi
|
|
||||||
AC_CHECK_SIZEOF(pthread_cond_t,,[AC_INCLUDES_DEFAULT
|
|
||||||
#include <pthread.h>])
|
|
||||||
if test $ac_cv_sizeof_pthread_cond_t = 0 ; then
|
|
||||||
AC_MSG_ERROR([Unable to find size of pthread_cond_t (required).])
|
|
||||||
fi
|
|
||||||
GS_SIZEOF_COND_T=$ac_cv_sizeof_pthread_cond_t
|
|
||||||
AC_SUBST(GS_SIZEOF_COND_T)
|
|
||||||
AC_CHECK_ALIGNOF(pthread_mutex_t,[AC_INCLUDES_DEFAULT
|
|
||||||
#include <pthread.h>])
|
|
||||||
GS_ALIGNOF_MUTEX_T=$ac_cv_alignof_pthread_mutex_t
|
|
||||||
if test $ac_cv_alignof_pthread_mutex_t = 0 ; then
|
|
||||||
AC_MSG_ERROR([Unable to find align of pthread_mutex_t (required).])
|
|
||||||
fi
|
fi
|
||||||
AC_SUBST(GS_ALIGNOF_MUTEX_T)
|
AC_SUBST(GS_ALIGNOF_MUTEX_T)
|
||||||
AC_CHECK_ALIGNOF(pthread_cond_t,[AC_INCLUDES_DEFAULT
|
|
||||||
#include <pthread.h>])
|
AC_CHECK_SIZEOF(CONDITION_VARIABLE,,[AC_INCLUDES_DEFAULT
|
||||||
if test $ac_cv_alignof_pthread_cond_t = 0 ; then
|
#include <windows.h>])
|
||||||
AC_MSG_ERROR([Unable to find align of pthread_cond_t (required).])
|
GS_SIZEOF_COND_T=$ac_cv_sizeof_CONDITION_VARIABLE
|
||||||
|
if test $ac_cv_sizeof_CONDITION_VARIABLE = 0 ; then
|
||||||
|
AC_MSG_ERROR([Unable to find size of CONDITION_VARIABLE (required).])
|
||||||
|
fi
|
||||||
|
AC_SUBST(GS_SIZEOF_COND_T)
|
||||||
|
|
||||||
|
AC_CHECK_ALIGNOF(CONDITION_VARIABLE,[AC_INCLUDES_DEFAULT
|
||||||
|
#include <windows.h>])
|
||||||
|
GS_ALIGNOF_COND_T=$ac_cv_alignof_CONDITION_VARIABLE
|
||||||
|
if test $ac_cv_alignof_CONDITION_VARIABLE = 0 ; then
|
||||||
|
AC_MSG_ERROR([Unable to find align of CONDITION_VARIABLE (required).])
|
||||||
fi
|
fi
|
||||||
GS_ALIGNOF_COND_T=$ac_cv_alignof_pthread_cond_t
|
|
||||||
AC_SUBST(GS_ALIGNOF_COND_T)
|
AC_SUBST(GS_ALIGNOF_COND_T)
|
||||||
else
|
|
||||||
AC_MSG_ERROR([Unable to find pthread.h (needed for thread support).])
|
AC_CHECK_SIZEOF(SRWLOCK,,[AC_INCLUDES_DEFAULT
|
||||||
fi
|
#include <windows.h>])
|
||||||
AC_CHECK_LIB(pthread, pthread_join, pthread_ok=yes, pthread_ok=no)
|
GS_SIZEOF_COND_MUTEX_T=$ac_cv_sizeof_SRWLOCK
|
||||||
ismingw=no
|
if test $ac_cv_sizeof_SRWLOCK = 0 ; then
|
||||||
checkinlibc=no
|
AC_MSG_ERROR([Unable to find size of SRWLOCK (required).])
|
||||||
case "$target_os" in
|
|
||||||
mingw*) ismingw=yes;;
|
|
||||||
windows) iswindows=yes;;
|
|
||||||
nto*) checkinlibc=yes;;
|
|
||||||
qnx*) checkinlibc=yes;;
|
|
||||||
*android*) checkinlibc=yes;;
|
|
||||||
esac
|
|
||||||
if test $pthread_ok = yes ; then
|
|
||||||
LIBS="$LIBS -lpthread"
|
|
||||||
else
|
|
||||||
if test $ismingw = yes ; then
|
|
||||||
AC_CHECK_LIB(pthreadGC2, pthread_join, pthread_ok=yes, pthread_ok=no)
|
|
||||||
if test $pthread_ok = yes ; then
|
|
||||||
LIBS="$LIBS -lpthreadGC2"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
if test $iswindows = yes ; then
|
AC_SUBST(GS_SIZEOF_COND_MUTEX_T)
|
||||||
AC_CHECK_LIB(pthreadVC2, pthread_join, pthread_ok=yes, pthread_ok=no)
|
|
||||||
if test $pthread_ok = yes ; then
|
AC_CHECK_ALIGNOF(SRWLOCK,[AC_INCLUDES_DEFAULT
|
||||||
LIBS="$LIBS -lpthreadVC2"
|
#include <windows.h>])
|
||||||
fi
|
GS_ALIGNOF_COND_MUTEX_T=$ac_cv_alignof_SRWLOCK
|
||||||
fi
|
if test $ac_cv_alignof_SRWLOCK = 0 ; then
|
||||||
# Android and QNX have pthread in libc instead of libpthread
|
AC_MSG_ERROR([Unable to find align of SRWLOCK (required).])
|
||||||
if test $checkinlibc = yes ; then
|
|
||||||
AC_CHECK_LIB(c, pthread_join, pthread_ok=yes, pthread_ok=no)
|
|
||||||
if test $pthread_ok = yes ; then
|
|
||||||
LIBS="$LIBS -lc"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
AC_SUBST(GS_ALIGNOF_COND_MUTEX_T)
|
||||||
fi
|
fi
|
||||||
if test $pthread_ok = no ; then
|
|
||||||
AC_MSG_ERROR([Unable to find pthread library (needed for thread support).])
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check threading extensions
|
|
||||||
AC_CHECK_FUNCS(pthread_getthreadid_np pthread_main_np)
|
|
||||||
|
|
||||||
# Typically need librt on Solaris for sched_yield
|
|
||||||
AC_CHECK_LIB(rt, sched_yield)
|
|
||||||
|
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
# One of these function needed by NSThread.m and objc initialize test
|
# One of these function needed by NSThread.m and objc initialize test
|
||||||
|
@ -1821,45 +1931,6 @@ AC_DEFINE_UNQUOTED(HAVE_OBJC_ROOT_CLASS_ATTRIBUTE,$gs_objc_root_class_attr,
|
||||||
[Says whether the objc_root_class attribute works])
|
[Says whether the objc_root_class attribute works])
|
||||||
CFLAGS=$saved_CFLAGS
|
CFLAGS=$saved_CFLAGS
|
||||||
|
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
|
||||||
# Check if we can name pthreads
|
|
||||||
#--------------------------------------------------------------------
|
|
||||||
|
|
||||||
AC_CACHE_CHECK([for pthread_setname_np()], gs_cv_pthread_setname_np,
|
|
||||||
[AC_LINK_IFELSE(
|
|
||||||
[AC_LANG_PROGRAM([#include <pthread.h>],
|
|
||||||
[pthread_setname_np("name");])],
|
|
||||||
[gs_cv_pthread_setname_np=darwin],
|
|
||||||
[AC_LINK_IFELSE(
|
|
||||||
[AC_LANG_PROGRAM([#include <pthread.h>],
|
|
||||||
[pthread_setname_np(pthread_self(), "name");])],
|
|
||||||
[gs_cv_pthread_setname_np=glibc],
|
|
||||||
[AC_LINK_IFELSE(
|
|
||||||
[AC_LANG_PROGRAM([#include <pthread.h>],
|
|
||||||
[pthread_setname_np(pthread_self(), "%s", "name");])],
|
|
||||||
[gs_cv_pthread_setname_np=netbsd],
|
|
||||||
[gs_cv_pthread_setname_np=none])])])])
|
|
||||||
case $gs_cv_pthread_setname_np in
|
|
||||||
darwin)
|
|
||||||
AC_DEFINE(PTHREAD_SETNAME(a), pthread_setname_np(a),
|
|
||||||
[Description: Define set name function for pthread with one arg])
|
|
||||||
;;
|
|
||||||
glibc)
|
|
||||||
AC_DEFINE(PTHREAD_SETNAME(a), pthread_setname_np(pthread_self(),a),
|
|
||||||
[Description: Define setname function for pthread with two args])
|
|
||||||
;;
|
|
||||||
netbsd)
|
|
||||||
AC_DEFINE(PTHREAD_SETNAME(a), pthread_setname_np(pthread_self(),"%s",a),
|
|
||||||
[Description: Define setname function for pthread with three args])
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
|
||||||
# Check if we have spinlock support
|
|
||||||
#--------------------------------------------------------------------
|
|
||||||
AC_CHECK_FUNCS(pthread_spin_lock)
|
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
# Check whether we can get the system thread ID
|
# Check whether we can get the system thread ID
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
|
@ -2362,12 +2433,15 @@ if test $bfd_section_vma = 1; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
if test $ismingw = yes ; then
|
case "$target_os" in
|
||||||
AC_CHECK_HEADERS(dbghelp.h)
|
mingw*)
|
||||||
else
|
AC_CHECK_HEADERS(dbghelp.h)
|
||||||
AC_CHECK_HEADERS(execinfo.h)
|
;;
|
||||||
AC_CHECK_FUNCS(backtrace)
|
*)
|
||||||
fi
|
AC_CHECK_HEADERS(execinfo.h)
|
||||||
|
AC_CHECK_FUNCS(backtrace)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
AC_CHECK_FUNCS(__builtin_extract_return_address)
|
AC_CHECK_FUNCS(__builtin_extract_return_address)
|
||||||
|
|
||||||
|
@ -2815,7 +2889,7 @@ elif test "$enable_pass_arguments" = "no"; then
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
case "$target_os" in
|
case "$target_os" in
|
||||||
mingw*|windows*) enable_fake_main=no; GS_FAKE_MAIN=0;;
|
mingw*|windows) enable_fake_main=no; GS_FAKE_MAIN=0;;
|
||||||
esac
|
esac
|
||||||
AC_SUBST(GS_FAKE_MAIN)
|
AC_SUBST(GS_FAKE_MAIN)
|
||||||
AC_MSG_RESULT($enable_fake_main)
|
AC_MSG_RESULT($enable_fake_main)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue