all: remove `rwshared` keyword, make its semantics default for `shared` (#5710)
parent
013c0e6e16
commit
ef02373061
|
@ -35,13 +35,20 @@ atomic d := ...
|
|||
- `c` can be passed to coroutines an accessed
|
||||
*concurrently*.<sup>2</sup> In order to avoid data races it has to
|
||||
be locked before access can occur and unlocked to allow access to
|
||||
other coroutines. This is done by the following block structure:
|
||||
other coroutines. This is done by one the following block structures:
|
||||
```v
|
||||
lock c {
|
||||
// read, modify, write c
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
```v
|
||||
rlock c {
|
||||
// read c
|
||||
...
|
||||
}
|
||||
```
|
||||
Several variables may be specified: `lock x, y, z { ... }`.
|
||||
They are unlocked in the opposite order.
|
||||
- `d` can be passed to coroutines and accessed *concurrently*,
|
||||
|
|
|
@ -402,6 +402,7 @@ fn C.pthread_mutex_unlock(voidptr) int
|
|||
|
||||
fn C.pthread_rwlockattr_init(voidptr) int
|
||||
fn C.pthread_rwlockattr_setkind_np(voidptr, int) int
|
||||
fn C.pthread_rwlockattr_setpshared(voidptr, int) int
|
||||
fn C.pthread_rwlock_init(voidptr, voidptr) int
|
||||
fn C.pthread_rwlock_rdlock(voidptr) int
|
||||
fn C.pthread_rwlock_wrlock(voidptr) int
|
||||
|
|
|
@ -33,6 +33,7 @@ pub fn new_rwmutex() &RwMutex {
|
|||
C.pthread_rwlockattr_init(&a.attr)
|
||||
// Give writer priority over readers
|
||||
C.pthread_rwlockattr_setkind_np(&a.attr, C.PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP)
|
||||
C.pthread_rwlockattr_setpshared(&a.attr, C.PTHREAD_PROCESS_PRIVATE)
|
||||
C.pthread_rwlock_init(&m.mutex, &a.attr)
|
||||
return m
|
||||
}
|
||||
|
|
|
@ -450,7 +450,6 @@ pub:
|
|||
pub mut:
|
||||
lockeds []Ident // `x`, `y` in `lock x, y {`
|
||||
is_expr bool
|
||||
is_rw bool // `rwshared` needs special special handling even in `lock` case
|
||||
typ table.Type
|
||||
}
|
||||
|
||||
|
|
|
@ -1158,9 +1158,6 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
|
|||
if call_arg.share == .shared_t {
|
||||
words = 'shared'
|
||||
tok = 'shared'
|
||||
} else if call_arg.share == .rwshared_t {
|
||||
words = 'read/write shared'
|
||||
tok = 'rwshared'
|
||||
} else if call_arg.share == .atomic_t {
|
||||
words = 'atomic'
|
||||
tok = 'atomic'
|
||||
|
@ -1176,9 +1173,6 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
|
|||
if arg.typ.share() == .shared_t {
|
||||
words = ' shared'
|
||||
tok = 'shared'
|
||||
} else if arg.typ.share() == .rwshared_t {
|
||||
words = ' read/write shared'
|
||||
tok = 'rwshared'
|
||||
} else if arg.typ.share() == .atomic_t {
|
||||
words = 'n atomic'
|
||||
tok = 'atomic'
|
||||
|
@ -1572,11 +1566,11 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
|
|||
}
|
||||
mut scope := c.file.scope.innermost(assign_stmt.pos.pos)
|
||||
mut ident_var_info := left.var_info()
|
||||
if ident_var_info.share in [.shared_t, .rwshared_t] {
|
||||
if ident_var_info.share == .shared_t {
|
||||
left_type = left_type.set_flag(.shared_f)
|
||||
}
|
||||
if ident_var_info.share in [.atomic_t, .rwshared_t] {
|
||||
left_type = left_type.set_flag(.atomic_or_rw)
|
||||
if ident_var_info.share == .atomic_t {
|
||||
left_type = left_type.set_flag(.atomic_f)
|
||||
}
|
||||
assign_stmt.left_types[i] = left_type
|
||||
ident_var_info.typ = left_type
|
||||
|
|
|
@ -59,10 +59,8 @@ mut:
|
|||
is_amp bool // for `&Foo{}` to merge PrefixExpr `&` and StructInit `Foo{}`; also for `&byte(0)` etc
|
||||
is_sql bool // Inside `sql db{}` statement, generating sql instead of C (e.g. `and` instead of `&&` etc)
|
||||
is_shared bool // for initialization of hidden mutex in `[rw]shared` literals
|
||||
is_rwshared bool
|
||||
optionals []string // to avoid duplicates TODO perf, use map
|
||||
shareds []int // types with hidden mutex for which decl has been emitted
|
||||
rwshareds []int // same with hidden rwmutex
|
||||
inside_ternary int // ?: comma separated statements on a single line
|
||||
inside_map_postfix bool // inside map++/-- postfix expr
|
||||
inside_map_infix bool // inside map<</+=/-= infix expr
|
||||
|
@ -408,22 +406,16 @@ fn (mut g Gen) register_optional(t table.Type) string {
|
|||
}
|
||||
|
||||
fn (mut g Gen) find_or_register_shared(t table.Type, base string) string {
|
||||
is_rw := t.has_flag(.atomic_or_rw)
|
||||
prefix := if is_rw { 'rw' } else { '' }
|
||||
sh_typ := '__${prefix}shared__$base'
|
||||
sh_typ := '__shared__$base'
|
||||
t_idx := t.idx()
|
||||
if (is_rw && t_idx in g.rwshareds) || (!is_rw && t_idx in g.shareds) {
|
||||
if t_idx in g.shareds {
|
||||
return sh_typ
|
||||
}
|
||||
mtx_typ := if is_rw { 'sync__RwMutex' } else { 'sync__Mutex' }
|
||||
mtx_typ := 'sync__RwMutex'
|
||||
g.hotcode_definitions.writeln('struct $sh_typ { $base val; $mtx_typ* mtx; };')
|
||||
g.typedefs2.writeln('typedef struct $sh_typ $sh_typ;')
|
||||
// println('registered shared type $sh_typ')
|
||||
if is_rw {
|
||||
g.rwshareds << t_idx
|
||||
} else {
|
||||
g.shareds << t_idx
|
||||
}
|
||||
return sh_typ
|
||||
}
|
||||
|
||||
|
@ -1192,11 +1184,11 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
|||
blank_assign = ident.kind == .blank_ident
|
||||
if ident.info is ast.IdentVar {
|
||||
share := (ident.info as ast.IdentVar).share
|
||||
if share in [.shared_t, .rwshared_t] {
|
||||
if share == .shared_t {
|
||||
var_type = var_type.set_flag(.shared_f)
|
||||
}
|
||||
if share in [.atomic_t, .rwshared_t] {
|
||||
var_type = var_type.set_flag(.atomic_or_rw)
|
||||
if share == .atomic_t {
|
||||
var_type = var_type.set_flag(.atomic_f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1327,7 +1319,6 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
|||
g.write('*($styp*)')
|
||||
}
|
||||
g.is_shared = var_type.has_flag(.shared_f)
|
||||
g.is_rwshared = var_type.has_flag(.atomic_or_rw)
|
||||
if !cloned {
|
||||
if is_decl {
|
||||
if is_fixed_array_init && !has_val {
|
||||
|
@ -1353,7 +1344,6 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
|||
g.write(' })')
|
||||
g.is_array_set = false
|
||||
}
|
||||
g.is_rwshared = false
|
||||
g.is_shared = false
|
||||
}
|
||||
g.right_is_opt = false
|
||||
|
@ -2073,17 +2063,10 @@ fn (mut g Gen) lock_expr(node ast.LockExpr) {
|
|||
mut lock_prefixes := []byte{len: 0, cap: node.lockeds.len}
|
||||
for id in node.lockeds {
|
||||
name := id.name
|
||||
// fields of `id` itself have no valid information, so look up type(flags) in scope
|
||||
obj := g.file.scope.innermost(id.pos.pos).find(name) or {
|
||||
verror('cgen: unable to get type for lock variable $name')
|
||||
ast.ScopeObject{}
|
||||
}
|
||||
typ := if obj is ast.Var { (*(obj as ast.Var)).typ } else { table.Type(0) }
|
||||
deref := if id.is_mut { '->' } else { '.' }
|
||||
lock_prefix := if node.is_rlock { `r` } else { if typ.has_flag(.atomic_or_rw) { `w` } else { `m` } }
|
||||
lock_prefix := if node.is_rlock { `r` } else { `w` }
|
||||
lock_prefixes << lock_prefix // keep for unlock
|
||||
mut_prefix := if lock_prefix == `m` { '' } else { 'Rw' }
|
||||
g.writeln('sync__${mut_prefix}Mutex_${lock_prefix:c}_lock(${name}${deref}mtx);')
|
||||
g.writeln('sync__RwMutex_${lock_prefix:c}_lock(${name}${deref}mtx);')
|
||||
}
|
||||
g.stmts(node.stmts)
|
||||
// unlock in reverse order
|
||||
|
@ -2092,9 +2075,7 @@ fn (mut g Gen) lock_expr(node ast.LockExpr) {
|
|||
lock_prefix := lock_prefixes[i]
|
||||
name := id.name
|
||||
deref := if id.is_mut { '->' } else { '.' }
|
||||
mut_prefix := if lock_prefix == `m` { '' } else { 'Rw' }
|
||||
unlock_type := if lock_prefix == `m` { '' } else { '${lock_prefix:c}_' }
|
||||
g.writeln('sync__${mut_prefix}Mutex_${unlock_type}unlock(${name}${deref}mtx);')
|
||||
g.writeln('sync__RwMutex_${lock_prefix:c}_unlock(${name}${deref}mtx);')
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2237,7 +2218,7 @@ fn (mut g Gen) ident(node ast.Ident) {
|
|||
g.write('(*($styp*)${name}.data)')
|
||||
return
|
||||
}
|
||||
if !g.is_assign_lhs && (ident_var.share == .shared_t || ident_var.share == .rwshared_t) {
|
||||
if !g.is_assign_lhs && ident_var.share == .shared_t {
|
||||
g.write('${name}.val')
|
||||
return
|
||||
}
|
||||
|
@ -2763,7 +2744,6 @@ const (
|
|||
fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
||||
styp := g.typ(struct_init.typ)
|
||||
mut shared_styp := '' // only needed for shared &St{...
|
||||
mut share_prefix := '' // 'rw' for `rwshared`
|
||||
if styp in skip_struct_init {
|
||||
g.go_back_out(3)
|
||||
return
|
||||
|
@ -2775,10 +2755,6 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
|||
g.out.go_back(1) // delete the `&` already generated in `prefix_expr()
|
||||
if g.is_shared {
|
||||
mut shared_typ := struct_init.typ.set_flag(.shared_f)
|
||||
if g.is_rwshared {
|
||||
shared_typ = shared_typ.set_flag(.atomic_or_rw)
|
||||
share_prefix = 'rw'
|
||||
}
|
||||
shared_styp = g.typ(shared_typ)
|
||||
g.writeln('($shared_styp*)memdup(&($shared_styp){.val = ($styp){')
|
||||
} else {
|
||||
|
@ -2883,7 +2859,7 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
|||
}
|
||||
g.write('}')
|
||||
if g.is_shared {
|
||||
g.write(', .mtx = sync__new_${share_prefix}mutex()}')
|
||||
g.write(', .mtx = sync__new_rwmutex()}')
|
||||
if is_amp {
|
||||
g.write(', sizeof($shared_styp))')
|
||||
}
|
||||
|
|
|
@ -100,16 +100,16 @@ pub fn (mut p Parser) call_expr(language table.Language, mod string) ast.CallExp
|
|||
pub fn (mut p Parser) call_args() []ast.CallArg {
|
||||
mut args := []ast.CallArg{}
|
||||
for p.tok.kind != .rpar {
|
||||
is_shared := p.tok.kind in [.key_shared, .key_rwshared]
|
||||
is_atomic_or_rw := p.tok.kind in [.key_rwshared, .key_atomic]
|
||||
is_mut := p.tok.kind == .key_mut || is_shared || is_atomic_or_rw
|
||||
is_shared := p.tok.kind == .key_shared
|
||||
is_atomic := p.tok.kind == .key_atomic
|
||||
is_mut := p.tok.kind == .key_mut || is_shared || is_atomic
|
||||
if is_mut {
|
||||
p.next()
|
||||
}
|
||||
e := p.expr(0)
|
||||
args << ast.CallArg{
|
||||
is_mut: is_mut
|
||||
share: table.sharetype_from_flags(is_shared, is_atomic_or_rw)
|
||||
share: table.sharetype_from_flags(is_shared, is_atomic)
|
||||
expr: e
|
||||
}
|
||||
if p.tok.kind != .rpar {
|
||||
|
@ -151,9 +151,9 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
|||
if p.tok.kind == .lpar {
|
||||
p.next() // (
|
||||
is_method = true
|
||||
is_shared := p.tok.kind in [.key_shared, .key_rwshared]
|
||||
is_atomic_or_rw := p.tok.kind in [.key_rwshared, .key_atomic]
|
||||
rec_mut = p.tok.kind == .key_mut || is_shared || is_atomic_or_rw
|
||||
is_shared := p.tok.kind == .key_shared
|
||||
is_atomic := p.tok.kind == .key_atomic
|
||||
rec_mut = p.tok.kind == .key_mut || is_shared || is_atomic
|
||||
if rec_mut {
|
||||
p.next() // `mut`
|
||||
}
|
||||
|
@ -179,8 +179,8 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
|||
if is_shared {
|
||||
rec_type = rec_type.set_flag(.shared_f)
|
||||
}
|
||||
if is_atomic_or_rw {
|
||||
rec_type = rec_type.set_flag(.atomic_or_rw)
|
||||
if is_atomic {
|
||||
rec_type = rec_type.set_flag(.atomic_f)
|
||||
}
|
||||
args << table.Arg{
|
||||
name: rec_name
|
||||
|
@ -400,9 +400,9 @@ fn (mut p Parser) fn_args() ([]table.Arg, bool, bool) {
|
|||
mut arg_no := 1
|
||||
for p.tok.kind != .rpar {
|
||||
arg_name := 'arg_$arg_no'
|
||||
is_shared := p.tok.kind in [.key_shared, .key_rwshared]
|
||||
is_atomic_or_rw := p.tok.kind in [.key_rwshared, .key_atomic]
|
||||
is_mut := p.tok.kind == .key_mut || is_shared || is_atomic_or_rw
|
||||
is_shared := p.tok.kind == .key_shared
|
||||
is_atomic := p.tok.kind == .key_atomic
|
||||
is_mut := p.tok.kind == .key_mut || is_shared || is_atomic
|
||||
if is_mut {
|
||||
p.next()
|
||||
}
|
||||
|
@ -416,13 +416,13 @@ fn (mut p Parser) fn_args() ([]table.Arg, bool, bool) {
|
|||
if !arg_type.has_flag(.generic) {
|
||||
if is_shared {
|
||||
p.check_fn_shared_arguments(arg_type, pos)
|
||||
} else if is_atomic_or_rw {
|
||||
} else if is_atomic {
|
||||
p.check_fn_atomic_arguments(arg_type, pos)
|
||||
} else {
|
||||
p.check_fn_mutable_arguments(arg_type, pos)
|
||||
}
|
||||
} else if is_shared || is_atomic_or_rw {
|
||||
p.error_with_pos('generic object cannot be `atomic`, `shared` or `rwshared`', pos)
|
||||
} else if is_shared || is_atomic {
|
||||
p.error_with_pos('generic object cannot be `atomic`or `shared`', pos)
|
||||
}
|
||||
// if arg_type.is_ptr() {
|
||||
// p.error('cannot mut')
|
||||
|
@ -432,8 +432,8 @@ fn (mut p Parser) fn_args() ([]table.Arg, bool, bool) {
|
|||
if is_shared {
|
||||
arg_type = arg_type.set_flag(.shared_f)
|
||||
}
|
||||
if is_atomic_or_rw {
|
||||
arg_type = arg_type.set_flag(.atomic_or_rw)
|
||||
if is_atomic {
|
||||
arg_type = arg_type.set_flag(.atomic_f)
|
||||
}
|
||||
}
|
||||
if is_variadic {
|
||||
|
@ -456,9 +456,9 @@ fn (mut p Parser) fn_args() ([]table.Arg, bool, bool) {
|
|||
}
|
||||
} else {
|
||||
for p.tok.kind != .rpar {
|
||||
is_shared := p.tok.kind in [.key_shared, .key_rwshared]
|
||||
is_atomic_or_rw := p.tok.kind in [.key_rwshared, .key_atomic]
|
||||
mut is_mut := p.tok.kind == .key_mut || is_shared || is_atomic_or_rw
|
||||
is_shared := p.tok.kind == .key_shared
|
||||
is_atomic := p.tok.kind == .key_atomic
|
||||
mut is_mut := p.tok.kind == .key_mut || is_shared || is_atomic
|
||||
if is_mut {
|
||||
p.next()
|
||||
}
|
||||
|
@ -485,20 +485,20 @@ fn (mut p Parser) fn_args() ([]table.Arg, bool, bool) {
|
|||
if !typ.has_flag(.generic) {
|
||||
if is_shared {
|
||||
p.check_fn_shared_arguments(typ, pos)
|
||||
} else if is_atomic_or_rw {
|
||||
} else if is_atomic {
|
||||
p.check_fn_atomic_arguments(typ, pos)
|
||||
} else {
|
||||
p.check_fn_mutable_arguments(typ, pos)
|
||||
}
|
||||
} else if is_shared || is_atomic_or_rw {
|
||||
p.error_with_pos('generic object cannot be `atomic`, `shared` or `rwshared`', pos)
|
||||
} else if is_shared || is_atomic {
|
||||
p.error_with_pos('generic object cannot be `atomic` or `shared`', pos)
|
||||
}
|
||||
typ = typ.set_nr_muls(1)
|
||||
if is_shared {
|
||||
typ = typ.set_flag(.shared_f)
|
||||
}
|
||||
if is_atomic_or_rw {
|
||||
typ = typ.set_flag(.atomic_or_rw)
|
||||
if is_atomic {
|
||||
typ = typ.set_flag(.atomic_f)
|
||||
}
|
||||
}
|
||||
if is_variadic {
|
||||
|
|
|
@ -133,11 +133,11 @@ pub fn (mut p Parser) parse_type() table.Type {
|
|||
return typ
|
||||
}
|
||||
}
|
||||
is_shared := p.tok.kind in [.key_shared, .key_rwshared]
|
||||
is_atomic_or_rw := p.tok.kind in [.key_rwshared, .key_atomic]
|
||||
is_shared := p.tok.kind == .key_shared
|
||||
is_atomic := p.tok.kind == .key_atomic
|
||||
|
||||
mut nr_muls := 0
|
||||
if p.tok.kind == .key_mut || is_shared || is_atomic_or_rw {
|
||||
if p.tok.kind == .key_mut || is_shared || is_atomic {
|
||||
nr_muls++
|
||||
p.next()
|
||||
}
|
||||
|
@ -161,8 +161,8 @@ pub fn (mut p Parser) parse_type() table.Type {
|
|||
if is_shared {
|
||||
typ = typ.set_flag(.shared_f)
|
||||
}
|
||||
if is_atomic_or_rw {
|
||||
typ = typ.set_flag(.atomic_or_rw)
|
||||
if is_atomic {
|
||||
typ = typ.set_flag(.atomic_f)
|
||||
}
|
||||
if nr_muls > 0 {
|
||||
typ = typ.set_nr_muls(nr_muls)
|
||||
|
|
|
@ -514,7 +514,7 @@ pub fn (mut p Parser) stmt(is_top_level bool) ast.Stmt {
|
|||
.key_for {
|
||||
return p.for_stmt()
|
||||
}
|
||||
.name, .key_mut, .key_shared, .key_atomic, .key_rwshared, .key_static, .mul {
|
||||
.name, .key_mut, .key_shared, .key_atomic, .key_static, .mul {
|
||||
if p.tok.kind == .name {
|
||||
if p.tok.lit == 'sql' {
|
||||
return p.sql_stmt()
|
||||
|
@ -783,9 +783,9 @@ fn (mut p Parser) parse_multi_expr(is_top_level bool) ast.Stmt {
|
|||
|
||||
pub fn (mut p Parser) parse_ident(language table.Language) ast.Ident {
|
||||
// p.warn('name ')
|
||||
is_shared := p.tok.kind in [.key_shared, .key_rwshared]
|
||||
is_atomic_or_rw := p.tok.kind in [.key_rwshared, .key_atomic]
|
||||
is_mut := p.tok.kind == .key_mut || is_shared || is_atomic_or_rw
|
||||
is_shared := p.tok.kind == .key_shared
|
||||
is_atomic := p.tok.kind == .key_atomic
|
||||
is_mut := p.tok.kind == .key_mut || is_shared || is_atomic
|
||||
if is_mut {
|
||||
p.next()
|
||||
}
|
||||
|
@ -823,7 +823,7 @@ pub fn (mut p Parser) parse_ident(language table.Language) ast.Ident {
|
|||
info: ast.IdentVar{
|
||||
is_mut: is_mut
|
||||
is_static: is_static
|
||||
share: table.sharetype_from_flags(is_shared, is_atomic_or_rw)
|
||||
share: table.sharetype_from_flags(is_shared, is_atomic)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -16,7 +16,7 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
|
|||
p.eat_comments()
|
||||
// Prefix
|
||||
match p.tok.kind {
|
||||
.key_mut, .key_shared, .key_rwshared, .key_atomic, .key_static {
|
||||
.key_mut, .key_shared, .key_atomic, .key_static {
|
||||
node = p.name_expr()
|
||||
p.is_stmt_ident = is_stmt_ident
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ pub enum TypeFlag {
|
|||
variadic
|
||||
generic
|
||||
shared_f
|
||||
atomic_or_rw
|
||||
atomic_f
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -54,7 +54,6 @@ pub enum ShareType {
|
|||
mut_t
|
||||
shared_t
|
||||
atomic_t
|
||||
rwshared_t
|
||||
}
|
||||
|
||||
pub fn (t ShareType) str() string {
|
||||
|
@ -62,7 +61,6 @@ pub fn (t ShareType) str() string {
|
|||
.mut_t { return 'mut' }
|
||||
.shared_t { return 'shared' }
|
||||
.atomic_t { return 'atomic' }
|
||||
.rwshared_t { return 'rwshared' }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,12 +76,12 @@ pub fn (t Type) atomic_typename() string {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn sharetype_from_flags(is_shared, is_atomic_or_rw bool) ShareType {
|
||||
return ShareType((int(is_atomic_or_rw) << 1) | int(is_shared))
|
||||
pub fn sharetype_from_flags(is_shared, is_atomic bool) ShareType {
|
||||
return ShareType((int(is_atomic) << 1) | int(is_shared))
|
||||
}
|
||||
|
||||
pub fn (t Type) share() ShareType {
|
||||
return sharetype_from_flags(t.has_flag(.shared_f), t.has_flag(.atomic_or_rw))
|
||||
return sharetype_from_flags(t.has_flag(.shared_f), t.has_flag(.atomic_f))
|
||||
}
|
||||
|
||||
pub fn (types []Type) contains(typ Type) bool {
|
||||
|
|
|
@ -6,7 +6,7 @@ mut:
|
|||
a int
|
||||
}
|
||||
|
||||
fn f(rwshared x St, shared z St) {
|
||||
fn f(shared x St, shared z St) {
|
||||
for _ in 0..reads_per_thread {
|
||||
rlock x { // other instances may read at the same time
|
||||
time.sleep_ms(1)
|
||||
|
@ -26,14 +26,14 @@ const (
|
|||
|
||||
fn test_shared_lock() {
|
||||
// object with separate read/write lock
|
||||
rwshared x := &St{
|
||||
shared x := &St{
|
||||
a: 5
|
||||
}
|
||||
shared z := &St{
|
||||
a: read_threads
|
||||
}
|
||||
for _ in 0..read_threads {
|
||||
go f(rwshared x, shared z)
|
||||
go f(shared x, shared z)
|
||||
}
|
||||
for i in 0..writes {
|
||||
lock x { // wait for ongoing reads to finish, don't start new ones
|
||||
|
|
|
@ -6,7 +6,7 @@ mut:
|
|||
a int
|
||||
}
|
||||
|
||||
fn (rwshared x St) f(shared z St) {
|
||||
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)
|
||||
|
@ -26,7 +26,7 @@ const (
|
|||
|
||||
fn test_shared_lock() {
|
||||
// object with separate read/write lock
|
||||
rwshared x := &St{
|
||||
shared x := &St{
|
||||
a: 5
|
||||
}
|
||||
shared z := &St{
|
||||
|
|
|
@ -109,7 +109,6 @@ pub enum Kind {
|
|||
key_module
|
||||
key_mut
|
||||
key_shared
|
||||
key_rwshared
|
||||
key_lock
|
||||
key_rlock
|
||||
key_none
|
||||
|
@ -231,7 +230,6 @@ fn build_token_str() []string {
|
|||
s[Kind.key_const] = 'const'
|
||||
s[Kind.key_mut] = 'mut'
|
||||
s[Kind.key_shared] = 'shared'
|
||||
s[Kind.key_rwshared] = 'rwshared'
|
||||
s[Kind.key_lock] = 'lock'
|
||||
s[Kind.key_rlock] = 'rlock'
|
||||
s[Kind.key_type] = 'type'
|
||||
|
|
Loading…
Reference in New Issue