fmt: make formatter know about new keywords `shared`, `rlock` (#5779)

pull/5780/head
Uwe Krüger 2020-07-09 22:41:45 +02:00 committed by GitHub
parent fb927dab60
commit 581603f2bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 128 additions and 6 deletions

View File

@ -32,7 +32,7 @@ pub fn (node &FnDecl) stringify(t &table.Table) string {
mut receiver := '' mut receiver := ''
if node.is_method { if node.is_method {
mut styp := t.type_to_str(node.receiver.typ) mut styp := t.type_to_str(node.receiver.typ)
mut m := if node.rec_mut { 'mut ' } else { '' } mut m := if node.rec_mut { node.receiver.typ.share().str() + ' ' } else { '' }
if node.rec_mut { if node.rec_mut {
styp = styp[1..] // remove & styp = styp[1..] // remove &
} }
@ -72,7 +72,7 @@ pub fn (node &FnDecl) stringify(t &table.Table) string {
should_add_type := is_last_arg || node.args[i + 1].typ != arg.typ || (node.is_variadic && should_add_type := is_last_arg || node.args[i + 1].typ != arg.typ || (node.is_variadic &&
i == node.args.len - 2) i == node.args.len - 2)
if arg.is_mut { if arg.is_mut {
f.write('mut ') f.write(arg.typ.share().str() + ' ')
} }
f.write(arg.name) f.write(arg.name)
mut s := t.type_to_str(arg.typ) mut s := t.type_to_str(arg.typ)

View File

@ -250,7 +250,7 @@ pub fn (mut f Fmt) stmt(node ast.Stmt) {
if left is ast.Ident { if left is ast.Ident {
var_info := left.var_info() var_info := left.var_info()
if var_info.is_mut { if var_info.is_mut {
f.write('mut ') f.write(var_info.share.str() + ' ')
} }
f.expr(left) f.expr(left)
if i < node.left.len - 1 { if i < node.left.len - 1 {
@ -517,7 +517,7 @@ pub fn (mut f Fmt) type_decl(node ast.TypeDecl) {
f.write(arg.name) f.write(arg.name)
mut s := f.table.type_to_str(arg.typ).replace(f.cur_mod + '.', '') mut s := f.table.type_to_str(arg.typ).replace(f.cur_mod + '.', '')
if arg.is_mut { if arg.is_mut {
f.write('mut ') f.write(arg.typ.share().str() + ' ')
if s.starts_with('&') { if s.starts_with('&') {
s = s[1..] s = s[1..]
} }
@ -1054,7 +1054,7 @@ pub fn (mut f Fmt) wrap_long_line(penalty int, add_indent bool) bool {
pub fn (mut f Fmt) call_args(args []ast.CallArg) { pub fn (mut f Fmt) call_args(args []ast.CallArg) {
for i, arg in args { for i, arg in args {
if arg.is_mut { if arg.is_mut {
f.write('mut ') f.write(arg.share.str() + ' ')
} }
if i > 0 { if i > 0 {
f.wrap_long_line(2, true) f.wrap_long_line(2, true)
@ -1173,7 +1173,11 @@ pub fn (mut f Fmt) short_module(name string) string {
} }
pub fn (mut f Fmt) lock_expr(lex ast.LockExpr) { pub fn (mut f Fmt) lock_expr(lex ast.LockExpr) {
f.write('lock ') f.write(if lex.is_rlock {
'rlock '
} else {
'lock '
})
for i, v in lex.lockeds { for i, v in lex.lockeds {
if i > 0 { if i > 0 {
f.write(', ') f.write(', ')

View File

@ -0,0 +1,58 @@
import sync
import time
struct St {
mut:
a int
}
fn (shared x St) f(shared z St) {
for _ in 0 .. reads_per_thread {
rlock x { // other instances may read at the same time
time.sleep_ms(1)
assert x.a == 7 || x.a == 5
}
}
lock z {
z.a--
}
}
const (
reads_per_thread = 30
read_threads = 10
writes = 5
)
fn test_shared_lock() {
// object with separate read/write lock
shared x := &St{
a: 5
}
shared z := &St{
a: read_threads
}
for _ in 0 .. read_threads {
go x.f(shared z)
}
for i in 0 .. writes {
lock x { // wait for ongoing reads to finish, don't start new ones
x.a = 17 // this value should never be read
time.sleep_ms(50)
x.a = if (i & 1) == 0 { 7 } else { 5 }
} // now new reads are possible again
time.sleep_ms(20)
}
// wait until all read threads are finished
for finished := false; true; {
mut rr := 0
rlock z {
rr = z.a
finished = z.a == 0
}
if finished {
break
}
time.sleep_ms(100)
}
}

View File

@ -0,0 +1,60 @@
import sync
import time
struct St {
mut:
a int
}
fn (shared x St) f(shared z St) {
for _ in 0 .. reads_per_thread {
rlock x { // other instances may read at the same time
time.sleep_ms(1)
assert x.a == 7 || x.a == 5
}
}
lock z {
z.a--
}
}
const (
reads_per_thread = 30
read_threads = 10
writes = 5
)
fn test_shared_lock() {
// object with separate read/write lock
shared x := &St {
a: 5
}
shared z :=
&St{
a: read_threads
}
for _ in 0.. read_threads {
go x.f(shared z)
}
for i in 0..writes {
lock x { // wait for ongoing reads to finish, don't start new ones
x.a = 17 // this value should never be read
time.sleep_ms(50)
x.a = if (i & 1) == 0 {
7} else {5}
} // now new reads are possible again
time.sleep_ms(20)
}
// wait until all read threads are finished
for finished:=false;; {
mut rr := 0
rlock z {
rr = z.a
finished = z.a == 0
}
if finished {
break
}
time.sleep_ms(100)
}
}