mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
sync/channels: fixes for try_push/pop()
, optimizations (#6352)
This commit is contained in:
parent
07b5d6b1b6
commit
b10d79c4d9
@ -20,10 +20,10 @@ nobj .... number of objects to pass thru the channel
|
|||||||
|
|
||||||
| nsend | nrec | buflen | **V (gcc -O2)** | **V (clang)** | **V (tcc)** | **Go (glang)** | **Go (gccgo -O2)** |
|
| nsend | nrec | buflen | **V (gcc -O2)** | **V (clang)** | **V (tcc)** | **Go (glang)** | **Go (gccgo -O2)** |
|
||||||
| :---: | :---:| :---: | :---: | :---: | :---: | :---: | :---: |
|
| :---: | :---:| :---: | :---: | :---: | :---: | :---: | :---: |
|
||||||
| 1 | 1 | 0 | 0.95 | 0.72 | 0.66 | 4.65 | 0.56 |
|
| 1 | 1 | 0 | 1.97 | 1.63 | 2.08 | 4.65 | 0.56 |
|
||||||
| 1 | 1 | 100 | 3.26 | 2.51 | 2.24 | 18.90 | 6.08 |
|
| 1 | 1 | 100 | 3.05 | 2.29 | 1.93 | 18.90 | 6.08 |
|
||||||
| 4 | 4 | 0 | 0.25 | 0.26 | 0.24 | 1.84 | 0.84 |
|
| 4 | 4 | 0 | 0.87 | 0.90 | 0.99 | 1.84 | 0.84 |
|
||||||
| 4 | 4 | 100 | 3.11 | 2.78 | 2.63 | 7.43 | 3.71 |
|
| 4 | 4 | 100 | 3.35 | 3.07 | 2.92 | 7.43 | 3.71 |
|
||||||
|
|
||||||
## AMD Ryzen 7 3800X, Windows 10 2004 x64
|
## AMD Ryzen 7 3800X, Windows 10 2004 x64
|
||||||
|
|
||||||
|
17
vlib/sync/channel_try_buf_test.v
Executable file
17
vlib/sync/channel_try_buf_test.v
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
fn test_channel_try_buffered() {
|
||||||
|
ch := chan int{cap: 5}
|
||||||
|
for z in 2..13 {
|
||||||
|
if ch.try_push(z) == .not_ready {
|
||||||
|
assert z == 7
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mut obj := int(0)
|
||||||
|
for ch.try_pop(obj) == .success {
|
||||||
|
println(obj)
|
||||||
|
}
|
||||||
|
assert obj == 6
|
||||||
|
ch <- 17
|
||||||
|
obj = <-ch
|
||||||
|
assert obj == 17
|
||||||
|
}
|
13
vlib/sync/channel_try_unbuf_test.v
Normal file
13
vlib/sync/channel_try_unbuf_test.v
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
fn test_channel_try_unbuffered() {
|
||||||
|
ch := chan int{}
|
||||||
|
for z in 5..8 {
|
||||||
|
if ch.try_push(z) == .not_ready {
|
||||||
|
assert z == 5
|
||||||
|
break
|
||||||
|
}
|
||||||
|
panic('push on non-ready channel not detected')
|
||||||
|
}
|
||||||
|
mut obj := -17
|
||||||
|
for ch.try_pop(obj) == .success {}
|
||||||
|
assert obj == -17
|
||||||
|
}
|
@ -165,14 +165,14 @@ pub fn (mut ch Channel) push(src voidptr) {
|
|||||||
|
|
||||||
[inline]
|
[inline]
|
||||||
pub fn (mut ch Channel) try_push(src voidptr) ChanState {
|
pub fn (mut ch Channel) try_push(src voidptr) ChanState {
|
||||||
return ch.try_push_priv(src, false)
|
return ch.try_push_priv(src, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut ch Channel) try_push_priv(src voidptr, no_block bool) ChanState {
|
fn (mut ch Channel) try_push_priv(src voidptr, no_block bool) ChanState {
|
||||||
if C.atomic_load_u16(&ch.closed) != 0 {
|
if C.atomic_load_u16(&ch.closed) != 0 {
|
||||||
return .closed
|
return .closed
|
||||||
}
|
}
|
||||||
spinloops_sem_, spinloops_ := if no_block { spinloops, spinloops_sem } else { 1, 1 }
|
spinloops_sem_, spinloops_ := if no_block { 1, 1 } else { spinloops, spinloops_sem }
|
||||||
mut have_swapped := false
|
mut have_swapped := false
|
||||||
for {
|
for {
|
||||||
mut got_sem := false
|
mut got_sem := false
|
||||||
@ -200,6 +200,9 @@ fn (mut ch Channel) try_push_priv(src voidptr, no_block bool) ChanState {
|
|||||||
got_sem = ch.writesem.try_wait()
|
got_sem = ch.writesem.try_wait()
|
||||||
}
|
}
|
||||||
if !got_sem {
|
if !got_sem {
|
||||||
|
if no_block {
|
||||||
|
return .not_ready
|
||||||
|
}
|
||||||
ch.writesem.wait()
|
ch.writesem.wait()
|
||||||
}
|
}
|
||||||
if ch.cap == 0 {
|
if ch.cap == 0 {
|
||||||
@ -311,6 +314,9 @@ fn (mut ch Channel) try_push_priv(src voidptr, no_block bool) ChanState {
|
|||||||
}
|
}
|
||||||
return .success
|
return .success
|
||||||
} else {
|
} else {
|
||||||
|
if no_block {
|
||||||
|
return .not_ready
|
||||||
|
}
|
||||||
ch.writesem.post()
|
ch.writesem.post()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -324,11 +330,11 @@ pub fn (mut ch Channel) pop(dest voidptr) bool {
|
|||||||
|
|
||||||
[inline]
|
[inline]
|
||||||
pub fn (mut ch Channel) try_pop(dest voidptr) ChanState {
|
pub fn (mut ch Channel) try_pop(dest voidptr) ChanState {
|
||||||
return ch.try_pop_priv(dest, false)
|
return ch.try_pop_priv(dest, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut ch Channel) try_pop_priv(dest voidptr, no_block bool) ChanState {
|
fn (mut ch Channel) try_pop_priv(dest voidptr, no_block bool) ChanState {
|
||||||
spinloops_sem_, spinloops_ := if no_block { spinloops, spinloops_sem } else { 1, 1 }
|
spinloops_sem_, spinloops_ := if no_block { 1, 1 } else { spinloops, spinloops_sem }
|
||||||
mut have_swapped := false
|
mut have_swapped := false
|
||||||
mut write_in_progress := false
|
mut write_in_progress := false
|
||||||
for {
|
for {
|
||||||
|
Loading…
Reference in New Issue
Block a user