CppCast - IncludeOS
Episode Date: July 14, 2016Rob and Jason are joined by Alfred Bratterud, CEO of IncludeOS to discuss Microservice applications with the IncludeOS platform. Alfred has been doing research towards IncludeOS since 2013, an...d got a PhD scholarship based on the early work in 2014. The IEEE CloudCom paper introducing the IncludeOS prototype was published in 2015 and he spun out a startup around IncludeOS in 2016, in collaboration with Oslo and Akershus university college (the largest institution for engineering education in Norway). He's currently focusing 100% on developing IncludeOS from research experiment to a production ready platform for cloud services. Alfred holds BSc and MSc in computer science, with focus on logic and computability, from the university of Oslo. He has 10+ years of industrial programming experience, mostly in web services. He's been working at Oslo university college since 2011, teaching various subjects ranging from operating systems, sysadmin and firewalls to web development. He started learning C++ when he took over a C++ course at the college in 2011. A very good year to start C++. News The new lightweight, cross platform C++11/14/17 IDE juCi++ v1.2.1 CppCon 2016 Program Preview: Algorithms, Exceptions and Games Second Episode of CppChat Sunday Meeting C++ interview with Sean Parent Alfred Bratterud @AlfredBratterud Alfred Bratterud's GithHub Links IncludeOS Repo IncludeOS IncludeOS: A Minimal, Resource Efficient Unikernel for Cloud Services Unikernels Unikernel Devel Sponsor Incredibuild
Transcript
Discussion (0)
This episode of CppCast is sponsored by Incredibuild.
You won't believe how fast your build can run until you download your free developer version
at incredibuild.com slash cppoffer or just click the link on our website.
CppCast is also sponsored by CppCon, the annual week-long face-to-face gathering
for the entire C++ community.
Episode 63 of CppCast with guest Alfred Braderud, recorded July 13th, 2016.
In this episode, we discuss a new open source C++ IDE.
And we talk to Alfred Bretterud from IncludeOS.
Alfred tells us about making microservice applications for C++ developers by C++ developers.
I'm your host, Rob Irving, joined by my co-host, Jason Turner.
Jason, how are you doing today?
Good, Rob. How about you?
Good. Do you want to quickly share what you were telling me about
with your latest C++ Weekly episode?
Okay, sure.
So I did a C++ Weekly episode where I demonstrate
how modern C++ can compile down to something efficient enough,
essentially, that can run on a Commodore 64.
And I published that, and I've had an extraordinary response to it as far as number of views.
It's by far the most viewed video I've done yet.
It was a lot of fun to do, though.
That's pretty awesome.
And basically, you compiled to assembly, and then you converted that assembly, right?
Yes, I compiled to x86 assembly, and then I wrote a conversion tool that can convert that to 6502 assembly, and then I assembled that on the Commodore 64 and executed it.
And there are several things wrong with this process, for sure, but it produces better code than I can get from any of the LLVM 6502 backends to produce.
And I had a lot of fun doing it and learned a lot about two different architectures at the same time.
Awesome.
Okay, well, at the top of our episode, I'd like to read a lot of fun doing it and learned a lot about two different architectures at the same time. Awesome. Okay.
Well, at the top of every episode, I'd like to read a piece of feedback.
This week, Sebastian wrote in to us on Facebook.
And he writes, thank you for the good work.
I'm learning a bunch of useful stuff.
I've not gone through all episodes yet, but I would love if you could have a talk about general advice and good practices for programming students.
Thanks again.
And this
must be, I don't know, Jason, the fourth or fifth time we've had a request like this. I'm still not
really sure how we should go about tackling such an episode. I don't know. Maybe we could have
someone like Scott Myers back on again and then ask him what new learners should be learning. I
don't know. or should we talk to
someone who just recently graduated and just got into the industry well we just talked to a high
school student we don't know if he was giving us beginner advice or not so well if anyone has any
ideas for uh for that type of episode we're definitely open to them um we'd love to hear
your thoughts about the show as well you You can always reach out to us on Facebook, Twitter, or email us at feedback at cpcast.com.
And don't forget to leave us reviews on iTunes as well.
Joining us today is Alfred Brederud.
Alfred has been doing research towards IncludeOS since 2013 and got a PhD scholarship based on the early work in 2014. The IEEE CloudCom paper introducing the IncludeOS prototype was published in 2015,
and he spun out a startup around IncludeOS in 2016 in collaboration with Oslo and Akershus University College,
which is the largest institution for engineering education in Norway.
He's currently focusing 100% on developing IncludeOS from research experiment to a production-ready platform for cloud services.
Alfred holds a BS and MS in computer science with more focus on logic and computability from the University of Oslo.
He has 10-plus years of industrial programming experience, mostly in web services.
He's been working at Oslo University College since 2011, teaching various subjects ranging from operating systems, sysadmin, and firewalls to web development.
He started learning C++ when he took over a C++ course at the college in 2011. teaching various subjects ranging from operating systems, sysadmin, and firewalls to web development.
He started learning C++ when he took over a C++ course at the college in 2011,
which was a very good year to start C++.
Alfred, welcome to the show.
Thanks. Great to be here and a great show you have.
Thank you.
2011 was a good year, but how did you get your start programming, Alfred?
That's what I'm curious about.
Right. Okay, so the very first start, that was BASIC.
I think it was a course in high school when I started writing code in BASIC.
And then, of course, later there was a lot of web development.
So I think the real place I started
was actually with Flash
which is completely dead
now but it was a great way to
you could draw stuff on a surface
vector graphics and then just
immediately start controlling that
graphics with code
so that kind of visual interaction
was when it really started
triggering my interest and from there I moved on to web.
And then in college, I really got into it.
Cool. Very cool. So we have
a couple news articles to discuss. Alfred, feel free to jump in with any
comments you have on these, and then we'll start talking to you more about IncludeOS, okay?
Great. Okay, so this
first one is a new
lightweight cross-platform C++
IDE called
Juicy, and this is an open-source
project, right, Jason? Yes.
So it's
all on GitHub. You can...
I guess you build it just from
source. I don't think they even have installers posted,
as far as I can tell, right?
No, they're definitely focusing on just source right now, according to the comments on Reddit.
Yeah.
And it looks like it has some strong features, syntax highlighting, C++ warnings and errors on the fly, auto-completion, all the good stuff.
So if you're looking for a nice, lightweight IDE, this might be a good option for you.
And it runs on Windows, Mac, and Linux, I believe.
Yeah, it looks like it targets MinGW on Windows right now.
So if you're hoping for Visual Studio support, maybe not yet.
Right.
And one of the top comments on Reddit is asking if it has a Vim-style input mode.
That is the most important feature.
They're saying not yet, but it sounds like they're going to work on integration with
NeoVim to bring that feature.
My first question was, does it support working over SSH?
So that's what I do a lot.
I mean, log into a virtual machine or a Linux server and then I start Emacs,
which is obviously the greatest
editor in the world.
Let's not get into that
right now. Let's not get into that.
Now it looks like a great project, and
in Includo, people are using
all kinds of editors, so I'm sure
somebody in my team is going to
find this really cool.
I have had problems with support for new C++ language features,
so that focus is definitely good.
It seems like being able to do some sort of remote coding
and remote debugging is a frequently requested feature
for a lot of cross-platform IDEs, and that kind of surprises me.
It's not something I expected to see, personally.
Yeah, it's something new for VS 2015.
They just brought that in with the remote Linux debugging.
And it's something that people ask about on...
CLion?
CLion, yes.
Okay, well, this next article is from the CppCon website,
and they haven't released the full schedule yet.
I think that comes out this weekend.
But they've been doing these program previews
where they go over a couple different talks
that are focused around a few topics.
So this week they're talking about talks
with generic algorithms, exceptions, and game development.
So all these talks look pretty interesting.
It's always great that they are able to bring in some real AAA
game developers to do talks.
This time they have Nicholas Flurry
who worked on Rainbow Six
Siege Quest.
So it looks like it'll be an interesting talk.
Was there anyone you guys wanted to highlight here?
Yeah, I was interested in several
of these. I'm also
going there
we're presenting
as well on CppCon so that's going to be
cool
I was looking at
for example regex
support, that's something I've been using
a lot and I was
really happy when that came into C++
I'm also glad to see
the standard reduce from C++. I'm also glad to see the standard reduce from C++17.
That looks pretty cool.
So it seems like that's kind of a move towards more functional programming style stuff.
The map and reduce concept is something I remember from Common Lisp during college.
So that looks interesting.
I'm kind of curious about this standard accumulate
exploring an algorithmic empire from Ben Dean.
Yeah, I agree.
It's quite a title.
It is.
I wonder how long it took him to decide
exactly what that title should be.
Oh, and Ben also happens to be a game developer.
He's over at Blizzard.
Yes.
I've met Ben, and I'm looking forward to that talk.
I hope I'm able to go to it.
Yeah, and Alfred, are you going as a speaker
or just as a conference-goer to listen?
No, I'm going as a speaker.
Okay.
Yeah, so I'll be presenting IncludeOS
from bootloader to RESTful API.
So the paper was, or the abstract was accepted,
and I haven't seen it in the program yet,
but yeah, we got accepted.
So very much looking forward to that.
Awesome.
Okay.
This next article is an announcement from our good friend, John Kalb.
They just started something new.
John Kalb with Bryce Lelback, CPP Chat, which is like a Google Hangout show that they're doing.
They started last Sunday.
They're having another one this Sunday.
And it's just like an IRC chat where they're talking about latest C++ news.
Video chat.
Video chat, yeah.
Okay.
It says watch live and join the IRC room.
Did you try to join this this past weekend, Jason?
I tried to, and I think I may have been too early or something,
because when I went to the link, I didn't find anything there.
No, I did not.
I forget why.
I believe I was unavailable.
I did go back and watch a few minutes of it,
even though it says it wasn't recorded.
Oh, so it was recorded.
Well, I don't...
There was part of it that you could still watch up on John's website.
That's all I know.
Okay.
I think Google just kind of kept the Hangout around or something.
Oh, okay.
Well, I think this is great that they're doing this.
John called this so much for the community and I know he reached out to me and
he made sure to let us know that this wasn't competing with CppCast and it's a different
format. But there's nothing wrong with competing with us if you wanted to make a podcast out of
this. Right. There's always plenty of room for more. Yeah, I saw John Kalb on CppCast and that
was a great episode. Oh yeah.
This looks very interesting.
And then this last one is an interview with Sean Parent
from Jens Weller.
Meeting C2Pcast. Jens Weller.
Jens Weller.
I'm sorry.
And it's a great interview.
He goes into a lot of interesting questions.
One of the ones I thought was interesting was
asking,
Sean Parent doesn't have any involvement with
the C++ committee, but if he
did, what was his opinion on
breaking things or staying backwards
compatible? And
I liked his idea of being able to
write kind of in a using statement
this code is if it's
C++ 20 and this code is if it's C++ 20, and this code is if it's C++ 17,
and the compiler being able to detect that if it supported both, or if it was an older compiler,
or something like that. I thought it was a really neat idea. And that would allow them to,
you know, break old features, because developers would be able to use this to keep their code
working. You know, you might be able to approximate something like that
with constexpr if and compiler traits that are now being...
Because, I mean, each time a compiler supports a feature
they're supposed to make a pound to find to go with it,
you might be able to get a similar kind of behavior.
That'd be very interesting.
I'm sure Sean would love to see that if he could do it.
Oh, although we just had this conversation on Twitter
that constexpr if in the
context of a non-template function each of the branches must be compilable oh okay well anyhow
is there anything else you wanted to highlight in here jason um that's well there were several
things at the moment i can't remember any of them of course course. But it's an interview with Sean,
so there's just interesting stuff in here, little details,
like wanting to get rid of argument-dependent lookup, if he could.
Right.
And his thoughts on how a garbage collector just has no business
in a general-purpose programming language.
Yeah.
I also thought it was kind of scary to see that you thought
shared pointers didn't have any place in an API.
So that's something we're violating in IncludoS
because we use smart pointers a lot,
especially for passing network packets off the stack.
So I definitely have to look into that
because I'm really interested in seeing
what these really experienced experts have to look into that because I'm really interested in seeing what these really experienced
experts have to say. So that was an interesting comment. Someone, it was Sean or Herb, I forget
who it was. Actually, it was probably someone else. I'm just reattributing it. Gave a talk on
how shared pointers are essentially global data. And if we're supposed to be avoiding global data,
then we should be avoiding shared pointers.
Right.
And so that might be something to look up.
I honestly, I cannot put my finger on when or where that talk was.
Yeah.
You know, so that's a really interesting, you know, thing for us
because network packets in CluedOS, they are essentially,
they have to be shared, you know, among several components.
You have to, you can't do copying because that's kind of the first rule
of writing an efficient network stack is to do zero copy.
So if you can't copy the packet,
then you have to provide the packet to various objects in some way.
And I think having a share pointer that owns the packet, that's been a good
solution for us. But it definitely has issues as well. So it's an interesting conversation.
We may be getting off the rails here, but I must ask, do you copy the shared pointers?
We pass them by value.
So you are copying them around?
Yes, we are.
You might want to look into the performance impact of that.
Sure.
Compared to just copying the data that it points to.
Yeah.
Well, if it's a whole network packet,
it's definitely potentially a lot of data.
So that's our current solution.
And I mean, part of what I really want to get out of this experience
is to get feedback from the C++ community
because this is a pretty radical approach
to designing an operating system.
So, you know, we don't presume to have the perfect solution for stuff,
and we really, really want to get feedback on our choices.
So that's also something we'll be encouraging on CppCon.
Yeah, we may as well actually get into the interview, I guess, here in a second and talk
about IncludeOS so we know where all this is coming from.
Great, yeah.
Right. So we already mentioned it a couple times in your bio, but what exactly is IncludeOS
for listeners who haven't heard of it yet?
Right. So IncludeOS, it's a library operating system for turning one single C++ program into a standalone virtual machine.
So essentially, it will turn your program into an ELF binary, which again will be turned into a virtual machine, a bootable disk image. So it's essentially a way to package all of the necessary drivers,
a network stack, et cetera, into a library, a statically compiled library that you can then
link to. So it turns your service into an ELF binary and we attach a bootloader in front of that so that your service can pretty much boot on x86 hardware.
So one other word for it is a unikernel.
So that's a pretty new concept.
I think it was coined in 2013 by Anil Madhavapedi and Richard Mortier.
A unikernel is what they describe as a single address space virtual machine image
or a machine image that's created by a library operating system.
So it's pretty much a single service operating system.
And the key features are one single address space,
because that means you know that there will only be one process running
inside of your operating system.
That means you can massively reduce the complexity of that operating system.
And the other really important feature is that it has to be created
by a library operating system so that you can avoid, you can bloat as much as you want.
I mean, we can keep adding features to IncludeOS.
We can, and then that means that the IncludeOS library is going to grow.
It can grow indefinitely. build your service, it will do static linking towards that library, and essentially only what
you actually use in your code is going to get included. And that means you get the smallest
possible, at least in a design perspective, that's kind of the slimmest way to design it,
so that your program essentially becomes a virtual machine. So you write your C++ program, then you compile it with the IncludeOS framework, and now you
have a thing that can just boot on a virtual computer.
That's it.
It's pretty cool.
I mean, it's almost too cool to believe in a way.
So what is the actual bootstrapping process? What does the
computer look like to your program once the booting is done, I guess, if you will?
Yeah. And that's going to, I hope that will be something you will enjoy having seen that
C++14 is now on the Commodore 64. I watched that cast and I thought it was just fantastic so yeah so
what we're doing is exactly the same
as when you booted
a normal x86 computer
back in the 90s or in the 80s
we see hardware exactly
like
exactly like the operating
saw the hardware back in
when the first IBM PC came out.
So, I mean, the Intel CPU architecture is backward compatible, right?
So what happens is, you know, we have a disk image, which is a bootable disk image.
It's just a bitwise image of something that is presented to the virtual hardware as a hard disk, right?
So the first sector of that, the first 512 bytes of that disk image, that's our bootloader.
It's custom made, handwritten in Assembler, just to make it really tiny and to get the
image as small as we can.
And then, you know, the BIOS is going to pick that sector out,
copy it into memory at a fixed predefined location,
and it's going to jump to that.
And from that point, our assembly bootloader is going to go back down to the hard disk and pick up the ELF binary,
which now will contain everything your service needed
because it's been statically linked.
So it's going to contain parts of the operating system.
For example, the start.
It's going to jump essentially to the start symbol,
which is then written by us.
Of course, before that, we switched to 32-bit protected mode
so that we get modern hardware.
I was wondering about that.
So a PC boots in 16-bit mode, right?
Yeah, exactly.
And then you jump to 32, not 64-bit?
Yeah, we jumped to 32,
and of course we've been considering jumping further into 64,
and frankly, we haven't really jumping further into 64 and frankly we
haven't really seen
the immediate use for it
currently. We do have
advanced CPU
features such as SSC
so we
definitely make use of all that
and at any time any of
you guys can just switch into 64
bit mode. I mean you have full access to the virtual hardware.
I know we're going to talk more about that.
But, yeah, so, you know, so it boots.
It means, you know, you jump to the ELF binary.
And, of course, we have then, in advance, we have told the bootloader exactly where that start symbol is going to be located in physical memory.
You jump there, and then we start initializing stuff.
So we do stuff like Linux and Windows.
We'll initialize the BSS segment.
We'll call the global constructors.
And then we'll do some hardware stuff like scan the PCI bus for devices.
But at this point, we're not going to instantiate or attach any drivers.
And I'll get back to why we're not doing that.
But essentially, it's because we don't want to have a lot of drivers in there in case we find a certain piece of hardware, we want to be able
to only
include the drivers that your code
will actually use.
So,
after doing
these initialization things and
mapping out, just scanning the PCI
bus, finding out what hardware is actually there,
then we'll
attach interrupt handlers.
And those interrupt handlers are,
essentially, we have an IRQ manager
that you can subscribe,
so that your service can subscribe directly
to any interrupt using a delegate
or a lambda or a standard function or whatever.
So you can actually just say, whenever this IRQ happens, then this code runs.
But of course, that's on the very low level.
So you probably don't want to do that unless you're especially interested in low level
stuff.
So of course, we provide a lot of events on top of that.
So at some point, we did the IRQ stuff.
We probed the hardware, found out what's there. on top of that. So at some point, you know, we did the IRQ stuff.
We probed the hardware, found out what's there.
And at that point, we jumped to your code.
And what's important is that then we're in an event loop where we will call a function that you're supposed to write
that's called service colon colon start instead of main.
That might be, you know be kind of alien to people.
You expect to have a main.
And the reason for not doing that, I mean, we could have done that.
It's just the name of a function, right?
But the reason for not doing that is because the signature of main
doesn't really make any sense in our context
because there are no command line parameters
because there is no command line interface.
Right.
Right?
It's just your program running on hardware.
Also, there is no reason to return anything
because where would you return to?
There is nothing except for your process in there.
So for that reason, we just decided to make a different signature.
So it's just a function that returns the void, and it doesn't take any arguments.
So at that point, what your service should do is to just subscribe to events.
And typically, what you would do is that you would say, for example, TCP bind to port 80.
You bind to that, and then you get back a socket object, and then on that socket,
you can say onAccept or onConnect or something. And again, you can pass in a lambda or a delegate
or a standard function, and then you can say whatever should happen when somebody connects
to port 80 so so so initially it's all event-based it's all asynchronous uh you know um the reason
for that is because because of single address space and because we found that the most efficient way to do virtual code inside virtual machines is
to not have context switches so i mean that's a really that's a that's a that's a topic of his
own i don't know how much you want to get into that i i find it really interesting but uh yeah
we'll see how much time we have sure yeah i think it might be worthwhile to take a step back and uh
you said the word service a couple of times.
Can we talk about what the intended use case is for IncludeOS?
Yeah.
Okay.
So, you know, we're making a platform.
So we don't have this one.
We're not making this one app or this.
And we're still kind of looking for what would be the killer app for IncludeOS.
So we're really hoping for the community
to kind of tell us that.
But we, of course, we have a lot of stuff
that we know will be sensible to make on our platform.
And for CppCon, you know, the goal is to make,
we have enough technology so that you can write drop-in replacement for a simple microservice with a RESTful API that's written in, for example, Node.js.
And you can rewrite that part of a service composition into an IncludeOS virtual machine, and it should be then faster and much safer
because this microservice is 100% isolated
from the rest of the hardware.
So services that we can already make and will make is,
for example, DHCP server, DNS server.
I already made that for the paper.
Message queue, load balancer, router.
So essentially like components inside of a virtual infrastructure.
But then, you know, after CppCon, hopefully we could provide enough technology to implement your website, the CppCast website.
Because, I mean, people aren't developing web services a lot with C++.
I mean, some companies are, but, you know,
it's not really the language that comes to mind when writing web services.
And I think, you know, after Herb Sutter's article,
you know, the free lunch is over, I think it's going to become more and more relevant to do more in the little time you have
for people click a link until you get the reply. And if the CPU isn't going to keep giving you more
and more cycles in that fixed amount of time, then, you know then you're going to have to start doing services
also in C++.
So how do you differentiate from what you're trying to accomplish to what Docker gives
us right now?
Yeah, that's interesting because people associate Docker with containers, and obviously that's
how they started. So just let me make clear that Docker isn't the container technology.
They're about tooling for managing containers and making containers easy to use.
I mean, Linux containers was part of the Linux kernel long before Docker came around. Docker made the containers manageable in a very elegant and user-friendly way.
So let me talk about those two things separately.
I mean, containers is also a way to isolate your service, but it's operating system level isolation. So essentially,
two containers, they share the same kernel. Now, that can be fine for a lot of application. But
if you want your hardware to be shared among different tenants, for example, if you want to
host a server, and you want to allow me to run my stuff on that server, and you want to host a server and you want to allow me to run my stuff on that server,
and you want to allow everyone from all countries in the world to also run their code on the same hardware, then you want to make extra sure that whatever they do in one of those containers is
not in any way going to be able to influence your hardware and also not anybody else's service.
So with real or true hardware virtualization,
you get the strongest possible form of service isolation
because there is absolutely zero bias of share code.
So all I do inside of IncludeOS,
it's calling instructions from the instruction set.
I don't do any calls to any function
that exists in a shared memory space.
So the container is just one way to isolate.
Hardware virtualization is another way to isolate.
And IncludeOS, we just aim to be the simplest way to get your C++ service
to run inside of that awesome form of isolation that's been around since the 70s or the 60s.
I want to play devil's advocate, if you don't mind, for just a moment.
Sure. Your OS
supports or if I get the wording right, relies on the virtual, that there's a standard for virtual
network driver, correct? That's right. So hypothetically, if there was a bug in that
virtual network driver on the host machine, someone writing an includeOS service could still muck with the host machine?
Well, the way we interact with that virtual device is through the instruction set.
And also through shared memory.
So you can say that that driver has access to my memory, but I don't have access to its memory.
Okay.
So, you know, I can't really, I mean, of course, there's hypothetically, there is, if there was a memory leak, for example, in that driver, I'm sure there is a theoretical way that, you know, some of my memory could be
leaked down to the host and from there potentially over to another process. But,
you know, the isolation is much, much, much stronger than any other form of isolation.
Okay.
So, obviously, even with hardware, I mean, you don't have absolute guarantees.
I mean, there's microcode.
You know, if people have physical access, you know,
then they'll get access to your memory anyway.
So, I'm not saying this is perfect or foolproof,
but it's definitely the best we have.
And I really love this paper from, I think it's from 1974,
where they give a kind of a mathematical definition
of exactly this kind of instruction-level virtualization.
So it's so simple that it's possible to define in a few pages
a simple mathematical model for exactly that kind of virtualization.
So that gives me a certain amount of confidence that when it's so simple,
it's much easier to do it right.
Okay, makes sense.
And also, you know, it's implemented in hardware
So, you know, I also think that when hardware is distributed
The quality control of that hardware is, you know, is really
Of course, it's not perfect
There was an Intel bug, a CPU bug, you know, in the 90s
Yeah
But, you know, CPU bugs are rare compared to software bugs in general.
So it gives me a lot of confidence in saying that, you know,
it's currently the best way to isolate a service.
I'm not saying it's a perfect way,
but it's certainly what I would feel most comfortable about
if I was to invite you guys to run your stuff on my physical computer.
Okay. Makes sense.
I wanted to interrupt this discussion for just a moment to bring you a word from our sponsors.
IncrediBuild dramatically reduces compilation and development times for both small and big companies like EA, Microsoft Game Studios, and NVIDIA.
IncrediBuild's unique process virtualization technology will transform your computer network into a virtual supercomputer and let each workstation use hundreds of idle cores across
the network.
Use IncrediBuild to accelerate more than just C++ compilations, speed up your unit tests,
run more development cycles, and scale your development to the cloud to unleash Unreal speeds.
Join more than 100,000 users
to save hundreds of monthly developer
hours using existing hardware.
Download your free developer
version at incredibuild.com
slash cppoffer
or just click on the link in our link
section.
Are there any current limitations
to what you can do in IncludeOS,
like bringing in different libraries to your C++ service?
Any limitations on that?
Yeah, there are limitations.
I mean, it's a really hard question when it comes to blocking calls
because if you want to do a blocking call,
it kind of implies that you have to do a context switch, right?
Because say you call fread to read a file from the file system,
it's going to take forever to get a response from hardware,
then what are you doing in between, right?
While waiting for that, the call is blocking.
What does that mean?
It usually means that your service or your process is just going to be context switched out,
taken out of the ready list in the kernel, and then they do other stuff in the meantime.
So the problem with context switches inside of virtual machines is that that introduces two levels of context switches.
So there's a lot of research gone into,
first of all, demonstrating
and then also into trying to alleviate this problem
because it turns out that thread synchronization
gets kind of messed up
by this double layer of context switches.
So essentially, it just means that threaded applications
inside a virtual machine will perform worse
compared to the same threaded application running directly on hardware
as compared to a non-threaded application.
So it introduces a new layer of complexity.
So that being said, we do have support for multiple processors
inside of IncludeOS.
We're not going live with that in a while, I think,
because we really want to take the single-threaded approach
as far as it can go.
And I think, for example, Node.js is a pretty good example
of showing that using asynchronous interfaces,
you can get really good performance out of a single thread.
So we want to take that as far as we can.
And eventually, we are going to support blocking interfaces probably by using something like green threads,
light context switches that pretty much is just a stack switch,
so that whenever you do a blocking call, we will do a stack switch,
and then we can go do other stuff,
like service other requests,
and then switch back to you.
So that's going to come up,
but we want to kind of prove that you can do a lot,
and you can get the most efficiency out of a single core
by not using blocking interfaces.
I'm interested to know if you could use coroutines
from C++20, presumably, instead of green threads.
Yeah, I'm actually really interested in that as well.
So we're definitely going to look into that.
It's also interesting to see if we could do,
like, with use futures and promises.
And instead of having threads do the concurrency
to have a multiple cores handled concurrency,
we're also looking into making something like a thread pool like interface
so that you kind of, you can throw a task at this thread pool
and behind the scenes, it will be handled by several virtual cores.
Because the interesting thing to notice is that
if you start a virtual machine with 20 virtual cores,
usually that will just turn into 20 threads on the main computer.
Right.
So the cores are already threads,
and the context switching is already being done.
So we're looking into more custom-tailored ways of doing concurrency inside of the Unikernel framework.
But we realize that we're going to have to support all of POSIX at some point. But when we do, we want there to be alternatives
so that we can show if there are alternatives
that will give you more performance, those are available.
So you just mentioned POSIX, and I was going to ask about that.
You support the C++ standard library currently,
but not POSIX currently?
Yeah, I mean, we do have all of the, we have the whole C standard library.
So a lot of POSIX is actually just all of the whole C library.
I mean, that's part of it.
So, but we don't support a lot of the blocking stuff.
So for example, Fread, we don't support that.
So we have our own asynchronous file system interface. Oh, okay. And we also don't support that, so we have our own asynchronous file system interface.
Oh, okay.
And we also don't support P-threads currently,
just because we want to make sure that when we introduce threading or concurrency,
we don't compromise with kind of the purest alternative,
which is to do it single-threaded.
And it also just introduces a lot of complexity that some people really need,
especially if you need to do, I mean, you want to write a chess engine,
you want to have many cores.
Obviously, you need to share memory between those cores.
But for a lot of purposes, I think you can get concurrency by just simply
booting up more instances of IncludeOS.
Right. Do you want to talk a little bit about that?
That's kind of a microservice architecture thing, just being able to boot up more instances of your program as opposed to scaling that one program out.
Yeah. So, I mean, for me, it's about separation of concern.
So, I mean, that's inherent in object-oriented programming.
You're writing a container or you're writing some abstract data structure.
Then you go into that and you interface so that, you know, users of that interface isn't going to have to deal with all the complexities inside.
So that idea of separation of concern, I think, is also what the microservices is about, so that you partition your service into several processes or, in our case, several virtual machines.
And by doing that, you will get more resilience.
So one important feature of microservices is that you can have several smaller services
written in completely different technologies.
So in our case, you could have certain parts of your system written in
highly efficient C++ in a include OS virtual machine, and then other parts of your service
could be Node.js or Java or whatnot. So I think there's a great article from NGINX talking about
how Netflix is doing this, and they're really taking it to the extreme. So they have smaller teams responsible for a small part of a huge service catalog,
and they can choose their own tools, whatever tools they see fit for the job.
They don't need to use the same tools or the same language or the same database as all the other projects. So obviously, that means it could potentially turn into a huge tangle of lots of databases everywhere.
And I was actually surprised to see that also the databases are separated into separate microservices,
and that there are several smaller databases.
But then the idea is that then you have another microservice
making sure that there's consistency across those databases.
So I think resilience and scalability is kind of the main features
for going with microservices.
So for IncludeOS, I think making a drop-in replacement for an
existing RESTful API,
it could be
a web service of
many kinds. It could be
your web page.
But in a microservice
architecture, I think the
way we're going now is to try to make
it possible to do a drop-in
replacement for one service that's suffering under performance constraints and helping you port that into IncludeOS and getting better performance and better security.
I'm personally kind of curious about this from an experimenting with hardware kind of perspective.
What am I allowed to do?
Could I write my own operating system in C++
starting from where you left off?
Yes, and please, please use IncludoS
for that kind of playful experimentation.
I mean, that's where I come from.
It really is the curiosity that drove me to do this project
the first kind of discovery that you
do is exactly booting up
in 16-bit mode and playing around with that
so I think the hardest part about
developing an operating system
from my perspective is just getting started
getting all the toolchain
laid out, having
standard libraries
compiled for your platform, you know, just making the whole tool chain, getting a debugger up and
running, all that kind of stuff. So within CluedOS, when you boot, I mean, you jump to a place in the
code called service start, and please just, you know, go right in there and do whatever. You have full access to
hardware. You have access to, so for example, if you use Kimu, which is the process that manages
the KVM instance in Linux and also on Mac, you can just, you know, add as command line parameters
to Kimu different kinds of hardware options. So you can say,
let me have a couple of network drives here.
Let me have several hard drives.
Give me
a sound card. Give me USB.
You could just ask for the hardware
you want, and it will be present.
So for
example, USB, you're not going to
get support for that
in IncludeOS, since currently you're not going to get support for that in IncludeOS
since currently we're targeting cloud
where you typically wouldn't go and plug in a USB device.
But you can just start writing to that device directly
using inline assembler or whatever.
And you can also write to address zero.
I thought that was pretty cool.
I mean, it's just an address, right?
So a null pointer does not cause a segfault.
Well, I mean, you could easily implement that
because you do set up segments,
and we do set up...
We don't use virtual memory.
We don't enable that.
You can enable that if you want to experiment with it.
We don't.
But we do set up segments.
But by default, we just have one big segment where everything is read and write
because essentially it's just your program.
So I look at virtual machines or Includo as virtual machines as just processes
that are more self-contained.
And switching from one version machine to the other
is essentially just a glorified context switch.
So do you have a published memory map
or a hardware guide of some kind to let us know,
well, if you overwrite memory location 1000,
you're overwriting the network driver or whatever?
Right, right.
Well, I mean, what we do is that we just use...
There are memory maps out there that will kind of tell you
exactly, for example, where hardware and mapped memory devices are, etc.
And then what you can do within CluedOS is to just ask...
You can read off the end symbol.
The end symbol will tell you where the service is done.
And then after that, there is the heap.
And then you can also ask the operating system where the heap ends.
And after that, it's all yours. Of course, calling malloc repeatedly might cause a system call to Sbreak,
which will essentially, in Includo, it will just increment the pointer with whatever malloc
asked for. So malloc typically, you know, it looks in its buckets to see if there's
room for what you asked for. If there isn't, it will ask for a couple more pages of memory. But if you don't use malloc or new dynamic allocation, then essentially
the heap isn't going to grow. Of course, provided that you don't use, for example,
the network stack that might allocate something dynamically. But I think another way you could go forward with that is just to say,
you know, let me just decide on how big the heap should be,
and then, you know, fire up memory, I'll just place my stuff.
Or you could place it at error zero.
We don't put anything there, so.
It's really cool to actually look into what actually is at a resume.
I thought it was pretty fun to experiment with the old 16-bit mode.
So it turns out there was actually interrupt vectors there, the old way of handling interrupts.
So the old style interrupt handlers in 16-bit modes will be located there.
So it's a small table.
But we don't use it anymore because with 30-t-boot mode,
there's a different way of handling interrupts.
So, yeah, that part of memory is available.
So, yeah, the service is in the middle,
and then the stack actually grows from the service and towards address zero.
And then the heap grows the other way.
So it's pretty simple, and apart
from that, it's all yours.
Cool. But of course,
it's also important to mention that for users
that they don't want to
deal with all of this, you really, really
don't have to. Right.
Right. So just
use smart pointers
or use the standard containers,
create a vector
put stuff in there, the vector
is going to call new, which is again
going to call malloc, it's going to
dynamically allocate and deallocate
exactly as you expect
and you really don't need
to access
memory directly, but of course
I think it's great fun to do so
for experiments. Also there's video map course, I think it's great fun to do so for experiments.
Also, there's video map memory.
I think that would be interesting for Commodore 64 programmers.
You can write...
We have a small game.
It's a snake game currently implemented
by just writing bytes of data to the area
in the first megabyte of memory
that's directly mapped to the VGA default
screen. That's exactly what I was wondering about, but I didn't want to go that route on the podcast.
Maybe it's worth asking, since we've kind of gone pretty deep into how IncludeOS works,
if you're writing a microservice using IncludeOS, what's kind of a very simple one look like from the programmer's perspective?
What are you writing?
Well, so, for example, you might want to write a small application that connects to a database.
You know, it registers users, user profiles for your website.
It does authentication, et cetera, by a RESTful API.
So what we're doing with core in CluedOS,
you're not going to get anything higher up in the stack than TCP.
But then for CppCon, we're going to open up some more code. We're actually doing a small asynchronous web application framework
where everything is asynchronous,
where it's really simple to just say,
okay, I want an HTTP web server,
and whenever there's a new connection coming in,
I want this to happen.
You can from there connect to a database,
authenticate users.
You can also serve
static web content. We're making a
really simple way to do that
so that you can, for example,
put in
all static content, which could be
really fancy JavaScript,
Angular, JS, React,
whatever.
It could be your HTML. It could be the whole user interface that's served statically.
And then that JavaScript could again access the RESTful API,
which is then implemented in C++ that can do computation.
It can do database lookups.
It can, yeah.
And also you'll get a lot of high-level stuff like, you know, cookies.
You'll get JSON parsing of the body for REST API.
So we use, yeah, so we use RapidJ JSON for that.
So you'll just get a rapid JSON object with whatever the web page sent you in JSON.
And you can access that with C++.
So our current goal is just to write something that's actually pretty similar to Node.js.
And it might seem like a strange choice,
but the reason why we did it is because Node is completely event-based,
which we are as well.
Node is single-threaded, which we are as well.
So a lot of the code we're going to open up
is going to look quite a lot like writing a Node.js service
with the Express framework for doing REST APIs.
So obviously we're a pretty small team,
and it's going to be limited what kind of stuff you'll find from us,
but it's going to be enough so that you guys can join us
and implement whatever isn't there.
So up until
now, I think Include Us has been about
the kernel and about
low-level stuff up
to TCP, and now
after CppCon,
we're going to be at the
point where application programmers can
come in and just write a simple
web service,
one that monitors a website to see if there's a change,
monitors to see if your other virtual machines are up.
You can write a DHCP server or low-level stuff like that.
But we really just want to make a good platform
for writing really
tiny, efficient, secure web services. And then from there, I think it's up to the community and
to the industry to drive development further. On GitHub right now, it says you're at version
0.8.1. Are you expecting to hit 1.0 around CppCon? Well, I don't think so.
I mean, the reason for that is that we are all...
I have to be honest.
I'd call myself an intermediate C++ programmer.
I mean, I'm definitely really interested.
I did teach C++ in college for several years,
so I really had to familiarize myself with the language.
But I have around five years of C++ development under my belt.
And people say you need 10 years to become an expert.
So I don't think I can call myself a true expert in C++.
And so I'm really looking forward to getting feedback from people. And I think the industry and the community, you know, they will
decide, you know, if we did what we got right and what we got wrong. And we're going to listen to
that. And we really want to be core guidelines compliant. So we're working hard at that. It's a lot of guidelines, and obviously
at the low level, the classical
way of implementing anything in the network stack is
really, it's obvious when you read the
RFCs that define all these protocols, it's just completely
obvious that these guys
are thinking in C when they're doing it, and
so you might still find some remnants of that,
but we're really working hard to remove all of the C stuff
that doesn't have to be there, and I think we've gotten pretty far.
So 1.0, for me, I hope we can get there by the end of the year.
But it really depends on what you guys say,
what the experts say, and what the community is saying.
So hopefully we'll get a lot of people playing around with it
and telling us what works and what doesn't work.
I can't speak for Jason, but I can't consider myself an expert either.
I'm just looking forward to playing with it.
That's great.
That's really all we want.
We want people to play with it.
And really, don't be shy. I think it's important for me to state that, you know,
we're really like a group of hackers. We love doing this stuff and, and, you know,
we don't presume to be the experts. We really try to make the best possible pure C++ implementation. And we'd like your
feedback. Okay. It's been
great having you on the show. Where can people
find more about you and more about IncludeOS
online? Right. You should
definitely go to our GitHub repository.
You'll find a wiki there.
We hope to keep that, or
we try to keep that pretty up-to-date.
You can also go to includeOS.org.
That page is a bit outdated, but we're working on a new version.
Eventually, that will be implemented in IncludeOS.
Once we hit 1.0, we're definitely going to do that.
You should also go to devil.unikernel.org. That's the place where it's a kind of a forum for all kinds of Unikernel-related stuff.
So anything we write elsewhere is going to also be mentioned there.
Also, please come chat with us in our Jitter channel.
There's a button on the GitHub page where you can click on that says chat with us on Twitter.
And we hang out there all the time.
So don't be shy.
Come in.
Ask stupid questions.
That's what we're there for.
Okay.
It's been great having you on today, Alfred.
And great being here.
Thanks a lot.
Thanks for joining us.
I can't speak for Jason, but I can't consider myself an expert either.
Thanks so much for listening as we chat about C++. I'd love to hear Jason, but I can't consider myself an expert either. Thanks so much for
listening as we chat about C++. I'd love to hear what you think of the podcast. Please let me know
if we're discussing the stuff you're interested in, or if you have a suggestion for a topic,
I'd love to hear that also. You can email all your thoughts to feedback at cppcast.com. I'd
also appreciate if you can follow CppCast on Twitter and like CppCast on Facebook.
And of course, you can find all that info and the show notes on the podcast website at cppcast.com.
Theme music for this episode is provided by podcastthemes.com.