LOCAL void exec_returnmsg(TEXECBASE *exec, TAPTR mem, TUINT status) { struct TMessage *msg = TGETMSGPTR(mem); struct TMsgPort *replyport = msg->tmsg_RPort; if (replyport) { TAPTR hal = exec->texb_HALBase; THALLock(hal, &replyport->tmp_Lock); TAddTail(&replyport->tmp_MsgList, (struct TNode *) msg); msg->tmsg_Flags = status; if (replyport->tmp_Hook) TCALLHOOKPKT(replyport->tmp_Hook, replyport, (TTAG) msg); THALUnlock(hal, &replyport->tmp_Lock); THALSignal(hal, &replyport->tmp_SigTask->tsk_Thread, replyport->tmp_Signal); } else { exec_Free(exec, mem); /* free one-way msg transparently */ TDBPRINTF(TDB_TRACE,("message returned to memory manager\n")); } }
static TBOOL hal_replytimereq(struct TTimeRequest *tr) { TBOOL success = TFALSE; struct TMessage *msg = TGETMSGPTR(tr); struct TMsgPort *mp = msg->tmsg_RPort; CRITICAL_SECTION *mplock = THALGetObject((TAPTR) &mp->tmp_Lock, CRITICAL_SECTION); if (TryEnterCriticalSection(mplock)) { struct TTask *sigtask = mp->tmp_SigTask; struct HALThread *t = THALGetObject((TAPTR) &sigtask->tsk_Thread, struct HALThread); if (TryEnterCriticalSection(&t->hth_SigLock)) { tr->ttr_Req.io_Error = 0; msg->tmsg_Flags = TMSG_STATUS_REPLIED | TMSGF_QUEUED; TAddTail(&mp->tmp_MsgList, &msg->tmsg_Node); if (mp->tmp_Signal & ~t->hth_SigState) { t->hth_SigState |= mp->tmp_Signal; SetEvent(t->hth_SigEvent); } LeaveCriticalSection(&t->hth_SigLock); success = TTRUE; } LeaveCriticalSection(mplock); } return success; }
LOCAL TUINT exec_sendmsg(TEXECBASE *TExecBase, struct TTask *task, struct TMsgPort *port, TAPTR mem) { TAPTR hal = TExecBase->texb_HALBase; struct TMessage *msg = TGETMSGPTR(mem); TAPTR reply; /* replyport is task's syncport */ msg->tmsg_RPort = &task->tsk_SyncPort; /* sender is local address space */ msg->tmsg_Sender = TNULL; THALLock(hal, &port->tmp_Lock); TAddTail(&port->tmp_MsgList, (struct TNode *) msg); msg->tmsg_Flags = TMSG_STATUS_SENT | TMSGF_QUEUED; if (port->tmp_Hook) TCALLHOOKPKT(port->tmp_Hook, port, (TTAG) msg); THALUnlock(hal, &port->tmp_Lock); THALSignal(hal, &port->tmp_SigTask->tsk_Thread, port->tmp_Signal); for (;;) { THALWait(TExecBase->texb_HALBase, task->tsk_SyncPort.tmp_Signal); reply = TGetMsg(msg->tmsg_RPort); if (reply) { TUINT status = msg->tmsg_Flags; TDBASSERT(99, reply == mem); msg->tmsg_Flags = 0; return status; } TDBPRINTF(TDB_FAIL,("signal on syncport, no message!\n")); } }
EXPORT void hal_beginio(struct THALBase *hal, struct TTimeRequest *req) { struct HALSpecific *hws = hal->hmb_Specific; TAPTR exec = hws->hsp_ExecBase; TTIME curtime; TINT64 x = 0; switch (req->ttr_Req.io_Command) { /* execute asynchronously */ case TTREQ_WAITLOCALDATE: /* microseconds west of GMT: */ x = hal_getdstfromlocaldate(hal, &req->ttr_Data.ttr_Date); x *= 1000000; case TTREQ_WAITUNIVERSALDATE: x += req->ttr_Data.ttr_Date.tdt_Int64; x -= 11644473600000000ULL; req->ttr_Data.ttr_Date.tdt_Int64 = x; #ifndef USE_MMTIMER hal_getsystime(hal, &curtime); TSubTime(&req->ttr_Data.ttr_Time, &curtime); #endif goto addtimereq; case TTREQ_WAITTIME: #ifdef USE_MMTIMER hal_getsystime(hal, &curtime); TAddTime(&req->ttr_Data.ttr_Time, &curtime); #endif addtimereq: { #ifdef USE_MMTIMER struct TMessage *msg = TGETMSGPTR(req); EnterCriticalSection(&hws->hsp_DevLock); msg->tmsg_Flags = TMSG_STATUS_SENT | TMSGF_QUEUED; msg->tmsg_RPort = req->ttr_Req.io_ReplyPort; TAddTail(&hws->hsp_ReqList, (struct TNode *) req); LeaveCriticalSection(&hws->hsp_DevLock); #else TExecPutMsg(exec, TExecGetUserPort(exec, hws->hsp_DevTask), req->ttr_Req.io_ReplyPort, req); #endif return; } /* execute synchronously */ default: case TTREQ_GETUNIVERSALDATE: { TINT timezone_bias; hal_getsysdate(hal, &req->ttr_Data.ttr_Date, &timezone_bias); break; } case TTREQ_GETLOCALDATE: hal_getsysdate(hal, &req->ttr_Data.ttr_Date, TNULL); break; case TTREQ_GETSYSTEMTIME: hal_getsystime(hal, &req->ttr_Data.ttr_Time); break; #if 0 case TTREQ_GETDSFROMDATE: req->ttr_Data.ttr_DSSec = hal_dsfromdate(hal, &req->ttr_Data.ttr_Date.ttr_Date); break; #endif } req->ttr_Req.io_Error = 0; if (!(req->ttr_Req.io_Flags & TIOF_QUICK)) { /* async operation indicated; reply to self */ TExecReplyMsg(exec, req); } }