wait_group.odin 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. package sync
  2. import "core:intrinsics"
  3. Wait_Group :: struct {
  4. counter: int,
  5. mutex: Blocking_Mutex,
  6. cond: Condition,
  7. }
  8. wait_group_init :: proc(wg: ^Wait_Group) {
  9. wg.counter = 0;
  10. blocking_mutex_init(&wg.mutex);
  11. condition_init(&wg.cond, &wg.mutex);
  12. }
  13. wait_group_destroy :: proc(wg: ^Wait_Group) {
  14. condition_destroy(&wg.cond);
  15. blocking_mutex_destroy(&wg.mutex);
  16. }
  17. wait_group_add :: proc(wg: ^Wait_Group, delta: int) {
  18. if delta == 0 {
  19. return;
  20. }
  21. blocking_mutex_lock(&wg.mutex);
  22. defer blocking_mutex_unlock(&wg.mutex);
  23. intrinsics.atomic_add(&wg.counter, delta);
  24. if wg.counter < 0 {
  25. panic("sync.Wait_Group negative counter");
  26. }
  27. if wg.counter == 0 {
  28. condition_broadcast(&wg.cond);
  29. if wg.counter != 0 {
  30. panic("sync.Wait_Group misuse: sync.wait_group_add called concurrently with sync.wait_group_wait");
  31. }
  32. }
  33. }
  34. wait_group_done :: proc(wg: ^Wait_Group) {
  35. wait_group_add(wg, -1);
  36. }
  37. wait_group_wait :: proc(wg: ^Wait_Group) {
  38. blocking_mutex_lock(&wg.mutex);
  39. defer blocking_mutex_unlock(&wg.mutex);
  40. if wg.counter != 0 {
  41. condition_wait_for(&wg.cond);
  42. if wg.counter != 0 {
  43. panic("sync.Wait_Group misuse: sync.wait_group_add called concurrently with sync.wait_group_wait");
  44. }
  45. }
  46. }