Browse Source

Add helgrind markers to package sync

gingerBill 2 years ago
parent
commit
117c0cceb1
2 changed files with 67 additions and 0 deletions
  1. 8 0
      core/sync/extended.odin
  2. 59 0
      core/sync/primitives_internal.odin

+ 8 - 0
core/sync/extended.odin

@@ -1,6 +1,8 @@
 package sync
 package sync
 
 
 import "core:time"
 import "core:time"
+import vg "core:sys/valgrind"
+_ :: vg
 
 
 // A Wait_Group waits for a collection of threads to finish
 // A Wait_Group waits for a collection of threads to finish
 //
 //
@@ -108,6 +110,9 @@ Barrier :: struct {
 }
 }
 
 
 barrier_init :: proc "contextless" (b: ^Barrier, thread_count: int) {
 barrier_init :: proc "contextless" (b: ^Barrier, thread_count: int) {
+	when ODIN_ARCH == .amd64 {
+		vg.helgrind_barrier_resize_pre(b, uint(thread_count))
+	}
 	b.index = 0
 	b.index = 0
 	b.generation_id = 0
 	b.generation_id = 0
 	b.thread_count = thread_count
 	b.thread_count = thread_count
@@ -116,6 +121,9 @@ barrier_init :: proc "contextless" (b: ^Barrier, thread_count: int) {
 // Block the current thread until all threads have rendezvoused
 // Block the current thread until all threads have rendezvoused
 // Barrier can be reused after all threads rendezvoused once, and can be used continuously
 // Barrier can be reused after all threads rendezvoused once, and can be used continuously
 barrier_wait :: proc "contextless" (b: ^Barrier) -> (is_leader: bool) {
 barrier_wait :: proc "contextless" (b: ^Barrier) -> (is_leader: bool) {
+	when ODIN_ARCH == .amd64 {
+		vg.helgrind_barrier_wait_pre(b)
+	}
 	guard(&b.mutex)
 	guard(&b.mutex)
 	local_gen := b.generation_id
 	local_gen := b.generation_id
 	b.index += 1
 	b.index += 1

+ 59 - 0
core/sync/primitives_internal.odin

@@ -2,20 +2,31 @@
 package sync
 package sync
 
 
 import "core:time"
 import "core:time"
+import vg "core:sys/valgrind"
+_ :: vg
 
 
 _Sema :: struct {
 _Sema :: struct {
 	atomic: Atomic_Sema,
 	atomic: Atomic_Sema,
 }
 }
 
 
 _sema_post :: proc "contextless" (s: ^Sema, count := 1) {
 _sema_post :: proc "contextless" (s: ^Sema, count := 1) {
+	when ODIN_ARCH == .amd64 {
+		vg.helgrind_sem_post_pre(s)
+	}
 	atomic_sema_post(&s.impl.atomic, count)
 	atomic_sema_post(&s.impl.atomic, count)
 }
 }
 
 
 _sema_wait :: proc "contextless" (s: ^Sema) {
 _sema_wait :: proc "contextless" (s: ^Sema) {
 	atomic_sema_wait(&s.impl.atomic)
 	atomic_sema_wait(&s.impl.atomic)
+	when ODIN_ARCH == .amd64 {
+		vg.helgrind_sem_wait_post(s)
+	}
 }
 }
 
 
 _sema_wait_with_timeout :: proc "contextless" (s: ^Sema, duration: time.Duration) -> bool {
 _sema_wait_with_timeout :: proc "contextless" (s: ^Sema, duration: time.Duration) -> bool {
+	when ODIN_ARCH == .amd64 {
+		defer vg.helgrind_sem_wait_post(s)
+	}
 	return atomic_sema_wait_with_timeout(&s.impl.atomic, duration)
 	return atomic_sema_wait_with_timeout(&s.impl.atomic, duration)
 }
 }
 
 
@@ -26,6 +37,11 @@ _Recursive_Mutex :: struct {
 }
 }
 
 
 _recursive_mutex_lock :: proc "contextless" (m: ^Recursive_Mutex) {
 _recursive_mutex_lock :: proc "contextless" (m: ^Recursive_Mutex) {
+	when ODIN_ARCH == .amd64 {
+		vg.helgrind_mutex_lock_pre(m, false)
+		defer vg.helgrind_mutex_lock_post(m)
+	}
+
 	tid := Futex(current_thread_id())
 	tid := Futex(current_thread_id())
 	for {
 	for {
 		prev_owner := atomic_compare_exchange_strong_explicit(&m.impl.owner, 0, tid, .Acquire, .Acquire)
 		prev_owner := atomic_compare_exchange_strong_explicit(&m.impl.owner, 0, tid, .Acquire, .Acquire)
@@ -41,6 +57,11 @@ _recursive_mutex_lock :: proc "contextless" (m: ^Recursive_Mutex) {
 }
 }
 
 
 _recursive_mutex_unlock :: proc "contextless" (m: ^Recursive_Mutex) {
 _recursive_mutex_unlock :: proc "contextless" (m: ^Recursive_Mutex) {
+	when ODIN_ARCH == .amd64 {
+		vg.helgrind_mutex_unlock_pre(m)
+		defer vg.helgrind_mutex_unlock_post(m)
+	}
+
 	m.impl.recursion -= 1
 	m.impl.recursion -= 1
 	if m.impl.recursion != 0 {
 	if m.impl.recursion != 0 {
 		return
 		return
@@ -71,14 +92,26 @@ when ODIN_OS != .Windows {
 	}
 	}
 
 
 	_mutex_lock :: proc "contextless" (m: ^Mutex) {
 	_mutex_lock :: proc "contextless" (m: ^Mutex) {
+		when ODIN_ARCH == .amd64 {
+			vg.helgrind_mutex_lock_pre(m, false)
+			defer vg.helgrind_mutex_lock_post(m)
+		}
 		atomic_mutex_lock(&m.impl.mutex)
 		atomic_mutex_lock(&m.impl.mutex)
 	}
 	}
 
 
 	_mutex_unlock :: proc "contextless" (m: ^Mutex) {
 	_mutex_unlock :: proc "contextless" (m: ^Mutex) {
+		when ODIN_ARCH == .amd64 {
+			vg.helgrind_mutex_unlock_pre(m)
+			defer vg.helgrind_mutex_unlock_post(m)
+		}
 		atomic_mutex_unlock(&m.impl.mutex)
 		atomic_mutex_unlock(&m.impl.mutex)
 	}
 	}
 
 
 	_mutex_try_lock :: proc "contextless" (m: ^Mutex) -> bool {
 	_mutex_try_lock :: proc "contextless" (m: ^Mutex) -> bool {
+		when ODIN_ARCH == .amd64 {
+			vg.helgrind_mutex_lock_pre(m, true)
+			defer vg.helgrind_mutex_lock_post(m)
+		}
 		return atomic_mutex_try_lock(&m.impl.mutex)
 		return atomic_mutex_try_lock(&m.impl.mutex)
 	}
 	}
 
 
@@ -87,18 +120,32 @@ when ODIN_OS != .Windows {
 	}
 	}
 
 
 	_cond_wait :: proc "contextless" (c: ^Cond, m: ^Mutex) {
 	_cond_wait :: proc "contextless" (c: ^Cond, m: ^Mutex) {
+		when ODIN_ARCH == .amd64 {
+			_ = vg.helgrind_cond_wait_pre(c, m)
+			defer _ = vg.helgrind_cond_wait_post(c, m)
+		}
 		atomic_cond_wait(&c.impl.cond, &m.impl.mutex)
 		atomic_cond_wait(&c.impl.cond, &m.impl.mutex)
 	}
 	}
 
 
 	_cond_wait_with_timeout :: proc "contextless" (c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool {
 	_cond_wait_with_timeout :: proc "contextless" (c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool {
+		when ODIN_ARCH == .amd64 {
+			_ = vg.helgrind_cond_wait_pre(c, m)
+			defer _ = vg.helgrind_cond_wait_post(c, m)
+		}
 		return atomic_cond_wait_with_timeout(&c.impl.cond, &m.impl.mutex, duration)
 		return atomic_cond_wait_with_timeout(&c.impl.cond, &m.impl.mutex, duration)
 	}
 	}
 
 
 	_cond_signal :: proc "contextless" (c: ^Cond) {
 	_cond_signal :: proc "contextless" (c: ^Cond) {
+		when ODIN_ARCH == .amd64 {
+			vg.helgrind_cond_signal_pre(c)
+		}
 		atomic_cond_signal(&c.impl.cond)
 		atomic_cond_signal(&c.impl.cond)
 	}
 	}
 
 
 	_cond_broadcast :: proc "contextless" (c: ^Cond) {
 	_cond_broadcast :: proc "contextless" (c: ^Cond) {
+		when ODIN_ARCH == .amd64 {
+			vg.helgrind_cond_broadcast_pre(c)
+		}
 		atomic_cond_broadcast(&c.impl.cond)
 		atomic_cond_broadcast(&c.impl.cond)
 	}
 	}
 
 
@@ -108,11 +155,17 @@ when ODIN_OS != .Windows {
 	}
 	}
 
 
 	_rw_mutex_lock :: proc "contextless" (rw: ^RW_Mutex) {
 	_rw_mutex_lock :: proc "contextless" (rw: ^RW_Mutex) {
+		when ODIN_ARCH == .amd64 {
+			vg.helgrind_rwlock_lock_pre(rw, true)
+		}
 		atomic_rw_mutex_lock(&rw.impl.mutex)
 		atomic_rw_mutex_lock(&rw.impl.mutex)
 	}
 	}
 
 
 	_rw_mutex_unlock :: proc "contextless" (rw: ^RW_Mutex) {
 	_rw_mutex_unlock :: proc "contextless" (rw: ^RW_Mutex) {
 		atomic_rw_mutex_unlock(&rw.impl.mutex)
 		atomic_rw_mutex_unlock(&rw.impl.mutex)
+		when ODIN_ARCH == .amd64 {
+			vg.helgrind_rwlock_unlock_post(rw, true)
+		}
 	}
 	}
 
 
 	_rw_mutex_try_lock :: proc "contextless" (rw: ^RW_Mutex) -> bool {
 	_rw_mutex_try_lock :: proc "contextless" (rw: ^RW_Mutex) -> bool {
@@ -120,11 +173,17 @@ when ODIN_OS != .Windows {
 	}
 	}
 
 
 	_rw_mutex_shared_lock :: proc "contextless" (rw: ^RW_Mutex) {
 	_rw_mutex_shared_lock :: proc "contextless" (rw: ^RW_Mutex) {
+		when ODIN_ARCH == .amd64 {
+			vg.helgrind_rwlock_lock_pre(rw, false)
+		}
 		atomic_rw_mutex_shared_lock(&rw.impl.mutex)
 		atomic_rw_mutex_shared_lock(&rw.impl.mutex)
 	}
 	}
 
 
 	_rw_mutex_shared_unlock :: proc "contextless" (rw: ^RW_Mutex) {
 	_rw_mutex_shared_unlock :: proc "contextless" (rw: ^RW_Mutex) {
 		atomic_rw_mutex_shared_unlock(&rw.impl.mutex)
 		atomic_rw_mutex_shared_unlock(&rw.impl.mutex)
+		when ODIN_ARCH == .amd64 {
+			vg.helgrind_rwlock_unlock_post(rw, false)
+		}
 	}
 	}
 
 
 	_rw_mutex_try_shared_lock :: proc "contextless" (rw: ^RW_Mutex) -> bool {
 	_rw_mutex_try_shared_lock :: proc "contextless" (rw: ^RW_Mutex) -> bool {