// standard library when you are dropped directly into a function.
__thread_initialize :: () {
__tls_base = raw_alloc(alloc.heap_allocator, __tls_size);
+ memory.set(__tls_base, 0, __tls_size);
__initialize(^context);
context.allocator = alloc.heap_allocator;
barrier_wait :: (b: ^Barrier) {
mutex_lock(^b.mutex);
+ defer mutex_unlock(^b.mutex);
local_gen := b.generation;
b.index += 1;
if b.index < b.thread_count {
- mutex_unlock(^b.mutex);
-
while local_gen == b.generation && b.index < b.thread_count {
- condition_wait(^b.cond);
+ condition_wait(^b.cond, ^b.mutex);
}
return;
}
b.index = 0;
b.generation += 1;
condition_broadcast(^b.cond);
-
- mutex_unlock(^b.mutex);
return;
}
\ No newline at end of file
mutex_destroy(^c.mutex);
}
-condition_wait :: (c: ^Condition_Variable) {
- self: Condition_Variable.Node;
-
- critical_section(^c.mutex, #code {
- self.next = c.queue;
- c.queue = ^self;
- semaphore_init(^self.semaphore, 0);
- });
-
- semaphore_wait(^self.semaphore);
+condition_wait :: (c: ^Condition_Variable, m: ^Mutex) {
+ node: Condition_Variable.Node;
+
+ mutex_lock(^c.mutex);
+ node.next = c.queue;
+ c.queue = ^node;
+ semaphore_init(^node.semaphore, 0);
+ mutex_unlock(^c.mutex);
+
+ mutex_unlock(m);
+ semaphore_wait(^node.semaphore);
+ mutex_lock(m);
}
condition_signal :: (c: ^Condition_Variable) {
if c.queue != null {
semaphore_post(^c.queue.semaphore);
- semaphore_destroy(^c.queue.semaphore);
c.queue = c.queue.next;
}
}
while c.queue != null {
semaphore_post(^c.queue.semaphore);
- semaphore_destroy(^c.queue.semaphore);
c.queue = c.queue.next;
}
}
\ No newline at end of file
mutex_destroy(^s.mutex);
}
-semaphore_post :: (s: ^Semaphore) {
+semaphore_post :: (s: ^Semaphore, count := 1) {
scoped_mutex(^s.mutex);
- s.counter += 1;
+ s.counter += count;
__atomic_notify(^s.counter, maximum = 1);
}