No Data Races
● Advanced4 minBefore this: Tasks, Values, Not ReferencesSpec 9.5
Each task works on its own copy of a value, so two tasks can't change the same thing at once. To share on purpose, use Shared.
A lambda, and so each task, gets its own copy of count. Changing the copy doesn't change the outside one, and the compiler warns about it:
fn main() {
let count = 0
const _ = [1, 2, 3].parallel_map(n => {
count += 1
n
})
print(count)
}The compiler warned, then the program ran:
kavach run copy.kav
warning: `count` is a copy inside this lambda: the change doesn't reach the outside. Give the value back instead, or use `Shared` to share it (spec 3.3)0
That is what makes data races impossible: there is nothing two tasks share by accident. To count across tasks, share the value on purpose with Shared, which locks for you:
fn main() {
const visits = Shared(0)
const _ = [1, 2, 3, 4, 5].parallel_map(n => {
visits.update(v => v + 1)
n
})
print(visits.get())
}The program ran and printed:
kavach run shared.kav
5In most languages, two threads adding to one counter can lose updates, a bug that shows up only sometimes. In Kavach the only shared value is a Shared, and its update takes the lock itself: there is no "remember to lock". See Shared State.
What Kavach does for you
No data races
Tasks can't change the same value at the same time: the compiler refuses code that could.