synchronization

This commit is contained in:
Tove 2025-01-30 07:19:36 +01:00
parent a8d5ab8bda
commit 5b501c7a8c
3 changed files with 66 additions and 1 deletions

View file

@ -905,3 +905,20 @@ func register-field { | with field-name namespace-name ;
iter:next dyn-call
iter:foreach<&dyn-objcall>
}
construct Synchronizer {
sync
;
construct { this | with this ;
0 this:=sync
this
}
do { | with callable this ;
"will increment the sync field if and only if it is zero. when it was incremented (returned zero), the loop will exit";
while { this "sync" atomic-get-inc-if-zero } { yield }
callable:call
0 this:=sync
}
}

View file

@ -1014,6 +1014,11 @@ pub fn time(stack: &mut Stack) -> OError {
Ok(())
}
pub fn thread_yield(stack: &mut Stack) -> OError {
thread::yield_now();
Ok(())
}
pub fn str_readf(stack: &mut Stack) -> OError {
require_on_stack!(string, Str, stack, "str-readf");
require_on_stack!(pat, Str, stack, "str-readf");
@ -1275,9 +1280,22 @@ pub fn json_parse(stack: &mut Stack) -> OError {
Ok(())
}
pub fn atomic_get_inc_if_zero(stack: &mut Stack) -> OError {
require_on_stack!(field, Str, stack, "atomic-get-inc-if-zero");
let o = stack.pop();
let o = o.lock_ro();
let f = o.field(&field, stack)?;
let mut f = f.lock();
stack.push(f.clone().spl());
if f.native == Value::Mega(0) {
f.native = Value::Mega(1);
}
Ok(())
}
pub fn register(r: &mut Stack, o: Arc<Frame>) {
type Fn = fn(&mut Stack) -> OError;
let fns: [(&str, Fn, u32); 71] = [
let fns: [(&str, Fn, u32); 73] = [
("pop", pop, 0),
("dup", dup, 2),
("dup2", dup2, 3),
@ -1340,6 +1358,7 @@ pub fn register(r: &mut Stack, o: Arc<Frame>) {
("write-file-sasm", write_file_sasm, 1),
("fork", fork, 0),
("sleeptime", time, 0),
("yield", thread_yield, 0),
("str-readf", str_readf, 1),
("str-to-mega-radix", str_to_mega_radix, 1),
("mega-to-str-radix", mega_to_str_radix, 1),
@ -1349,6 +1368,7 @@ pub fn register(r: &mut Stack, o: Arc<Frame>) {
("delete-file", delete_file, 1),
("delete-dir", delete_dir, 1),
("chdir", chdir, 0),
("atomic-get-inc-if-zero", atomic_get_inc_if_zero, 1),
// ("json-parse", json_parse, 1),
];
for f in fns {

View file

@ -464,6 +464,34 @@ func main { int | with args ;
println
}
"" println;
"testing sync (should be 5)" println;
def x 5 =x
def sync Synchronizer:new =sync
10 :foreach<|
fork<| 10 :foreach<| sync:do<| x ++ =x > > >
fork<| 10 :foreach<| sync:do<| x -- =x > > >
>
1000 time:sleep;
x println
"nonsynced for comparison:" println
def x 5 =x
10 :foreach<|
fork<| 10 :foreach<| x ++ =x > >
fork<| 10 :foreach<| x -- =x > >
>
1000 time:sleep;
x println