3 releases
0.1.2 | Mar 4, 2022 |
---|---|
0.1.1 | Mar 3, 2022 |
0.1.0 | Mar 3, 2022 |
#958 in Asynchronous
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
- The thread run some basic book-keeping tasks (more on this later).
- 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
- 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:
- Looping through elapsed timers and putting them in a ready state
- 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
~169K SLoC