summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--macosx/tclMacOSXNotify.c41
-rwxr-xr-xunix/configure2
-rw-r--r--unix/tcl.m42
4 files changed, 39 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index 2e8a2d0..e82d508 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2007-03-07 Daniel Steffen <das@users.sourceforge.net>
+
+ * macosx/tclMacOSXNotify.c: add spinlock debugging and sanity checks.
+
+ * unix/tcl.m4 (Darwin): s/CFLAGS/CPPFLAGS/ in macosx-version-min check.
+ * unix/configure: autoconf-2.13
+
2007-03-01 Donal K. Fellows <donal.k.fellows@man.ac.uk>
* generic/tclCompCmds.c (TclCompileForeachCmd): Prevent an unexpected
diff --git a/macosx/tclMacOSXNotify.c b/macosx/tclMacOSXNotify.c
index 3c89d20..8a5fe0f 100644
--- a/macosx/tclMacOSXNotify.c
+++ b/macosx/tclMacOSXNotify.c
@@ -13,7 +13,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclMacOSXNotify.c,v 1.1.2.10 2007/01/19 01:05:50 das Exp $
+ * RCS: @(#) $Id: tclMacOSXNotify.c,v 1.1.2.11 2007/03/07 23:44:33 das Exp $
*/
#include "tclInt.h"
@@ -150,11 +150,12 @@ static int triggerPipe = -1;
static int receivePipe = -1; /* Output end of triggerPipe */
/*
- * We use Darwin-native spinlocks instead of pthread mutexes for notifier
- * locking: this radically simplifies the implementation and lowers overhead.
- * Note that these are not pure spinlocks, they employ various strategies to
- * back off, making them immune to most priority-inversion livelocks (c.f. man
- * 3 OSSpinLockLock).
+ * We use the Darwin-native spinlock API rather than pthread mutexes for
+ * notifier locking: this radically simplifies the implementation and lowers
+ * overhead. Note that these are not pure spinlocks, they employ various
+ * strategies to back off and relinquish the processor, making them immune to
+ * most priority-inversion livelocks (c.f. 'man 3 OSSpinLockLock' and Darwin
+ * sources: xnu/osfmk/{ppc,i386}/commpage/spinlocks.s).
*/
#if defined(HAVE_LIBKERN_OSATOMIC_H) && defined(HAVE_OSSPINLOCKLOCK)
@@ -174,27 +175,37 @@ static int receivePipe = -1; /* Output end of triggerPipe */
#else
#define VOLATILE
#endif
+#ifndef bool
+#define bool int
+#endif
extern void OSSpinLockLock(VOLATILE OSSpinLock *lock) WEAK_IMPORT_ATTRIBUTE;
extern void OSSpinLockUnlock(VOLATILE OSSpinLock *lock) WEAK_IMPORT_ATTRIBUTE;
+extern bool OSSpinLockTry(VOLATILE OSSpinLock *lock) WEAK_IMPORT_ATTRIBUTE;
extern void _spin_lock(VOLATILE OSSpinLock *lock) WEAK_IMPORT_ATTRIBUTE;
extern void _spin_unlock(VOLATILE OSSpinLock *lock) WEAK_IMPORT_ATTRIBUTE;
+extern bool _spin_lock_try(VOLATILE OSSpinLock *lock) WEAK_IMPORT_ATTRIBUTE;
static void (* lockLock)(VOLATILE OSSpinLock *lock) = NULL;
static void (* lockUnlock)(VOLATILE OSSpinLock *lock) = NULL;
+static bool (* lockTry)(VOLATILE OSSpinLock *lock) = NULL;
#undef VOLATILE
static pthread_once_t spinLockLockInitControl = PTHREAD_ONCE_INIT;
static void SpinLockLockInit(void) {
lockLock = OSSpinLockLock != NULL ? OSSpinLockLock : _spin_lock;
lockUnlock = OSSpinLockUnlock != NULL ? OSSpinLockUnlock : _spin_unlock;
+ lockTry = OSSpinLockTry != NULL ? OSSpinLockTry : _spin_lock_try;
if (lockLock == NULL || lockUnlock == NULL) {
Tcl_Panic("SpinLockLockInit: no spinlock API available");
}
}
#define SpinLockLock(p) lockLock(p)
#define SpinLockUnlock(p) lockUnlock(p)
+#define SpinLockTry(p) lockTry(p)
#else
#define SpinLockLock(p) OSSpinLockLock(p)
#define SpinLockUnlock(p) OSSpinLockUnlock(p)
+#define SpinLockTry(p) OSSpinLockTry(p)
#endif /* HAVE_WEAK_IMPORT */
+#define SPINLOCK_INIT OS_SPINLOCK_INIT
#else
/*
@@ -202,10 +213,13 @@ static void SpinLockLockInit(void) {
*/
typedef uint32_t OSSpinLock;
-extern void _spin_lock(OSSpinLock *lock);
-extern void _spin_unlock(OSSpinLock *lock);
+extern void _spin_lock(OSSpinLock *lock);
+extern void _spin_unlock(OSSpinLock *lock);
+extern int _spin_lock_try(OSSpinLock *lock);
#define SpinLockLock(p) _spin_lock(p)
#define SpinLockUnlock(p) _spin_unlock(p)
+#define SpinLockTry(p) _spin_lock_try(p)
+#define SPINLOCK_INIT 0
#endif /* HAVE_LIBKERN_OSATOMIC_H && HAVE_OSSPINLOCKLOCK */
@@ -213,8 +227,8 @@ extern void _spin_unlock(OSSpinLock *lock);
* These spinlocks lock access to the global notifier state.
*/
-static OSSpinLock notifierInitLock = 0;
-static OSSpinLock notifierLock = 0;
+static OSSpinLock notifierInitLock = SPINLOCK_INIT;
+static OSSpinLock notifierLock = SPINLOCK_INIT;
/*
* Macros abstracting notifier locking/unlocking
@@ -839,6 +853,9 @@ Tcl_WaitForEvent(timePtr)
*/
LOCK_NOTIFIER_INIT;
+ if (!notifierCount) {
+ Tcl_Panic("Tcl_WaitForEvent: notifier not initialized");
+ }
if (!notifierThread) {
int result;
pthread_attr_t attr;
@@ -862,7 +879,9 @@ Tcl_WaitForEvent(timePtr)
*/
LOCK_NOTIFIER;
-
+ if (!tsdPtr->runLoop) {
+ Tcl_Panic("Tcl_WaitForEvent: CFRunLoop not initialized");
+ }
waitForFiles = (tsdPtr->numFdBits > 0);
if (timePtr != NULL && timePtr->sec == 0 && timePtr->usec == 0) {
/*
diff --git a/unix/configure b/unix/configure
index 317eb2a..0ae6764 100755
--- a/unix/configure
+++ b/unix/configure
@@ -3588,7 +3588,7 @@ echo "$ac_t""$tcl_cv_ld_single_module" 1>&6
DL_LIBS=""
# Don't use -prebind when building for Mac OS X 10.4 or later only:
test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int($2)}'`" -lt 4 -a \
- "`echo "${CFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int($2)}'`" -lt 4 && \
+ "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int($2)}'`" -lt 4 && \
LDFLAGS="$LDFLAGS -prebind"
LDFLAGS="$LDFLAGS -headerpad_max_install_names"
echo $ac_n "checking if ld accepts -search_paths_first flag""... $ac_c" 1>&6
diff --git a/unix/tcl.m4 b/unix/tcl.m4
index 24a0899..cf27917 100644
--- a/unix/tcl.m4
+++ b/unix/tcl.m4
@@ -1622,7 +1622,7 @@ dnl AC_CHECK_TOOL(AR, ar)
DL_LIBS=""
# Don't use -prebind when building for Mac OS X 10.4 or later only:
test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \
- "`echo "${CFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4 && \
+ "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4 && \
LDFLAGS="$LDFLAGS -prebind"
LDFLAGS="$LDFLAGS -headerpad_max_install_names"
AC_CACHE_CHECK([if ld accepts -search_paths_first flag], tcl_cv_ld_search_paths_first, [