Mattise IPC Specification

This forums is for OS project announcements including project openings, new releases, update notices, test requests, and job openings (both paying and volunteer).
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Mattise IPC Specification

Post by pcmattman »

I've just drafted up the initial version of the Mattise IPC Specification. It's really basic and hasn't been implemented yet, but I think it's worth putting it up here for you to look at and give constructive criticism about.

It's here.

(the conversion from the Word document into a webpage didn't work quite as nicely as I'd hoped, but it's good enough)
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

SYSCALL_RECVMSG

This system call takes the first message off the message queue and fills a passed buffer with its data. This is a non-blocking call.

Arguments

EAX: 28d
EDI: the address of a local buffer in which to place the new message.
EDX: the maximum count of octets that can be placed into the local buffer.

Return Values
EBX: 0
Under the assumption that this is indeed a non-blocking call, I miss what would happen if there were no messages? (the buffer isn't filled?), and how to determine that the message received is the same as the one queried by a previous call to message size.
In either case, I'd return a length of the message (or -1 if none), so that we can pop messages non-blocking and with enough information to allow concurrent receivers.

A second issue is one that has to do when the passed buffer is too small to hold the entire message - will the remainder of the message get discarded, is it kept for subsequent read calls, or will it provide an error code to tell the user that the buffer is too small?
int mattiseRecvMessage( struct RecvMsgData* dat )

Header
#include <mmsg.h>

Parameters
dat: a pointer to a buffer to receive an information structure about the received message

Return Value
The total size of the message data.
I have to assume that the caller allocated *dat, and that the callee allocates and fills dat->msgbuff.
To ease the work on the programmer, a set of helpers should be added, a bit like the following:

Code: Select all

int matisseRecvMessage(RecvMsgData * dat);
RecvMsgData * matisseAllocMessage();
void matisseFreeMessage(RecvMsgData * dat);
char * mattisseGetMessageContents(RecvMsgData * dat);
Also, a set of blocking calls are useful to have been provided to the software developer rather than needing to be written manually.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

Combuster wrote:Under the assumption that this is indeed a non-blocking call, I miss what would happen if there were no messages? (the buffer isn't filled?), and how to determine that the message received is the same as the one queried by a previous call to message size.
The system call does not return a failure code if no messages. I might have to revise that so that I don't try to pop an invalid message off the list.
In either case, I'd return a length of the message (or -1 if none), so that we can pop messages non-blocking and with enough information to allow concurrent receivers.
Sounds like a good idea, I was thinking that message receives would be facilitated through the mattiseRecvMessage which performs all this automatically.
A second issue is one that has to do when the passed buffer is too small to hold the entire message - will the remainder of the message get discarded, is it kept for subsequent read calls, or will it provide an error code to tell the user that the buffer is too small?
The system call will put -1 into EBX (this was revised during implementation and I have not updated the spec yet) if the message buffer is too small.
I have to assume that the caller allocated *dat, and that the callee allocates and fills dat->msgbuff.
Again, this is about to be re-implemented (will have to revise the spec) - I probably will have functionality to allocate the message for you.
Also, a set of blocking calls are useful to have been provided to the software developer rather than needing to be written manually.
I'll look into implementing a set of blocking calls. The only reason I haven't used them is because all system calls are via an interrupt (that isn't a trap gate) and doing a while loop with an interrupt call each time doesn't really work too well.

The reason I don't use trap gates is to give a rudimentary form of mutual exclusion - for example only one process can write to the console at once.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

OK, I've just revised the spec and uploaded the changes to that same location.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

I have one remark left:
SYSCALL_RECVMSG
(...)
EBX: -1 if an error was encountered
Wouldn't it be useful to be able to determine wether the error was due to no message present, or that the message was too long?
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Combuster: you could just set errno with ETOOLONG, EEXIST etc?
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

JamesM wrote:Combuster: you could just set errno with ETOOLONG, EEXIST etc?
These are kernel calls, errno is a userland (libc) thing.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

Wouldn't it be useful to be able to determine wether the error was due to no message present, or that the message was too long?
I'll change the return codes to have different values for different errors, instead of just "-1" (ie. -1 = message too small, -2 = no messages, etc...).
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Combuster: my crt0 tells the kernel where errno is. So the kernel can set errno itself. It takes a lot of complexity out of the libc wrapper I find.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

my crt0 tells the kernel where errno is. So the kernel can set errno itself.
:shock: You sure you don't need a check on your specifications? That's about the ugliest hack I've heard of in a long time... :shock:
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Heh, doesn't seem that ugly to me. Matter of personal opinion I suppose - I use syscall/sysret and my stubs only support the returning of one value (so I can't stick the errno in another register for example).
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

Combuster wrote:
my crt0 tells the kernel where errno is. So the kernel can set errno itself.
:shock: You sure you don't need a check on your specifications? That's about the ugliest hack I've heard of in a long time... :shock:
Agreed - I don't see why a system call needs to set errno... You check errno after finding out a function call just failed, if you're coding assembly why would you need to worry about errno?
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Well, errno needs to be set with the appropriate value when a syscall fails, *somehow*. As far as I can see, there are only 3 ways of doing this.

1. Setting it in the kernel, when the function call fails.
2. Returning the value errno should take (ETOOLONG, etc) as well as the normal function "failed" return value (which differs depending on the function, if you're going by POSIX standards)
3. Returning the new value of errno encoded into the return value (negated or something) and hoping that it doesn't clash with a valid return value.

Many people opt for 2. I couldnt, so I opted for 1.

JamesM
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

errno needs to be set with the appropriate value when a syscall fails
It shouldn't. As I said before, errno is part of the C library, NOT of the kernel. if you want to report error codes from the kernel, you should use a kernel-specific function.
Even the C99 standard suggests that errno is restricted for use by the C library. Interfering kernel calls might therefore break C99 compliance which is a Bad Thing.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

A system call is called, for example, like this:

Code: Select all

uint32_t ebx;
asm( "int $0x80" : "=b" (ebx) : "a" (27) /*args...*/ );

// ebx = error code on failure, 0 if success
You don't use errno because then assembly language programs (assuming the programmer does not link in system libraries) would not be able to detect reasons for failure...

On the other hand, my libc functionality for message passing can set errno, based on what it reads from the return value of the syscall.

It is your choice how you make it all work though...
Post Reply