From 25a9d30a70ac7b6578b0c2c70b2405e4b6301c02 Mon Sep 17 00:00:00 2001 From: ka-weihe Date: Thu, 15 Apr 2021 01:44:39 +0200 Subject: [PATCH] channels: fix C warnings (#9732) --- .github/workflows/ci.yml | 2 +- cmd/tools/vtest-self.v | 74 ++--------------- thirdparty/stdatomic/nix/atomic.h | 44 +++++------ vlib/sync/channels.v | 127 ++++++++++++++++++------------ vlib/v/gen/c/cgen.v | 4 +- 5 files changed, 109 insertions(+), 142 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0308a159d8..884d3a54ac 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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 diff --git a/cmd/tools/vtest-self.v b/cmd/tools/vtest-self.v index c26f0e462e..b27874e619 100644 --- a/cmd/tools/vtest-self.v +++ b/cmd/tools/vtest-self.v @@ -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 = [ diff --git a/thirdparty/stdatomic/nix/atomic.h b/thirdparty/stdatomic/nix/atomic.h index 886d21aded..4da37f85fd 100644 --- a/thirdparty/stdatomic/nix/atomic.h +++ b/thirdparty/stdatomic/nix/atomic.h @@ -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) { diff --git a/vlib/sync/channels.v b/vlib/sync/channels.v index 70b17491f0..bda7135421 100644 --- a/vlib/sync/channels.v +++ b/vlib/sync/channels.v @@ -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(n u32) &Channel { @@ -118,8 +118,8 @@ pub fn new_channel(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 { diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 32189fff1f..f6c605355d 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -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++ }