fix time module

This commit is contained in:
blueloveTH 2025-11-26 22:56:39 +08:00
parent e2c065d18d
commit 1d30103f6a
8 changed files with 75 additions and 22 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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],