Commits

Sümer Cip  committed 8517f0b

changing the clock type on the fly in works. timing.c implemented, thinking about the interface.

  • Participants
  • Parent commits 0cb85d8

Comments (0)

Files changed (4)

 }
 
 static PyObject *
-thread_times(PyObject *self, PyObject *args)
-{
-    return Py_BuildValue("f", tickcount() * tickfactor());
-}
-
-static PyObject *
 mem_usage(PyObject *self, PyObject *args)
 {
     return Py_BuildValue("l", ymemusage());
 
 
 static PyObject *
-clock_type(PyObject *self, PyObject *args)
+get_clock_info(PyObject *self, PyObject *args)
 {
-    PyObject *type,*result,*resolution;
+    PyObject *api,*result,*resolution;
+    clock_type_t clk_type;
 
     result = PyDict_New();
-
+    
+    clk_type = get_timing_clock_type();
+    if (clk_type == WALL_CLOCK) {
+        // continue;
+    }  else {
 #if defined(USE_CLOCK_TYPE_GETTHREADTIMES)
-    type = Py_BuildValue("s", "getthreadtimes");
-    resolution = Py_BuildValue("s", "100ns");
+            api = Py_BuildValue("s", "getthreadtimes");
+            resolution = Py_BuildValue("s", "100ns");
 #elif defined(USE_CLOCK_TYPE_THREADINFO)
-    type = Py_BuildValue("s", "threadinfo");
-    resolution = Py_BuildValue("s", "1000ns");
+            api = Py_BuildValue("s", "threadinfo");
+            resolution = Py_BuildValue("s", "1000ns");
 #elif defined(USE_CLOCK_TYPE_CLOCKGETTIME)
-    type = Py_BuildValue("s", "clockgettime");
-    resolution = Py_BuildValue("s", "1ns");
+            api = Py_BuildValue("s", "clockgettime");
+            resolution = Py_BuildValue("s", "1ns");
 #elif defined(USE_CLOCK_TYPE_RUSAGE)
-    type = Py_BuildValue("s", "getrusage");
-    resolution = Py_BuildValue("s", "1000ns");
+            api = Py_BuildValue("s", "getrusage");
+            resolution = Py_BuildValue("s", "1000ns");
 #endif
-
-    PyDict_SetItemString(result, "clock_type", type);
+    }
+    
+    //PyDict_SetItemString(result, "type", type);
+    PyDict_SetItemString(result, "api", api);
     PyDict_SetItemString(result, "resolution", resolution);
 
     return result;
     {"enum_thread_stats", enum_thread_stats, METH_VARARGS, NULL},
     {"clear_stats", clear_stats, METH_VARARGS, NULL},
     {"is_running", is_running, METH_VARARGS, NULL},
-    {"clock_type", clock_type, METH_VARARGS, NULL},
-    {"thread_times", thread_times, METH_VARARGS, NULL},
+    {"get_clock_info", get_clock_info, METH_VARARGS, NULL},
     {"mem_usage", mem_usage, METH_VARARGS, NULL},
     {"profile_event", profile_event, METH_VARARGS, NULL}, // for internal usage. do not call this.
     {NULL, NULL}      /* sentinel */
 #include "timing.h"
 
+static clock_type_t g_clock_type = WALL_CLOCK;
+
+void set_timing_clock_type(clock_type_t type)
+{
+    g_clock_type = type;
+}
+
+clock_type_t get_timing_clock_type(void)
+{
+    return g_clock_type;
+}
+
+#if !defined(_WINDOWS)
+static gettimeofday_usec(void)
+{
+    struct timeval tv;
+    long long rc;
+#ifdef GETTIMEOFDAY_NO_TZ
+    gettimeofday(&tv);
+#else
+    gettimeofday(&tv, (struct timezone *)NULL);
+#endif
+    rc = tv.tv_sec;
+    rc = rc * 1000000 + tv.tv_usec;
+    return rc;
+}
+#endif
+
 #if defined(_WINDOWS)
 
 long long
 {
     LARGE_INTEGER li;
     FILETIME ftCreate, ftExit, ftKernel, ftUser;
-    
-    GetThreadTimes(GetCurrentThread(), &ftCreate, &ftExit, &ftKernel, &ftUser);
-    
-    li.LowPart = ftKernel.dwLowDateTime+ftUser.dwLowDateTime;
-    li.HighPart = ftKernel.dwHighDateTime+ftUser.dwHighDateTime;
-    
-    return li.QuadPart; 
-    
+        
+    if (g_clock_type == CPU_CLOCK) {
+        GetThreadTimes(GetCurrentThread(), &ftCreate, &ftExit, &ftKernel, &ftUser);
+        li.LowPart = ftKernel.dwLowDateTime+ftUser.dwLowDateTime;
+        li.HighPart = ftKernel.dwHighDateTime+ftUser.dwHighDateTime;
+    } else if (g_clock_type == WALL_CLOCK) {
+        QueryPerformanceCounter(&li);
+    }
+    return li.QuadPart;
 }
 
 double
 tickfactor(void)
 {
-    return 0.0000001;
+    LARGE_INTEGER li;
+    
+    if (g_clock_type == WALL_CLOCK) {
+        if (QueryPerformanceFrequency(&li)) {
+            return 1.0 / li.QuadPart;
+        } else {
+            return 0.000001;
+        }
+    } else if (g_clock_type == CPU_CLOCK) {
+        return 0.0000001;
+    }
+    
+    return 0.0000001; // for suppressing warning: all paths must return a value
 }
 
 #elif defined(_MACH)
 tickcount(void)
 {
     long long rc;
-    kern_return_t kr;
-    thread_basic_info_t tinfo_b;
-    thread_info_data_t tinfo_d;
-    mach_msg_type_number_t tinfo_cnt;
+    
+    if (g_clock_type == CPU_CLOCK) {
+        kern_return_t kr;
+        thread_basic_info_t tinfo_b;
+        thread_info_data_t tinfo_d;
+        mach_msg_type_number_t tinfo_cnt;
 
-    tinfo_cnt = THREAD_INFO_MAX;
-    kr = thread_info(mach_thread_self(), THREAD_BASIC_INFO, (thread_info_t)tinfo_d, &tinfo_cnt);
-    tinfo_b = (thread_basic_info_t)tinfo_d;
-    
-    rc = 0;
-    if (!(tinfo_b->flags & TH_FLAGS_IDLE))
-    {
-        rc = (tinfo_b->user_time.seconds + tinfo_b->system_time.seconds);
-        rc = (rc * 1000000) + (tinfo_b->user_time.microseconds + tinfo_b->system_time.microseconds);
+        tinfo_cnt = THREAD_INFO_MAX;
+        kr = thread_info(mach_thread_self(), THREAD_BASIC_INFO, (thread_info_t)tinfo_d, &tinfo_cnt);
+        tinfo_b = (thread_basic_info_t)tinfo_d;
+        
+        rc = 0;
+        if (!(tinfo_b->flags & TH_FLAGS_IDLE))
+        {
+            rc = (tinfo_b->user_time.seconds + tinfo_b->system_time.seconds);
+            rc = (rc * 1000000) + (tinfo_b->user_time.microseconds + tinfo_b->system_time.microseconds);
+        }
+    } else if (g_clock_type == WALL_CLOCK) {
+        rc = gettimeofday_usec();
     }
     return rc;
 }
 tickcount(void)
 {
     long long rc;
+    
+    if (g_clock_type == CPU_CLOCK) {
 #if defined(USE_CLOCK_TYPE_CLOCKGETTIME)
-    struct timespec tp;
-    
-    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp);
-    rc = tp.tv_sec;
-    rc = rc * 1000000000 + (tp.tv_nsec);
+            struct timespec tp;
+            
+            clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp);
+            rc = tp.tv_sec;
+            rc = rc * 1000000000 + (tp.tv_nsec);
 #elif (defined(USE_CLOCK_TYPE_RUSAGE) && defined(RUSAGE_WHO))
-    struct timeval tv;
-    struct rusage usage;
-    
-    getrusage(RUSAGE_WHO, &usage);
-    rc = (usage.ru_utime.tv_sec + usage.ru_stime.tv_sec);
-    rc = (rc * 1000000) + (usage.ru_utime.tv_usec + usage.ru_stime.tv_usec);
+            struct timeval tv;
+            struct rusage usage;
+            
+            getrusage(RUSAGE_WHO, &usage);
+            rc = (usage.ru_utime.tv_sec + usage.ru_stime.tv_sec);
+            rc = (rc * 1000000) + (usage.ru_utime.tv_usec + usage.ru_stime.tv_usec);
 #endif
+    } else if (g_clock_type == WALL_CLOCK) {
+        rc = gettimeofday_usec();
+    }
     return rc;    
 }
 
 double
 tickfactor(void)
 {
+    if (g_clock_type == CPU_CLOCK) {
 #if defined(USE_CLOCK_TYPE_CLOCKGETTIME)
-    return 0.000000001;
+            return 0.000000001;
 #elif defined(USE_CLOCK_TYPE_RUSAGE)
-    return 0.000001;
+            return 0.000001;
 #endif
+    } else if (g_clock_type == WALL_CLOCK) {
+        return 0.000001;
+    }
 }
 
 #endif /* *nix */
 #endif
 #endif
 
+typedef enum
+{
+    WALL_CLOCK = 0x00,
+    CPU_CLOCK = 0x01,
+}clock_type_t;
+
 long long tickcount(void);
 double tickfactor(void);
+void set_timing_clock_type(clock_type_t type);
+clock_type_t get_timing_clock_type(void);
 
 #endif
 
 class YappiError(Exception): pass
 
 __all__ = ['start', 'stop', 'get_func_stats', 'get_thread_stats', 'clear_stats', 'is_running',
-           'clock_type', 'mem_usage', 'thread_times']
+           'get_clock_info', 'mem_usage']
 
 CRLF = '\n'
 COLUMN_GAP = 2
     Returns the internal native(OS dependant) API used to retrieve per-thread cputime and
     its resolution.
     """
-    return _yappi.clock_type()
+    return _yappi.get_clock_type()
 
 def thread_times():
     """