Parallel programs run on many threads of execution at the same time.
To make them safe and predictable, we need to ensure they’re not conflicting with each other as they operate on data.
Parallel programs run on many threads of execution at the same time.
To make them safe and predictable, we need to ensure they’re not conflicting with each other as they operate on data.
Preventing data races can be boiled down to two simple rules:
If I’m reading data, no other thread can write to that data at the same time.
If I’m writing data, no other thread can write to that data at the same time.
Soon we’ll see how Savi’s type system exists to prove at compile time that your programs satisfy these two fundamental rules. But first, let’s see some other common ways to address these concerns.
A parallel program can be made safe by simply never sharing any data among threads. Data is strictly partitioned so that each thread is an exclusive owner of its data, and no other thread can read or write to that data, so they will never break the two rules.
We can extend the “share nothing” model to allow for transferring ownership of mutable data from one thread to another. As long as we can guarantee that the old thread fully stops reading or writing the data before the new ones starts using it, we satisfy the two rules. However, in many programming languages upholding this guarantee is a matter of personal discipline, without enforcement at the language level.
Functional programming languages usually aim to satisfy these rules by preventing writes at the language level, enforcing that a program is composed only of immutable data structures. Data can be shared among threads freely without breaking the two rules, because both of the safety rules are about preventing concurrent writes (which are not possible in the language).
Savi’s concurrency-aware type system allows us to write programs using all of the above patterns, coexisting in the same program with a static guarantee of safety by enforcing those concurrency patterns at compile time.
TODO: Illustration
In strongly typed languages, values have types that describe the shape of the data and restrictions on what functions they are compatible with, and these are checked at compile time to guarantee type safety of your program.
Savi takes this idea further: Savi types have an additional notation called reference capabilities (or caps, for short) that describe restrictions on reading and writing to the associated data, and these are checked at compile time to guarantee concurrency safety of your program.
TODO: Illustration