+#include "OSThreads.h"
+#include "Schedule.h"
+
+#if defined(RTS_SUPPORTS_THREADS)
+/* Cheesy locking scheme while waiting for the
+ * RTS API to change.
+ */
+static Mutex alloc_mutex = INIT_MUTEX_VAR;
+static Condition alloc_cond = INIT_COND_VAR;
+#define INVALID_THREAD_ID ((OSThreadId)(-1))
+
+/* Thread currently owning the allocator */
+static OSThreadId c_id = INVALID_THREAD_ID;
+
+static StgPtr alloc(nat n)
+{
+ OSThreadId tid = osThreadId();
+ ACQUIRE_LOCK(&alloc_mutex);
+ if (tid == c_id) {
+ /* I've got the lock, just allocate() */
+ ;
+ } else if (c_id == INVALID_THREAD_ID) {
+ c_id = tid;
+ } else {
+ waitCondition(&alloc_cond, &alloc_mutex);
+ c_id = tid;
+ }
+ RELEASE_LOCK(&alloc_mutex);
+ return allocate(n);
+}
+
+static void releaseAllocLock(void)
+{
+ ACQUIRE_LOCK(&alloc_mutex);
+ /* Reset the allocator owner */
+ c_id = INVALID_THREAD_ID;
+ RELEASE_LOCK(&alloc_mutex);
+
+ /* Free up an OS thread waiting to get in */
+ signalCondition(&alloc_cond);
+}
+#else
+# define alloc(n) allocate(n)
+# define releaseAllocLock() /* nothing */
+#endif
+