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")); } }
LOCAL void exec_freesignal(TEXECBASE *exec, struct TTask *task, TUINT signals) { TAPTR hal = exec->texb_HALBase; THALLock(hal, &task->tsk_TaskLock); if ((task->tsk_SigUsed & signals) != signals) TDBPRINTF(TDB_ERROR, ("signals freed did not match signals allocated\n")); task->tsk_SigFree |= signals; task->tsk_SigUsed &= ~signals; THALUnlock(hal, &task->tsk_TaskLock); }
static int tek_lib_exec_waitmsg(lua_State *L) { struct LuaExecTask *lexec = tek_lib_exec_check(L); struct TExecBase *TExecBase = lexec->exec; TTIME dt, *pdt = TNULL, destt, nowt; int narg; TAPTR hal = TExecBase->texb_HALBase; struct TMsgPort *port = TGetUserPort(TNULL); struct TNode *node; TUINT sig = TSetSignal(0, 0) & (TTASK_SIG_USER | TTASK_SIG_ABORT); tek_lib_exec_checkabort(L, lexec->exec, sig); dt.tdt_Int64 = luaL_optnumber(L, 1, 0) * 1000; if (dt.tdt_Int64) { TGetSystemTime(&destt); TAddTime(&destt, &dt); pdt = &dt; } for (;;) { THALLock(hal, &port->tmp_Lock); node = port->tmp_MsgList.tlh_Head.tln_Succ; if (node->tln_Succ == TNULL) node = TNULL; THALUnlock(hal, &port->tmp_Lock); if (node) break; sig = TWaitTime(pdt, TTASK_SIG_USER | TTASK_SIG_ABORT); tek_lib_exec_checkabort(L, lexec->exec, sig); if (sig == 0) break; if (pdt) { dt = destt; TGetSystemTime(&nowt); TSubTime(&dt, &nowt); } } narg = tek_lib_exec_getmsg(L); return tek_lib_exec_return_sig2string(L, sig, narg); }
LOCAL TUINT exec_allocsignal(TEXECBASE *exec, struct TTask *task, TUINT signals) { TUINT newsignal = 0; TAPTR hal = exec->texb_HALBase; THALLock(hal, &task->tsk_TaskLock); if (signals) { if ((signals & task->tsk_SigFree) == signals) newsignal = signals; } else { TINT x; TUINT trysignal = 0x00000001; for (x = 0; x < 32; ++x) { if (!(trysignal & TTASK_SIG_RESERVED)) { if (trysignal & task->tsk_SigFree) { newsignal = trysignal; break; } } trysignal <<= 1; } } task->tsk_SigFree &= ~newsignal; task->tsk_SigUsed |= newsignal; THALUnlock(hal, &task->tsk_TaskLock); return newsignal; }
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")); } }