@@ -392,20 +392,53 @@ def test_process_time(self):
392392 @unittest .skipUnless (threading ,
393393 'need threading' )
394394 def test_process_time_threads (self ):
395- class BusyThread (threading .Thread ):
395+ def factorial (n ):
396+ if n >= 2 :
397+ return n * factorial (n - 1 )
398+ else :
399+ return 1
400+
401+ def use_cpu (n , loops ):
402+ for loop in range (loops ):
403+ factorial (n )
404+
405+ class FactorialThread (threading .Thread ):
406+ def __init__ (self , n , loops ):
407+ threading .Thread .__init__ (self )
408+ self .n = n
409+ self .loops = loops
410+
396411 def run (self ):
397- while not self .stop :
398- pass
412+ use_cpu (self .n , self .loops )
413+
414+ # Calibrate use_cpu() to use at least 1 ms of system time
415+ n = 50
416+ loops = 1
417+ resolution = time .get_clock_info ('process_time' ).resolution
418+ min_rdt = max (resolution , 0.001 )
419+ while 1 :
420+ rt1 = time .time ()
421+ t1 = time .process_time ()
422+ use_cpu (n , loops )
423+ t2 = time .process_time ()
424+ rt2 = time .time ()
425+ rdt = rt2 - rt1
426+ if rdt >= min_rdt :
427+ break
428+ loops *= 2
429+ busy = t2 - t1
399430
400- thread = BusyThread ()
401- thread . stop = False
431+ # Ensure that time.process_time() includes the CPU time of all threads
432+ thread = FactorialThread ( n , loops )
402433 t1 = time .process_time ()
403434 thread .start ()
404- time .sleep (0.2 )
435+ # Use sleep() instead of thread.join() because thread.join() time may
436+ # be included in time.process_time() depending on its implementation
437+ time .sleep (rdt * 2 )
405438 t2 = time .process_time ()
406439 thread .stop = True
407440 thread .join ()
408- self .assertGreater (t2 - t1 , 0.1 )
441+ self .assertGreaterEqual (t2 - t1 , busy )
409442
410443 @unittest .skipUnless (hasattr (time , 'monotonic' ),
411444 'need time.monotonic' )
0 commit comments