synchronization
This commit is contained in:
parent
a8d5ab8bda
commit
5b501c7a8c
3 changed files with 66 additions and 1 deletions
17
spl/std.spl
17
spl/std.spl
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
28
test.spl
28
test.spl
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue