@@ -9,7 +9,7 @@ import * as logger from '../logger'
99import { Timeout , CancellationError , waitUntil } from './timeoutUtils'
1010import { PollingSet } from './pollingSet'
1111import { getLogger } from '../logger/logger'
12- import pidusage from 'pidusage '
12+ import { isWin } from '../vscode/env '
1313
1414export interface RunParameterContext {
1515 /** Reports an error parsed from the stdin/stdout streams. */
@@ -67,14 +67,12 @@ export const eof = Symbol('EOF')
6767export interface ProcessStats {
6868 memory : number
6969 cpu : number
70- elapsed : number
7170}
7271export class ChildProcessTracker {
7372 static readonly pollingInterval : number = 10000
7473 static readonly thresholds : ProcessStats = {
7574 memory : 100 * 1024 * 1024 , // 100 MB
7675 cpu : 50 ,
77- elapsed : 30 * 1000 , // 30 seconds
7876 }
7977 static readonly logger = getLogger ( 'childProcess' )
8078 #processByPid: Map < number , ChildProcess > = new Map < number , ChildProcess > ( )
@@ -118,11 +116,6 @@ export class ChildProcessTracker {
118116 if ( stats . cpu > ChildProcessTracker . thresholds . cpu ) {
119117 ChildProcessTracker . logger . warn ( `ChildProcess: Process ${ pid } exceeded cpu threshold: ${ stats . cpu } ` )
120118 }
121- if ( stats . elapsed > ChildProcessTracker . thresholds . elapsed ) {
122- ChildProcessTracker . logger . warn (
123- `ChildProcess: Process ${ pid } exceeded time threshold: ${ stats . elapsed } `
124- )
125- }
126119 }
127120 }
128121
@@ -154,11 +147,47 @@ export class ChildProcessTracker {
154147 }
155148
156149 public async getUsage ( pid : number ) : Promise < ProcessStats > {
157- const stats = await pidusage ( pid )
158- return {
159- memory : stats . memory ,
160- cpu : stats . cpu ,
161- elapsed : stats . elapsed ,
150+ const getWindowsUsage = ( ) => {
151+ const cpuOutput = proc
152+ . execFileSync ( 'wmic' , [
153+ 'path' ,
154+ 'Win32_PerfFormattedData_PerfProc_Process' ,
155+ 'where' ,
156+ `IDProcess=${ pid } ` ,
157+ 'get' ,
158+ 'PercentProcessorTime' ,
159+ ] )
160+ . toString ( )
161+ const memOutput = proc
162+ . execFileSync ( 'wmic' , [ 'process' , 'where' , `ProcessId=${ pid } ` , 'get' , 'WorkingSetSize' ] )
163+ . toString ( )
164+
165+ const cpuPercentage = parseFloat ( cpuOutput . split ( '\n' ) [ 1 ] )
166+ const memoryBytes = parseInt ( memOutput . split ( '\n' ) [ 1 ] ) * 1024
167+
168+ return {
169+ cpu : isNaN ( cpuPercentage ) ? 0 : cpuPercentage ,
170+ memory : memoryBytes ,
171+ }
172+ }
173+ const getUnixUsage = ( ) => {
174+ const cpuMemOutput = proc . execFileSync ( 'ps' , [ '-p' , pid . toString ( ) , '-o' , '%cpu,%mem' ] ) . toString ( )
175+ const rssOutput = proc . execFileSync ( 'ps' , [ '-p' , pid . toString ( ) , '-o' , 'rss' ] ) . toString ( )
176+
177+ const cpuMemLines = cpuMemOutput . split ( '\n' ) [ 1 ] . trim ( ) . split ( / \s + / )
178+ const cpuPercentage = parseFloat ( cpuMemLines [ 0 ] )
179+ const memoryBytes = parseInt ( rssOutput . split ( '\n' ) [ 1 ] ) * 1024
180+
181+ return {
182+ cpu : isNaN ( cpuPercentage ) ? 0 : cpuPercentage ,
183+ memory : memoryBytes ,
184+ }
185+ }
186+ try {
187+ return isWin ( ) ? getWindowsUsage ( ) : getUnixUsage ( )
188+ } catch ( e ) {
189+ ChildProcessTracker . logger . warn ( `ChildProcess: Failed to get process stats for ${ pid } : ${ e } ` )
190+ return { cpu : 0 , memory : 0 }
162191 }
163192 }
164193}
0 commit comments