Simon Cozens wrote:
> 
> On Tue, Jan 16, 2001 at 08:49:57PM +0000, David L. Nicol wrote:
> > http://www.eros-os.org/pipermail/eros-arch/2001-January/002683.html
> 
> Uhm. That's not *why* they're doing it, it's how they're doing it.
> Did you get the right URL?

I thought I did -- now that message is

http://www.eros-os.org/pipermail/eros-arch/2001-January/002666.html

maybe pipermail is dynamic and gives new numbers each time it generates
a list, that would suck.

Here's the one I meant to give a pointer to:


> [EROS-Arch] Conversion to C
> 
> Jonathan S. Shapiro [EMAIL PROTECTED]
> Sat, 13 Jan 2001 10:47:19 -0500 
> 
>      Previous message: [EROS-Arch] Conversion to C 
>      Next message: [EROS-Arch] Conversion to C 
>      Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] 
> 
> 
> 
> > Pardon my ignorance.  I haven't been following the list too
> > closely to understand the reasons EROS is being rewritten
> > in C.
> 
> I now have a more thorough answer, so I'm replying in detail. For a record
> of the earlier conversation on this topic, see the email archives at
> 
>     http://www.eros-os.org/mailman/listinfo
> 
> The messages are archived in the eros-arch archive. Look for the early
> messages with the "Conversion to C" subject.
> 
> > Is it a performance issue?
> 
> Indirectly, C++ is a performance problem. The C++ compiler generates code
> for exceptions unless this feature is disabled. The exception handling code
> has performance consequences. In particular, it restricts various kinds of
> code motion that the optimizer would like to perform.
> 
> In a more immediate sense, however, the exception handling code also leads
> to greater contention in the instruction cache, and we are fighting fairly
> hard to keep the entire EROS working set in a small fraction of the I-cache.
> The EROS kernel does not generate exceptions (ever). Unfortunately, the
> compiler must compile under the assumption that operator new/ will be called
> somewhere and must therefore generate exception handling code. Typically,
> about 1/3 to 1/2 of the total code generated is exception handling code.
> Bjarne argues that this code is never executed, and he is mostly correct.
> Unfortunately, this code is interspersed with the ordinary code, so it
> changes the cache contention behavior. [Note that this could be fixed by
> collecting the exception code into a seperate code segment at the end of the
> application, and perhaps I should suggest this to the G++ team.]
> 
> At the moment, we disable exception generation by passing extra options to
> the G++ compiler. The problem with this is that we are no longer compiling
> in standard C++. We are compiling in an odd extension that happens to be
> supported by G++. I am concerned both about code portability and about code
> clarity.
> 
> Finally, name mangling schemes in C++ are not consistent across compilers,
> so writing assembly code that calls C++ with some semblance of portability
> is a problem. You can call a procedure that uses C linkage convention easily
> enough, and this can call the corresponding C++ procedure, but the extra
> call is undesirable overhead.
> 
> > Did you find that even with
> > C++ your code was largely functional?
> 
> No, but it is almost entirely *procedural*, which is probably what you
> meant. While there are many member functions, these could equally well be
> coded as C procedures taking a struct pointer. The current kernel makes
> essentially NO use of inheritance, which is what you would expect in a
> microkernel -- if you have complex enough structure to need inheritance, you
> aren't building a microkernel.
> 
> The one place where inheritance was used (there is a Link structure for
> doubly linked list chains, but this doesn't qualify as serious) was in the
> driver code. Here it proved to be a mistake, because drivers need something
> more flexible -- something much closer to Java-style interface pointers. The
> difficulty here is that the C++ type checking is actually too strong. You
> can declare a pointer to a member function, but there is no way to declare
> "pointer to object s.t. object has a member function of type T". In fact,
> what you really want to declare is a pair of the form
> 
>     (X *, RetType (*X::someFunc(...args...))
> 
> without being obliged to ever say what X would be. Note that the compiler
> doesn't need to know. It really only needs to know that X* will be an
> appropriate thing to use as a /this/ pointer in an invocation of
> X::someFunc(). What's needed here is something like ML pattern matching, and
> C++ doesn't have it.
> 
> The result is that there is no way to capture interface dispatch gracefully.
> In C, it is easier to do this because you can declare X* to be a void
> pointer. Actually, what is really going on in this case is a violation of
> the static type system in C++.  In summary, using inheritance was a mistake.
> 
> A secondary issue concerns the Process class. The vast majority of the
> kernel code (not surprisingly) is concerned in some form with manipulating
> processes, and in particular with manipulating the state of the *current*
> process. At the moment, most of this code is written using member functions,
> and this is a mistake. The cost is that the /this/ pointer must be copied
> around on the stack a lot, when the code in this case should really be using
> a per-processor global variable. This may not seem like a big deal, but it
> really does add up. It also serves to significantly reduce clarity of the
> code.
> 
> > I guess it interests me because of the general premise that
> > OO programming with an OO language produces a
> > more flexible and reuseable code base.  Is this premise not
> > necessary when considering microkernels?
> 
> If you look at it in a certain way, a microkernel is what you get after you
> remove all of the code that can be modularized. What is left, almost by
> definition, is the stuff that is so hopelessly and intimately
> self-referential that it is almost certainly not reusable in any way at all.
> Arguably, if it *is* reusable you should still be taking things out.
> 
> Flexibility doesn't come from using an OO language. Flexibility is a
> consequence of a clean architecture and design that has been realized in
> appropriately structured code using appropriate interfaces. For many
> (perhaps mosst) programmers, using an OO language helps them achieve this
> kind of structure and interface discipline. Kernel hackers (arguably) work
> on some of the most challenging and difficult code out there -- there is no
> debugger, there are gobs and gobs of race conditions, there are hundreds of
> things that can go wrong, and your primary diagnostic for impending doom is
> that the machine spontaneously reboots. At the risk of a gross
> generalization, there are two kinds of kernel programmers: kernel
> programmers who should be doing some other kind of programming and kernel
> programmers who already have a firm grasp on how to structure code and
> interfaces and (most difficult) have a sense of taste that lets them
> correctly identify the rare occasions when violating the rules results in a
> clearer system -- the current process pointer might be an example. [Note
> that I don't claim to have such taste reliably.]  Hm. Perhaps I should add a
> third category for kernel programmers in training, but hopefully you get the
> point.
> 
> > I'm new to OOP, and I haven't had the traditional CS training.  I'm
> > learning most of my programming skills from experience and my own
> > self-training, so any input from you would be greatly appreciated.
> 
> At the time I started the EROS project, I had recently completed writing "A
> C++ Toolkit", which was the first book on building reusable code in C++. At
> the beginning, I expected (as you did) that there would be reuse in the EROS
> code. I also liked the style of C++, and features like inlining were not yet
> widely available in C compilers. So I used C++.
> 
> I think that OO programming remains a good idea, and that for an awful lot
> of code it provides an exceptionally useful tool. Bjarne has never proposed
> C++ as a universal solution, and I no longer think that it is an appropriate
> tool for Coperating system construction. I have spoken to a number of other
> kernel designers who chose to use C++, and they almost universally say that
> if they had it to do again they would do the code in C.
> 
> 
> There is a final reason for the rewrite that doesn't really have anything to
> do with C++. I would ultimately like for EROS to be a teaching tool as well
> as a practical system. In doing the rewrite, I intend to clean up, simplify,
> and redocument the code. This has inherent value, but of course, it could
> also be done by rewriting to C++. In this case, I think C is a better
> choice.
> 
> 
> Jonathan

Reply via email to