+/* A helper structure for data local to a thread, which is not pointer-sized.
+ *
+ * Originally, all layouting of these fields was done manually in C code
+ * with pointer arithmetic. We let the C compiler figure it out now.
+ *
+ * (Why is this not part of `struct thread'? Because that structure is
+ * declared using genesis, and we would run into issues with fields that
+ * are of unknown length.)
+ */
+struct nonpointer_thread_data
+{
+#ifdef LISP_FEATURE_SB_THREAD
+ os_sem_t state_sem;
+ os_sem_t state_not_running_sem;
+ os_sem_t state_not_stopped_sem;
+# ifdef LISP_FEATURE_SB_SAFEPOINT
+ /* For safepoint-based builds, together with thread's
+ * csp_around_foreign_call pointer target, thread_qrl(thread) makes
+ * `quickly revokable lock'. Unlike most mutexes, this one is
+ * normally locked; by convention, other thread may read and use the
+ * thread's FFI-CSP location _either_ when the former holds the
+ * lock(mutex) _or_ when page permissions for FFI-CSP location were
+ * set to read-only.
+ *
+ * Combined semantic of QRL is not the same as the semantic of mutex
+ * returned by this function; rather, the mutex, when released by the
+ * owning thread, provides an edge-triggered notification of QRL
+ * release, which is represented by writing non-null
+ * csp_around_foreign_call.
+ *
+ * When owner thread is `in Lisp' (i.e. a heap mutator), its FFI-CSP
+ * contains null, otherwise it points to the top of C stack that
+ * should be preserved by GENCGC. If another thread needs to wait for
+ * mutator state change with `in Lisp => in C' direction, it disables
+ * FFI-CSP overwrite using page protection, and takes the mutex
+ * returned by thread_qrl(). Page fault handler normally ends up in a
+ * routine releasing this mutex and waiting for some appropriate
+ * event to take it back.
+ *
+ * This way, each thread may modify its own FFI-CSP content freely
+ * without memory barriers (paying with exception handling overhead
+ * whenever a contention happens). */
+ pthread_mutex_t qrl_lock;
+# endif
+#else
+ /* An unused field follows, to ensure that the struct in non-empty
+ * for non-GCC compilers. */
+ int unused;
+#endif
+};
+
+extern struct thread *all_threads;