11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst { mustCall, mustCallAtLeast } = require('../common'); 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ciconst assert = require('assert'); 61cb0ef41Sopenharmony_ciconst { 71cb0ef41Sopenharmony_ci Worker, 81cb0ef41Sopenharmony_ci MessageChannel, 91cb0ef41Sopenharmony_ci MessagePort, 101cb0ef41Sopenharmony_ci parentPort, 111cb0ef41Sopenharmony_ci} = require('worker_threads'); 121cb0ef41Sopenharmony_ciconst { eventLoopUtilization, now } = require('perf_hooks').performance; 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_ci// Use argv to detect whether we're running as a Worker called by this test vs. 151cb0ef41Sopenharmony_ci// this test also being called as a Worker. 161cb0ef41Sopenharmony_ciif (process.argv[2] === 'iamalive') { 171cb0ef41Sopenharmony_ci const iaElu = idleActive(eventLoopUtilization()); 181cb0ef41Sopenharmony_ci // Checks that the worker bootstrap is running after the event loop started. 191cb0ef41Sopenharmony_ci assert.ok(iaElu > 0, `${iaElu} <= 0`); 201cb0ef41Sopenharmony_ci parentPort.once('message', mustCall((msg) => { 211cb0ef41Sopenharmony_ci assert.ok(msg.metricsCh instanceof MessagePort); 221cb0ef41Sopenharmony_ci msg.metricsCh.on('message', mustCallAtLeast(workerOnMetricsMsg, 1)); 231cb0ef41Sopenharmony_ci })); 241cb0ef41Sopenharmony_ci return; 251cb0ef41Sopenharmony_ci} 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_cifunction workerOnMetricsMsg(msg) { 281cb0ef41Sopenharmony_ci if (msg.cmd === 'close') { 291cb0ef41Sopenharmony_ci return this.close(); 301cb0ef41Sopenharmony_ci } 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci if (msg.cmd === 'elu') { 331cb0ef41Sopenharmony_ci return this.postMessage(eventLoopUtilization()); 341cb0ef41Sopenharmony_ci } 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_ci if (msg.cmd === 'spin') { 371cb0ef41Sopenharmony_ci const elu = eventLoopUtilization(); 381cb0ef41Sopenharmony_ci const t = now(); 391cb0ef41Sopenharmony_ci while (now() - t < msg.dur); 401cb0ef41Sopenharmony_ci return this.postMessage(eventLoopUtilization(elu)); 411cb0ef41Sopenharmony_ci } 421cb0ef41Sopenharmony_ci} 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_cilet worker; 451cb0ef41Sopenharmony_cilet metricsCh; 461cb0ef41Sopenharmony_cilet mainElu; 471cb0ef41Sopenharmony_cilet workerELU; 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ci(function r() { 501cb0ef41Sopenharmony_ci // Force some idle time to accumulate before proceeding with test. 511cb0ef41Sopenharmony_ci if (eventLoopUtilization().idle <= 0) 521cb0ef41Sopenharmony_ci return setTimeout(mustCall(r), 5); 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ci mainElu = eventLoopUtilization(); 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ci worker = new Worker(__filename, { argv: [ 'iamalive' ] }); 571cb0ef41Sopenharmony_ci metricsCh = new MessageChannel(); 581cb0ef41Sopenharmony_ci worker.postMessage({ metricsCh: metricsCh.port1 }, [ metricsCh.port1 ]); 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci workerELU = worker.performance.eventLoopUtilization; 611cb0ef41Sopenharmony_ci metricsCh.port2.once('message', mustCall(checkWorkerIdle)); 621cb0ef41Sopenharmony_ci metricsCh.port2.postMessage({ cmd: 'elu' }); 631cb0ef41Sopenharmony_ci // Make sure it's still safe to call eventLoopUtilization() after the worker 641cb0ef41Sopenharmony_ci // hass been closed. 651cb0ef41Sopenharmony_ci worker.on('exit', mustCall(() => { 661cb0ef41Sopenharmony_ci assert.deepStrictEqual(worker.performance.eventLoopUtilization(), 671cb0ef41Sopenharmony_ci { idle: 0, active: 0, utilization: 0 }); 681cb0ef41Sopenharmony_ci })); 691cb0ef41Sopenharmony_ci})(); 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_cifunction checkWorkerIdle(wElu) { 721cb0ef41Sopenharmony_ci const perfWorkerElu = workerELU(); 731cb0ef41Sopenharmony_ci const tmpMainElu = eventLoopUtilization(mainElu); 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci assert.ok(idleActive(wElu) > 0, `${idleActive(wElu)} <= 0`); 761cb0ef41Sopenharmony_ci assert.ok(idleActive(workerELU(wElu)) > 0, 771cb0ef41Sopenharmony_ci `${idleActive(workerELU(wElu))} <= 0`); 781cb0ef41Sopenharmony_ci assert.ok(idleActive(perfWorkerElu) > idleActive(wElu), 791cb0ef41Sopenharmony_ci `${idleActive(perfWorkerElu)} <= ${idleActive(wElu)}`); 801cb0ef41Sopenharmony_ci assert.ok(idleActive(tmpMainElu) > idleActive(perfWorkerElu), 811cb0ef41Sopenharmony_ci `${idleActive(tmpMainElu)} <= ${idleActive(perfWorkerElu)}`); 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci wElu = workerELU(); 841cb0ef41Sopenharmony_ci setTimeout(mustCall(() => { 851cb0ef41Sopenharmony_ci wElu = workerELU(wElu); 861cb0ef41Sopenharmony_ci // Some clocks fire early. Removing a few milliseconds to cover that. 871cb0ef41Sopenharmony_ci assert.ok(idleActive(wElu) >= 45, `${idleActive(wElu)} < 45`); 881cb0ef41Sopenharmony_ci // Cutting the idle time in half since it's possible that the call took a 891cb0ef41Sopenharmony_ci // lot of resources to process? 901cb0ef41Sopenharmony_ci assert.ok(wElu.idle >= 25, `${wElu.idle} < 25`); 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ci checkWorkerActive(); 931cb0ef41Sopenharmony_ci }), 50); 941cb0ef41Sopenharmony_ci} 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_cifunction checkWorkerActive() { 971cb0ef41Sopenharmony_ci const w = workerELU(); 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ci metricsCh.port2.postMessage({ cmd: 'spin', dur: 50 }); 1001cb0ef41Sopenharmony_ci metricsCh.port2.once('message', (wElu) => { 1011cb0ef41Sopenharmony_ci const w2 = workerELU(w); 1021cb0ef41Sopenharmony_ci 1031cb0ef41Sopenharmony_ci assert.ok(w2.active >= 50, `${w2.active} < 50`); 1041cb0ef41Sopenharmony_ci assert.ok(wElu.active >= 50, `${wElu.active} < 50`); 1051cb0ef41Sopenharmony_ci assert.ok(idleActive(wElu) < idleActive(w2), 1061cb0ef41Sopenharmony_ci `${idleActive(wElu)} >= ${idleActive(w2)}`); 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_ci metricsCh.port2.postMessage({ cmd: 'close' }); 1091cb0ef41Sopenharmony_ci }); 1101cb0ef41Sopenharmony_ci} 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_cifunction idleActive(elu) { 1131cb0ef41Sopenharmony_ci return elu.idle + elu.active; 1141cb0ef41Sopenharmony_ci} 115