Browse Source

Add different variants for `once_do`

gingerBill 2 years ago
parent
commit
f8452bf1fc
1 changed files with 59 additions and 2 deletions
  1. 59 2
      core/sync/extended.odin

+ 59 - 2
core/sync/extended.odin

@@ -282,7 +282,15 @@ Once :: struct {
 }
 
 // once_do calls the procedure fn if and only if once_do is being called for the first for this instance of Once.
-once_do :: proc(o: ^Once, fn: proc()) {
+once_do :: proc{
+	once_do_without_data,
+	once_do_without_data_contextless,
+	once_do_with_data,
+	once_do_with_data_contextless,
+}
+
+// once_do_without_data calls the procedure fn if and only if once_do_without_data is being called for the first for this instance of Once.
+once_do_without_data :: proc(o: ^Once, fn: proc()) {
 	@(cold)
 	do_slow :: proc(o: ^Once, fn: proc()) {
 		guard(&o.m)
@@ -292,12 +300,61 @@ once_do :: proc(o: ^Once, fn: proc()) {
 		}
 	}
 
-	
 	if atomic_load_explicit(&o.done, .Acquire) == false {
 		do_slow(o, fn)
 	}
 }
 
+// once_do_without_data calls the procedure fn if and only if once_do_without_data is being called for the first for this instance of Once.
+once_do_without_data_contextless :: proc(o: ^Once, fn: proc "contextless" ()) {
+	@(cold)
+	do_slow :: proc(o: ^Once, fn: proc "contextless" ()) {
+		guard(&o.m)
+		if !o.done {
+			fn()
+			atomic_store_explicit(&o.done, true, .Release)
+		}
+	}
+
+	if atomic_load_explicit(&o.done, .Acquire) == false {
+		do_slow(o, fn)
+	}
+}
+
+// once_do_with_data calls the procedure fn if and only if once_do_with_data is being called for the first for this instance of Once.
+once_do_with_data :: proc(o: ^Once, fn: proc(data: rawptr), data: rawptr) {
+	@(cold)
+	do_slow :: proc(o: ^Once, fn: proc(data: rawptr), data: rawptr) {
+		guard(&o.m)
+		if !o.done {
+			fn(data)
+			atomic_store_explicit(&o.done, true, .Release)
+		}
+	}
+
+	if atomic_load_explicit(&o.done, .Acquire) == false {
+		do_slow(o, fn, data)
+	}
+}
+
+// once_do_with_data_contextless calls the procedure fn if and only if once_do_with_data_contextless is being called for the first for this instance of Once.
+once_do_with_data_contextless :: proc "contextless" (o: ^Once, fn: proc "contextless" (data: rawptr), data: rawptr) {
+	@(cold)
+	do_slow :: proc "contextless" (o: ^Once, fn: proc "contextless" (data: rawptr), data: rawptr) {
+		guard(&o.m)
+		if !o.done {
+			fn(data)
+			atomic_store_explicit(&o.done, true, .Release)
+		}
+	}
+
+	if atomic_load_explicit(&o.done, .Acquire) == false {
+		do_slow(o, fn, data)
+	}
+}
+
+
+
 
 
 // A Parker is an associated token which is initially not present: