dillon@CORY.BERKELEY.EDU (Matt Dillon) (03/26/88)
I seem to remember somebody commenting that PutMsg() did not
always set the ln_Type field in the message to NT_MESSAGE...
I looked at the ROM code. The very first thing PutMsg does
is:
move.b #5,8(A1)
Which places NT_MESSAGE on the ln_Type field of the message.
Therefore, PutMsg() *always* does this. This means you can
write an equivalent for WaitIO() for messages, since ReplyMsg()
will modify the ln_Type to NT_REPLYMSG (NT_FREEMSG if there is not
replyport).
This example works for PA_SIGNAL replyports only. Note that I
check the type first. If the type is NT_MESSAGE, than the
message has not been replied yet and thus we can use Wait() since
we are guarenteed a signal. The Forbid()/Permit() pair is needed
for the routine to work properly with tasks which use exception
handlers (so the Wait signal is not prematurely removed in the
condition loop). The Disable()/Enable() pair is needed for the
routine to work in tandem with interrupts (an interrupt decides
to send a message to that particular port).
In my dealings with signals, I've always thought they should
reflect a certain amount of real information. thus, I restore
the signal if messages still exist on the port so the rest of the
program doesn't have to check the port first before going into
its master Wait() loop.
WaitMsg(msg)
MSG *msg;
{
register PORT *port = msg->mn_ReplyPort;
register long mask = 1 << port->mp_SigBit;
Forbid();
while (msg->mn_Node.ln_Type == NT_MESSAGE)
Wait(mask);
Permit();
Disable();
Remove(msg);
Enable();
if (port->mp_MsgList.lh_Head != (NODE *)&port->mp_MsgList.lh_Tail)
SetSignal(mask, mask);
}
This is something one would probably want to do in assembly.
-Matt
rminnich@udel.EDU (Ron Minnich) (03/29/88)
In article <8803260947.AA25241@cory.Berkeley.EDU> dillon@CORY.BERKELEY.EDU (Matt Dillon) writes: > I seem to remember somebody commenting that PutMsg() did not > always set the ln_Type field in the message to NT_MESSAGE... > I looked at the ROM code. The very first thing PutMsg does > is: > move.b #5,8(A1) > Which places NT_MESSAGE on the ln_Type field of the message. > Therefore, PutMsg() *always* does this. This means you can Well, what can i say. That was me who wrote that. And on my system, SendIO (which i thought called PutMsg) did not set the type to NT_MESSAGE. I had to set it by hand in internet.device, else the type was always NT_REPLYMSG. What is going on here? I don't know. ALl i know is that on my machine, in the driver, i had to jam the message type else it never changed back from NT_REPLYMSG. -- ron (rminnich@udel.edu)
dillon@CORY.BERKELEY.EDU (Matt Dillon) (03/29/88)
> Well, what can i say. That was me who wrote that. And on my >system, SendIO (which i thought called PutMsg) did not set the >type to NT_MESSAGE. I had to set it by hand in internet.device, >else the type was always NT_REPLYMSG. > What is going on here? I don't know. ALl i know is that >on my machine, in the driver, i had to jam the message type >else it never changed back from NT_REPLYMSG. Ah Hah! SendIO() doesn't call PutMsg(), it calls the BeginIO() entry for the device with IOF_QUICK cleared. The device then does whatever it wants. Some devices just AddTail() the request to some queue for processing by an interrupt, or do the request synchronously and then ReplyMsg() it. Thus, you must set the ln_Type field of the request to NT_MESSAGE yourself before dispatching it with SendIO(). (I.E. don't trust the device designers to have remembered that little detailed). I'll bet a lot of people got caught by that! -Matt