diff --git a/examples/test262/index.js b/examples/test262/index.js index e54d756..ee220ad 100755 --- a/examples/test262/index.js +++ b/examples/test262/index.js @@ -205,6 +205,15 @@ function buildScreen() { lines.push(` Size: ${c.bold}${fmt(mem.arenaSize)}${c.reset}`); lines.push(''); + if (mem.external) { + lines.push(`${c.cyan}External${c.reset}`); + lines.push(` Buffers: ${c.bold}${fmt(mem.external.buffers)}${c.reset}`); + lines.push(` Code: ${c.bold}${fmt(mem.external.code)}${c.reset}`); + lines.push(` Collections: ${c.bold}${fmt(mem.external.collections)}${c.reset}`); + lines.push(` Total: ${c.bold}${fmt(mem.external.total)}${c.reset}`); + lines.push(''); + } + lines.push(`${c.cyan}Process${c.reset}`); lines.push(` RSS: ${c.bold}${fmt(mem.rss)}${c.reset}`); if (mem.virtualSize) { @@ -230,9 +239,11 @@ function buildScreen() { } function render() { + if (pendingRender) return; fps.update(); const screen = buildScreen(); - process.stdout.write(`${term.syncStart}${term.hideCursor}${term.home}${screen}${term.syncEnd}`); + const ok = process.stdout.write(`${term.syncStart}${term.hideCursor}${term.home}${screen}${term.syncEnd}`); + if (!ok) pendingRender = true; } function applyFilter(filter) { @@ -368,6 +379,7 @@ process.stdin.resume(); process.stdout.write(`${term.altScreenOn}${term.hideCursor}`); let inputBuf = ''; +let pendingRender = false; process.stdin.on('data', chunk => { const str = chunk.toString(); let needsRender = false; @@ -392,6 +404,11 @@ process.stdin.on('data', chunk => { }); process.stdout.on('resize', render); +process.stdout.on('drain', () => { + if (!pendingRender) return; + pendingRender = false; + render(); +}); process.on('SIGINT', cleanup); process.on('SIGTERM', cleanup); diff --git a/src/modules/timer.c b/src/modules/timer.c index f27fe7b..5556596 100644 --- a/src/modules/timer.c +++ b/src/modules/timer.c @@ -111,7 +111,7 @@ static jsval_t js_set_timeout(struct js *js, jsval_t *args, int nargs) { jsval_t callback = args[0]; double delay_ms = js_getnum(args[1]); - if (delay_ms < 0) delay_ms = 0; + uint64_t ms = delay_ms < 1 ? 0 : (uint64_t)delay_ms; timer_entry_t *entry = ant_calloc(sizeof(timer_entry_t)); if (entry == NULL) return js_mkerr(js, "failed to allocate timer"); @@ -130,7 +130,7 @@ static jsval_t js_set_timeout(struct js *js, jsval_t *args, int nargs) { add_timer_entry(entry); timer_state.active_timer_count++; - uv_timer_start(&entry->handle, timer_callback, (uint64_t)delay_ms, 0); + uv_timer_start(&entry->handle, timer_callback, ms, 0); return js_mknum((double)entry->timer_id); } @@ -143,7 +143,7 @@ static jsval_t js_set_interval(struct js *js, jsval_t *args, int nargs) { jsval_t callback = args[0]; double delay_ms = js_getnum(args[1]); - if (delay_ms < 0) delay_ms = 0; + uint64_t ms = delay_ms < 1 ? 1 : (uint64_t)delay_ms; timer_entry_t *entry = ant_calloc(sizeof(timer_entry_t)); if (entry == NULL) return js_mkerr(js, "failed to allocate timer"); @@ -162,7 +162,7 @@ static jsval_t js_set_interval(struct js *js, jsval_t *args, int nargs) { add_timer_entry(entry); timer_state.active_timer_count++; - uv_timer_start(&entry->handle, timer_callback, (uint64_t)delay_ms, (uint64_t)delay_ms); + uv_timer_start(&entry->handle, timer_callback, ms, ms); return js_mknum((double)entry->timer_id); } diff --git a/src/reactor.c b/src/reactor.c index d7a3917..5712f46 100644 --- a/src/reactor.c +++ b/src/reactor.c @@ -23,9 +23,9 @@ void js_reactor_set_poll_hook(reactor_poll_hook_t hook, void *data) { void js_poll_events(ant_t *js) { coros_this_tick = 0; - fetch_poll_events(); - fs_poll_events(); - child_process_poll_events(); + if (has_pending_fetches()) fetch_poll_events(); + if (has_pending_fs_ops()) fs_poll_events(); + if (has_pending_child_processes()) child_process_poll_events(); process_immediates(js); process_microtasks(js); @@ -51,16 +51,16 @@ void js_poll_events(ant_t *js) { static inline work_flags_t get_pending_work(void) { work_flags_t flags = 0; - if (has_pending_microtasks()) flags |= WORK_MICROTASKS; - if (has_pending_timers()) flags |= WORK_TIMERS; - if (has_pending_immediates()) flags |= WORK_IMMEDIATES; - if (has_pending_coroutines()) flags |= WORK_COROUTINES; - if (has_ready_coroutines()) flags |= WORK_COROUTINES_READY; - if (has_pending_fetches()) flags |= WORK_FETCHES; - if (has_pending_fs_ops()) flags |= WORK_FS_OPS; - if (has_pending_child_processes()) flags |= WORK_CHILD_PROCS; - if (has_active_readline_interfaces()) flags |= WORK_READLINE; - if (has_active_stdin()) flags |= WORK_STDIN; + if (has_pending_microtasks()) flags |= WORK_MICROTASKS; + if (has_pending_timers()) flags |= WORK_TIMERS; + if (has_pending_immediates()) flags |= WORK_IMMEDIATES; + if (has_pending_coroutines()) flags |= WORK_COROUTINES; + if (has_ready_coroutines()) flags |= WORK_COROUTINES_READY; + if (has_pending_fetches()) flags |= WORK_FETCHES; + if (has_pending_fs_ops()) flags |= WORK_FS_OPS; + if (has_pending_child_processes()) flags |= WORK_CHILD_PROCS; + if (has_active_readline_interfaces()) flags |= WORK_READLINE; + if (has_active_stdin()) flags |= WORK_STDIN; return flags; } diff --git a/tests/bench_timers.js b/tests/bench_timers.js new file mode 100644 index 0000000..5c05129 --- /dev/null +++ b/tests/bench_timers.js @@ -0,0 +1,18 @@ +let frameCount = 0; +let startTime = Date.now(); + +function tick() { + frameCount++; +} + +setInterval(tick, 0.5); + +setInterval(() => { + const elapsed = Date.now() - startTime; + const actualHz = frameCount / (elapsed / 1000); + console.log(`Elapsed: ${elapsed}ms | Frames: ${frameCount} | Actual Hz: ${actualHz.toFixed(2)}`); +}, 1000); + +setTimeout(() => { + process.exit(0); +}, 10000);