bpo-32025: Add time.thread_time() (#4410)
* bpo-32025: Add time.thread_time()
* Add missing #endif
* Add NEWS blurb
* Add docs and whatsnew
* Address review comments
* Review comments
diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py
index b44646d..eda3885 100644
--- a/Lib/test/test_time.py
+++ b/Lib/test/test_time.py
@@ -47,6 +47,12 @@
)
+def busy_wait(duration):
+ deadline = time.monotonic() + duration
+ while time.monotonic() < deadline:
+ pass
+
+
class TimeTestCase(unittest.TestCase):
def setUp(self):
@@ -81,6 +87,10 @@
check_ns(time.process_time(),
time.process_time_ns())
+ if hasattr(time, 'thread_time'):
+ check_ns(time.thread_time(),
+ time.thread_time_ns())
+
if hasattr(time, 'clock_gettime'):
check_ns(time.clock_gettime(time.CLOCK_REALTIME),
time.clock_gettime_ns(time.CLOCK_REALTIME))
@@ -486,10 +496,57 @@
# on Windows
self.assertLess(stop - start, 0.020)
+ # process_time() should include CPU time spent in any thread
+ start = time.process_time()
+ busy_wait(0.100)
+ stop = time.process_time()
+ self.assertGreaterEqual(stop - start, 0.020) # machine busy?
+
+ t = threading.Thread(target=busy_wait, args=(0.100,))
+ start = time.process_time()
+ t.start()
+ t.join()
+ stop = time.process_time()
+ self.assertGreaterEqual(stop - start, 0.020) # machine busy?
+
info = time.get_clock_info('process_time')
self.assertTrue(info.monotonic)
self.assertFalse(info.adjustable)
+ def test_thread_time(self):
+ if not hasattr(time, 'thread_time'):
+ if sys.platform.startswith(('linux', 'win')):
+ self.fail("time.thread_time() should be available on %r"
+ % (sys.platform,))
+ else:
+ self.skipTest("need time.thread_time")
+
+ # thread_time() should not include time spend during a sleep
+ start = time.thread_time()
+ time.sleep(0.100)
+ stop = time.thread_time()
+ # use 20 ms because thread_time() has usually a resolution of 15 ms
+ # on Windows
+ self.assertLess(stop - start, 0.020)
+
+ # thread_time() should include CPU time spent in current thread...
+ start = time.thread_time()
+ busy_wait(0.100)
+ stop = time.thread_time()
+ self.assertGreaterEqual(stop - start, 0.020) # machine busy?
+
+ # ...but not in other threads
+ t = threading.Thread(target=busy_wait, args=(0.100,))
+ start = time.thread_time()
+ t.start()
+ t.join()
+ stop = time.thread_time()
+ self.assertLess(stop - start, 0.020)
+
+ info = time.get_clock_info('thread_time')
+ self.assertTrue(info.monotonic)
+ self.assertFalse(info.adjustable)
+
@unittest.skipUnless(hasattr(time, 'clock_settime'),
'need time.clock_settime')
def test_monotonic_settime(self):