22#include "frameobject.h"
33#include "rotatingtree.h"
44
5- /*** Selection of a high-precision timer ***/
6-
7- #ifdef MS_WINDOWS
8-
9- #include <windows.h>
10-
11- static long long
12- hpTimer (void )
13- {
14- LARGE_INTEGER li ;
15- QueryPerformanceCounter (& li );
16- return li .QuadPart ;
17- }
18-
19- static double
20- hpTimerUnit (void )
21- {
22- LARGE_INTEGER li ;
23- if (QueryPerformanceFrequency (& li ))
24- return 1.0 / li .QuadPart ;
25- else
26- return 0.000001 ; /* unlikely */
27- }
28-
29- #else /* !MS_WINDOWS */
30-
31- #ifndef HAVE_GETTIMEOFDAY
32- #error "This module requires gettimeofday() on non-Windows platforms!"
33- #endif
34-
35- #include <sys/resource.h>
36- #include <sys/times.h>
37-
38- static long long
39- hpTimer (void )
40- {
41- struct timeval tv ;
42- long long ret ;
43- #ifdef GETTIMEOFDAY_NO_TZ
44- gettimeofday (& tv );
45- #else
46- gettimeofday (& tv , (struct timezone * )NULL );
47- #endif
48- ret = tv .tv_sec ;
49- ret = ret * 1000000 + tv .tv_usec ;
50- return ret ;
51- }
52-
53- static double
54- hpTimerUnit (void )
55- {
56- return 0.000001 ;
57- }
58-
59- #endif /* MS_WINDOWS */
60-
615/************************************************************/
626/* Written by Brett Rosen and Ted Czotter */
637
@@ -115,12 +59,11 @@ static PyTypeObject PyProfiler_Type;
11559/*** External Timers ***/
11660
11761#define DOUBLE_TIMER_PRECISION 4294967296.0
118- static PyObject * empty_tuple ;
11962
12063static long long CallExternalTimer (ProfilerObject * pObj )
12164{
12265 long long result ;
123- PyObject * o = PyObject_Call (pObj -> externalTimer , empty_tuple , NULL );
66+ PyObject * o = _PyObject_CallNoArg (pObj -> externalTimer );
12467 if (o == NULL ) {
12568 PyErr_WriteUnraisable (pObj -> externalTimer );
12669 return 0 ;
@@ -146,9 +89,17 @@ static long long CallExternalTimer(ProfilerObject *pObj)
14689 return result ;
14790}
14891
149- #define CALL_TIMER (pObj ) ((pObj)->externalTimer ? \
150- CallExternalTimer(pObj) : \
151- hpTimer())
92+ static inline long long
93+ call_timer (ProfilerObject * pObj )
94+ {
95+ if (pObj -> externalTimer != NULL ) {
96+ return CallExternalTimer (pObj );
97+ }
98+ else {
99+ return (long long )_PyTime_GetPerfCounter ();
100+ }
101+ }
102+
152103
153104/*** ProfilerObject ***/
154105
@@ -332,13 +283,13 @@ initContext(ProfilerObject *pObj, ProfilerContext *self, ProfilerEntry *entry)
332283 if (subentry )
333284 ++ subentry -> recursionLevel ;
334285 }
335- self -> t0 = CALL_TIMER (pObj );
286+ self -> t0 = call_timer (pObj );
336287}
337288
338289static void
339290Stop (ProfilerObject * pObj , ProfilerContext * self , ProfilerEntry * entry )
340291{
341- long long tt = CALL_TIMER (pObj ) - self -> t0 ;
292+ long long tt = call_timer (pObj ) - self -> t0 ;
342293 long long it = tt - self -> subt ;
343294 if (self -> previous )
344295 self -> previous -> subt += tt ;
@@ -632,7 +583,7 @@ profiler_getstats(ProfilerObject *pObj, PyObject* noarg)
632583 if (pending_exception (pObj ))
633584 return NULL ;
634585 if (!pObj -> externalTimer )
635- collect .factor = hpTimerUnit ();
586+ collect .factor = 1e-9 ; // _Py_time_t is nanosecond
636587 else if (pObj -> externalTimerUnit > 0.0 )
637588 collect .factor = pObj -> externalTimerUnit ;
638589 else
@@ -882,7 +833,6 @@ PyInit__lsprof(void)
882833 (PyObject * ) & StatsEntryType );
883834 PyModule_AddObject (module , "profiler_subentry" ,
884835 (PyObject * ) & StatsSubEntryType );
885- empty_tuple = PyTuple_New (0 );
886836 initialized = 1 ;
887837 return module ;
888838}
0 commit comments