Jelajahi Sumber

fix time module

blueloveTH 3 bulan lalu
induk
melakukan
1d30103f6a

+ 3 - 3
include/pocketpy/interpreter/heap.h

@@ -17,9 +17,9 @@ typedef struct ManagedHeap {
 } ManagedHeap;
 
 typedef struct {
-    clock_t start;
-    clock_t mark_end;
-    clock_t swpet_end;
+    int64_t start_ns;
+    int64_t mark_end_ns;
+    int64_t swpet_end_ns;
 
     int types_length;
     int* small_types;

+ 2 - 0
include/pocketpy/pocketpy.h

@@ -801,6 +801,8 @@ PK_API void py_profiler_reset();
 PK_API char* py_profiler_report();
 
 /************* Others *************/
+int64_t time_ns();
+int64_t time_monotonic_ns();
 
 /// An utility function to read a line from stdin for REPL.
 PK_API int py_replinput(char* buf, int max_size);

+ 0 - 2
src/common/threads.c

@@ -75,8 +75,6 @@ void c11_cond__broadcast(c11_cond_t* cond) { cnd_broadcast(cond); }
 #define C11_THRDPOOL_DEBUG 0
 
 #if C11_THRDPOOL_DEBUG
-int64_t time_ns();
-
 static void c11_thrdpool_debug_log(int index, const char* format, ...) {
     va_list args;
     va_start(args, format);

+ 9 - 8
src/interpreter/heap.c

@@ -6,6 +6,7 @@
 #include "pocketpy/pocketpy.h"
 #include <assert.h>
 
+
 void ManagedHeap__ctor(ManagedHeap* self) {
     MultiPool__ctor(&self->small_objects);
     c11_vector__ctor(&self->large_objects, sizeof(PyObject*));
@@ -39,12 +40,12 @@ static void ManagedHeap__fire_debug_callback(ManagedHeap* self, ManagedHeapSwpet
     c11_sbuf buf;
     c11_sbuf__ctor(&buf);
 
-    const clock_t CLOCKS_PER_MS = CLOCKS_PER_SEC / 1000;
+    const int64_t NANOS_PER_SEC = 1000000000;
     const char* DIVIDER = "------------------------------------------------------------\n";
 
-    clock_t start = out_info->start / CLOCKS_PER_MS;
-    clock_t mark_ms = (out_info->mark_end - out_info->start) / CLOCKS_PER_MS;
-    clock_t swpet_ms = (out_info->swpet_end - out_info->mark_end) / CLOCKS_PER_MS;
+    double start = out_info->start_ns / 1e9;
+    int64_t mark_ms = (out_info->mark_end_ns - out_info->start_ns) / NANOS_PER_SEC;
+    int64_t swpet_ms = (out_info->swpet_end_ns - out_info->mark_end_ns) / NANOS_PER_SEC;
 
     c11_sbuf__write_cstr(&buf, DIVIDER);
     pk_sprintf(&buf, "start:        %f\n", (double)start / 1000);
@@ -102,9 +103,9 @@ void ManagedHeap__collect_hint(ManagedHeap* self) {
     if(!py_isnone(&self->debug_callback)) out_info = ManagedHeapSwpetInfo__new();
     
     ManagedHeap__mark(self);
-    if(out_info) out_info->mark_end = clock();
+    if(out_info) out_info->mark_end_ns = time_ns();
     int freed = ManagedHeap__sweep(self, out_info);
-    if(out_info) out_info->swpet_end = clock();
+    if(out_info) out_info->swpet_end_ns = time_ns();
 
     // adjust `gc_threshold` based on `freed_ma`
     self->freed_ma[0] = self->freed_ma[1];
@@ -138,9 +139,9 @@ int ManagedHeap__collect(ManagedHeap* self) {
     if(!py_isnone(&self->debug_callback)) out_info = ManagedHeapSwpetInfo__new();
     
     ManagedHeap__mark(self);
-    if(out_info) out_info->mark_end = clock();
+    if(out_info) out_info->mark_end_ns = time_ns();
     int freed = ManagedHeap__sweep(self, out_info);
-    if(out_info) out_info->swpet_end = clock();
+    if(out_info) out_info->swpet_end_ns = time_ns();
 
     if(out_info) {
         out_info->auto_thres.before = self->gc_threshold;

+ 1 - 1
src/interpreter/vmx.c

@@ -140,7 +140,7 @@ ManagedHeapSwpetInfo* ManagedHeapSwpetInfo__new() {
         self->small_types[i] = 0;
         self->large_types[i] = 0;
     }
-    self->start = clock();
+    self->start_ns = time_ns();
     return self;
 }
 

+ 0 - 3
src/modules/random.c

@@ -1,8 +1,5 @@
 #include "pocketpy/interpreter/vm.h"
 #include "pocketpy/pocketpy.h"
-#include <time.h>
-
-int64_t time_ns();  // from random.c
 
 /* https://github.com/clibs/mt19937ar
 

+ 56 - 2
src/modules/time.c

@@ -2,6 +2,13 @@
 #include <time.h>
 #undef _XOPEN_SOURCE
 
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <profileapi.h>
+#undef WIN32_LEAN_AND_MEAN
+#endif
+
 #include "pocketpy/pocketpy.h"
 #include "pocketpy/common/threads.h"
 #include <assert.h>
@@ -23,8 +30,34 @@ int64_t time_ns() {
     nanos += tms.tv_nsec;
     return nanos;
 }
+
+int64_t time_monotonic_ns() {
+#ifdef _WIN32
+    LARGE_INTEGER now;
+    QueryPerformanceCounter(&now);
+    LONGLONG ticksll = now.QuadPart;
+    static LARGE_INTEGER freq;
+    if(freq.QuadPart == 0) QueryPerformanceFrequency(&freq);
+    /* Convert ticks to nanoseconds */
+    return (ticksll * NANOS_PER_SEC) / freq.QuadPart;
+#endif
+
+    struct timespec tms;
+#ifdef CLOCK_MONOTONIC
+    clock_gettime(CLOCK_MONOTONIC, &tms);
+#else
+    /* The C11 way */
+    timespec_get(&tms, TIME_UTC);
+#endif
+    /* seconds, multiplied with 1 billion */
+    int64_t nanos = tms.tv_sec * (int64_t)NANOS_PER_SEC;
+    /* Add full nanoseconds */
+    nanos += tms.tv_nsec;
+    return nanos;
+}
 #else
 int64_t time_ns() { return 0; }
+int64_t time_monotonic_ns() { return 0; }
 #endif
 
 static bool time_time(int argc, py_Ref argv) {
@@ -41,7 +74,25 @@ static bool time_time_ns(int argc, py_Ref argv) {
     return true;
 }
 
+static bool time_time_monotonic(int argc, py_Ref argv) {
+    PY_CHECK_ARGC(0);
+    int64_t nanos = time_monotonic_ns();
+    py_newfloat(py_retval(), (double)nanos / NANOS_PER_SEC);
+    return true;
+}
+
+static bool time_time_monotonic_ns(int argc, py_Ref argv) {
+    PY_CHECK_ARGC(0);
+    int64_t nanos = time_monotonic_ns();
+    py_newint(py_retval(), nanos);
+    return true;
+}
+
 static bool time_perf_counter(int argc, py_Ref argv) {
+    return time_time_monotonic(argc, argv);
+}
+
+static bool time_process_time(int argc, py_Ref argv) {
     PY_CHECK_ARGC(0);
     py_newfloat(py_retval(), (double)clock() / CLOCKS_PER_SEC);
     return true;
@@ -52,10 +103,10 @@ static bool time_sleep(int argc, py_Ref argv) {
     py_f64 secs;
     if(!py_castfloat(argv, &secs)) return false;
 
-    int64_t start = time_ns();
+    int64_t start = time_monotonic_ns();
     const int64_t end = start + secs * NANOS_PER_SEC;
     while(true) {
-        int64_t now = time_ns();
+        int64_t now = time_monotonic_ns();
         if(now >= end) break;
 #if PK_ENABLE_THREADS
         c11_thrd__yield();
@@ -112,7 +163,10 @@ void pk__add_module_time() {
 
     py_bindfunc(mod, "time", time_time);
     py_bindfunc(mod, "time_ns", time_time_ns);
+    py_bindfunc(mod, "monotonic", time_time_monotonic);
+    py_bindfunc(mod, "monotonic_ns", time_time_monotonic_ns);
     py_bindfunc(mod, "perf_counter", time_perf_counter);
+    py_bindfunc(mod, "process_time", time_process_time);
     py_bindfunc(mod, "sleep", time_sleep);
     py_bindfunc(mod, "localtime", time_localtime);
 }

+ 4 - 3
src2/test_threads.c

@@ -1,7 +1,7 @@
 #include "pocketpy/common/threads.h"
 #include <stdio.h>
 
-int64_t time_ns();
+int64_t time_monotonic_ns();
 
 static void func(void* arg) {
     long long* val = (long long*)arg;
@@ -31,10 +31,11 @@ int main(int argc, char** argv) {
         }
 
         printf("==> %dth run\n", i + 1);
-        int64_t start_ns = time_ns();
+        int64_t start_ns = time_monotonic_ns();
         c11_thrdpool__map(&pool, func, args, num_tasks);
         c11_thrdpool__join(&pool);
-        int64_t end_ns = time_ns();
+        int64_t end_ns = time_monotonic_ns();
+        printf("==> %lld -> %lld\n", (long long)start_ns, (long long)end_ns);
         double elapsed = (end_ns - start_ns) / 1e9;
         printf("  Results: %lld, %lld, %lld, %lld, %lld\n",
                data[0],