This document outlines coroutines as a way to run multiple tasks with a single CPU by allowing tasks to yield control back and forth. It discusses processes, threads, and events, and then introduces coroutines as a way to run tasks concurrently without threads. It presents three C coroutine library approaches - protothreads using switch/case, state threads using longjmp/setjmp, and coroutines using ucontext. It provides an example of a protothread implementation and references for further reading.