@@ -2361,19 +2361,65 @@ pub(crate) fn builtin_current_cpu_time(args: Vec<Value>) -> EvalResult {
23612361
23622362 // GNU timefns.c Fcurrent_cpu_time: (clock() . CLOCKS_PER_SEC) — CPU time
23632363 // consumed by the process (all threads), not wall time, so a sleeping or
2364- // descheduled process accrues nothing. glibc clock() reads
2365- // CLOCK_PROCESS_CPUTIME_ID truncated to CLOCKS_PER_SEC (1e6) ticks;
2366- // do the same directly.
2367- let mut ts = libc:: timespec {
2368- tv_sec : 0 ,
2369- tv_nsec : 0 ,
2370- } ;
2371- let ticks = if unsafe { libc:: clock_gettime ( libc:: CLOCK_PROCESS_CPUTIME_ID , & mut ts) } == 0 {
2372- ts. tv_sec as i64 * 1_000_000 + ts. tv_nsec as i64 / 1_000
2373- } else {
2374- 0
2375- } ;
2376- Ok ( Value :: cons ( Value :: fixnum ( ticks) , Value :: fixnum ( 1_000_000 ) ) )
2364+ // descheduled process accrues nothing.
2365+ Ok ( Value :: cons (
2366+ Value :: fixnum ( process_cpu_time_micros ( ) ) ,
2367+ Value :: fixnum ( 1_000_000 ) ,
2368+ ) )
2369+ }
2370+
2371+ fn process_cpu_time_micros ( ) -> i64 {
2372+ std:: cfg_select! {
2373+ unix => {
2374+ // glibc clock() reads CLOCK_PROCESS_CPUTIME_ID truncated to
2375+ // CLOCKS_PER_SEC (1e6) ticks; do the same directly.
2376+ let mut ts = libc:: timespec {
2377+ tv_sec: 0 ,
2378+ tv_nsec: 0 ,
2379+ } ;
2380+ if unsafe {
2381+ libc:: clock_gettime( libc:: CLOCK_PROCESS_CPUTIME_ID , & mut ts)
2382+ } == 0 {
2383+ ts. tv_sec as i64 * 1_000_000 + ts. tv_nsec as i64 / 1_000
2384+ } else {
2385+ 0
2386+ }
2387+ }
2388+ windows => {
2389+ use windows_sys:: Win32 :: Foundation :: FILETIME ;
2390+ use windows_sys:: Win32 :: System :: Threading :: {
2391+ GetCurrentProcess , GetProcessTimes ,
2392+ } ;
2393+
2394+ let mut creation = FILETIME :: default ( ) ;
2395+ let mut exit = FILETIME :: default ( ) ;
2396+ let mut kernel = FILETIME :: default ( ) ;
2397+ let mut user = FILETIME :: default ( ) ;
2398+ let ok = unsafe {
2399+ GetProcessTimes (
2400+ GetCurrentProcess ( ) ,
2401+ & mut creation,
2402+ & mut exit,
2403+ & mut kernel,
2404+ & mut user,
2405+ )
2406+ } ;
2407+ if ok == 0 {
2408+ return 0 ;
2409+ }
2410+
2411+ let filetime_ticks = |time: FILETIME | {
2412+ ( ( time. dwHighDateTime as u64 ) << 32 ) | time. dwLowDateTime as u64
2413+ } ;
2414+ // FILETIME counts 100 ns intervals. GNU-compatible ticks are
2415+ // microseconds.
2416+ let micros = filetime_ticks( kernel) . saturating_add( filetime_ticks( user) ) / 10 ;
2417+ micros. min( i64 :: MAX as u64 ) as i64
2418+ }
2419+ _ => {
2420+ 0
2421+ }
2422+ }
23772423}
23782424
23792425pub ( crate ) fn builtin_current_idle_time (
0 commit comments