Skip to content
Sword

Tasks

This is what the language is for, so it has a chapter of its own. The shape of it:

import "std/mem"
func fill(mut xs []i64, v i64) {
for i in 0..xs.len {
xs[i] = v
}
}
func main() !int {
mut backing := [2048]u8{}
mut arena := mem.NewArena(backing[..])
mut data := mem.Alloc[i64](&arena, 64) orelse return error.OutOfMemory
scope {
for part in data.chunks(8) {
spawn fill(part, 2)
}
}
mut total i64 = 0
for i in 0..data.len {
total += data[i]
}
return int(total % 100)
}

Eight tasks, each writing its own piece. The closing brace of scope waits for all of them. Nothing here is a convention you have to remember — the compiler rejects the versions of this program that would race.

When tasks really do need to share one structure, shared[T] puts a mutex in front of it and lock is the only way in:

lock m := table {
try m.Set(key, 1)
}

The brace releases it, and so does every other way out of the block.