sync
Mutexes, condition variables, wait groups, read-write locks, semaphores and once, for coordinating threads.
import sync
When several threads change the same variable they have to take turns, or the result depends on the order the threads happen to run in. A mutex is the simplest answer: each thread takes the lock before touching the data and releases it afterwards.
A wait group is for waiting until several pieces of work are done: call Add before starting them, Done at the end of each, and Wait on the main thread. Every tool in this package is created with a New... function and released with a Destroy... one.
Types
Mutex
struct Mutex| Name | Type | Description |
|---|---|---|
handle | void* | The operating system's lock. |
import sync
mut balance := 0
mut lock := sync.Mutex {}
mut group := sync.WaitGroup {}
func deposit():
repeat 500:
sync.Lock(lock)
balance += 1
sync.Unlock(lock)
end
sync.Done(group)
end
func main:
lock = sync.NewMutex()
group = sync.NewWaitGroup()
sync.Wait(group)
sync.Add(group, 4)
a := spawn(deposit)
b := spawn(deposit)
c := spawn(deposit)
d := spawn(deposit)
sync.Wait(group)
join(a)
join(b)
join(c)
join(d)
println "balance:", balance
sync.DestroyWaitGroup(group)
sync.Destroy(lock)
endCondVar
struct CondVar| Name | Type | Description |
|---|---|---|
handle | void* | The operating system's condition variable. |
import sync
mut ready := false
mut lock := sync.Mutex {}
mut cond := sync.CondVar {}
func producer():
sync.SleepMs(20)
sync.Lock(lock)
ready = true
sync.Broadcast(cond)
sync.Unlock(lock)
end
func main:
lock = sync.NewMutex()
cond = sync.NewCondVar()
start := sync.NowMs()
sync.Lock(lock)
println sync.WaitCondTimeout(cond, lock, 10)
t := spawn(producer)
until not ready:
sync.WaitCond(cond, lock)
end
sync.Unlock(lock)
join(t)
println ready, sync.NowMs() - start >= 20
sync.Signal(cond)
sync.DestroyCondVar(cond)
sync.Destroy(lock)
endWaitGroup
struct WaitGroup| Name | Type | Description |
|---|---|---|
counter | i64* | The number of unfinished pieces of work. |
mu | void* | The internal lock. |
cv | void* | The internal condition variable. |
The example for this item is shown with the ones above: sync-Mutex.salam
RWMutex
struct RWMutex| Name | Type | Description |
|---|---|---|
state | i64* | The internal state: the readers, the writer and the waiting writers. |
mu | void* | The internal lock. |
cv | void* | The internal condition variable. |
import sync
func main:
rw := sync.NewRWMutex()
sync.RLock(rw)
sync.RLock(rw)
println "two readers together"
sync.RUnlock(rw)
sync.RUnlock(rw)
sync.WLock(rw)
println "one writer alone"
sync.WUnlock(rw)
sync.DestroyRWMutex(rw)
sem := sync.NewSemaphore(2)
sync.Acquire(sem)
println sync.TryAcquire(sem), sync.TryAcquire(sem)
sync.Release(sem)
println sync.TryAcquire(sem)
sync.DestroySemaphore(sem)
once := sync.NewOnce()
repeat 3:
sync.Do(once, (): println "only once" end)
end
sync.DestroyOnce(once)
endSemaphore
struct Semaphore| Name | Type | Description |
|---|---|---|
permits | i64* | The number of free permits. |
mu | void* | The internal lock. |
cv | void* | The internal condition variable. |
The example for this item is shown with the ones above: sync-RWMutex.salam
Once
struct Once| Name | Type | Description |
|---|---|---|
done | i64* | Whether the function has run. |
mu | void* | The internal lock. |
The example for this item is shown with the ones above: sync-RWMutex.salam
Functions
NewMutex
func NewMutex(): MutexThe example for this item is shown with the ones above: sync-Mutex.salam
Lock
func Lock(m: Mutex): intThe example for this item is shown with the ones above: sync-Mutex.salam
Unlock
func Unlock(m: Mutex): intThe example for this item is shown with the ones above: sync-Mutex.salam
Destroy
func Destroy(m: Mutex)The example for this item is shown with the ones above: sync-Mutex.salam
SleepMs
func SleepMs(ms: int)The example for this item is shown with the ones above: sync-CondVar.salam
NewCondVar
func NewCondVar(): CondVarThe example for this item is shown with the ones above: sync-CondVar.salam
WaitCond
func WaitCond(cv: CondVar, m: Mutex)The example for this item is shown with the ones above: sync-CondVar.salam
WaitCondTimeout
func WaitCondTimeout(cv: CondVar, m: Mutex, ms: i64): boolWaitCond, but for at most ms milliseconds. It returns false when the time runs out.The example for this item is shown with the ones above: sync-CondVar.salam
NowMs
func NowMs(): i64The example for this item is shown with the ones above: sync-CondVar.salam
Signal
func Signal(cv: CondVar)The example for this item is shown with the ones above: sync-CondVar.salam
Broadcast
func Broadcast(cv: CondVar)The example for this item is shown with the ones above: sync-CondVar.salam
DestroyCondVar
func DestroyCondVar(cv: CondVar)The example for this item is shown with the ones above: sync-CondVar.salam
NewWaitGroup
func NewWaitGroup(): WaitGroupThe example for this item is shown with the ones above: sync-Mutex.salam
Add
func Add(wg: WaitGroup, delta: i64)delta.The example for this item is shown with the ones above: sync-Mutex.salam
Done
func Done(wg: WaitGroup)The example for this item is shown with the ones above: sync-Mutex.salam
Wait
func Wait(wg: WaitGroup)The example for this item is shown with the ones above: sync-Mutex.salam
DestroyWaitGroup
func DestroyWaitGroup(wg: WaitGroup)The example for this item is shown with the ones above: sync-Mutex.salam
NewRWMutex
func NewRWMutex(): RWMutexThe example for this item is shown with the ones above: sync-RWMutex.salam
RLock
func RLock(rw: RWMutex)The example for this item is shown with the ones above: sync-RWMutex.salam
RUnlock
func RUnlock(rw: RWMutex)The example for this item is shown with the ones above: sync-RWMutex.salam
WLock
func WLock(rw: RWMutex)The example for this item is shown with the ones above: sync-RWMutex.salam
WUnlock
func WUnlock(rw: RWMutex)The example for this item is shown with the ones above: sync-RWMutex.salam
DestroyRWMutex
func DestroyRWMutex(rw: RWMutex)The example for this item is shown with the ones above: sync-RWMutex.salam
NewSemaphore
func NewSemaphore(permits: i64): SemaphoreThe example for this item is shown with the ones above: sync-RWMutex.salam
Acquire
func Acquire(sem: Semaphore)The example for this item is shown with the ones above: sync-RWMutex.salam
TryAcquire
func TryAcquire(sem: Semaphore): boolThe example for this item is shown with the ones above: sync-RWMutex.salam
Release
func Release(sem: Semaphore)The example for this item is shown with the ones above: sync-RWMutex.salam
DestroySemaphore
func DestroySemaphore(sem: Semaphore)The example for this item is shown with the ones above: sync-RWMutex.salam
NewOnce
func NewOnce(): OnceThe example for this item is shown with the ones above: sync-RWMutex.salam
Do
func Do(o: Once, f: func())The example for this item is shown with the ones above: sync-RWMutex.salam
DestroyOnce
func DestroyOnce(o: Once)The example for this item is shown with the ones above: sync-RWMutex.salam