Process monitor on Linux shows wrong process load, #51200

This commit is contained in:
Rachel Macfarlane 2018-06-06 17:09:27 -07:00
parent 9a1a486df9
commit 2040792965
4 changed files with 101 additions and 2 deletions

View file

@ -49,6 +49,7 @@ const indentationFilter = [
'!src/vs/base/common/marked/marked.js',
'!src/vs/base/common/winjs.base.js',
'!src/vs/base/node/terminateProcess.sh',
'!src/vs/base/node/cpuUsage.sh',
'!test/assert.js',
// except specific folders

View file

@ -73,7 +73,7 @@ const vscodeResources = [
'out-build/paths.js',
'out-build/vs/**/*.{svg,png,cur,html}',
'out-build/vs/base/common/performance.js',
'out-build/vs/base/node/{stdForkStart.js,terminateProcess.sh}',
'out-build/vs/base/node/{stdForkStart.js,terminateProcess.sh, cpuUsage.sh}',
'out-build/vs/base/browser/ui/octiconLabel/octicons/**',
'out-build/vs/workbench/browser/media/*-theme.css',
'out-build/vs/workbench/electron-browser/bootstrap/**',

64
src/vs/base/node/cpuUsage.sh Executable file
View file

@ -0,0 +1,64 @@
#!/bin/bash
function get_total_cpu_time() {
# Read the first line of /proc/stat and remove the cpu prefix
CPU=(`sed -n 's/^cpu\s//p' /proc/stat`)
# Sum all of the values in CPU to get total time
for VALUE in "${CPU[@]}"; do
let $1=$1+$VALUE
done
}
TOTAL_TIME_BEFORE=0
get_total_cpu_time TOTAL_TIME_BEFORE
# Loop over the arguments, which are a list of PIDs
# The 13th and 14th words in /proc/<PID>/stat are the user and system time
# the process has used, so sum these to get total process run time
declare -a PROCESS_BEFORE_TIMES
ITER=0
for PID in "$@"; do
if [ -f /proc/$PID/stat ]
then
PROCESS_STATS=`cat /proc/$PID/stat`
PROCESS_STAT_ARRAY=($PROCESS_STATS)
let PROCESS_TIME_BEFORE="${PROCESS_STAT_ARRAY[13]}+${PROCESS_STAT_ARRAY[14]}"
else
let PROCESS_TIME_BEFORE=0
fi
PROCESS_BEFORE_TIMES[$ITER]=$PROCESS_TIME_BEFORE
((ITER++))
done
# Wait for a second
sleep 1
TOTAL_TIME_AFTER=0
get_total_cpu_time TOTAL_TIME_AFTER
# Check the user and system time sum of each process again and compute the change
# in process time used over total system time
ITER=0
for PID in "$@"; do
if [ -f /proc/$PID/stat ]
then
PROCESS_STATS=`cat /proc/$PID/stat`
PROCESS_STAT_ARRAY=($PROCESS_STATS)
let PROCESS_TIME_AFTER="${PROCESS_STAT_ARRAY[13]}+${PROCESS_STAT_ARRAY[14]}"
else
let PROCESS_TIME_AFTER=${PROCESS_BEFORE_TIMES[$ITER]}
fi
PROCESS_TIME_BEFORE=${PROCESS_BEFORE_TIMES[$ITER]}
let PROCESS_DELTA=$PROCESS_TIME_AFTER-$PROCESS_TIME_BEFORE
let TOTAL_DELTA=$TOTAL_TIME_AFTER-$TOTAL_TIME_BEFORE
CPU_USAGE=`echo "100*$PROCESS_DELTA/$TOTAL_DELTA" | bc -l`
# Parent script reads from stdout, so echo result to be read
echo $CPU_USAGE
((ITER++))
done

View file

@ -6,6 +6,7 @@
'use strict';
import { exec } from 'child_process';
import URI from 'vs/base/common/uri';
export interface ProcessItem {
name: string;
@ -191,7 +192,40 @@ export function listProcesses(rootPid: number): Promise<ProcessItem> {
}
}
resolve(rootItem);
if (process.platform === 'linux') {
// Flatten rootItem to get a list of all VSCode processes
let processes = [rootItem];
const pids = [];
while (processes.length) {
const process = processes.shift();
pids.push(process.pid);
if (process.children) {
processes = processes.concat(process.children);
}
}
// The cpu usage value reported on Linux is the average over the process lifetime,
// recalculate the usage over a one second interval
let cmd = URI.parse(require.toUrl('vs/base/node/cpuUsage.sh')).fsPath;
cmd += ' ' + pids.join(' ');
exec(cmd, {}, (err, stdout, stderr) => {
if (err || stderr) {
reject(err || stderr.toString());
} else {
const cpuUsage = stdout.toString().split('\n');
for (let i = 0; i < pids.length; i++) {
const processInfo = map.get(pids[i]);
processInfo.load = parseFloat(cpuUsage[i]);
}
resolve(rootItem);
}
});
} else {
resolve(rootItem);
}
}
});
}