Creating Your Own Runtime 272 Epilogue So, you have reached the end. First of all, congratulations! Y ou've come to the end of quite a journey! We started by talking about concurrency and parallelism in Chapter 1. We even covered a bit about the history, CPUs and OSs, hardware, and interrupts. In Chapter 2, we discussed how programming languages modeled asynchronous program flow. We introduced coroutines and how stackful and stackless coroutines differ. We discussed OS threads, fibers/green threads, and callbacks and their pros and cons. Then, in Chapter 3, we took a look at OS-backed event queues such as epoll, kqueue, and IOCP. We even took quite a deep dive into syscalls and cross-platform abstractions. In Chapter 4, we hit some quite difficult terrain when implementing our own mio-like event queue using epoll. We even had to learn about the difference between edge-triggered and level-triggered events. If Chapter 4 was somewhat rough terrain, Chapter 5 was more like climbing Mount Everest. No one expects you to remember everything covered there, but you read through it and have a working example you can use to experiment with. We implemented our own fibers/green threads, and while doing so, we learned a little bit about processor architectures, ISAs, ABIs, and calling conventions. We even learned quite a bit about inline assembly in Rust. If you ever felt insecure about the stack versus heap difference, you surely understand it now that you've created stacks that we made our CPU jump to ourselves. In Chapter 6, we got a high-level introduction to asynchronous Rust, before we took a deep dive from Chapter 7 and onward, starting with creating our own coroutines and our own coroutine/wait syntax. In Chapter 8, we created the first versions of our own runtime while discussing basic runtime design. We also deep-dived into reactors, executors, and wakers. In Chapter 9, we improved our runtime and discovered the dangers of self-referential structs in Rust. We then took a thorough look at pinning in Rust and how that helped us solve the problems we got into. Finally, in Chapter 10, we saw that by making some rather minor changes, our runtime became a fully functioning runtime for Rust futures. We rounded everything off by discussing some well-known challenges with asynchronous Rust and some expectations for the future. The Rust community is very inclusive and welcoming, and we' d happily welcome you to engage and contribute if you find this topic interesting and want to learn more. One of the ways asynchronous Rust gets better is through contributions by people with all levels of experience. If you want to get involved, then the async work group ( https://rust-lang. github. io/wg-async/welcome. html ) is a good place to start. There is also a very active community centered around the Tokio project (https://github. com/tokio-rs/tokio/blob/master/CONTRIBUTING. md ), and many, many more depending on what specific area you want to dive deeper into. Don't be afraid to join the different channels and ask questions.