all: remove `rwshared` keyword, make its semantics default for `shared` (#5710)

pull/5712/head
Uwe Krüger 2020-07-07 01:57:31 +02:00 committed by GitHub
parent 013c0e6e16
commit ef02373061
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 70 additions and 96 deletions

View File

@ -35,13 +35,20 @@ atomic d := ...
- `c` can be passed to coroutines an accessed - `c` can be passed to coroutines an accessed
*concurrently*.<sup>2</sup> In order to avoid data races it has to *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 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 ```v
lock c { lock c {
// read, modify, write c // read, modify, write c
... ...
} }
``` ```
```v
rlock c {
// read c
...
}
```
Several variables may be specified: `lock x, y, z { ... }`. Several variables may be specified: `lock x, y, z { ... }`.
They are unlocked in the opposite order. They are unlocked in the opposite order.
- `d` can be passed to coroutines and accessed *concurrently*, - `d` can be passed to coroutines and accessed *concurrently*,

View File

@ -402,6 +402,7 @@ fn C.pthread_mutex_unlock(voidptr) int
fn C.pthread_rwlockattr_init(voidptr) int fn C.pthread_rwlockattr_init(voidptr) int
fn C.pthread_rwlockattr_setkind_np(voidptr, int) 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_init(voidptr, voidptr) int
fn C.pthread_rwlock_rdlock(voidptr) int fn C.pthread_rwlock_rdlock(voidptr) int
fn C.pthread_rwlock_wrlock(voidptr) int fn C.pthread_rwlock_wrlock(voidptr) int

View File

@ -33,6 +33,7 @@ pub fn new_rwmutex() &RwMutex {
C.pthread_rwlockattr_init(&a.attr) C.pthread_rwlockattr_init(&a.attr)
// Give writer priority over readers // Give writer priority over readers
C.pthread_rwlockattr_setkind_np(&a.attr, C.PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP) 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) C.pthread_rwlock_init(&m.mutex, &a.attr)
return m return m
} }

View File

@ -450,7 +450,6 @@ pub:
pub mut: pub mut:
lockeds []Ident // `x`, `y` in `lock x, y {` lockeds []Ident // `x`, `y` in `lock x, y {`
is_expr bool is_expr bool
is_rw bool // `rwshared` needs special special handling even in `lock` case
typ table.Type typ table.Type
} }

View File

@ -1158,9 +1158,6 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
if call_arg.share == .shared_t { if call_arg.share == .shared_t {
words = 'shared' words = 'shared'
tok = 'shared' tok = 'shared'
} else if call_arg.share == .rwshared_t {
words = 'read/write shared'
tok = 'rwshared'
} else if call_arg.share == .atomic_t { } else if call_arg.share == .atomic_t {
words = 'atomic' words = 'atomic'
tok = '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 { if arg.typ.share() == .shared_t {
words = ' shared' words = ' shared'
tok = 'shared' tok = 'shared'
} else if arg.typ.share() == .rwshared_t {
words = ' read/write shared'
tok = 'rwshared'
} else if arg.typ.share() == .atomic_t { } else if arg.typ.share() == .atomic_t {
words = 'n atomic' words = 'n atomic'
tok = '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 scope := c.file.scope.innermost(assign_stmt.pos.pos)
mut ident_var_info := left.var_info() 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) left_type = left_type.set_flag(.shared_f)
} }
if ident_var_info.share in [.atomic_t, .rwshared_t] { if ident_var_info.share == .atomic_t {
left_type = left_type.set_flag(.atomic_or_rw) left_type = left_type.set_flag(.atomic_f)
} }
assign_stmt.left_types[i] = left_type assign_stmt.left_types[i] = left_type
ident_var_info.typ = left_type ident_var_info.typ = left_type

View File

@ -59,10 +59,8 @@ mut:
is_amp bool // for `&Foo{}` to merge PrefixExpr `&` and StructInit `Foo{}`; also for `&byte(0)` etc 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_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_shared bool // for initialization of hidden mutex in `[rw]shared` literals
is_rwshared bool
optionals []string // to avoid duplicates TODO perf, use map optionals []string // to avoid duplicates TODO perf, use map
shareds []int // types with hidden mutex for which decl has been emitted 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_ternary int // ?: comma separated statements on a single line
inside_map_postfix bool // inside map++/-- postfix expr inside_map_postfix bool // inside map++/-- postfix expr
inside_map_infix bool // inside map<</+=/-= infix 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 { fn (mut g Gen) find_or_register_shared(t table.Type, base string) string {
is_rw := t.has_flag(.atomic_or_rw) sh_typ := '__shared__$base'
prefix := if is_rw { 'rw' } else { '' }
sh_typ := '__${prefix}shared__$base'
t_idx := t.idx() 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 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.hotcode_definitions.writeln('struct $sh_typ { $base val; $mtx_typ* mtx; };')
g.typedefs2.writeln('typedef struct $sh_typ $sh_typ;') g.typedefs2.writeln('typedef struct $sh_typ $sh_typ;')
// println('registered shared type $sh_typ') // println('registered shared type $sh_typ')
if is_rw { g.shareds << t_idx
g.rwshareds << t_idx
} else {
g.shareds << t_idx
}
return sh_typ return sh_typ
} }
@ -1192,11 +1184,11 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
blank_assign = ident.kind == .blank_ident blank_assign = ident.kind == .blank_ident
if ident.info is ast.IdentVar { if ident.info is ast.IdentVar {
share := (ident.info as ast.IdentVar).share 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) var_type = var_type.set_flag(.shared_f)
} }
if share in [.atomic_t, .rwshared_t] { if share == .atomic_t {
var_type = var_type.set_flag(.atomic_or_rw) 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.write('*($styp*)')
} }
g.is_shared = var_type.has_flag(.shared_f) g.is_shared = var_type.has_flag(.shared_f)
g.is_rwshared = var_type.has_flag(.atomic_or_rw)
if !cloned { if !cloned {
if is_decl { if is_decl {
if is_fixed_array_init && !has_val { 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.write(' })')
g.is_array_set = false g.is_array_set = false
} }
g.is_rwshared = false
g.is_shared = false g.is_shared = false
} }
g.right_is_opt = 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} mut lock_prefixes := []byte{len: 0, cap: node.lockeds.len}
for id in node.lockeds { for id in node.lockeds {
name := id.name 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 { '.' } 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 lock_prefixes << lock_prefix // keep for unlock
mut_prefix := if lock_prefix == `m` { '' } else { 'Rw' } g.writeln('sync__RwMutex_${lock_prefix:c}_lock(${name}${deref}mtx);')
g.writeln('sync__${mut_prefix}Mutex_${lock_prefix:c}_lock(${name}${deref}mtx);')
} }
g.stmts(node.stmts) g.stmts(node.stmts)
// unlock in reverse order // unlock in reverse order
@ -2092,9 +2075,7 @@ fn (mut g Gen) lock_expr(node ast.LockExpr) {
lock_prefix := lock_prefixes[i] lock_prefix := lock_prefixes[i]
name := id.name name := id.name
deref := if id.is_mut { '->' } else { '.' } deref := if id.is_mut { '->' } else { '.' }
mut_prefix := if lock_prefix == `m` { '' } else { 'Rw' } g.writeln('sync__RwMutex_${lock_prefix:c}_unlock(${name}${deref}mtx);')
unlock_type := if lock_prefix == `m` { '' } else { '${lock_prefix:c}_' }
g.writeln('sync__${mut_prefix}Mutex_${unlock_type}unlock(${name}${deref}mtx);')
} }
} }
@ -2237,7 +2218,7 @@ fn (mut g Gen) ident(node ast.Ident) {
g.write('(*($styp*)${name}.data)') g.write('(*($styp*)${name}.data)')
return 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') g.write('${name}.val')
return return
} }
@ -2763,7 +2744,6 @@ const (
fn (mut g Gen) struct_init(struct_init ast.StructInit) { fn (mut g Gen) struct_init(struct_init ast.StructInit) {
styp := g.typ(struct_init.typ) styp := g.typ(struct_init.typ)
mut shared_styp := '' // only needed for shared &St{... mut shared_styp := '' // only needed for shared &St{...
mut share_prefix := '' // 'rw' for `rwshared`
if styp in skip_struct_init { if styp in skip_struct_init {
g.go_back_out(3) g.go_back_out(3)
return 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() g.out.go_back(1) // delete the `&` already generated in `prefix_expr()
if g.is_shared { if g.is_shared {
mut shared_typ := struct_init.typ.set_flag(.shared_f) 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) shared_styp = g.typ(shared_typ)
g.writeln('($shared_styp*)memdup(&($shared_styp){.val = ($styp){') g.writeln('($shared_styp*)memdup(&($shared_styp){.val = ($styp){')
} else { } else {
@ -2883,7 +2859,7 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
} }
g.write('}') g.write('}')
if g.is_shared { if g.is_shared {
g.write(', .mtx = sync__new_${share_prefix}mutex()}') g.write(', .mtx = sync__new_rwmutex()}')
if is_amp { if is_amp {
g.write(', sizeof($shared_styp))') g.write(', sizeof($shared_styp))')
} }

View File

@ -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 { pub fn (mut p Parser) call_args() []ast.CallArg {
mut args := []ast.CallArg{} mut args := []ast.CallArg{}
for p.tok.kind != .rpar { for p.tok.kind != .rpar {
is_shared := p.tok.kind in [.key_shared, .key_rwshared] is_shared := p.tok.kind == .key_shared
is_atomic_or_rw := p.tok.kind in [.key_rwshared, .key_atomic] is_atomic := p.tok.kind == .key_atomic
is_mut := p.tok.kind == .key_mut || is_shared || is_atomic_or_rw is_mut := p.tok.kind == .key_mut || is_shared || is_atomic
if is_mut { if is_mut {
p.next() p.next()
} }
e := p.expr(0) e := p.expr(0)
args << ast.CallArg{ args << ast.CallArg{
is_mut: is_mut 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 expr: e
} }
if p.tok.kind != .rpar { if p.tok.kind != .rpar {
@ -151,9 +151,9 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
if p.tok.kind == .lpar { if p.tok.kind == .lpar {
p.next() // ( p.next() // (
is_method = true is_method = true
is_shared := p.tok.kind in [.key_shared, .key_rwshared] is_shared := p.tok.kind == .key_shared
is_atomic_or_rw := p.tok.kind in [.key_rwshared, .key_atomic] is_atomic := p.tok.kind == .key_atomic
rec_mut = p.tok.kind == .key_mut || is_shared || is_atomic_or_rw rec_mut = p.tok.kind == .key_mut || is_shared || is_atomic
if rec_mut { if rec_mut {
p.next() // `mut` p.next() // `mut`
} }
@ -179,8 +179,8 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
if is_shared { if is_shared {
rec_type = rec_type.set_flag(.shared_f) rec_type = rec_type.set_flag(.shared_f)
} }
if is_atomic_or_rw { if is_atomic {
rec_type = rec_type.set_flag(.atomic_or_rw) rec_type = rec_type.set_flag(.atomic_f)
} }
args << table.Arg{ args << table.Arg{
name: rec_name name: rec_name
@ -400,9 +400,9 @@ fn (mut p Parser) fn_args() ([]table.Arg, bool, bool) {
mut arg_no := 1 mut arg_no := 1
for p.tok.kind != .rpar { for p.tok.kind != .rpar {
arg_name := 'arg_$arg_no' arg_name := 'arg_$arg_no'
is_shared := p.tok.kind in [.key_shared, .key_rwshared] is_shared := p.tok.kind == .key_shared
is_atomic_or_rw := p.tok.kind in [.key_rwshared, .key_atomic] is_atomic := p.tok.kind == .key_atomic
is_mut := p.tok.kind == .key_mut || is_shared || is_atomic_or_rw is_mut := p.tok.kind == .key_mut || is_shared || is_atomic
if is_mut { if is_mut {
p.next() p.next()
} }
@ -416,13 +416,13 @@ fn (mut p Parser) fn_args() ([]table.Arg, bool, bool) {
if !arg_type.has_flag(.generic) { if !arg_type.has_flag(.generic) {
if is_shared { if is_shared {
p.check_fn_shared_arguments(arg_type, pos) 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) p.check_fn_atomic_arguments(arg_type, pos)
} else { } else {
p.check_fn_mutable_arguments(arg_type, pos) p.check_fn_mutable_arguments(arg_type, pos)
} }
} else if is_shared || is_atomic_or_rw { } else if is_shared || is_atomic {
p.error_with_pos('generic object cannot be `atomic`, `shared` or `rwshared`', pos) p.error_with_pos('generic object cannot be `atomic`or `shared`', pos)
} }
// if arg_type.is_ptr() { // if arg_type.is_ptr() {
// p.error('cannot mut') // p.error('cannot mut')
@ -432,8 +432,8 @@ fn (mut p Parser) fn_args() ([]table.Arg, bool, bool) {
if is_shared { if is_shared {
arg_type = arg_type.set_flag(.shared_f) arg_type = arg_type.set_flag(.shared_f)
} }
if is_atomic_or_rw { if is_atomic {
arg_type = arg_type.set_flag(.atomic_or_rw) arg_type = arg_type.set_flag(.atomic_f)
} }
} }
if is_variadic { if is_variadic {
@ -456,9 +456,9 @@ fn (mut p Parser) fn_args() ([]table.Arg, bool, bool) {
} }
} else { } else {
for p.tok.kind != .rpar { for p.tok.kind != .rpar {
is_shared := p.tok.kind in [.key_shared, .key_rwshared] is_shared := p.tok.kind == .key_shared
is_atomic_or_rw := p.tok.kind in [.key_rwshared, .key_atomic] is_atomic := p.tok.kind == .key_atomic
mut is_mut := p.tok.kind == .key_mut || is_shared || is_atomic_or_rw mut is_mut := p.tok.kind == .key_mut || is_shared || is_atomic
if is_mut { if is_mut {
p.next() p.next()
} }
@ -485,20 +485,20 @@ fn (mut p Parser) fn_args() ([]table.Arg, bool, bool) {
if !typ.has_flag(.generic) { if !typ.has_flag(.generic) {
if is_shared { if is_shared {
p.check_fn_shared_arguments(typ, pos) p.check_fn_shared_arguments(typ, pos)
} else if is_atomic_or_rw { } else if is_atomic {
p.check_fn_atomic_arguments(typ, pos) p.check_fn_atomic_arguments(typ, pos)
} else { } else {
p.check_fn_mutable_arguments(typ, pos) p.check_fn_mutable_arguments(typ, pos)
} }
} else if is_shared || is_atomic_or_rw { } else if is_shared || is_atomic {
p.error_with_pos('generic object cannot be `atomic`, `shared` or `rwshared`', pos) p.error_with_pos('generic object cannot be `atomic` or `shared`', pos)
} }
typ = typ.set_nr_muls(1) typ = typ.set_nr_muls(1)
if is_shared { if is_shared {
typ = typ.set_flag(.shared_f) typ = typ.set_flag(.shared_f)
} }
if is_atomic_or_rw { if is_atomic {
typ = typ.set_flag(.atomic_or_rw) typ = typ.set_flag(.atomic_f)
} }
} }
if is_variadic { if is_variadic {

View File

@ -133,11 +133,11 @@ pub fn (mut p Parser) parse_type() table.Type {
return typ return typ
} }
} }
is_shared := p.tok.kind in [.key_shared, .key_rwshared] is_shared := p.tok.kind == .key_shared
is_atomic_or_rw := p.tok.kind in [.key_rwshared, .key_atomic] is_atomic := p.tok.kind == .key_atomic
mut nr_muls := 0 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++ nr_muls++
p.next() p.next()
} }
@ -161,8 +161,8 @@ pub fn (mut p Parser) parse_type() table.Type {
if is_shared { if is_shared {
typ = typ.set_flag(.shared_f) typ = typ.set_flag(.shared_f)
} }
if is_atomic_or_rw { if is_atomic {
typ = typ.set_flag(.atomic_or_rw) typ = typ.set_flag(.atomic_f)
} }
if nr_muls > 0 { if nr_muls > 0 {
typ = typ.set_nr_muls(nr_muls) typ = typ.set_nr_muls(nr_muls)

View File

@ -514,7 +514,7 @@ pub fn (mut p Parser) stmt(is_top_level bool) ast.Stmt {
.key_for { .key_for {
return p.for_stmt() 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.kind == .name {
if p.tok.lit == 'sql' { if p.tok.lit == 'sql' {
return p.sql_stmt() 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 { pub fn (mut p Parser) parse_ident(language table.Language) ast.Ident {
// p.warn('name ') // p.warn('name ')
is_shared := p.tok.kind in [.key_shared, .key_rwshared] is_shared := p.tok.kind == .key_shared
is_atomic_or_rw := p.tok.kind in [.key_rwshared, .key_atomic] is_atomic := p.tok.kind == .key_atomic
is_mut := p.tok.kind == .key_mut || is_shared || is_atomic_or_rw is_mut := p.tok.kind == .key_mut || is_shared || is_atomic
if is_mut { if is_mut {
p.next() p.next()
} }
@ -823,7 +823,7 @@ pub fn (mut p Parser) parse_ident(language table.Language) ast.Ident {
info: ast.IdentVar{ info: ast.IdentVar{
is_mut: is_mut is_mut: is_mut
is_static: is_static 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 { } else {

View File

@ -16,7 +16,7 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
p.eat_comments() p.eat_comments()
// Prefix // Prefix
match p.tok.kind { 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() node = p.name_expr()
p.is_stmt_ident = is_stmt_ident p.is_stmt_ident = is_stmt_ident
} }

View File

@ -42,7 +42,7 @@ pub enum TypeFlag {
variadic variadic
generic generic
shared_f shared_f
atomic_or_rw atomic_f
} }
/* /*
@ -54,7 +54,6 @@ pub enum ShareType {
mut_t mut_t
shared_t shared_t
atomic_t atomic_t
rwshared_t
} }
pub fn (t ShareType) str() string { pub fn (t ShareType) str() string {
@ -62,7 +61,6 @@ pub fn (t ShareType) str() string {
.mut_t { return 'mut' } .mut_t { return 'mut' }
.shared_t { return 'shared' } .shared_t { return 'shared' }
.atomic_t { return 'atomic' } .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 { pub fn sharetype_from_flags(is_shared, is_atomic bool) ShareType {
return ShareType((int(is_atomic_or_rw) << 1) | int(is_shared)) return ShareType((int(is_atomic) << 1) | int(is_shared))
} }
pub fn (t Type) share() ShareType { 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 { pub fn (types []Type) contains(typ Type) bool {

View File

@ -6,7 +6,7 @@ mut:
a int a int
} }
fn f(rwshared x St, shared z St) { fn f(shared x St, shared z St) {
for _ in 0..reads_per_thread { for _ in 0..reads_per_thread {
rlock x { // other instances may read at the same time rlock x { // other instances may read at the same time
time.sleep_ms(1) time.sleep_ms(1)
@ -26,14 +26,14 @@ const (
fn test_shared_lock() { fn test_shared_lock() {
// object with separate read/write lock // object with separate read/write lock
rwshared x := &St{ shared x := &St{
a: 5 a: 5
} }
shared z := &St{ shared z := &St{
a: read_threads a: read_threads
} }
for _ in 0..read_threads { for _ in 0..read_threads {
go f(rwshared x, shared z) go f(shared x, shared z)
} }
for i in 0..writes { for i in 0..writes {
lock x { // wait for ongoing reads to finish, don't start new ones lock x { // wait for ongoing reads to finish, don't start new ones

View File

@ -6,7 +6,7 @@ mut:
a int a int
} }
fn (rwshared x St) f(shared z St) { fn (shared x St) f(shared z St) {
for _ in 0..reads_per_thread { for _ in 0..reads_per_thread {
rlock x { // other instances may read at the same time rlock x { // other instances may read at the same time
time.sleep_ms(1) time.sleep_ms(1)
@ -26,7 +26,7 @@ const (
fn test_shared_lock() { fn test_shared_lock() {
// object with separate read/write lock // object with separate read/write lock
rwshared x := &St{ shared x := &St{
a: 5 a: 5
} }
shared z := &St{ shared z := &St{

View File

@ -109,7 +109,6 @@ pub enum Kind {
key_module key_module
key_mut key_mut
key_shared key_shared
key_rwshared
key_lock key_lock
key_rlock key_rlock
key_none key_none
@ -231,7 +230,6 @@ fn build_token_str() []string {
s[Kind.key_const] = 'const' s[Kind.key_const] = 'const'
s[Kind.key_mut] = 'mut' s[Kind.key_mut] = 'mut'
s[Kind.key_shared] = 'shared' s[Kind.key_shared] = 'shared'
s[Kind.key_rwshared] = 'rwshared'
s[Kind.key_lock] = 'lock' s[Kind.key_lock] = 'lock'
s[Kind.key_rlock] = 'rlock' s[Kind.key_rlock] = 'rlock'
s[Kind.key_type] = 'type' s[Kind.key_type] = 'type'