From ac4791045feaebc2cf2560517c159e5aeac21ed5 Mon Sep 17 00:00:00 2001 From: zakuro Date: Mon, 22 Feb 2021 00:05:03 +0900 Subject: [PATCH] time: consolidate the different sleep functions into time.wait(Duration) (#8853) --- cmd/tools/fast/fast_job.v | 3 +- cmd/tools/test_os_process.v | 8 ++--- cmd/tools/vtest-parser.v | 8 ++--- examples/buf_reader.v | 2 +- examples/concurrency/concurrency.v | 2 +- examples/flappylearning/game.v | 2 +- examples/game_of_life/life.v | 2 +- examples/hot_reload/bounce.v | 36 ++++++++++----------- examples/hot_reload/message.v | 2 +- examples/lander.v | 8 +++-- examples/sokol/sounds/melody.v | 21 +++++++------ examples/sokol/sounds/simple_sin_tones.v | 16 +++++----- examples/sokol/sounds/wav_player.v | 2 +- examples/tetris/tetris.v | 2 +- examples/vweb/server_sent_events/server.v | 2 +- examples/websocket/ping.v | 38 +++++++---------------- vlib/clipboard/x11/clipboard.c.v | 21 ++++++------- vlib/encoding/base64/base64_memory_test.v | 12 +++---- vlib/math/big/big.v | 2 +- vlib/os/os_c.v | 2 +- vlib/os/process_test.v | 2 +- vlib/rand/random_identifiers_test.v | 4 +-- vlib/sync/channel_select_2_test.v | 7 ++--- vlib/sync/pool/pool_test.v | 4 +-- vlib/szip/szip.v | 9 +++--- vlib/term/ui/termios_nix.c.v | 6 ++-- vlib/time/operator_test.v | 2 +- vlib/time/stopwatch_test.v | 8 ++--- vlib/time/time.v | 22 ++++--------- vlib/time/time_nix.c.v | 8 +++++ vlib/time/time_test.v | 2 +- vlib/time/time_windows.c.v | 5 +++ vlib/v/live/executable/reloader.v | 2 +- vlib/v/live/live_test.v | 8 ++--- vlib/v/live/live_test_template.vv | 2 +- vlib/v/parser/parser.v | 7 ----- vlib/v/tests/autolock_array1_test.v | 2 +- vlib/v/tests/go_wait_2_test.v | 2 +- vlib/v/tests/shared_array_test.v | 2 +- vlib/v/tests/shared_lock_2_test.v | 2 +- vlib/v/tests/shared_lock_3_test.v | 8 ++--- vlib/v/tests/shared_lock_4_test.v | 8 ++--- vlib/v/tests/shared_lock_test.v | 2 +- vlib/v/tests/type_voidptr_test.v | 2 +- vlib/v/util/util.v | 2 +- vlib/vweb/tests/vweb_test.v | 4 +-- vlib/vweb/tests/vweb_test_server.v | 4 +-- vlib/x/websocket/websocket_server.v | 2 +- vlib/x/websocket/websocket_test.v | 6 ++-- 49 files changed, 156 insertions(+), 179 deletions(-) diff --git a/cmd/tools/fast/fast_job.v b/cmd/tools/fast/fast_job.v index 2eb108ae15..26707aa47c 100644 --- a/cmd/tools/fast/fast_job.v +++ b/cmd/tools/fast/fast_job.v @@ -36,7 +36,6 @@ fn main() { os.system('git push origin gh-pages') os.chdir('..') } - // println('sleeping 60') - time.sleep(60) + time.wait(60 * time.second) } } diff --git a/cmd/tools/test_os_process.v b/cmd/tools/test_os_process.v index fb01cbbe98..82f27576f4 100644 --- a/cmd/tools/test_os_process.v +++ b/cmd/tools/test_os_process.v @@ -44,7 +44,7 @@ fn (mut ctx Context) println(s string) { fn do_timeout(c &Context) { mut ctx := c - time.sleep_ms(ctx.timeout_ms) + time.wait(ctx.timeout_ms * time.millisecond) exit(ctx.exitcode) } @@ -58,7 +58,7 @@ fn main() { After a while (-timeout_ms), exit with (-exitcode). This program is useful for platform independent testing of child process/standart input/output control. - It is used in V\'s `os` module tests. + It is used in V's `os` module tests. ") } ctx.is_verbose = '-v' in args @@ -75,7 +75,7 @@ fn main() { go do_timeout(&ctx) for i := 1; true; i++ { ctx.println('$i') - time.sleep_ms(ctx.period_ms) + time.wait(ctx.period_ms * time.millisecond) } - time.sleep(100000) + time.wait(100 * time.second) } diff --git a/cmd/tools/vtest-parser.v b/cmd/tools/vtest-parser.v index 2c7dfc30b3..a492a8813c 100644 --- a/cmd/tools/vtest-parser.v +++ b/cmd/tools/vtest-parser.v @@ -14,7 +14,7 @@ const ( ecode_timeout = 101 ecode_memout = 102 ecode_exec = 103 - ecode_details = { + ecode_details = map{ '101': 'too slow' '102': 'too memory hungry' '103': 'worker executable not found' @@ -60,7 +60,7 @@ fn main() { source = source[..context.cut_index] go fn (ms int) { - time.sleep_ms(ms) + time.wait(ms * time.millisecond) exit(ecode_timeout) }(context.timeout_ms) _ := parser.parse_text(source, context.path, context.table, .skip_comments, context.pref, @@ -259,7 +259,7 @@ fn (mut context Context) start_printing() { fn (mut context Context) stop_printing() { context.stop_print = true - time.sleep_ms(context.period_ms / 5) + time.wait(time.millisecond * context.period_ms / 5) } fn (mut context Context) print_status() { @@ -284,7 +284,7 @@ fn (mut context Context) print_periodic_status() { for !context.stop_print { context.print_status() for i := 0; i < 10 && !context.stop_print; i++ { - time.sleep_ms(context.period_ms / 10) + time.wait(time.millisecond * context.period_ms / 10) if context.cut_index > 50 && !printed_at_least_once { context.print_status() printed_at_least_once = true diff --git a/examples/buf_reader.v b/examples/buf_reader.v index a4268367ad..8eca29afa6 100644 --- a/examples/buf_reader.v +++ b/examples/buf_reader.v @@ -14,6 +14,6 @@ fn main() { l := r.read_line() or { break } println('$l') // Make it nice and obvious that we are doing this line by line - time.sleep_ms(100) + time.wait(100 * time.millisecond) } } diff --git a/examples/concurrency/concurrency.v b/examples/concurrency/concurrency.v index 3ef598ce33..31e2c32ea2 100644 --- a/examples/concurrency/concurrency.v +++ b/examples/concurrency/concurrency.v @@ -4,7 +4,7 @@ import time // Simulate expensive computing using sleep function fn expensive_computing(id int, duration int, mut wg sync.WaitGroup) { println('Executing expensive computing task ($id)...') - time.sleep_ms(duration) + time.wait(duration * time.millisecond) println('Finish task $id on $duration ms') wg.done() } diff --git a/examples/flappylearning/game.v b/examples/flappylearning/game.v index 3bba3bc73c..a35265d717 100644 --- a/examples/flappylearning/game.v +++ b/examples/flappylearning/game.v @@ -206,7 +206,7 @@ fn main() { fn (mut app App) run() { for { app.update() - time.sleep_ms(app.timer_period_ms) + time.wait(app.timer_period_ms * time.millisecond) } } diff --git a/examples/game_of_life/life.v b/examples/game_of_life/life.v index 06e847f61e..c0958d5df2 100644 --- a/examples/game_of_life/life.v +++ b/examples/game_of_life/life.v @@ -20,6 +20,6 @@ fn main() { for { a.update() print_automaton(a) - time.sleep_ms(100) + time.wait(100 * time.millisecond) } } diff --git a/examples/hot_reload/bounce.v b/examples/hot_reload/bounce.v index b806b99c85..9737bc54dd 100644 --- a/examples/hot_reload/bounce.v +++ b/examples/hot_reload/bounce.v @@ -8,20 +8,20 @@ import time struct Game { mut: - gg &gg.Context - x int - y int - dy int - dx int - height int - width int - draw_fn voidptr + gg &gg.Context + x int + y int + dy int + dx int + height int + width int + draw_fn voidptr } const ( - window_width = 400 + window_width = 400 window_height = 300 - width = 50 + width = 50 ) fn main() { @@ -33,7 +33,7 @@ fn main() { width: window_width draw_fn: 0 } - game.gg = gg.new_context({ + game.gg = gg.new_context( width: window_width height: window_height font_size: 20 @@ -44,22 +44,22 @@ fn main() { frame_fn: frame bg_color: gx.white font_path: gg.system_font_path() - }) + ) // window.onkeydown(key_down) println('Starting the game loop...') go game.run() game.gg.run() } - // Try uncommenting or changing the lines inside the live functions. // Guess what will happen: [live] -fn frame (mut game Game) { +fn frame(mut game Game) { game.gg.begin() game.gg.draw_text_def(10, 5, 'Modify examples/hot_reload/bounce.v to get instant updates') game.gg.draw_rect(game.x, game.y, width, width, gx.blue) - game.gg.draw_rect(window_width - width - game.x + 10, 200 - game.y + width, width, width, gx.rgb(228, 10, 55)) + game.gg.draw_rect(window_width - width - game.x + 10, 200 - game.y + width, width, + width, gx.rgb(228, 10, 55)) game.gg.draw_rect(game.x - 25, 250 - game.y, width, width, gx.rgb(28, 240, 55)) game.gg.end() } @@ -80,10 +80,6 @@ fn (mut game Game) update_model() { fn (mut game Game) run() { for { game.update_model() - //glfw.post_empty_event() // Refresh - time.sleep_ms(17) // 60fps + time.wait(16 * time.millisecond) // 60fps } } - - - diff --git a/examples/hot_reload/message.v b/examples/hot_reload/message.v index 2ef9c812c7..8f214013b6 100644 --- a/examples/hot_reload/message.v +++ b/examples/hot_reload/message.v @@ -13,6 +13,6 @@ fn print_message() { fn main() { for { print_message() - time.sleep_ms(500) + time.wait(500 * time.millisecond) } } diff --git a/examples/lander.v b/examples/lander.v index d1c81cda04..91dbd0b0a3 100644 --- a/examples/lander.v +++ b/examples/lander.v @@ -8,6 +8,7 @@ struct Moon { struct Mars { } + fn (m Mars) dust_storm() bool { return rand.int() >= 0 } @@ -15,10 +16,11 @@ fn (m Mars) dust_storm() bool { struct Venus { } -type World = Moon | Mars | Venus +type World = Mars | Moon | Venus struct Lander { } + fn (l Lander) deorbit() { println('leaving orbit') } @@ -28,7 +30,7 @@ fn (l Lander) open_parachutes(n int) { fn wait() { println('waiting...') - time.sleep(1) + time.wait(1 * time.second) } fn (l Lander) land(w World) { @@ -53,7 +55,7 @@ fn (l Lander) land(w World) { } fn main() { - l := Lander {} + l := Lander{} l.land(Venus{}) l.land(Mars{}) } diff --git a/examples/sokol/sounds/melody.v b/examples/sokol/sounds/melody.v index fed732999a..04cd7a4427 100644 --- a/examples/sokol/sounds/melody.v +++ b/examples/sokol/sounds/melody.v @@ -2,11 +2,13 @@ import gg import gx import sokol.audio +const credits = 'Based on the ByteBeat formula from: https://www.youtube.com/watch?v=V4GfkFbDojc \n "Techno" by Gabriel Miceli' + struct AppState { mut: - gframe int // the current graphical frame - frame_0 int // offset of the current audio frames, relative to the start of the music - frames [2048]f32 // a copy of the last rendered audio frames + gframe int // the current graphical frame + frame_0 int // offset of the current audio frames, relative to the start of the music + frames [2048]f32 // a copy of the last rendered audio frames gg &gg.Context // used for drawing } @@ -14,10 +16,8 @@ fn my_audio_stream_callback(buffer &f32, num_frames int, num_channels int, mut a mut soundbuffer := buffer for frame := 0; frame < num_frames; frame++ { t := int(f32(acontext.frame_0 + frame) * 0.245) - // Credits for the formula below: https://www.youtube.com/watch?v=V4GfkFbDojc // "Techno" by Gabriel Miceli - y := (t * (((t / 10 | 0) ^ ((t / 10 | 0) - - 1280)) % 11) / 2 & 127) + + y := (t * (((t / 10 | 0) ^ ((t / 10 | 0) - 1280)) % 11) / 2 & 127) + (t * (((t / 640 | 0) ^ ((t / 640 | 0) - 2)) % 13) / 2 & 127) for ch := 0; ch < num_channels; ch++ { idx := frame * num_channels + ch @@ -32,14 +32,15 @@ fn my_audio_stream_callback(buffer &f32, num_frames int, num_channels int, mut a } fn main() { + println(credits) mut state := &AppState{ gg: 0 } - audio.setup({ + audio.setup( stream_userdata_cb: my_audio_stream_callback user_data: state - }) - state.gg = gg.new_context({ + ) + state.gg = gg.new_context( bg_color: gx.rgb(50, 50, 50) width: 1024 height: 400 @@ -48,7 +49,7 @@ fn main() { window_title: 'ByteBeat Music' frame_fn: graphics_frame user_data: state - }) + ) state.gg.run() audio.shutdown() } diff --git a/examples/sokol/sounds/simple_sin_tones.v b/examples/sokol/sounds/simple_sin_tones.v index 16510c78ed..7cacc545bc 100644 --- a/examples/sokol/sounds/simple_sin_tones.v +++ b/examples/sokol/sounds/simple_sin_tones.v @@ -19,14 +19,14 @@ fn my_audio_stream_callback(buffer &f32, num_frames int, num_channels int) { for frame := 0; frame < num_frames; frame++ { for ch := 0; ch < num_channels; ch++ { idx := frame * num_channels + ch - if ms < 500 { - soundbuffer[idx] = sintone(20, frame, num_frames) - } else if ms < 1000 { - soundbuffer[idx] = sintone(25, frame, num_frames) + if ms < 250 { + soundbuffer[idx] = 0.5 * sintone(20, frame, num_frames) + } else if ms < 300 { + soundbuffer[idx] = 0.5 * sintone(25, frame, num_frames) } else if ms < 1500 { soundbuffer[idx] *= sintone(22, frame, num_frames) } else { - soundbuffer[idx] = sintone(25, frame, num_frames) + soundbuffer[idx] = 0.5 * sintone(25, frame, num_frames) } } } @@ -34,9 +34,9 @@ fn my_audio_stream_callback(buffer &f32, num_frames int, num_channels int) { } fn main() { - audio.setup({ + audio.setup( stream_cb: my_audio_stream_callback - }) - time.sleep_ms(2500) + ) + time.wait(2000 * time.millisecond) audio.shutdown() } diff --git a/examples/sokol/sounds/wav_player.v b/examples/sokol/sounds/wav_player.v index 2a9de0b165..7bb748f8b8 100644 --- a/examples/sokol/sounds/wav_player.v +++ b/examples/sokol/sounds/wav_player.v @@ -72,7 +72,7 @@ fn (mut p Player) play_wav_file(fpath string) ? { p.samples << samples p.finished = false for !p.finished { - time.sleep_ms(16) + time.wait(16 * time.millisecond) } p.free() } diff --git a/examples/tetris/tetris.v b/examples/tetris/tetris.v index 2da4f2f1b4..abfacec9a5 100644 --- a/examples/tetris/tetris.v +++ b/examples/tetris/tetris.v @@ -218,7 +218,7 @@ fn (mut g Game) run() { g.delete_completed_lines() } // glfw.post_empty_event() // force window redraw - time.sleep_ms(timer_period) + time.wait(timer_period * time.millisecond) } } diff --git a/examples/vweb/server_sent_events/server.v b/examples/vweb/server_sent_events/server.v index e5216a837d..3d38df3176 100644 --- a/examples/vweb/server_sent_events/server.v +++ b/examples/vweb/server_sent_events/server.v @@ -32,7 +32,7 @@ fn (mut app App) sse() vweb.Result { data := '{"time": "$time.now().str()", "random_id": "$rand.ulid()"}' session.send_message(event: 'ping', data: data) or { return app.server_error(501) } println('> sent event: $data') - time.sleep_ms(1000) + time.wait(1 * time.second) } return app.server_error(501) } diff --git a/examples/websocket/ping.v b/examples/websocket/ping.v index 9db616aba5..7298f92ea1 100644 --- a/examples/websocket/ping.v +++ b/examples/websocket/ping.v @@ -5,10 +5,10 @@ import os import x.websocket fn main() { + println('press enter to quit...\n') go start_server() - time.sleep_ms(100) + time.wait(100 * time.millisecond) go start_client() - println('press enter to quit...') os.get_line() } @@ -23,25 +23,21 @@ fn start_server() ? { return false } return true - })? + }) ? s.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ? { - ws.write(msg.payload, msg.opcode) or { - panic(err) - } + ws.write(msg.payload, msg.opcode) or { panic(err) } }) s.on_close(fn (mut ws websocket.Client, code int, reason string) ? { // println('client ($ws.id) closed connection') }) - s.listen() or { - // println('error on server listen: $err') - } + s.listen() or { println('error on server listen: $err') } unsafe { s.free() } } fn start_client() ? { - mut ws := websocket.new_client('ws://localhost:30000')? + mut ws := websocket.new_client('ws://localhost:30000') ? // mut ws := websocket.new_client('wss://echo.websocket.org:443')? // use on_open_ref if you want to send any reference object ws.on_open(fn (mut ws websocket.Client) ? { @@ -67,15 +63,9 @@ fn start_client() ? { // ws.on_message_ref(fn (mut ws websocket.Client, msg &websocket.Message, r &SomeRef)? { // // println('type: $msg.opcode payload:\n$msg.payload ref: $r') // }, &r) - ws.connect() or { - println('error on connect: $err') - } - go write_echo(mut ws) or { - println('error on write_echo $err') - } - ws.listen() or { - println('error on listen $err') - } + ws.connect() or { println('error on connect: $err') } + go write_echo(mut ws) or { println('error on write_echo $err') } + ws.listen() or { println('error on listen $err') } unsafe { ws.free() } @@ -85,12 +75,8 @@ fn write_echo(mut ws websocket.Client) ? { message := 'echo this' for i := 0; i <= 10; i++ { // Server will send pings every 30 seconds - ws.write_str(message) or { - println('panicing writing $err') - } - time.sleep_ms(100) - } - ws.close(1000, 'normal') or { - println('panicing $err') + ws.write_str(message) or { println('panicing writing $err') } + time.wait(100 * time.millisecond) } + ws.close(1000, 'normal') or { println('panicing $err') } } diff --git a/vlib/clipboard/x11/clipboard.c.v b/vlib/clipboard/x11/clipboard.c.v index a7f5af04d7..1a2b94c9e5 100644 --- a/vlib/clipboard/x11/clipboard.c.v +++ b/vlib/clipboard/x11/clipboard.c.v @@ -239,7 +239,7 @@ pub fn (mut cb Clipboard) set_text(text string) bool { C.XFlush(cb.display) cb.mutex.unlock() // sleep a little bit - time.sleep(1) + time.wait(1 * time.millisecond) return cb.is_owner } @@ -262,7 +262,7 @@ fn (mut cb Clipboard) get_text() string { if cb.got_text || retries == 0 { break } - time.usleep(50000) + time.wait(50 * time.millisecond) retries-- } return cb.text @@ -306,8 +306,7 @@ fn (mut cb Clipboard) start_listener() { C.SelectionClear { if unsafe { event.xselectionclear.window == cb.window } && unsafe { event.xselectionclear.selection == cb.selection - } - { + } { cb.mutex.@lock() cb.is_owner = false cb.text = '' @@ -339,9 +338,9 @@ fn (mut cb Clipboard) start_listener() { } C.SelectionNotify { if unsafe { - event.xselection.selection == cb.selection && event.xselection.property != C.Atom(C.None) - } - { + event.xselection.selection == cb.selection + && event.xselection.property != C.Atom(C.None) + } { if unsafe { event.xselection.target == cb.get_atom(.targets) && !sent_request } { sent_request = true prop := read_property(cb.display, cb.window, cb.selection) @@ -385,7 +384,7 @@ fn (mut cb Clipboard) start_listener() { fn (mut cb Clipboard) intern_atoms() { cb.atoms << C.Atom(4) // XA_ATOM cb.atoms << C.Atom(31) // XA_STRING - for i, name in atom_names { + for i, name in x11.atom_names { only_if_exists := if i == int(AtomType.utf8_string) { 1 } else { 0 } cb.atoms << C.XInternAtom(cb.display, name.str, only_if_exists) if i == int(AtomType.utf8_string) && cb.atoms[i] == C.Atom(C.None) { @@ -419,10 +418,8 @@ fn read_property(d &C.Display, w C.Window, p C.Atom) Property { fn (cb &Clipboard) pick_target(prop Property) C.Atom { // The list of targets is a list of atoms, so it should have type XA_ATOM // but it may have the type TARGETS instead. - if (prop.actual_type != cb.get_atom(.xa_atom) && - prop.actual_type != cb.get_atom(.targets)) || - prop.actual_format != 32 - { + if (prop.actual_type != cb.get_atom(.xa_atom) && prop.actual_type != cb.get_atom(.targets)) + || prop.actual_format != 32 { // This would be really broken. Targets have to be an atom list // and applications should support this. Nevertheless, some // seem broken (MATLAB 7, for instance), so ask for STRING diff --git a/vlib/encoding/base64/base64_memory_test.v b/vlib/encoding/base64/base64_memory_test.v index 99828a36cb..cb85183fe2 100644 --- a/vlib/encoding/base64/base64_memory_test.v +++ b/vlib/encoding/base64/base64_memory_test.v @@ -1,6 +1,6 @@ import encoding.base64 -fn test_long_encoding(){ +fn test_long_encoding() { repeats := 1000 input_size := 3000 @@ -13,20 +13,20 @@ fn test_long_encoding(){ mut s := 0 - ebuffer := malloc( s_encoded.len ) - for _ in 0..repeats { + ebuffer := unsafe { malloc(s_encoded.len) } + for _ in 0 .. repeats { resultsize := base64.encode_in_buffer(s_original, ebuffer) s += resultsize assert resultsize == s_encoded.len } - dbuffer := malloc( s_decoded.len ) - for _ in 0..repeats { + dbuffer := unsafe { malloc(s_decoded.len) } + for _ in 0 .. repeats { resultsize := base64.decode_in_buffer(s_encoded, dbuffer) s += resultsize assert resultsize == s_decoded.len } - println( 'Final s: $s' ) + println('Final s: $s') // assert s == 39147008 } diff --git a/vlib/math/big/big.v b/vlib/math/big/big.v index f8b4a94575..451fcb17c4 100644 --- a/vlib/math/big/big.v +++ b/vlib/math/big/big.v @@ -149,7 +149,7 @@ pub fn (n Number) hexstr() string { mut buf := [8192]byte{} // NB: C.bignum_to_string(), returns the HEXADECIMAL representation of the bignum n C.bignum_to_string(&n, buf, 8192) - s := tos_clone(buf) + s := unsafe { tos_clone(buf) } if s.len == 0 { return '0' } diff --git a/vlib/os/os_c.v b/vlib/os/os_c.v index 351bec6f00..0af029a8f3 100644 --- a/vlib/os/os_c.v +++ b/vlib/os/os_c.v @@ -551,7 +551,7 @@ pub fn read_file_array(path string) []T { C.rewind(fp) // read the actual data from the file len := fsize / tsize - buf := malloc(fsize) + buf := unsafe { malloc(fsize) } C.fread(buf, fsize, 1, fp) C.fclose(fp) return array{ diff --git a/vlib/os/process_test.v b/vlib/os/process_test.v index 7e6aef0cf9..da1ec7471d 100644 --- a/vlib/os/process_test.v +++ b/vlib/os/process_test.v @@ -24,7 +24,7 @@ fn test_run() { break } os.system('ps -opid= -oppid= -ouser= -onice= -of= -ovsz= -orss= -otime= -oargs= -p $p.pid') - time.sleep_ms(50) + time.wait(50 * time.millisecond) i++ } p.wait() diff --git a/vlib/rand/random_identifiers_test.v b/vlib/rand/random_identifiers_test.v index 290a133398..39f4b27ed0 100644 --- a/vlib/rand/random_identifiers_test.v +++ b/vlib/rand/random_identifiers_test.v @@ -53,9 +53,9 @@ fn test_ulids_generated_in_the_same_millisecond_have_the_same_prefix() { fn test_ulids_should_be_lexicographically_ordered_when_not_in_same_millisecond() { ulid1 := rand.ulid() - time.sleep_ms(1) + time.wait(1 * time.millisecond) ulid2 := rand.ulid() - time.sleep_ms(1) + time.wait(1 * time.millisecond) ulid3 := rand.ulid() mut all := [ulid3, ulid2, ulid1] // eprintln('all before: $all') diff --git a/vlib/sync/channel_select_2_test.v b/vlib/sync/channel_select_2_test.v index 5640fc7d94..d30fb33af1 100644 --- a/vlib/sync/channel_select_2_test.v +++ b/vlib/sync/channel_select_2_test.v @@ -1,4 +1,3 @@ -import sync import time fn do_rec_i64(ch chan i64) { @@ -57,9 +56,7 @@ fn test_select() { } // Use Gauß' formula for the first 2 contributions // the 3rd contribution is `byte` and must be seen modulo 256 - expected_sum := 2 * (300 * (300 - 1) / 2) + - 256 * (256 - 1) / 2 + - 44 * (44 - 1) / 2 + expected_sum := 2 * (300 * (300 - 1) / 2) + 256 * (256 - 1) / 2 + 44 * (44 - 1) / 2 assert sum == expected_sum - time.sleep_ms(20) // to give assert in coroutine enough time + time.wait(20 * time.millisecond) // to give assert in coroutine enough time } diff --git a/vlib/sync/pool/pool_test.v b/vlib/sync/pool/pool_test.v index 17da78d347..3aebf1a9a3 100644 --- a/vlib/sync/pool/pool_test.v +++ b/vlib/sync/pool/pool_test.v @@ -12,14 +12,14 @@ pub struct IResult { fn worker_s(p &pool.PoolProcessor, idx int, worker_id int) &SResult { item := p.get_item(idx) println('worker_s worker_id: $worker_id | idx: $idx | item: $item') - time.sleep_ms(3) + time.wait(3 * time.millisecond) return &SResult{'$item $item'} } fn worker_i(p &pool.PoolProcessor, idx int, worker_id int) &IResult { item := p.get_item(idx) println('worker_i worker_id: $worker_id | idx: $idx | item: $item') - time.sleep_ms(5) + time.wait(5 * time.millisecond) return &IResult{item * 1000} } diff --git a/vlib/szip/szip.v b/vlib/szip/szip.v index cc7a907694..9a3df4df4d 100644 --- a/vlib/szip/szip.v +++ b/vlib/szip/szip.v @@ -3,6 +3,7 @@ module szip #flag -I @VROOT/thirdparty/zip #include "zip.c" #include "zip.h" + struct C.zip_t { } @@ -66,13 +67,13 @@ open opens zip archive with compression level using the given mode. */ pub fn open(name string, level int, mode byte) ?&Zip { mut nlevel := level - if (nlevel & 0xF) > uber_compression { - nlevel = default_level + if (nlevel & 0xF) > szip.uber_compression { + nlevel = szip.default_level } if name.len == 0 { return error('szip: name of file empty') } - if mode !in [m_write, m_ronly, m_append] { + if mode !in [szip.m_write, szip.m_ronly, szip.m_append] { return error('szip: invalid provided open mode') } p_zip := &Zip(C.zip_open(name.str, nlevel, mode)) @@ -140,7 +141,7 @@ pub fn (mut zentry Zip) name() string { if name == 0 { return '' } - return tos_clone(name) + return unsafe { tos_clone(name) } } /* diff --git a/vlib/term/ui/termios_nix.c.v b/vlib/term/ui/termios_nix.c.v index cb0b0873b3..e324313b43 100644 --- a/vlib/term/ui/termios_nix.c.v +++ b/vlib/term/ui/termios_nix.c.v @@ -9,6 +9,7 @@ import time #include #include #include + fn C.tcgetattr() fn C.tcsetattr() @@ -222,7 +223,7 @@ fn (mut ctx Context) termios_loop() { } // println('SLEEPING: $sleep_len') if sleep_len > 0 { - time.usleep(sleep_len) + time.wait(sleep_len * time.microsecond) } if !ctx.paused { sw.restart() @@ -287,7 +288,8 @@ fn single_char(buf string) &Event { // 65 ... 90 { event = Event{ ...event, code: KeyCode(32 | ch), modifiers: .shift } } // The bit `or`s here are really just `+`'s, just written in this way for a tiny performance improvement // don't treat tab, enter as ctrl+i, ctrl+j - 1...8, 11...26 { event = &Event{ + 1...8, 11...26 { + event = &Event{ typ: event.typ ascii: event.ascii utf8: event.utf8 diff --git a/vlib/time/operator_test.v b/vlib/time/operator_test.v index 9961071446..424322f48f 100644 --- a/vlib/time/operator_test.v +++ b/vlib/time/operator_test.v @@ -1,7 +1,7 @@ module time fn assert_greater_time(ms int, t1 Time) { - sleep_ms(ms) + wait(ms * millisecond) t2 := now() assert t2 > t1 } diff --git a/vlib/time/stopwatch_test.v b/vlib/time/stopwatch_test.v index cfaf985214..f0eb926e36 100644 --- a/vlib/time/stopwatch_test.v +++ b/vlib/time/stopwatch_test.v @@ -7,7 +7,7 @@ fn test_stopwatch_works_as_intended() { mut sw := time.new_stopwatch({}) // sample code that you want to measure: println('Hello world') - time.sleep_ms(1) + time.wait(1 * time.millisecond) // println('Greeting the world took: ${sw.elapsed().nanoseconds()}ns') assert sw.elapsed().nanoseconds() > 0 @@ -16,18 +16,18 @@ fn test_stopwatch_works_as_intended() { fn test_stopwatch_time_between_pause_and_start_should_be_skipped_in_elapsed() { println('Testing pause function') mut sw := time.new_stopwatch({}) - time.sleep_ms(10) // A + time.wait(10 * time.millisecond) // A eprintln('Elapsed after 10ms nap: ${sw.elapsed().milliseconds()}ms') assert sw.elapsed().milliseconds() >= 8 // sometimes it sleeps for 9ms on windows.. sw.pause() - time.sleep_ms(10) + time.wait(10 * time.millisecond) eprintln('Elapsed after pause and another 10ms nap: ${sw.elapsed().milliseconds()}ms') assert sw.elapsed().milliseconds() >= 8 $if stopwatch ? { assert sw.elapsed().milliseconds() < 20 } sw.start() - time.sleep_ms(10) // B + time.wait(10 * time.millisecond) // B eprintln('Elapsed after resume and another 10ms nap: ${sw.elapsed().milliseconds()}ms') assert sw.elapsed().milliseconds() >= 18 $if stopwatch ? { diff --git a/vlib/time/time.v b/vlib/time/time.v index c881c83641..adddf54e3d 100644 --- a/vlib/time/time.v +++ b/vlib/time/time.v @@ -325,31 +325,21 @@ pub fn ticks() i64 { } // sleep makes the calling thread sleep for a given number of seconds. +[deprecated: 'call time.wait(n * time.second)'] pub fn sleep(seconds int) { - $if windows { - C.Sleep(seconds * 1000) - } $else { - C.sleep(seconds) - } + wait(seconds * time.second) } // sleep_ms makes the calling thread sleep for a given number of milliseconds. +[deprecated: 'call time.wait(n * time.millisecond)'] pub fn sleep_ms(milliseconds int) { - $if windows { - C.Sleep(milliseconds) - } $else { - C.usleep(milliseconds * 1000) - } + wait(milliseconds * time.millisecond) } // usleep makes the calling thread sleep for a given number of microseconds. +[deprecated: 'call time.wait(n * time.microsecond)'] pub fn usleep(microseconds int) { - $if windows { - milliseconds := microseconds / 1000 - C.Sleep(milliseconds) - } $else { - C.usleep(microseconds) - } + wait(microseconds * time.microsecond) } // is_leap_year checks if a given a year is a leap year. diff --git a/vlib/time/time_nix.c.v b/vlib/time/time_nix.c.v index 8c5e5759b0..76e285593e 100644 --- a/vlib/time/time_nix.c.v +++ b/vlib/time/time_nix.c.v @@ -45,6 +45,8 @@ mut: // the first arg is defined in include/bits/types.h as `__S32_TYPE`, which is `int` fn C.clock_gettime(int, &C.timespec) +fn C.nanosleep(req &C.timespec, rem &C.timespec) int + // sys_mono_now returns a *monotonically increasing time*, NOT a time adjusted for daylight savings, location etc. pub fn sys_mono_now() u64 { $if macos { @@ -127,3 +129,9 @@ pub fn zero_timespec() C.timespec { } return ts } + +// wait makes the calling thread sleep for a given duration (in nanoseconds). +pub fn wait(duration Duration) { + ts := &C.timespec{duration / second, duration % second} + C.nanosleep(ts, C.NULL) +} diff --git a/vlib/time/time_test.v b/vlib/time/time_test.v index 4b3a26534d..a0608b328c 100644 --- a/vlib/time/time_test.v +++ b/vlib/time/time_test.v @@ -208,7 +208,7 @@ fn test_utc() { fn test_unix_time() { t1 := time.utc() - time.sleep_ms(50) + time.wait(50 * time.millisecond) t2 := time.utc() ut1 := t1.unix_time() ut2 := t2.unix_time() diff --git a/vlib/time/time_windows.c.v b/vlib/time/time_windows.c.v index 021207976f..4a0a76d4c4 100644 --- a/vlib/time/time_windows.c.v +++ b/vlib/time/time_windows.c.v @@ -212,3 +212,8 @@ pub struct C.timeval { tv_sec u64 tv_usec u64 } + +// wait makes the calling thread sleep for a given duration (in nanoseconds). +pub fn wait(duration Duration) { + C.Sleep(int(duration / millisecond)) +} diff --git a/vlib/v/live/executable/reloader.v b/vlib/v/live/executable/reloader.v index 45c35fc440..b04d4fc3e3 100644 --- a/vlib/v/live/executable/reloader.v +++ b/vlib/v/live/executable/reloader.v @@ -160,7 +160,7 @@ fn reloader(mut r live.LiveReloadInfo) { } } if r.recheck_period_ms > 0 { - time.sleep_ms(r.recheck_period_ms) + time.wait(r.recheck_period_ms * time.millisecond) } } } diff --git a/vlib/v/live/live_test.v b/vlib/v/live/live_test.v index b4ae91d4ec..acca77db45 100644 --- a/vlib/v/live/live_test.v +++ b/vlib/v/live/live_test.v @@ -110,14 +110,14 @@ fn testsuite_end() { } fn change_source(new string) { - time.sleep_ms(100) + time.wait(100 * time.millisecond) vprintln('> change ORIGINAL to: $new') atomic_write_source(live_program_source.replace('ORIGINAL', new)) wait_for_file(new) } fn wait_for_file(new string) { - time.sleep_ms(100) + time.wait(100 * time.millisecond) expected_file := os.join_path(os.temp_dir(), new + '.txt') eprintln('waiting for $expected_file ...') max_wait_cycles := edefault('WAIT_CYCLES', '1').int() @@ -128,10 +128,10 @@ fn wait_for_file(new string) { if os.exists(expected_file) { assert true vprintln('> done.') - time.sleep_ms(100) + time.wait(100 * time.millisecond) break } - time.sleep_ms(5) + time.wait(5 * time.millisecond) } } diff --git a/vlib/v/live/live_test_template.vv b/vlib/v/live/live_test_template.vv index ab2ed0f709..0cf9d9490c 100644 --- a/vlib/v/live/live_test_template.vv +++ b/vlib/v/live/live_test_template.vv @@ -57,7 +57,7 @@ fn main() { if s == 'STOP' { break } - time.sleep_ms(delay) + time.wait(delay * time.millisecond) } pmessage() pmessage() diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 7277a379ca..63091b4a13 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -12,8 +12,6 @@ import v.util import v.vet import v.errors import os -import runtime -import time const ( builtin_functions = ['print', 'println', 'eprint', 'eprintln', 'isnil', 'panic', 'exit'] @@ -313,11 +311,6 @@ pub fn parse_files(paths []string, table &table.Table, pref &pref.Preferences, g } */ } - if false { - // TODO: remove this; it just prevents warnings about unused time and runtime - time.sleep_ms(1) - println(runtime.nr_cpus()) - } // /////////////// mut files := []ast.File{} for path in paths { diff --git a/vlib/v/tests/autolock_array1_test.v b/vlib/v/tests/autolock_array1_test.v index 5d8637a34f..bc10956eca 100644 --- a/vlib/v/tests/autolock_array1_test.v +++ b/vlib/v/tests/autolock_array1_test.v @@ -30,7 +30,7 @@ fn test_autolocked_array() { if finished_threads == 2 { break } - time.sleep_ms(100) + time.wait(100 * time.millisecond) } // create histogram of results mut result := [0, 0, 0, 0] diff --git a/vlib/v/tests/go_wait_2_test.v b/vlib/v/tests/go_wait_2_test.v index d02c525f11..fd909d9abc 100644 --- a/vlib/v/tests/go_wait_2_test.v +++ b/vlib/v/tests/go_wait_2_test.v @@ -6,7 +6,7 @@ mut: } fn f(x int, y f64, shared s St) { - time.usleep(50000) + time.wait(50 * time.millisecond) lock s { s.x = x * y } diff --git a/vlib/v/tests/shared_array_test.v b/vlib/v/tests/shared_array_test.v index 41b6a2d32d..5ba6fc0ce3 100644 --- a/vlib/v/tests/shared_array_test.v +++ b/vlib/v/tests/shared_array_test.v @@ -31,7 +31,7 @@ fn test_shared_array() { if finished_threads == 4 { break } - time.sleep_ms(100) + time.wait(100 * time.millisecond) } rlock foo { f0 := foo[0] diff --git a/vlib/v/tests/shared_lock_2_test.v b/vlib/v/tests/shared_lock_2_test.v index 9785cb3153..b2d9f66b41 100644 --- a/vlib/v/tests/shared_lock_2_test.v +++ b/vlib/v/tests/shared_lock_2_test.v @@ -44,7 +44,7 @@ fn test_shared_receiver_lock() { if finished { break } - time.sleep_ms(100) + time.wait(100 * time.millisecond) } rlock x, y { assert x.a == 7 && y.a == 5 diff --git a/vlib/v/tests/shared_lock_3_test.v b/vlib/v/tests/shared_lock_3_test.v index c045390263..5d1f70fa19 100644 --- a/vlib/v/tests/shared_lock_3_test.v +++ b/vlib/v/tests/shared_lock_3_test.v @@ -8,7 +8,7 @@ mut: fn f(shared x St, shared z St) { for _ in 0 .. reads_per_thread { rlock x { // other instances may read at the same time - time.sleep_ms(1) + time.wait(time.millisecond) assert x.a == 7 || x.a == 5 } } @@ -37,10 +37,10 @@ fn test_shared_lock() { for i in 0 .. writes { lock x { // wait for ongoing reads to finish, don't start new ones x.a = 17 // this should never be read - time.sleep_ms(50) + time.wait(50 * time.millisecond) x.a = if (i & 1) == 0 { 7 } else { 5 } } // now new reads are possible again - time.sleep_ms(20) + time.wait(20 * time.millisecond) } // wait until all read threads are finished for finished := false; true; { @@ -52,6 +52,6 @@ fn test_shared_lock() { if finished { break } - time.sleep_ms(100) + time.wait(100 * time.millisecond) } } diff --git a/vlib/v/tests/shared_lock_4_test.v b/vlib/v/tests/shared_lock_4_test.v index 9b9ddc25fe..ca0c4c7366 100644 --- a/vlib/v/tests/shared_lock_4_test.v +++ b/vlib/v/tests/shared_lock_4_test.v @@ -8,7 +8,7 @@ mut: fn (shared x St) f(shared z St) { for _ in 0 .. reads_per_thread { rlock x { // other instances may read at the same time - time.sleep_ms(1) + time.wait(time.millisecond) assert x.a == 7 || x.a == 5 } } @@ -37,10 +37,10 @@ fn test_shared_lock() { for i in 0 .. writes { lock x { // wait for ongoing reads to finish, don't start new ones x.a = 17 // this value should never be read - time.sleep_ms(50) + time.wait(50 * time.millisecond) x.a = if (i & 1) == 0 { 7 } else { 5 } } // now new reads are possible again - time.sleep_ms(20) + time.wait(20 * time.millisecond) } // wait until all read threads are finished for finished := false; true; { @@ -52,6 +52,6 @@ fn test_shared_lock() { if finished { break } - time.sleep_ms(100) + time.wait(100 * time.millisecond) } } diff --git a/vlib/v/tests/shared_lock_test.v b/vlib/v/tests/shared_lock_test.v index f848e63f2a..0293fe1488 100644 --- a/vlib/v/tests/shared_lock_test.v +++ b/vlib/v/tests/shared_lock_test.v @@ -44,7 +44,7 @@ fn test_shared_lock() { if finished { break } - time.sleep_ms(100) + time.wait(100 * time.millisecond) } rlock x, y { assert x.a == 7 && y.a == 5 diff --git a/vlib/v/tests/type_voidptr_test.v b/vlib/v/tests/type_voidptr_test.v index 03de9bb56d..d0b95da741 100644 --- a/vlib/v/tests/type_voidptr_test.v +++ b/vlib/v/tests/type_voidptr_test.v @@ -16,6 +16,6 @@ fn memcpy(mut dest voidptr, src voidptr, len u32) voidptr { fn test_mut_voidptr_arg() { mut a := [1, 2]! b := [3, 4]! - memcpy(mut a, b, sizeof(int)) + unsafe { memcpy(mut a, b, sizeof(int)) } assert a == [3, 2]! } diff --git a/vlib/v/util/util.v b/vlib/v/util/util.v index d9f32cbb38..c22ce068d6 100644 --- a/vlib/v/util/util.v +++ b/vlib/v/util/util.v @@ -509,7 +509,7 @@ pub fn prepare_tool_when_needed(source_name string) { stool := os.join_path(vroot, 'cmd', 'tools', source_name) tool_name, tool_exe := tool_source2name_and_exe(stool) if should_recompile_tool(vexe, stool, tool_name, tool_exe) { - time.sleep_ms(1001) // TODO: remove this when we can get mtime with a better resolution + time.wait(1001 * time.millisecond) // TODO: remove this when we can get mtime with a better resolution recompile_file(vexe, stool) } } diff --git a/vlib/vweb/tests/vweb_test.v b/vlib/vweb/tests/vweb_test.v index 0c7886f005..439a4fa541 100644 --- a/vlib/vweb/tests/vweb_test.v +++ b/vlib/vweb/tests/vweb_test.v @@ -50,7 +50,7 @@ fn test_a_simple_vweb_app_runs_in_the_background() { res := os.system(server_exec_cmd) assert res == 0 } - time.sleep_ms(100) + time.wait(100 * time.millisecond) } // web client tests follow @@ -238,7 +238,7 @@ fn simple_tcp_client(config SimpleTcpClientConfig) ?string { if tries > config.retries { return error(err) } - time.sleep_ms(100) + time.wait(100 * time.millisecond) continue } break diff --git a/vlib/vweb/tests/vweb_test_server.v b/vlib/vweb/tests/vweb_test_server.v index 08d2a907b0..84aeb4c11d 100644 --- a/vlib/vweb/tests/vweb_test_server.v +++ b/vlib/vweb/tests/vweb_test_server.v @@ -15,7 +15,7 @@ struct App { } fn exit_after_timeout(timeout_in_ms int) { - time.sleep_ms(timeout_in_ms) + time.wait(timeout_in_ms * time.millisecond) // eprintln('webserver is exiting ...') exit(0) } @@ -105,6 +105,6 @@ pub fn (mut app App) shutdown() vweb.Result { fn (mut app App) gracefull_exit() { eprintln('>> webserver: gracefull_exit') - time.sleep_ms(100) + time.wait(100 * time.millisecond) exit(0) } diff --git a/vlib/x/websocket/websocket_server.v b/vlib/x/websocket/websocket_server.v index bd4887016e..b67f9ee8ce 100644 --- a/vlib/x/websocket/websocket_server.v +++ b/vlib/x/websocket/websocket_server.v @@ -72,7 +72,7 @@ fn (mut s Server) close() { fn (mut s Server) handle_ping() { mut clients_to_remove := []string{} for s.state == .open { - time.sleep(s.ping_interval) + time.wait(s.ping_interval * time.second) for i, _ in s.clients { mut c := s.clients[i] if c.client.state == .open { diff --git a/vlib/x/websocket/websocket_test.v b/vlib/x/websocket/websocket_test.v index 926ebfa814..0bff4c8b30 100644 --- a/vlib/x/websocket/websocket_test.v +++ b/vlib/x/websocket/websocket_test.v @@ -20,7 +20,7 @@ fn test_ws() { } port := 30000 + rand.intn(1024) go start_server(port) - time.sleep_ms(500) + time.wait(500 * time.millisecond) ws_test('ws://localhost:$port') or { assert false } } @@ -92,10 +92,10 @@ fn ws_test(uri string) ? { for msg in text { ws.write(msg.bytes(), .text_frame) or { panic('fail to write to websocket') } // sleep to give time to recieve response before send a new one - time.sleep_ms(100) + time.wait(100 * time.millisecond) } // sleep to give time to recieve response before asserts - time.sleep_ms(1500) + time.wait(1500 * time.millisecond) // We expect at least 2 pongs, one sent directly and one indirectly assert test_results.nr_pong_received >= 2 assert test_results.nr_messages == 2