channels: fix C warnings (#9732)
parent
1250ce4353
commit
25a9d30a70
|
@ -79,7 +79,7 @@ jobs:
|
|||
- name: Self tests
|
||||
run: ./v -silent test-self
|
||||
- name: Self tests (-Werror)
|
||||
run: ./v -cflags "-Werror" test-self
|
||||
run: ./v -cflags -Werror test-self
|
||||
- name: Test time functions in a timezone UTC-12
|
||||
run: TZ=Etc/GMT+12 ./v test vlib/time/
|
||||
- name: Test time functions in a timezone UTC-3
|
||||
|
|
|
@ -33,115 +33,53 @@ const (
|
|||
skip_with_werror = [
|
||||
'vlib/clipboard/clipboard_test.v',
|
||||
'vlib/eventbus/eventbus_test.v',
|
||||
'vlib/json/json_test.v',
|
||||
'vlib/orm/orm_test.v',
|
||||
'vlib/regex/regex_test.v',
|
||||
'vlib/sqlite/sqlite_test.v',
|
||||
'vlib/strconv/atof_test.v',
|
||||
'vlib/regex/regex_test.v',
|
||||
'vlib/strconv/f32_f64_to_string_test.v',
|
||||
'vlib/strconv/number_to_base_test.v',
|
||||
'vlib/context/value_test.v' /* the following tests need C casts in `sync` and/or thirdparty/stdatomic */,
|
||||
'vlib/context/empty_test.v',
|
||||
'vlib/context/cancel_test.v',
|
||||
'vlib/context/deadline_test.v',
|
||||
'vlib/sync/array_rlock_test.v',
|
||||
'vlib/sync/atomic2/atomic_test.v',
|
||||
'vlib/sync/channel_2_test.v',
|
||||
'vlib/sync/channel_1_test.v',
|
||||
'vlib/sync/channel_3_test.v',
|
||||
'vlib/sync/channel_4_test.v',
|
||||
'vlib/sync/channel_array_mut_test.v',
|
||||
'vlib/sync/channel_close_test.v',
|
||||
'vlib/sync/channel_fill_test.v',
|
||||
'vlib/sync/channel_polling_test.v',
|
||||
'vlib/sync/channel_opt_propagate_test.v',
|
||||
'vlib/sync/channel_push_or_1_test.v',
|
||||
'vlib/sync/channel_push_or_2_test.v',
|
||||
'vlib/sync/channel_select_2_test.v',
|
||||
'vlib/sync/channel_select_3_test.v',
|
||||
'vlib/sync/channel_select_4_test.v',
|
||||
'vlib/sync/channel_select_5_test.v',
|
||||
'vlib/sync/channel_select_6_test.v',
|
||||
'vlib/sync/channel_select_test.v',
|
||||
'vlib/sync/channel_try_buf_test.v',
|
||||
'vlib/sync/select_close_test.v',
|
||||
'vlib/sync/struct_chan_init_test.v',
|
||||
'vlib/sync/pool/pool_test.v',
|
||||
'vlib/sync/channel_try_unbuf_test.v',
|
||||
'vlib/szip/szip_test.v',
|
||||
'vlib/v/compiler_errors_test.v',
|
||||
'vlib/v/gen/js/jsgen_test.v',
|
||||
'vlib/v/tests/anon_fn_test.v',
|
||||
'vlib/v/tests/array_map_ref_test.v',
|
||||
'vlib/v/tests/array_test.v',
|
||||
'vlib/v/tests/assert_sumtype_test.v',
|
||||
'vlib/v/tests/autolock_array2_test.v',
|
||||
'vlib/v/tests/autolock_array1_test.v',
|
||||
'vlib/v/tests/blank_ident_test.v',
|
||||
'vlib/v/tests/comptime_at_test.v',
|
||||
'vlib/v/tests/comptime_call_test.v',
|
||||
'vlib/v/tests/comptime_at_test.v',
|
||||
'vlib/v/tests/comptime_if_expr_test.v',
|
||||
'vlib/v/tests/cstrings_test.v',
|
||||
'vlib/v/tests/enum_test.v',
|
||||
'vlib/v/tests/fixed_array_test.v',
|
||||
'vlib/v/tests/fn_shared_return_test.v',
|
||||
'vlib/v/tests/fn_variadic_test.v',
|
||||
'vlib/v/tests/for_loops_2_test.v',
|
||||
'vlib/v/tests/generic_chan_test.v',
|
||||
'vlib/v/tests/generics_method_test.v',
|
||||
'vlib/v/tests/go_array_wait_test.v',
|
||||
'vlib/v/tests/go_call_generic_fn_test.v',
|
||||
'vlib/v/tests/generics_test.v',
|
||||
'vlib/v/tests/go_wait_2_test.v',
|
||||
'vlib/v/tests/if_guard_test.v',
|
||||
'vlib/v/tests/in_expression_test.v',
|
||||
'vlib/v/tests/interface_edge_cases/assign_to_interface_field_test.v',
|
||||
'vlib/v/tests/interface_fields_test.v',
|
||||
'vlib/v/tests/interface_variadic_test.v',
|
||||
'vlib/v/tests/keep_args_alive_test.v',
|
||||
'vlib/v/tests/option_2_test.v',
|
||||
'vlib/v/tests/operator_overloading_with_string_interpolation_test.v',
|
||||
'vlib/v/tests/orm_sub_struct_test.v',
|
||||
'vlib/v/tests/ref_struct_test.v',
|
||||
'vlib/v/tests/repl/repl_test.v',
|
||||
'vlib/v/tests/semaphore_test.v',
|
||||
'vlib/v/tests/semaphore_timed_test.v',
|
||||
'vlib/v/tests/shared_arg_test.v',
|
||||
'vlib/v/tests/shared_array_test.v',
|
||||
'vlib/v/tests/shared_autolock_test.v',
|
||||
'vlib/v/tests/shared_fn_return_test.v',
|
||||
'vlib/v/tests/shared_lock_2_test.v',
|
||||
'vlib/v/tests/shared_elem_test.v',
|
||||
'vlib/v/tests/shared_lock_4_test.v',
|
||||
'vlib/v/tests/shared_lock_2_test.v',
|
||||
'vlib/v/tests/shared_lock_3_test.v',
|
||||
'vlib/v/tests/shared_lock_6_test.v',
|
||||
'vlib/v/tests/shared_lock_expr_test.v',
|
||||
'vlib/v/tests/shared_lock_5_test.v',
|
||||
'vlib/v/tests/shared_lock_4_test.v',
|
||||
'vlib/v/tests/shared_lock_test.v',
|
||||
'vlib/v/tests/shared_map_test.v',
|
||||
'vlib/v/tests/shared_unordered_mixed_test.v',
|
||||
'vlib/v/tests/shift_test.v',
|
||||
'vlib/v/tests/str_gen_test.v',
|
||||
'vlib/v/tests/string_interpolation_multi_return_test.v',
|
||||
'vlib/v/tests/string_interpolation_shared_test.v',
|
||||
'vlib/v/tests/string_interpolation_test.v',
|
||||
'vlib/v/tests/struct_allow_both_field_defaults_and_skip_flag_test.v',
|
||||
'vlib/v/tests/struct_test.v',
|
||||
'vlib/v/tests/sum_type_test.v',
|
||||
'vlib/v/tests/type_name_test.v',
|
||||
'vlib/v/tests/unsafe_test.v',
|
||||
'vlib/v/tests/voidptr_to_u64_cast_a_test.v',
|
||||
'vlib/v/tests/voidptr_to_u64_cast_b_test.v',
|
||||
'vlib/v/tests/working_with_an_empty_struct_test.v',
|
||||
'vlib/vweb/tests/vweb_test.v',
|
||||
'vlib/vweb/request_test.v',
|
||||
'vlib/vweb/route_test.v',
|
||||
'vlib/x/websocket/websocket_test.v',
|
||||
'vlib/x/ttf/ttf_test.v',
|
||||
]
|
||||
skip_with_asan_compiler = [
|
||||
'vlib/readline/readline_test.v',
|
||||
'vlib/vweb/tests/vweb_test.v',
|
||||
]
|
||||
skip_with_asan_compiler = []string{}
|
||||
skip_with_msan_compiler = []string{}
|
||||
skip_test_files = []string{}
|
||||
skip_on_musl = [
|
||||
|
|
|
@ -102,20 +102,20 @@ extern unsigned char __atomic_fetch_xor_1(unsigned char* x, unsigned char y, int
|
|||
#define memory_order_acq_rel 4
|
||||
#define memory_order_seq_cst 5
|
||||
|
||||
static inline uintptr_t atomic_load(uintptr_t* x) {
|
||||
return atomic_load_explicit(x, memory_order_seq_cst);
|
||||
static inline void** atomic_load(void** x) {
|
||||
return (void**)atomic_load_explicit((unsigned long long*)x, memory_order_seq_cst);
|
||||
}
|
||||
static inline void atomic_store(uintptr_t* x, uintptr_t y) {
|
||||
atomic_store_explicit(x, y, memory_order_seq_cst);
|
||||
static inline void atomic_store(void** x, void* y) {
|
||||
atomic_store_explicit((unsigned long long*)x, (uintptr_t)y, memory_order_seq_cst);
|
||||
}
|
||||
static inline int atomic_compare_exchange_weak(uintptr_t* x, uintptr_t* expected, uintptr_t y) {
|
||||
return (int)atomic_compare_exchange_weak_explicit(x, expected, y, memory_order_seq_cst, memory_order_seq_cst);
|
||||
static inline int atomic_compare_exchange_weak(void** x, void** expected, void* y) {
|
||||
return (int)atomic_compare_exchange_weak_explicit((unsigned long long*)x, (unsigned long long*)expected, (uintptr_t)y, memory_order_seq_cst, memory_order_seq_cst);
|
||||
}
|
||||
static inline int atomic_compare_exchange_strong(uintptr_t* x, uintptr_t* expected, uintptr_t y) {
|
||||
return (int)atomic_compare_exchange_strong_explicit(x, expected, y, memory_order_seq_cst, memory_order_seq_cst);
|
||||
static inline int atomic_compare_exchange_strong(void** x, void** expected, void* y) {
|
||||
return (int)atomic_compare_exchange_strong_explicit((unsigned long long*)x, (unsigned long long*)expected, (uintptr_t)y, memory_order_seq_cst, memory_order_seq_cst);
|
||||
}
|
||||
static inline uintptr_t atomic_exchange(uintptr_t* x, uintptr_t y) {
|
||||
return atomic_exchange_explicit(x, y, memory_order_seq_cst);
|
||||
static inline uintptr_t atomic_exchange(void** x, void* y) {
|
||||
return atomic_exchange_explicit((unsigned long long*)x, (uintptr_t)y, memory_order_seq_cst);
|
||||
}
|
||||
static inline uintptr_t atomic_fetch_add(uintptr_t* x, uintptr_t y) {
|
||||
return atomic_fetch_add_explicit(x, y, memory_order_seq_cst);
|
||||
|
@ -307,34 +307,34 @@ static inline unsigned long long atomic_fetch_xor_u64(unsigned long long* x, uns
|
|||
|
||||
|
||||
static inline void* atomic_load_ptr(void** x) {
|
||||
return atomic_load_explicit((_Atomic uintptr_t*)x, memory_order_seq_cst);
|
||||
return (void*)atomic_load_explicit((_Atomic uintptr_t*)x, memory_order_seq_cst);
|
||||
}
|
||||
static inline void atomic_store_ptr(void** x, void* y) {
|
||||
atomic_store_explicit((_Atomic uintptr_t*)x, y, memory_order_seq_cst);
|
||||
atomic_store_explicit((_Atomic uintptr_t*)x, (uintptr_t)y, memory_order_seq_cst);
|
||||
}
|
||||
static inline int atomic_compare_exchange_weak_ptr(void** x, void** expected, void* y) {
|
||||
return (int)atomic_compare_exchange_weak_explicit((_Atomic uintptr_t*)x, expected, y, memory_order_seq_cst, memory_order_seq_cst);
|
||||
return (int)atomic_compare_exchange_weak_explicit((_Atomic uintptr_t*)x, (unsigned long *)expected, (uintptr_t)y, memory_order_seq_cst, memory_order_seq_cst);
|
||||
}
|
||||
static inline int atomic_compare_exchange_strong_ptr(void** x, void** expected, void* y) {
|
||||
return (int)atomic_compare_exchange_strong_explicit((_Atomic uintptr_t*)x, expected, y, memory_order_seq_cst, memory_order_seq_cst);
|
||||
return (int)atomic_compare_exchange_strong_explicit((_Atomic uintptr_t*)x, (unsigned long *)expected, (uintptr_t)y, memory_order_seq_cst, memory_order_seq_cst);
|
||||
}
|
||||
static inline void* atomic_exchange_ptr(void** x, void* y) {
|
||||
return atomic_exchange_explicit((_Atomic uintptr_t*)x, y, memory_order_seq_cst);
|
||||
return (void*)atomic_exchange_explicit((_Atomic uintptr_t*)x, (uintptr_t)y, memory_order_seq_cst);
|
||||
}
|
||||
static inline void* atomic_fetch_add_ptr(void** x, void* y) {
|
||||
return atomic_fetch_add_explicit((_Atomic uintptr_t*)x, y, memory_order_seq_cst);
|
||||
return (void*)atomic_fetch_add_explicit((_Atomic uintptr_t*)x, (uintptr_t)y, memory_order_seq_cst);
|
||||
}
|
||||
static inline void* atomic_fetch_sub_ptr(void** x, void* y) {
|
||||
return atomic_fetch_sub_explicit((_Atomic uintptr_t*)x, y, memory_order_seq_cst);
|
||||
return (void*)atomic_fetch_sub_explicit((_Atomic uintptr_t*)x, (uintptr_t)y, memory_order_seq_cst);
|
||||
}
|
||||
static inline void* atomic_fetch_and_ptr(void** x, void* y) {
|
||||
return atomic_fetch_and_explicit((_Atomic uintptr_t*)x, y, memory_order_seq_cst);
|
||||
return (void*)atomic_fetch_and_explicit((_Atomic uintptr_t*)x, (uintptr_t)y, memory_order_seq_cst);
|
||||
}
|
||||
static inline void* atomic_fetch_or_ptr(void** x, void* y) {
|
||||
return atomic_fetch_or_explicit((_Atomic uintptr_t*)x, y, memory_order_seq_cst);
|
||||
return (void*)atomic_fetch_or_explicit((_Atomic uintptr_t*)x, (uintptr_t)y, memory_order_seq_cst);
|
||||
}
|
||||
static inline void* atomic_fetch_xor_ptr(void** x, void* y) {
|
||||
return atomic_fetch_xor_explicit((_Atomic uintptr_t*)x, y, memory_order_seq_cst);
|
||||
return (void*)atomic_fetch_xor_explicit((_Atomic uintptr_t*)x, (uintptr_t)y, memory_order_seq_cst);
|
||||
}
|
||||
|
||||
|
||||
|
@ -372,10 +372,10 @@ static inline unsigned atomic_fetch_xor_u32(unsigned* x, unsigned y) {
|
|||
static inline unsigned short atomic_load_u16(unsigned short* x) {
|
||||
return atomic_load_explicit((_Atomic unsigned short*)x, memory_order_seq_cst);
|
||||
}
|
||||
static inline void atomic_store_u16(unsigned short* x, unsigned short y) {
|
||||
static inline void atomic_store_u16(void* x, unsigned short y) {
|
||||
atomic_store_explicit((_Atomic unsigned short*)x, y, memory_order_seq_cst);
|
||||
}
|
||||
static inline int atomic_compare_exchange_weak_u16(unsigned short* x, unsigned short* expected, unsigned short y) {
|
||||
static inline int atomic_compare_exchange_weak_u16(void* x, unsigned short* expected, unsigned short y) {
|
||||
return (int)atomic_compare_exchange_weak_explicit((_Atomic unsigned short*)x, expected, y, memory_order_seq_cst, memory_order_seq_cst);
|
||||
}
|
||||
static inline int atomic_compare_exchange_strong_u16(unsigned short* x, unsigned short* expected, unsigned short y) {
|
||||
|
|
|
@ -60,7 +60,7 @@ fn C.atomic_fetch_sub_u64(voidptr, u64) u64
|
|||
|
||||
const (
|
||||
// how often to try to get data without blocking before to wait for semaphore
|
||||
spinloops = 750
|
||||
spinloops = 750
|
||||
spinloops_sem = 4000
|
||||
)
|
||||
|
||||
|
@ -73,9 +73,9 @@ enum BufferElemStat {
|
|||
|
||||
struct Subscription {
|
||||
mut:
|
||||
sem &Semaphore
|
||||
sem &Semaphore
|
||||
prev &&Subscription
|
||||
nxt &Subscription
|
||||
nxt &Subscription
|
||||
}
|
||||
|
||||
enum Direction {
|
||||
|
@ -84,9 +84,9 @@ enum Direction {
|
|||
}
|
||||
|
||||
struct Channel {
|
||||
ringbuf byteptr // queue for buffered channels
|
||||
statusbuf byteptr // flags to synchronize write/read in ringbuf
|
||||
objsize u32
|
||||
ringbuf &byte // queue for buffered channels
|
||||
statusbuf &byte // flags to synchronize write/read in ringbuf
|
||||
objsize u32
|
||||
mut: // atomic
|
||||
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
|
||||
|
@ -101,13 +101,13 @@ mut: // atomic
|
|||
buf_elem_write_idx u32
|
||||
buf_elem_read_idx u32
|
||||
// for select
|
||||
write_subscriber &Subscription
|
||||
read_subscriber &Subscription
|
||||
write_sub_mtx u16
|
||||
read_sub_mtx u16
|
||||
closed u16
|
||||
write_subscriber &Subscription
|
||||
read_subscriber &Subscription
|
||||
write_sub_mtx u16
|
||||
read_sub_mtx u16
|
||||
closed u16
|
||||
pub:
|
||||
cap u32 // queue length in #objects
|
||||
cap u32 // queue length in #objects
|
||||
}
|
||||
|
||||
pub fn new_channel<T>(n u32) &Channel {
|
||||
|
@ -118,8 +118,8 @@ pub fn new_channel<T>(n u32) &Channel {
|
|||
fn new_channel_st(n u32, st u32) &Channel {
|
||||
wsem := if n > 0 { n } else { 1 }
|
||||
rsem := if n > 0 { u32(0) } else { 1 }
|
||||
rbuf := if n > 0 { unsafe {malloc(int(n * st))} } else { byteptr(0) }
|
||||
sbuf := if n > 0 { vcalloc(int(n * 2)) } else { byteptr(0) }
|
||||
rbuf := if n > 0 { unsafe { malloc(int(n * st)) } } else { &byte(0) }
|
||||
sbuf := if n > 0 { vcalloc(int(n * 2)) } else { &byte(0) }
|
||||
mut ch := &Channel{
|
||||
objsize: st
|
||||
cap: n
|
||||
|
@ -143,7 +143,8 @@ pub fn (mut ch Channel) close() {
|
|||
return
|
||||
}
|
||||
mut nulladr := voidptr(0)
|
||||
for !C.atomic_compare_exchange_weak_ptr(&ch.adr_written, &nulladr, voidptr(-1)) {
|
||||
for !C.atomic_compare_exchange_weak_ptr(unsafe { &voidptr(&ch.adr_written) }, &nulladr,
|
||||
voidptr(-1)) {
|
||||
nulladr = voidptr(0)
|
||||
}
|
||||
ch.readsem_im.post()
|
||||
|
@ -166,7 +167,7 @@ pub fn (mut ch Channel) close() {
|
|||
C.atomic_store_u16(&ch.write_sub_mtx, u16(0))
|
||||
ch.writesem.post()
|
||||
if ch.cap == 0 {
|
||||
C.atomic_store_ptr(&ch.read_adr, voidptr(0))
|
||||
C.atomic_store_ptr(unsafe { &voidptr(&ch.read_adr) }, voidptr(0))
|
||||
}
|
||||
ch.writesem_im.post()
|
||||
}
|
||||
|
@ -197,17 +198,20 @@ fn (mut ch Channel) try_push_priv(src voidptr, no_block bool) ChanState {
|
|||
if C.atomic_load_u16(&ch.closed) != 0 {
|
||||
return .closed
|
||||
}
|
||||
spinloops_sem_, spinloops_ := if no_block { 1, 1 } else { spinloops, spinloops_sem }
|
||||
spinloops_sem_, spinloops_ := if no_block { 1, 1 } else { sync.spinloops, sync.spinloops_sem }
|
||||
mut have_swapped := false
|
||||
for {
|
||||
mut got_sem := false
|
||||
mut wradr := C.atomic_load_ptr(&ch.write_adr)
|
||||
mut wradr := C.atomic_load_ptr(unsafe { &voidptr(&ch.write_adr) })
|
||||
for wradr != C.NULL {
|
||||
if C.atomic_compare_exchange_strong_ptr(&ch.write_adr, &wradr, voidptr(0)) {
|
||||
if C.atomic_compare_exchange_strong_ptr(unsafe { &voidptr(&ch.write_adr) },
|
||||
&wradr, voidptr(0))
|
||||
{
|
||||
// there is a reader waiting for us
|
||||
unsafe { C.memcpy(wradr, src, ch.objsize) }
|
||||
mut nulladr := voidptr(0)
|
||||
for !C.atomic_compare_exchange_weak_ptr(&ch.adr_written, &nulladr, wradr) {
|
||||
for !C.atomic_compare_exchange_weak_ptr(unsafe { &voidptr(&ch.adr_written) },
|
||||
&nulladr, wradr) {
|
||||
nulladr = voidptr(0)
|
||||
}
|
||||
ch.readsem_im.post()
|
||||
|
@ -237,11 +241,13 @@ fn (mut ch Channel) try_push_priv(src voidptr, no_block bool) ChanState {
|
|||
if ch.cap == 0 {
|
||||
// try to advertise current object as readable
|
||||
mut read_in_progress := false
|
||||
C.atomic_store_ptr(&ch.read_adr, src)
|
||||
wradr = C.atomic_load_ptr(&ch.write_adr)
|
||||
C.atomic_store_ptr(unsafe { &voidptr(&ch.read_adr) }, src)
|
||||
wradr = C.atomic_load_ptr(unsafe { &voidptr(&ch.write_adr) })
|
||||
if wradr != C.NULL {
|
||||
mut src2 := src
|
||||
if C.atomic_compare_exchange_strong_ptr(&ch.read_adr, &src2, voidptr(0)) {
|
||||
if C.atomic_compare_exchange_strong_ptr(unsafe { &voidptr(&ch.read_adr) },
|
||||
&src2, voidptr(0))
|
||||
{
|
||||
ch.writesem.post()
|
||||
continue
|
||||
} else {
|
||||
|
@ -250,7 +256,8 @@ fn (mut ch Channel) try_push_priv(src voidptr, no_block bool) ChanState {
|
|||
}
|
||||
if !read_in_progress {
|
||||
mut null16 := u16(0)
|
||||
for !C.atomic_compare_exchange_weak_u16(&ch.read_sub_mtx, &null16, u16(1)) {
|
||||
for !C.atomic_compare_exchange_weak_u16(voidptr(&ch.read_sub_mtx), &null16,
|
||||
u16(1)) {
|
||||
null16 = u16(0)
|
||||
}
|
||||
if ch.read_subscriber != voidptr(0) {
|
||||
|
@ -260,7 +267,9 @@ fn (mut ch Channel) try_push_priv(src voidptr, no_block bool) ChanState {
|
|||
}
|
||||
mut src2 := src
|
||||
for sp := u32(0); sp < spinloops_ || read_in_progress; sp++ {
|
||||
if C.atomic_compare_exchange_strong_ptr(&ch.adr_read, &src2, voidptr(0)) {
|
||||
if C.atomic_compare_exchange_strong_ptr(unsafe { &voidptr(&ch.adr_read) },
|
||||
&src2, voidptr(0))
|
||||
{
|
||||
have_swapped = true
|
||||
read_in_progress = true
|
||||
break
|
||||
|
@ -281,14 +290,16 @@ fn (mut ch Channel) try_push_priv(src voidptr, no_block bool) ChanState {
|
|||
ch.writesem_im.wait()
|
||||
}
|
||||
if C.atomic_load_u16(&ch.closed) != 0 {
|
||||
if have_swapped || C.atomic_compare_exchange_strong_ptr(&ch.adr_read, &src2, voidptr(0)) {
|
||||
if have_swapped
|
||||
|| C.atomic_compare_exchange_strong_ptr(unsafe { &voidptr(&ch.adr_read) }, &src2, voidptr(0)) {
|
||||
ch.writesem.post()
|
||||
return .success
|
||||
} else {
|
||||
return .closed
|
||||
}
|
||||
}
|
||||
if have_swapped || C.atomic_compare_exchange_strong_ptr(&ch.adr_read, &src2, voidptr(0)) {
|
||||
if have_swapped
|
||||
|| C.atomic_compare_exchange_strong_ptr(unsafe { &voidptr(&ch.adr_read) }, &src2, voidptr(0)) {
|
||||
ch.writesem.post()
|
||||
break
|
||||
} else {
|
||||
|
@ -307,7 +318,8 @@ fn (mut ch Channel) try_push_priv(src voidptr, no_block bool) ChanState {
|
|||
mut space_in_queue := false
|
||||
mut wr_free := C.atomic_load_u32(&ch.write_free)
|
||||
for wr_free > 0 {
|
||||
space_in_queue = C.atomic_compare_exchange_weak_u32(&ch.write_free, &wr_free, wr_free-1)
|
||||
space_in_queue = C.atomic_compare_exchange_weak_u32(&ch.write_free, &wr_free,
|
||||
wr_free - 1)
|
||||
if space_in_queue {
|
||||
break
|
||||
}
|
||||
|
@ -319,7 +331,9 @@ fn (mut ch Channel) try_push_priv(src voidptr, no_block bool) ChanState {
|
|||
for new_wr_idx >= ch.cap {
|
||||
new_wr_idx -= ch.cap
|
||||
}
|
||||
if C.atomic_compare_exchange_strong_u32(&ch.buf_elem_write_idx, &wr_idx, new_wr_idx) {
|
||||
if C.atomic_compare_exchange_strong_u32(&ch.buf_elem_write_idx, &wr_idx,
|
||||
new_wr_idx)
|
||||
{
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -330,13 +344,14 @@ fn (mut ch Channel) try_push_priv(src voidptr, no_block bool) ChanState {
|
|||
status_adr += wr_idx * sizeof(u16)
|
||||
}
|
||||
mut expected_status := u16(BufferElemStat.unused)
|
||||
for !C.atomic_compare_exchange_weak_u16(status_adr, &expected_status, u16(BufferElemStat.writing)) {
|
||||
for !C.atomic_compare_exchange_weak_u16(unsafe { &u16(status_adr) },
|
||||
&expected_status, u16(BufferElemStat.writing)) {
|
||||
expected_status = u16(BufferElemStat.unused)
|
||||
}
|
||||
unsafe {
|
||||
C.memcpy(wr_ptr, src, ch.objsize)
|
||||
}
|
||||
C.atomic_store_u16(status_adr, u16(BufferElemStat.written))
|
||||
C.atomic_store_u16(unsafe { &u16(status_adr) }, u16(BufferElemStat.written))
|
||||
C.atomic_fetch_add_u32(&ch.read_avail, 1)
|
||||
ch.readsem.post()
|
||||
mut null16 := u16(0)
|
||||
|
@ -372,20 +387,23 @@ pub fn (mut ch Channel) try_pop(dest voidptr) ChanState {
|
|||
}
|
||||
|
||||
fn (mut ch Channel) try_pop_priv(dest voidptr, no_block bool) ChanState {
|
||||
spinloops_sem_, spinloops_ := if no_block { 1, 1 } else { spinloops, spinloops_sem }
|
||||
spinloops_sem_, spinloops_ := if no_block { 1, 1 } else { sync.spinloops, sync.spinloops_sem }
|
||||
mut have_swapped := false
|
||||
mut write_in_progress := false
|
||||
for {
|
||||
mut got_sem := false
|
||||
if ch.cap == 0 {
|
||||
// unbuffered channel - first see if a `push()` has adversized
|
||||
mut rdadr := C.atomic_load_ptr(&ch.read_adr)
|
||||
mut rdadr := C.atomic_load_ptr(unsafe { &voidptr(&ch.read_adr) })
|
||||
for rdadr != C.NULL {
|
||||
if C.atomic_compare_exchange_strong_ptr(&ch.read_adr, &rdadr, voidptr(0)) {
|
||||
if C.atomic_compare_exchange_strong_ptr(unsafe { &voidptr(&ch.read_adr) },
|
||||
&rdadr, voidptr(0))
|
||||
{
|
||||
// there is a writer waiting for us
|
||||
unsafe { C.memcpy(dest, rdadr, ch.objsize) }
|
||||
mut nulladr := voidptr(0)
|
||||
for !C.atomic_compare_exchange_weak_ptr(&ch.adr_read, &nulladr, rdadr) {
|
||||
for !C.atomic_compare_exchange_weak_ptr(unsafe { &voidptr(&ch.adr_read) },
|
||||
&nulladr, rdadr) {
|
||||
nulladr = voidptr(0)
|
||||
}
|
||||
ch.writesem_im.post()
|
||||
|
@ -422,7 +440,8 @@ fn (mut ch Channel) try_pop_priv(dest voidptr, no_block bool) ChanState {
|
|||
mut obj_in_queue := false
|
||||
mut rd_avail := C.atomic_load_u32(&ch.read_avail)
|
||||
for rd_avail > 0 {
|
||||
obj_in_queue = C.atomic_compare_exchange_weak_u32(&ch.read_avail, &rd_avail, rd_avail-1)
|
||||
obj_in_queue = C.atomic_compare_exchange_weak_u32(&ch.read_avail, &rd_avail,
|
||||
rd_avail - 1)
|
||||
if obj_in_queue {
|
||||
break
|
||||
}
|
||||
|
@ -434,7 +453,9 @@ fn (mut ch Channel) try_pop_priv(dest voidptr, no_block bool) ChanState {
|
|||
for new_rd_idx >= ch.cap {
|
||||
new_rd_idx -= ch.cap
|
||||
}
|
||||
if C.atomic_compare_exchange_weak_u32(&ch.buf_elem_read_idx, &rd_idx, new_rd_idx) {
|
||||
if C.atomic_compare_exchange_weak_u32(&ch.buf_elem_read_idx, &rd_idx,
|
||||
new_rd_idx)
|
||||
{
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -445,13 +466,14 @@ fn (mut ch Channel) try_pop_priv(dest voidptr, no_block bool) ChanState {
|
|||
status_adr += rd_idx * sizeof(u16)
|
||||
}
|
||||
mut expected_status := u16(BufferElemStat.written)
|
||||
for !C.atomic_compare_exchange_weak_u16(status_adr, &expected_status, u16(BufferElemStat.reading)) {
|
||||
for !C.atomic_compare_exchange_weak_u16(unsafe { &u16(status_adr) },
|
||||
&expected_status, u16(BufferElemStat.reading)) {
|
||||
expected_status = u16(BufferElemStat.written)
|
||||
}
|
||||
unsafe {
|
||||
C.memcpy(dest, rd_ptr, ch.objsize)
|
||||
}
|
||||
C.atomic_store_u16(status_adr, u16(BufferElemStat.unused))
|
||||
C.atomic_store_u16(unsafe { &u16(status_adr) }, u16(BufferElemStat.unused))
|
||||
C.atomic_fetch_add_u32(&ch.write_free, 1)
|
||||
ch.writesem.post()
|
||||
mut null16 := u16(0)
|
||||
|
@ -466,12 +488,14 @@ fn (mut ch Channel) try_pop_priv(dest voidptr, no_block bool) ChanState {
|
|||
}
|
||||
}
|
||||
// try to advertise `dest` as writable
|
||||
C.atomic_store_ptr(&ch.write_adr, dest)
|
||||
C.atomic_store_ptr(unsafe { &voidptr(&ch.write_adr) }, dest)
|
||||
if ch.cap == 0 {
|
||||
mut rdadr := C.atomic_load_ptr(&ch.read_adr)
|
||||
mut rdadr := C.atomic_load_ptr(unsafe { &voidptr(&ch.read_adr) })
|
||||
if rdadr != C.NULL {
|
||||
mut dest2 := dest
|
||||
if C.atomic_compare_exchange_strong_ptr(&ch.write_adr, &dest2, voidptr(0)) {
|
||||
if C.atomic_compare_exchange_strong_ptr(unsafe { &voidptr(&ch.write_adr) },
|
||||
&dest2, voidptr(0))
|
||||
{
|
||||
ch.readsem.post()
|
||||
continue
|
||||
} else {
|
||||
|
@ -491,7 +515,9 @@ fn (mut ch Channel) try_pop_priv(dest voidptr, no_block bool) ChanState {
|
|||
}
|
||||
mut dest2 := dest
|
||||
for sp := u32(0); sp < spinloops_ || write_in_progress; sp++ {
|
||||
if C.atomic_compare_exchange_strong_ptr(&ch.adr_written, &dest2, voidptr(0)) {
|
||||
if C.atomic_compare_exchange_strong_ptr(unsafe { &voidptr(&ch.adr_written) },
|
||||
&dest2, voidptr(0))
|
||||
{
|
||||
have_swapped = true
|
||||
break
|
||||
} else if dest2 == voidptr(-1) {
|
||||
|
@ -513,7 +539,8 @@ fn (mut ch Channel) try_pop_priv(dest voidptr, no_block bool) ChanState {
|
|||
} else {
|
||||
ch.readsem_im.wait()
|
||||
}
|
||||
if have_swapped || C.atomic_compare_exchange_strong_ptr(&ch.adr_written, &dest2, voidptr(0)) {
|
||||
if have_swapped
|
||||
|| C.atomic_compare_exchange_strong_ptr(unsafe { &voidptr(&ch.adr_written) }, &dest2, voidptr(0)) {
|
||||
ch.readsem.post()
|
||||
break
|
||||
} else {
|
||||
|
@ -526,7 +553,7 @@ fn (mut ch Channel) try_pop_priv(dest voidptr, no_block bool) ChanState {
|
|||
dest2 = dest
|
||||
}
|
||||
}
|
||||
break
|
||||
break
|
||||
}
|
||||
return .success
|
||||
}
|
||||
|
@ -553,7 +580,8 @@ pub fn channel_select(mut channels []&Channel, dir []Direction, mut objrefs []vo
|
|||
}
|
||||
subscr[i].prev = &ch.write_subscriber
|
||||
unsafe {
|
||||
subscr[i].nxt = C.atomic_exchange_ptr(&ch.write_subscriber, &subscr[i])
|
||||
subscr[i].nxt = &Subscription(C.atomic_exchange_ptr(&voidptr(&ch.write_subscriber),
|
||||
&subscr[i]))
|
||||
}
|
||||
if voidptr(subscr[i].nxt) != voidptr(0) {
|
||||
subscr[i].nxt.prev = &subscr[i].nxt
|
||||
|
@ -566,7 +594,8 @@ pub fn channel_select(mut channels []&Channel, dir []Direction, mut objrefs []vo
|
|||
}
|
||||
subscr[i].prev = &ch.read_subscriber
|
||||
unsafe {
|
||||
subscr[i].nxt = C.atomic_exchange_ptr(&ch.read_subscriber, &subscr[i])
|
||||
subscr[i].nxt = &Subscription(C.atomic_exchange_ptr(&voidptr(&ch.read_subscriber),
|
||||
&subscr[i]))
|
||||
}
|
||||
if voidptr(subscr[i].nxt) != voidptr(0) {
|
||||
subscr[i].nxt.prev = &subscr[i].nxt
|
||||
|
@ -576,8 +605,8 @@ pub fn channel_select(mut channels []&Channel, dir []Direction, mut objrefs []vo
|
|||
}
|
||||
stopwatch := if timeout <= 0 { time.StopWatch{} } else { time.new_stopwatch({}) }
|
||||
mut event_idx := -1 // negative index means `timed out`
|
||||
outer:
|
||||
for {
|
||||
|
||||
outer: for {
|
||||
rnd := rand.u32_in_range(0, u32(channels.len))
|
||||
mut num_closed := 0
|
||||
for j, _ in channels {
|
||||
|
|
|
@ -3825,7 +3825,7 @@ fn (mut g Gen) lock_expr(node ast.LockExpr) {
|
|||
if !node.is_rlock[i] {
|
||||
name := id.name
|
||||
deref := if id.is_mut { '->' } else { '.' }
|
||||
g.writeln('_arr_$mtxs[$j] = &$name${deref}mtx;')
|
||||
g.writeln('_arr_$mtxs[$j] = (uintptr_t)&$name${deref}mtx;')
|
||||
g.writeln('_isrlck_$mtxs[$j] = false;')
|
||||
j++
|
||||
}
|
||||
|
@ -3834,7 +3834,7 @@ fn (mut g Gen) lock_expr(node ast.LockExpr) {
|
|||
if node.is_rlock[i] {
|
||||
name := id.name
|
||||
deref := if id.is_mut { '->' } else { '.' }
|
||||
g.writeln('_arr_$mtxs[$j] = &$name${deref}mtx;')
|
||||
g.writeln('_arr_$mtxs[$j] = (uintptr_t)&$name${deref}mtx;')
|
||||
g.writeln('_isrlck_$mtxs[$j] = true;')
|
||||
j++
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue