Skip to content

Commit

Permalink
sync: use mfence on windows-tcc (#6079)
Browse files Browse the repository at this point in the history
  • Loading branch information
UweKrueger authored Aug 6, 2020
1 parent ea76a33 commit d63daa0
Show file tree
Hide file tree
Showing 9 changed files with 17 additions and 11 deletions.
2 changes: 1 addition & 1 deletion thirdparty/stdatomic/win/atomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ __CRT_INLINE SHORT _InterlockedExchangeAdd16(SHORT volatile *Addend, SHORT Value
#define InterlockedIncrement64 _InterlockedExchangeAdd64

__CRT_INLINE VOID __faststorefence() {
__asm__ __volatile__ ("sfence");
__asm__ __volatile__ ("mfence");
}

#endif
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fn test_select() {
go do_send_byte(mut chb)
go do_send_i64(mut chl)
mut channels := [chi, recch, chl, chb]
directions := [false, true, false, false]
directions := [sync.Direction.pop, .push, .pop, .pop]
mut sum := i64(0)
mut rl := i64(0)
mut ri := int(0)
Expand Down
24 changes: 15 additions & 9 deletions vlib/sync/channels.v
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ mut:
nxt &Subscription
}

enum Direction {
pop
push
}

struct Channel {
writesem Semaphore // to wake thread that wanted to write, but buffer was full
readsem Semaphore // to wake thread that wanted to read, but buffer was empty
Expand All @@ -97,17 +102,18 @@ mut: // atomic
}

pub fn new_channel<T>(n u32) &Channel {
st := sizeof(T)
return &Channel{
writesem: new_semaphore_init(if n > 0 { n + 1 } else { 1 })
readsem: new_semaphore_init(if n > 0 { u32(0) } else { 1 })
writesem_im: new_semaphore()
readsem_im: new_semaphore()
objsize: sizeof(T)
objsize: st
queue_length: n
write_free: n
read_avail: 0
ringbuf: if n > 0 { malloc(int(n * sizeof(T))) } else { byteptr(0) }
statusbuf: if n > 0 { vcalloc(int(n * sizeof(u16))) } else { byteptr(0) }
ringbuf: if n > 0 { malloc(int(n * st)) } else { byteptr(0) }
statusbuf: if n > 0 { vcalloc(int(n * 2)) } else { byteptr(0) }
write_subscriber: 0
read_subscriber: 0
}
Expand Down Expand Up @@ -412,13 +418,13 @@ fn (mut ch Channel) try_pop(dest voidptr, no_block bool) bool {
// Wait `timeout` on any of `channels[i]` until one of them can push (`is_push[i] = true`) or pop (`is_push[i] = false`)
// object referenced by `objrefs[i]`. `timeout = 0` means wait unlimited time

pub fn channel_select(mut channels []&Channel, is_push []bool, mut objrefs []voidptr, timeout time.Duration) int {
assert channels.len == is_push.len
assert is_push.len == objrefs.len
pub fn channel_select(mut channels []&Channel, dir []Direction, mut objrefs []voidptr, timeout time.Duration) int {
assert channels.len == dir.len
assert dir.len == objrefs.len
mut subscr := []Subscription{len: channels.len}
sem := new_semaphore()
for i, ch in channels {
if is_push[i] {
if dir[i] == .push {
mut null16 := u16(0)
for !C.atomic_compare_exchange_weak_u16(&ch.write_sub_mtx, &null16, u16(1)) {
null16 = u16(0)
Expand Down Expand Up @@ -453,7 +459,7 @@ pub fn channel_select(mut channels []&Channel, is_push []bool, mut objrefs []voi
if i >= channels.len {
i -= channels.len
}
if is_push[i] {
if dir[i] == .push {
if channels[i].try_push(objrefs[i], true) {
event_idx = i
goto restore
Expand All @@ -477,7 +483,7 @@ pub fn channel_select(mut channels []&Channel, is_push []bool, mut objrefs []voi
restore:
// reset subscribers
for i, ch in channels {
if is_push[i] {
if dir[i] == .push {
mut null16 := u16(0)
for !C.atomic_compare_exchange_weak_u16(&ch.write_sub_mtx, &null16, u16(1)) {
null16 = u16(0)
Expand Down

0 comments on commit d63daa0

Please sign in to comment.