Dear Hackers,
I've been studying the descriptions of IPC in the L4 Reference Manual (x86) and the L4 User Manual (MIPS) and would be grateful if someone could confirm to me that I've correctly understood some points which are not explicitly stated in those manuals. Here's are my hypotheses/deductions; please tell me if I'm right or wrong!
(1) Both the "send message descriptor" and the "receive message descriptor" allow in-line data, strings and fpages to be transmitted in both directions. In fact, the names are confusing and they might better be referred to as "client message descriptor" and "server message descriptor" as the only differences between them relate to the way the other party is addressed - plus one little optimisation for the case where a "receive message descriptor" wants to receive just an fpage.
(2) If you want to transmit some data from thread S to thread T, one way of doing it is to get thread S to do a SEND operation and thread T to do a RECEIVE FROM operation, but you could equally well get thread S to do a RECEIVE FROM and thread T to do a SEND, as the "RECEIVE FROM" and "SEND" IPC types have nothing to do with "receive" and "send", really.
(3) When you do a CALL operation, specifying both a "send message descriptor" and a "receive message descriptor" in the same system call, in most cases you probably only want to send data with the former and only receive data with the latter. Since both descriptors have space for both directions, you can use the same message descriptor as both send message descriptor and receive message descriptor, if you want. But you don't have to.
Edmund
"e" == edmundo edmundo@rano.demon.co.uk writes:
e> Dear Hackers, e> I've been studying the descriptions of IPC in the L4 Reference Manual e> (x86) and the L4 User Manual (MIPS)
Note that the User Manual uses the MIPS API in examples, but describes L4 in a mostly hardware-independent way.
e> and would be grateful if someone e> could confirm to me that I've correctly understood some points which e> are not explicitly stated in those manuals. Here's are my e> hypotheses/deductions; please tell me if I'm right or wrong!
e> (1) Both the "send message descriptor" and the "receive message e> descriptor" allow in-line data, strings and fpages to be transmitted e> in both directions. In fact, the names are confusing and they might e> better be referred to as "client message descriptor" and "server e> message descriptor" as the only differences between them relate to the e> way the other party is addressed - plus one little optimisation for e> the case where a "receive message descriptor" wants to receive just an e> fpage.
Not correct. A single IPC system call can have a send and a receive phase. The "send descriptor" describes what is to be sent, and the receive descriptor describes what can be received. For the IPC to be successful, the sender's send descriptor and the receiver's receive descriptor must be compatible.
Every successful IPC transfers some by-value data: the register part of the direct string (8 bytes on ix86, 64 bytes on R4x00). In addition, the following may be transferred, provided the send descriptor says so, and the receive descriptor allows it:
- a bigger direct string, provided that - the send descriptor points to a "message" struct specifying a non-zero number of dwords in the "send dope", and - the receive descriptor points to a "message" struct specifying a non-zero number of dwords in the "size dope", and - there is no error
- one or more indirect strings, provided that - the send descriptor points to a "message" struct specifying a non-zero number of strings in the "send dope", and - the receive descriptor points to a "message" struct specifying a non-zero number of strings in the "size dope", and - there is no error
- one or more page mappings or grants, provided that - the "m" bit is set in the send descriptor, and - the beginning of the sender's direct string (starting with the register part) contains at least one valid "send fpage", and - the receive descriptor either has the form of a valid "receive fpage", or points to a "message" struct containing a valid "receive fpage", and - there is no error
e> (2) If you want to transmit some data from thread S to thread T, one e> way of doing it is to get thread S to do a SEND operation and thread T e> to do a RECEIVE FROM operation, but you could equally well get thread e> S to do a RECEIVE FROM and thread T to do a SEND, as the "RECEIVE e> FROM" and "SEND" IPC types have nothing to do with "receive" and e> "send", really.
Incorrect, see above. A "SEND" IPC is a special case of the general IPC op, where a nil receive descriptor is specified, and thus no receive takes place. Similarly, a "RECEIVE FROM" is a special case of the general IPC op, where a nil send descriptor is specified, and thus no send takes place.
e> (3) When you do a CALL operation, specifying both a "send message e> descriptor" and a "receive message descriptor" in the same system e> call, in most cases you probably only want to send data with the e> former and only receive data with the latter.
Whether you want it or not, that's what you get at best. The send descriptor specifies the send operation, the receive descriptor specifies the receive operation of the IPC.
e> Since both descriptors have space for both directions, you can use e> the same message descriptor as both send message descriptor and e> receive message descriptor, if you want. But you don't have to.
Yes. Both, the send and receive descriptors can point to the same struct, which then describes both the send and receive part of the IPC. This is frequently used, and means that the direct string of the send gets overwritten by the receive, as get indirect strings (if any).
I'll put some of this into the user manual for further clarification.
Gernot -- Gernot Heiser ,--_|\ School of Computer Sci. & Engin. Phone: +61 2 9385 5156 / \ The University of NSW Fax: +61 2 9385 5995 _,--._* Sydney, Australia 2052 E-mail: G.Heiser@unsw.edu.au v http://www.cse.unsw.edu.au/~gernot PGP fingerprint: 94 1E B8 28 25 FD 7C 94 20 10 92 E5 0B FF 39 8F
Sorry, but I'm still confused ...
Both manuals have the same picture which shows a "string dope" consisting of four components:
- rcv string - rcv string size - snd string - snd string size
It looks as though the long part of any message (send or receive) may contain such string dopes.
So, does the message buffer of a send message descriptor contain these fields called "rcv string" and "rcv string size", and if so, how are they used?
Also, why does the User Manual say "Specifying send dope values less than the size dope values makes sense when the caller is willing to receive more data than it is sending"?
This is referring to the "Message Header" which is apparently found at the start of the "long part of the message" whose "presense is indicated by the message descriptor (snd msg/recv msg)".
So, in the case of a send message descriptor, what is the "size dope value" used for and why is it there? Similarly, what use is the "send dope value" in a receive message descriptor?
Edmund
PS. I'm getting this error now when I try to boot Fiasco:
... DD-L4/x86 microkernel ... space.cc:179: failed assertion `size == PAGE_SIZE'
I get this on a 686 and one 486 machine, but not on a different 486 machine. I don't know what the significant difference is between the two 486 machines; there are a lot of differences between them, including processor manufacturer (Intel?/AMD?) and quantity of memory (8 MB/32 MB). The 686 machine has a Cyrix processor and 64 MB.
"e" == edmundo edmundo@rano.demon.co.uk writes:
e> Sorry, but I'm still confused ... e> Both manuals have the same picture which shows a "string dope" e> consisting of four components:
e> - rcv string e> - rcv string size e> - snd string e> - snd string size
e> It looks as though the long part of any message (send or receive) may e> contain such string dopes.
It contains string dopes iff the msg size dope "strings" field is non-zero, and in that case, that field gives the number of string dopes the kernel expects to find.
e> So, does the message buffer of a send message descriptor contain these e> fields called "rcv string" and "rcv string size", and if so, how are e> they used?
e> Also, why does the User Manual say "Specifying send dope values less e> than the size dope values makes sense when the caller is willing to e> receive more data than it is sending"?
e> This is referring to the "Message Header" which is apparently found at e> the start of the "long part of the message" whose "presense is e> indicated by the message descriptor (snd msg/recv msg)".
e> So, in the case of a send message descriptor, what is the "size dope e> value" used for and why is it there? Similarly, what use is the "send e> dope value" in a receive message descriptor?
This is to support using the same message structure for the send and the receive part (i.e. pointing "snd descriptor" and "rcv descriptor" to the same address). In that case, the send dope tells the kernel how much is to be sent, while the size dope tells it how much space there is to accommodating data to be received.
Similarly, a sting dope consists of a send and a receive part, the one describing the strings to be sent (if any), the other describing the buffers for strings to be received (if any).
I've added comments along these lines to the user manual. Please check to see if it's clearer now.
Gernot -- Gernot Heiser ,--_|\ School of Computer Sci. & Engin. Phone: +61 2 9385 5156 / \ The University of NSW Fax: +61 2 9385 5995 _,--._* Sydney, Australia 2052 E-mail: G.Heiser@unsw.edu.au v http://www.cse.unsw.edu.au/~gernot PGP fingerprint: 94 1E B8 28 25 FD 7C 94 20 10 92 E5 0B FF 39 8F
l4-hackers@os.inf.tu-dresden.de