Skip to content

Commit

Permalink
Use time.perf_counter for portability
Browse files Browse the repository at this point in the history
  • Loading branch information
user202729 committed Feb 25, 2025
1 parent a00f98b commit 7289aaf
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 32 deletions.
3 changes: 1 addition & 2 deletions src/cysignals/signals.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#*****************************************************************************

from cpython.object cimport PyObject
from posix.time cimport timespec

cdef extern from *:
int unlikely(int) nogil # Defined by Cython
Expand All @@ -30,7 +29,7 @@ cdef extern from "struct_signals.h":
cy_atomic_int block_sigint
const char* s
PyObject* exc_value
timespec gc_pause_until
double gc_pause_until


cdef extern from "macros.h" nogil:
Expand Down
33 changes: 5 additions & 28 deletions src/cysignals/signals.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -29,35 +29,13 @@ from cpython.ref cimport Py_XINCREF, Py_CLEAR
from cpython.exc cimport (PyErr_Occurred, PyErr_NormalizeException,
PyErr_Fetch, PyErr_Restore)
from cpython.version cimport PY_MAJOR_VERSION
from posix.time cimport clock_gettime, CLOCK_MONOTONIC
import time

cimport cython
import sys
from gc import collect


cdef inline bint timespec_is_zero(timespec t):
return t.tv_sec == 0 and t.tv_nsec == 0


cdef inline bint timespec_less(timespec a, timespec b):
return a.tv_sec < b.tv_sec or (a.tv_sec == b.tv_sec and a.tv_nsec < b.tv_nsec)


cdef inline timespec timespec_add(timespec a, long long b):
cdef long long d = cython.cdiv(a.tv_nsec + b, 1000000000)
a.tv_sec += d
a.tv_nsec += b - d * 1000000000
if a.tv_nsec < 0:
a.tv_nsec += 1000000000
a.tv_sec -= 1
return a


cdef inline long long timespec_diff(timespec a, timespec b):
return (a.tv_sec - b.tv_sec) * <long long>1000000000 + a.tv_nsec - b.tv_nsec


# On Windows, some signals are not pre-defined.
# We define them here with values that will never occur in practice
# (to avoid compilation errors and conditional compilation).
Expand Down Expand Up @@ -421,9 +399,8 @@ cdef void verify_exc_value() noexcept:
Py_CLEAR(cysigs.exc_value)
return

cdef timespec cur_time, finish_time
clock_gettime(CLOCK_MONOTONIC, &cur_time)
if timespec_is_zero(cysigs.gc_pause_until) or timespec_less(cysigs.gc_pause_until, cur_time):
cdef double cur_time = time.perf_counter(), finish_time
if cysigs.gc_pause_until == 0 or cysigs.gc_pause_until < cur_time:
# To be safe, we run the garbage collector because it may clear
# references to our exception.
try:
Expand All @@ -433,8 +410,8 @@ cdef void verify_exc_value() noexcept:
# is not functional anymore.
pass

clock_gettime(CLOCK_MONOTONIC, &finish_time)
cysigs.gc_pause_until = timespec_add(finish_time, timespec_diff(finish_time, cur_time) * 5)
finish_time = time.perf_counter()
cysigs.gc_pause_until = finish_time + (finish_time - cur_time) * 5

# Make sure we still have cysigs.exc_value at all; if this function was
# called again during garbage collection it might have already been set
Expand Down
4 changes: 2 additions & 2 deletions src/cysignals/struct_signals.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ typedef struct
* This is used by the sig_occurred function. */
PyObject* exc_value;

/* Time until calling garbage collector is allowed. Using monotonic clock.
/* Time until calling garbage collector is allowed. Using Python time.perf_counter.
* See https://github.com/sagemath/cysignals/issues/215. */
struct timespec gc_pause_until;
double gc_pause_until;

#if ENABLE_DEBUG_CYSIGNALS
int debug_level;
Expand Down

0 comments on commit 7289aaf

Please sign in to comment.