“Previously, we have presented one of the two opensource licensed projects related to creating a C# kernel. Now it’s the time to complete the set by rightfully presenting SharpOS, an effort to build a GPL version 3 + runtime exception licensed system, around a C# kernel of their own design. It is my pleasure and priviledge to host a set of questions and answers from four active developers of SharpOS, that is William Lahti, Bruce Markham, Mircea – Cristian Racasan and Sander van Rossen in order to get some insight into what they are doing with SharpOS, their goals, their different design and inspiration.”
I keep reading about all these experimental OSs build with C# (and other managed languages) and I’m still a little confused about one thing:
What makes C# better for building a kernel than C/++ and/or assembly?
Don’t get me wrong, I’m all for progress and experimentation, I’m just a little puzzled what such a high level language can offer in terms of kernel performance and stability that lower level languages haven’t offered for a great deal of time already. Is it just a case that these are geeky projects some programmers have taken up “just because they can” (which is as good a reason as any for building experimental systems) or do these projects offer some serious future gain which I’m naively overlooking?
Just like Jnode with Java,
Basically safety is the answer. no buffer overflows or easy memory leaks. Also development speed is a big bonus.
To my understanding, buffer overflows and memory leaks are only a fraction of the sources of instability in modern kernels, while synchronization issues in highly parallel asynchronous environment and general complexity problems are probably more significant and harder to solve. Managed languages don’t help with the latter, so it’s not a silver bullet.
Well, actually all you do is delegate the safety checks to the developers of the language/compiler/whatever. In the long run all I see emerging from this is something I don’t really like, coders who say are experienced and perform horribly when needed to code in c++ and the likes. And disregard c/c++/vc/etc. all you want, it’s still mighty important. Don’t get this wrong, I personally don’t have anything against c# (although winforms is a no-go for me), on my better days I tend even to like it somewhat
This is simply solved by hireing people with the skills you actually need. If you need a C++ programmer hire someone with C and/or C++ experience. Expecting someone who knows how to ‘program’ to perform equally well at all programming tasks and in all languages is silly.
If I need someone to write numerical analysis software in C I wouldn’t hire someone who’s an expert at writing web apps in perl.
“This is simply solved by hireing people with the skills you actually need. If you need a C++ programmer hire someone with C and/or C++ experience”
As I’ve developed in the software engineering world, I’ve come to have an infinite amount of sympathy for hiring managers. It’s virtually impossible to tell who is a good programmer. Much less what is ‘experience’?
I’m worked at places with dead weight programmers who quite frankly are idiots. I’m sure their resume looks great with 10 years experience with Nortel (speaking as a Canadian…seen too many of these) or some other company.
I’ve met guys with 10 years c++ experience who still don’t really understand how to program properly for it. On the other hand, a good engineer DOES investigate and make sure they understand the language before going into the code. For example, I used to be a purely c/c++ guy, but was eventually assigned to a c# project. I read up on it, made sure I understood it. Suddenly I start seeing fundamental flaws in how the project was currently written (by people with 3-4 years c# experience.
Also, c/C++ are not the same thing. Hiring someone with C experience to do C++ is a recipe for disaster. Just last night I spent 3 hours debugging a problem because someone forget to implement a c++ copy constructor for a class when using the STL. None of those terms mean jack for a C programmer.
So in conclusion. Hiring a programmer/software engineer is insane. There’s no magic in it. I really think everyone should make use of that 3 month probation rule that comes with most contracts. If the person is not as capable as you thought, let me go in the first 3 months. If the worker doesn’t quite like the workplace…they should feel no guilt leaving the company.
Well, I half agree. It is certainly difficult to find good programmers — but not impossible. My interviews are pretty thorough, and they definitely tell me whether a candidate has the technical proficiency to succeed in my org. HOWEVER, what’s unknown are the intangibles: personality, fit, motivation, drive, etc. And, to some degree, it’s the intangibles that separate the mediocre programmer from the amazing programmer. What usually convinces me are the things that a programmer does in his/her free time BESIDES their usual work. Let’s face it: Outstanding programmers don’t just confine their obsession to their 9-to-5 jobs. Usually, they have some kind of project outside of work; for example, a game or a prototype or whatever. When devs tell me that they don’t do anything other than their work, it often raises a red flag in my mind. Not that that is the only data point, but it can be a significant one, if you are on the fence about a particular candidate. I like to see evidence of passion and drive and ambition. Granted, somebody could be blowing smoke up my ass, but it’s usually possible to see through that nonsense by asking successively deeper questions; how did you solve X? did you think about Y? what kinds of potential changes would you make now? etc.
The big advantage is software isolated processes.
If your user mode programs use the verifiable subset of the MSIL instruction set, you can let all processes run in the same address space without security problems.
This gives a huge performance increase since interprocess communication can be done by just passing around pointers. A kernel call does no longer involve costly copying of arguments and CPU mode switches.
In the long term, a CPU designed for running an OS using software isolated processes could be simplified tremendously. So you could squeeze many more cores on the same die space.
The performance of C# and java actually are quite close to the performance of C++ when done right. Especially for .NET languages that support value types (structs), there is no theoretical reason why C# should be slower than C++. Of course C++ compilers have more mature and more optimized code generation algorithms, but that is slowly changing. For example, the next version of the JVM will get stack allocation, and the next version of the CLR will do much better struct inlining.
Unfortunately, most java and C# programmers do not realize the performance potential of managed languages because they are creating thousands of objects in inner loops. To write high performance code, you need to know how the language constructs are mapped to machine language, and most programmers simply do not know or care about such details.
Like I said, better security, much faster IPC and less requirements on the underlying CPU are the major advantages.
What makes C# better for building a kernel than C/++ and/or assembly?
– You can run everything in kernel space. No syscalls, no context switching. Because the code is managed – the processes are still separate.
– You can pass objects directly to and from the kernel or between processes. Because each application and the kernel own their own chunks of memory – the current kernels have to do a lot of tricks to pass data around – using copying, the stack, messages, etc. With managed code in many cases – you can just pass a pointer.
– and of course – security
I think I still have a long road to go down on, to arrive to a place where I might think that’s something I’d like to have in a kernel just being developed.
Using a Managed Language, you can verify your assemblies and essentially guarantee it will never spill over into another process.
Additionally, if that’s not enough (At least in Singularity) you can selectively isolate the processes in Hardware as well.
But really, it’s all about zero-copy process communication and ease of development.
That is one thing I dislike about singularity. A great part of the attraction of an OS using software isolated processes is its simplicity. The only security-critical part of such an OS is the MSIL->native JIT/AOT compiler.
If you provide an additional mode of process isolation, a large part of that simplicity goes out of the window. But microsoft never got the whole KISS approach anyway. Just look at the bloat in the C# language specification.
Well, it’s to take into account that humans make mistakes and therefore the Software Isolation could be compromised in theory.
Not that it’s at all likely, but even for things that don’t conform to the philosophies of managed code (Sandboxing Native code using a VM for example), this is a very good compromise.
That way you can run “Trusted” applications using only a SIP, and untrusted or native applications using a SIP with additional hardware protection.
I think it would work if used sparingly, but that remains to be seen.
Correct. But hardware isolation can also be compromised in theory. Sometimes there is a bug in a CPU that lets a user level process gain access to privileged instructions. An operating system using pure software isolated processes would not be affected by such CPU bugs.
I agree that for practical usability there needs to be some way to run traditional hardware isolated processes. But that should be done in some kind of compatibility layer to avoid bloating the core OS.
Maybe run the new OS and the old processes side by side using some kind of supervisor. But do not compromise the design of the new OS for backward compatibility!
If it is used sparingly, there is no need to compromise the core OS. Running a legacy OS side by side to the new SIP OS under some kind of supervisor would have some overhead when communicating between new and old processes, but I would gladly accept that penalty for a clean and minimalistic design.
Except that in this case, without being able to also use HW protection you must dump all exisiting SW written in ‘unsafe’ language which makes your OS quite useless..
So I think that it’s nice to have both possibilities.
Sometimes I feel that those C# kernels are more like a ‘microkernel rocks’ rehash ( like Linus vs. Tannenbaum ) than genuinely innovative designs, especially comparing to the legendary Smalltalk and Lisp machines.
The memory sharing and protection stuff has been discussed for ages. Everything runs in kernel space: Bwahahahahahahah
I feel that with current mainstream hardware, it is more interesting to build a world inside a virtual machine than doing an OS from scratch.
If a C# OS does nothing to change the way applications run and share data, … (try Squeak as an example), It seems pretty useless.
And using C# in small embedded designs is laugable.
Could anyone tell me what is so amazing about C# ?
Seriously, what wonderful things shall I wait for ?
Now, mod me down 😉
It’s not C# in and of itself that is “so amazing”, although it seems to be a fairly well designed language. The cool thing is the CLR, C# is just a way of using the CLR.
Perhaps in this scenario (OS) its the CLR that is the cool thing, but I have to argue that C# (and the .NET class library) itself is rather amazing. Ofcourse you have to compare it with something in order to draw that conclusion.
For me, which are educated as C++ and Java programmer, I just love the fact that C# is as powerful as both those languages together. Its as simple (both in language features and level of abstraction) as Java, yet got all the features of C++ (unsafe code). It got a clean class library with the same features as Java’s, but without all the legacy/compatibility code and overengineered factoryfactory factories classes…and much better feature-set than any C++ library I have ever used. Abstraction for rapid application development and readability, is worth its weight in gold for alot of programmers (especially in the enterprise market where it has to fit within the business models and so on…).
Last but not least, anyone still using C/C++ for applications and then gets rooted because some stupid buffer overflow can only blame themselves. It has been known for ages that code written in C/C++ WILL lead to these problems…even at the hands of experienced programmers. If you ever written a C++ code with more than 1000 lines, don’t come here and tell me you never had dangling pointers, insufficient bounds checking, string formating errors, and what not in your code… I certainly have. Getting these kinds of problems OUT from the core of the operating system should be enough reason to embrace C# (or any other similar language) at once.
Buffer overflow and memory leaks are only a small part of the issues operating systems face. A more serious issue is general *resource* leaks (which C# can do nothing about that can’t be done with even C) and excess memory usage which anything but referenced counted garbage collectors are notorious for having (memory is eventually recovered, but you in the m-allocated memory), treating different things the same (i.e. if you try to treat register memory the same way you treat swap memory, you’re going to have serious performance and behavioral issues), ignoring the hardware to make developer’s lives easier like using the stack exclusively in preference to fast registers (if you ignore the hardware, the hardware will ignore you).
IMO, writing an OS in Java or C# might be good for educational purposes and OSes where latency makes speed a nonissue (e.g. a distributed OS over a slow network) or when you have tonnes of memory and CPU to waste. But I don’t see it reaching the desktop any time soon. But it *might* change with time. After all, anyone who’s had a 1MHz Commodore 64 or Amiga 1000 knows that those seriously underpowered machines could do wonders because of their tight coding (which included now taboo performance techniques like self-modifying assembly code). Compared to those standards, these days, even Linux is a memory hog for the sake of maintainability and functionality.
OTOH, given that applications of the average user keep finding ways to stress memory and CPU (Compiz, Video processing, Human Genome projects, Weather prediction, etc) in ways that we didn’t even think of 10 years ago and the fact that Moores law has a limit which which we might reach within the next five years (i.e. atomic level), I’m skeptical.
I agree that the state of the art of managed runtime environments leaves a lot to be desired. But it is not quite as bad as you describe:
All current runtime environments (CLR, JVM) use registers whenever possible. That includes using registers for passing function parameters and return values.
The new JVM will even stack allocate thread-local objects like local variables to reduce the stress on the garbage collector.
And in .NET it is possible to write complex programs that do not use the heap at all by using structs.
Resource leaks can be dealt with by using the ‘Resource Acquisition is Initialization’ pattern. It is not as elegant as in C++, but definitely possible. I use this all the time.
Correct. And there are many many ways to do nice things in C++. It is just hard when you begin, but not at all once you start relying on efficient design and solid implementation to develop your ideas further. It does not attempt to make things easy for the sake of making them easy to begin with. Sure, nothing is perfect, but a multiparadigm language that allows you to be able to work at _any_ level you wish to work with your hardware may be a best fit in many scenarios.
However, language shoot – outs serve no particular purpose, for the record, I will quote B. Stroustrup on this, from his page at
http://www.research.att.com/~bs/bs_faq.html
where you can see the context the words below are written in:
I believe that the above apply to many situations.
C# does not have all the features of C++. For example, C++ has multiple inheritance and C++ templates are more powerful then C# templates. Of course one can argue that it is actually a good thing that C# does not have multiple inheritance and I partly agree. But other languages like Scala and, I think, D provide mixins, which gives you some of the possibilities of multiple inheritance without causing the problems that multiple inheritance can cause. C# also lacks some other powerful features like pattern matching, which is often found in functional languages, e.g. Haskell.
Parts of the .Net libraries are crap, e.g. Windows.Forms. On the other hand, it is now replaced by WPF, which is really quite nice. Also, I found managed DirectX applications really hard to debug. If something goes wrong in your Shader code, you just get an “Error in application” exception, which is not helpful at all. At least the same code in OpenGL and C++, the error message includes a line number. And Qt is a C++ library, that more or less has the same feature set as the .Net class libraries. Qt4.4 even includes a multimedia API (Phonon), has its own HTML rendering engine (based on Webkit) and can render widgets on a canvas, similar to what you can do with WPF.
You can avoid many of these problems by using a decent framework like Qt, which does most of the memory managment for you and which has powerful string classes. Also there are numerous smart pointer classes which solve most of the memory related problems.
That sad, I also think C# is a decent language and I like programming with it. But C# and the .Net framework is certainly not perfect and there are other languages which are better than C# in certain areas like Haskell, Scala etc.
What exactly is useless about those two points?
Memory is completely isolated from process to process, and communication is done via secured channels.
Optional hardware isolation for untrusted (or even legacy and VM’ed native code) processes, and the ability to proof code before it’s ever run.
The advantages are all about making these assumptions, and taking the stress off of the developer to do this tedious work.
This is basically software memory protection and instant IPC without using the processor at all.
This does two things:
It frees you of the speed penalty of many context switches (so you don’t have to do something dangerous like implement shared memory), and it makes your code heavily portable.
Since you’re using no features from the Intel architecture you would easily be able to port it to another platform.
Now when you look at Channels for IPC it seems like a bad idea, until you factor in that it’s an instant transfer of data.. and a secure one at that.
The concepts start to look a hell of a lot more attractive given the details.
I find these projects (not only sharpos, but also other typical innovative OS’es) really interesting, but lets face it: Unless they get driver support they WILL not be usable for most people…for anything.
My idea (and I am not an OS designer so please correct me if the idea is impossible) is to make a wrapper/compability layer which resembles the Linux driver interfaces. This will open up the OS up for everyone to use. Let these drivers run in some sort of jail, and encourage writing native drivers instead as it gets popular.
That does happen to some degree with other platforms (the ndiswapper (or however it’s spelt) for running Windows wifi drivers in linux and I believe Hakiu has a wrapper to run linux drivers).
however I think, in the case of C# OSs, it would be counter productive having a linux wrapper going by the comments raised here about the advantages gained of managed code.
What are the advantages of an operating system that won’t work on your computer because the lack of device drivers then? The wrapper itself could be abstracted and object-oriented to the point where only the actual interface between the driver and the wrapper is not taking advantage of the managed code. Furthermore, for other issues, what about emulating the drivers in a virtual jail/machine?
What’s the point building an experimental OS if you fill it full of non-native drivers which effectively force the Os into running simularly to existing systems?
You forget, that most code will run in kernel mode. This can greatly cancel out any performance penalty from using a wrapper or sandboxing native drivers.
Additionally, more and more hardware vendors are opening their specs, so this won’t be a problem for much longer.
Here’s what I get when I attempt to read the article:
Microsoft Internet Explorer Versions below 7.x are NOT supported
Have a nice day!
Since us peons at work have to use what the company gives us (IE 6), I can’t read it.