+ * In some ways it makes sense to continue to hold the thread-suspend
+ * lock while we issue the wakeup broadcast. It allows us to complete
+ * one operation before moving on to the next, which simplifies the
+ * thread activity debug traces.
+ *
+ * This approach caused us some difficulty under Linux, because the
+ * condition variable broadcast not only made the threads runnable,
+ * but actually caused them to execute, and it was a while before
+ * the thread performing the wakeup had an opportunity to release the
+ * thread-suspend lock.
+ *
+ * This is a problem because, when a thread tries to acquire that
+ * lock, it times out after 3 seconds. If at some point the thread
+ * is told to suspend, the clock resets; but since the VM is still
+ * theoretically mid-resume, there's no suspend pending. If, for
+ * example, the GC was waking threads up while the SIGQUIT handler
+ * was trying to acquire the lock, we would occasionally time out on
+ * a busy system and SignalCatcher would abort.
+ *
+ * We now perform the unlock before the wakeup broadcast. The next
+ * suspend can't actually start until the broadcast completes and
+ * returns, because we're holding the thread-suspend-count lock, but the
+ * suspending thread is now able to make progress and we avoid the abort.
+ *
+ * (Technically there is a narrow window between when we release
+ * the thread-suspend lock and grab the thread-suspend-count lock.
+ * This could cause us to send a broadcast to threads with nonzero
+ * suspend counts, but this is expected and they'll all just fall
+ * right back to sleep. It's probably safe to grab the suspend-count
+ * lock before releasing thread-suspend, since we're still following
+ * the correct order of acquisition, but it feels weird.)
+ */
+
+ LOG_THREAD("threadid=%d: ResumeAll waking others\n", self->threadId);
+ unlockThreadSuspend();
+
+ /*