just curious

Peter da Silva peter-200306 at taronga.com
Fri Jul 18 06:35:41 PDT 2003


Gunther Nikl  wrote:
>  In which way are the messages changed? Do you refer to ln_Type or some
>  private data in an extended message?

As I understand it the Dragonfly API allows for a message port to have any Send() function it wants, so for intra-address-space calls there's no reason to do anything but call the remote method directly or change a couple of pointers to put the message on a queue and return EASYNC. That means you could change the message (for example, adding more elements to a list) before it's actually read.

Even if the operation is atomic (as it could be in this case: lastmsg->next = newmsg) there's still a potential for race conditions if the receiving code accesses that element twice.

If the Send() method changes to a copy (say, a protection barrier is added) there's no race condition but now changing the local copy has no effect... messages start dropping.

Looking at the code I posted, it would probably be better to have separate calls for Queue()... Commit() or Send() than have message lists assembled outside the API. Queue() could probably be implemented with a macro in the first pass, with Commit(ASYNC) just being a series of Send() calls, and Commit(SYNC) always returns EASYNC if there's more than one queued message.

Maybe it would be better to have the SYNC/ASYNC flag in the Queue() call. That would allow Dragonfly to grab any pending ASYNC messages and toss them over the memory barrier whenever a syscall happened... it's easier to code for, too, and you're letting the OS know you don't care if there's some latency when you Queue(ASYNC) ... but as soon as you Send() or Wait() or Commit() over they go.

In fact I think you have to do things this way, because otherwise the program will have too hard a time keeping track of when it can reuse buffers and the like.







More information about the Kernel mailing list