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
|
- `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*,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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))')
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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{
|
||||||
|
|
|
@ -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'
|
||||||
|
|
Loading…
Reference in New Issue