Concurrency
Jda has built-in concurrency primitives: lightweight green threads, typed channels, atomics, and deadlock detection.
Green Threads (J-Threads)
spawn launches a function in a new green thread:
fn worker(id: i64) {
print("worker ")
print_i64(id)
print("\n")
}
fn main() -> i64 {
spawn worker(1)
spawn worker(2)
spawn worker(3)
ret 0
}J-Threads are cooperatively scheduled and much cheaper than OS threads. You can spawn thousands of them.
Channels
Channels provide typed communication between threads:
fn producer(ch: Channel<i64>) {
for i in range(100) {
channel_send(ch, i)
}
channel_close(ch)
}
fn consumer(ch: Channel<i64>) {
loop channel_is_open(ch) {
let val = channel_recv(ch)
print_i64(val)
print(" ")
}
print("\n")
}
fn main() -> i64 {
let ch = channel_new<i64>()
spawn producer(ch)
spawn consumer(ch)
ret 0
}channel_send blocks if the channel is full. channel_recv blocks if the channel is empty. channel_close signals that no more values will be sent.
Fan-Out Pattern
Distribute work across multiple workers:
fn worker(id: i64, jobs: Channel<i64>, results: Channel<i64>) {
loop channel_is_open(jobs) {
let job = channel_recv(jobs)
let result = process(job)
channel_send(results, result)
}
}
fn main() -> i64 {
let jobs = channel_new<i64>()
let results = channel_new<i64>()
// spawn 4 workers
for i in range(4) {
spawn worker(i, jobs, results)
}
// send 100 jobs
for i in range(100) {
channel_send(jobs, i)
}
channel_close(jobs)
ret 0
}Atomics
For shared mutable state without channels:
let counter = atomic_new(0)
fn increment() {
atomic_add(counter, 1)
}
fn main() -> i64 {
for i in range(1000) {
spawn increment()
}
let val = atomic_load(counter)
print_i64(val)
ret 0
}| Function | Description |
|---|---|
atomic_new(val) | Create atomic variable |
atomic_load(a) | Read current value |
atomic_store(a, val) | Write value |
atomic_add(a, val) | Add and return old value |
atomic_cas(a, expected, new) | Compare-and-swap |
Deadlock Detection
Jda includes built-in deadlock detection. If all threads are blocked waiting on channels and no progress can be made, the runtime reports the deadlock and exits with an error message showing which threads are blocked and on which channels.
Race Detection
Use jda race to detect data races in concurrent programs:
jda race myapp.jdaThis compiles with instrumentation for epoch-based happens-before analysis and reports any detected races.