Linked by Hadrien Grasland on Sun 29th May 2011 09:42 UTC
OSNews, Generic OSes It's funny how trying to have a consistent system design makes you constantly jump from one area of the designed OS to another. I initially just tried to implement interrupt handling, and now I'm cleaning up the design of an RPC-based daemon model, which will be used to implement interrupt handlers, along with most other system services. Anyway, now that I get to something I'm personally satisfied with, I wanted to ask everyone who's interested to check that design and tell me if anything in it sounds like a bad idea to them in the short or long run. That's because this is a core part of this OS' design, and I'm really not interested in core design mistakes emerging in a few years if I can fix them now. Many thanks in advance.
Thread beginning with comment 475753
To view parent comment, click here.
To read all comments associated with this story, please click here.
RE[9]: RPC considered harmful
by Alfman on Thu 2nd Jun 2011 18:44 UTC in reply to "RE[8]: RPC considered harmful"
Alfman
Member since:
2011-01-28

Brendan,

"You could speed it up by having a per-process "thread cache". Rather than actually destroying a thread, you could pretend to destroy it and put it into a "disused thread pool" instead, and then recycle these existing/disused threads when a new thread needs to be created."


Yes, many MT devs use this design, I use it in my async package because dynamic thread creation via pthreads is so costly. But I do wonder if it is inherently slow, or just that pthreads/linux are inefficient at it.

In theory, one could just alloc a stack, register swap area, TLS and accounting structure (possibly in one call to malloc). Then we add this structure to a linked list of threads and fire off the thread function.

It wouldn't even be necessary to coordinate the above with other CPUs if each CPU had it's own process thread "list".

It wouldn't even be necessary to coordinate with any syscalls (if userspace could be trusted with managing the thread list within it's own process, as long as the process only endangers itself, this might not be an issue).

The entire thread lifecycle could take place on a single CPU with no inter CPU synchronization at all.

Now obviously, there would need to be a separate mechanism to migrate threads between CPUs. But this migration process might be able to take the synchronization hits once per cycle, instead of once per thread.

During an interrupt (pre-emptive threads), an explicit yield, or a blocking OS call, the OS would swap the cpu state and start another thread in the queue.

That summerizes the lightest thread implementation I can conceive of, and if it worked that way, I would think the performance between a thread pool and ordinary thread creation might be a wash (particularly with an efficient or pooled malloc).



"Most things aren't streams of bytes though - they're streams of 'some sort of data structure'."

The lack of message boundaries has always been a major design flaw in my opinion.

There's no reason (other than legacy design) that pipes shouldn't allow us to send discrete packets. It should be possible for high level application code to specify boundaries (even if very large packets still span multiple read requests).

This deficiency has lead to the same design patterns being reimplemented over and over again inside of network applications needing to reassemble messages from the stream.

"Also, for messaging each message typically has a "message type" associated with it. This means that the same receiver can handle many different things at the same time"

Yes, but if the OS has explicit support for RPC, wouldn't the need for discrete messages and message types be largely eliminated?

Reply Parent Score: 2