#run-time #async #timer #threaded #bad #impl #educational

tl-async-runtime

A bad runtime impl for educational purposes only

3 releases

0.1.2 Mar 4, 2022
0.1.1 Mar 3, 2022
0.1.0 Mar 3, 2022

#876 in Asynchronous

MIT license

27KB
534 lines

tl-async-runtime

A fairly basic runtime example in <600 lines of logic

Features

  • Single threaded async
  • Multi threaded async
  • Timer support
  • Basic IO (only TCP for now)

Bugs

Many.

Architecure

The runtime is first created by calling the block_on function, passing in a future. The runtime will start up the threads and spawns the given future on the runtime.

At this point, all threads are 'workers'. Workers do a few things

  1. The thread run some basic book-keeping tasks (more on this later).
  2. Request a ready task from the runtime
    • If it can get a task, it will poll it once
    • If it can't get a task, it will 'park' the thread
  3. Repeat

The main thread does 1 extra step, which is polling the channel future returned by the initial spawn. This is so that we can exit as soon as that task has been completed.

Bookkeeping

The core of the async runtime is scheduling tasks and managing the threads.

There's only 2 steps to this:

  1. Looping through elapsed timers and putting them in a ready state
  2. Polling the OS for events and dispatching them

Timers

The timers are very rudementary. When a timer is first polled, it gets the thread-local executor object and pushes a (Time, TaskId) pair into a priority queue (ordered by time ascending).

The book-keepers will loop through this priority queue and send the respective task IDs into the ready queue.

OS Events

Using mio, event sources are registered with the OS when they are created.

When events are requested for a specific source, a [RegistrationToken -> Sender] entry is pushed into a hashmap.

The book-keepers will poll the OS for new events. If a corresponding token is found in the hashmap, it will send the event along the channel. Since it's using a future-aware channel, it will auto-wake any tasks that are waiting for the event

Dependencies

~5–15MB
~163K SLoC