+FN_(waitWritezh_fast)
+{
+ FB_
+ /* args: R1.i */
+ ASSERT(CurrentTSO->why_blocked == NotBlocked);
+ CurrentTSO->why_blocked = BlockedOnWrite;
+ CurrentTSO->block_info.fd = R1.i;
+ ACQUIRE_LOCK(&sched_mutex);
+ APPEND_TO_BLOCKED_QUEUE(CurrentTSO);
+ RELEASE_LOCK(&sched_mutex);
+ JMP_(stg_block_noregs);
+ FE_
+}
+
+FN_(delayzh_fast)
+{
+#ifdef mingw32_TARGET_OS
+ StgAsyncIOResult* ares;
+ unsigned int reqID;
+#else
+ StgTSO *t, *prev;
+ nat target;
+#endif
+ FB_
+ /* args: R1.i (microsecond delay amount) */
+ ASSERT(CurrentTSO->why_blocked == NotBlocked);
+ CurrentTSO->why_blocked = BlockedOnDelay;
+
+ ACQUIRE_LOCK(&sched_mutex);
+#ifdef mingw32_TARGET_OS
+ /* could probably allocate this on the heap instead */
+ ares = (StgAsyncIOResult*)RET_STGCALL2(P_,stgMallocBytes,sizeof(StgAsyncIOResult), "delayzh_fast");
+ reqID = RET_STGCALL1(W_,addDelayRequest,R1.i);
+ ares->reqID = reqID;
+ ares->len = 0;
+ ares->errCode = 0;
+ CurrentTSO->block_info.async_result = ares;
+ /* Having all async-blocked threads reside on the blocked_queue simplifies matters, so
+ * change the status to OnDoProc & put the delayed thread on the blocked_queue.
+ */
+ CurrentTSO->why_blocked = BlockedOnDoProc;
+ APPEND_TO_BLOCKED_QUEUE(CurrentTSO);
+#else
+ target = ((R1.i + TICK_MILLISECS*1000-1) / (TICK_MILLISECS*1000)) + getourtimeofday();
+ CurrentTSO->block_info.target = target;
+
+ /* Insert the new thread in the sleeping queue. */
+ prev = NULL;
+ t = sleeping_queue;
+ while (t != END_TSO_QUEUE && t->block_info.target < target) {
+ prev = t;
+ t = t->link;
+ }
+
+ CurrentTSO->link = t;
+ if (prev == NULL) {
+ sleeping_queue = CurrentTSO;
+ } else {
+ prev->link = CurrentTSO;
+ }
+#endif
+ RELEASE_LOCK(&sched_mutex);
+ JMP_(stg_block_noregs);
+ FE_
+}
+
+#ifdef mingw32_TARGET_OS
+FN_(asyncReadzh_fast)
+{
+ StgAsyncIOResult* ares;
+ unsigned int reqID;
+ FB_
+ /* args: R1.i = fd, R2.i = isSock, R3.i = len, R4.p = buf */
+ ASSERT(CurrentTSO->why_blocked == NotBlocked);
+ CurrentTSO->why_blocked = BlockedOnRead;
+ ACQUIRE_LOCK(&sched_mutex);
+ /* could probably allocate this on the heap instead */
+ ares = (StgAsyncIOResult*)RET_STGCALL2(P_,stgMallocBytes,sizeof(StgAsyncIOResult), "asyncReadzh_fast");
+ reqID = RET_STGCALL5(W_,addIORequest,R1.i,FALSE,R2.i,R3.i,(char*)R4.p);
+ ares->reqID = reqID;
+ ares->len = 0;
+ ares->errCode = 0;
+ CurrentTSO->block_info.async_result = ares;
+ APPEND_TO_BLOCKED_QUEUE(CurrentTSO);
+ RELEASE_LOCK(&sched_mutex);
+ JMP_(stg_block_async);
+ FE_
+}
+
+FN_(asyncWritezh_fast)
+{
+ StgAsyncIOResult* ares;
+ unsigned int reqID;
+ FB_
+ /* args: R1.i */
+ /* args: R1.i = fd, R2.i = isSock, R3.i = len, R4.p = buf */
+ ASSERT(CurrentTSO->why_blocked == NotBlocked);
+ CurrentTSO->why_blocked = BlockedOnWrite;
+ ACQUIRE_LOCK(&sched_mutex);
+ ares = (StgAsyncIOResult*)RET_STGCALL2(P_,stgMallocBytes,sizeof(StgAsyncIOResult), "asyncWritezh_fast");
+ reqID = RET_STGCALL5(W_,addIORequest,R1.i,TRUE,R2.i,R3.i,(char*)R4.p);
+ ares->reqID = reqID;
+ ares->len = 0;
+ ares->errCode = 0;
+ CurrentTSO->block_info.async_result = ares;
+ APPEND_TO_BLOCKED_QUEUE(CurrentTSO);
+ RELEASE_LOCK(&sched_mutex);
+ JMP_(stg_block_async);
+ FE_
+}
+
+FN_(asyncDoProczh_fast)
+{
+ StgAsyncIOResult* ares;
+ unsigned int reqID;
+ FB_
+ /* args: R1.i = proc, R2.i = param */
+ ASSERT(CurrentTSO->why_blocked == NotBlocked);
+ CurrentTSO->why_blocked = BlockedOnDoProc;
+ ACQUIRE_LOCK(&sched_mutex);
+ /* could probably allocate this on the heap instead */
+ ares = (StgAsyncIOResult*)RET_STGCALL2(P_,stgMallocBytes,sizeof(StgAsyncIOResult), "asyncDoProczh_fast");
+ reqID = RET_STGCALL2(W_,addDoProcRequest,R1.p,R2.p);
+ ares->reqID = reqID;
+ ares->len = 0;
+ ares->errCode = 0;
+ CurrentTSO->block_info.async_result = ares;
+ APPEND_TO_BLOCKED_QUEUE(CurrentTSO);
+ RELEASE_LOCK(&sched_mutex);
+ JMP_(stg_block_async);
+ FE_
+}
+#endif
+