kirr has uploaded this change for review.

View Change

trx_toolkit/_clck_gen: Unroll our own timerfd_* functions

Iaa675c95059ec8ccfad667f69984d5a7f608c249 (trx_toolkit/clck_gen: Don't
use threads because Python GIL is latency killer) switched CLCKGen to
use timerfd and noted

Unfortunately os.timerfd_create() & friends are only available starting
from Python 3.13 . If this poses a problem it can be easily solved by
doing those timerfd related system calls in Cython, after we switch most
of the codebase to Cython later.

As we are currently using py3.11 on the testing infrastructure it makes
sense not to force us to upgrade to py3.13 there.

-> Unroll our own timerfd_* wrappers so that clck_gen and fake_trx work
again on all py3 versions, not only on py3 ≥ 3.13 .

Change-Id: I39e4e05ba65fcb3e07bcfe19a3ef95201aaa40d0
---
M src/target/trx_toolkit/_clck_gen.pyx
1 file changed, 49 insertions(+), 4 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/92/40092/1
diff --git a/src/target/trx_toolkit/_clck_gen.pyx b/src/target/trx_toolkit/_clck_gen.pyx
index 3a6bfc7..dbd3c75 100644
--- a/src/target/trx_toolkit/_clck_gen.pyx
+++ b/src/target/trx_toolkit/_clck_gen.pyx
@@ -53,7 +53,7 @@
self._t_tick = int(self.ctr_interval // ns)

# Initialize timer fd
- self._timerfd = os.timerfd_create(time.CLOCK_MONOTONIC)
+ self._timerfd = _os_timerfd_create(time.CLOCK_MONOTONIC)

# (Optional) clock consumer
self.clck_handler = None
@@ -63,7 +63,7 @@

@property
def running(self):
- t_next, _ = os.timerfd_gettime_ns(self._timerfd)
+ t_next, _ = _os_timerfd_gettime_ns(self._timerfd)
return (t_next != 0)

def start(self):
@@ -71,11 +71,11 @@
self.clck_src = self.clck_start

# start timer fd
- os.timerfd_settime_ns(self._timerfd, initial=self._t_tick, interval=self._t_tick)
+ _os_timerfd_settime_ns(self._timerfd, flags=0, initial=self._t_tick, interval=self._t_tick)

def stop(self):
# stop timer fd
- os.timerfd_settime_ns(self._timerfd, initial=0, interval=0)
+ _os_timerfd_settime_ns(self._timerfd, flags=0, initial=0, interval=0)

# tick must be called periodically by CLCKGen user.
#
@@ -129,3 +129,48 @@

# Increase frame count (modular arithmetic)
self.clck_src = (self.clck_src + 1) % GSM_HYPERFRAME
+
+
+# ---- misc ----
+
+# _os_timerfd_<func> is like os.timerfd_<func> but works on all python versions.
+# we do it ourselves because os.timerfd_* is available only for py ≥ 3.13
+
+from posix.time cimport timespec, itimerspec
+
+cdef extern from "<sys/timerfd.h>":
+ int timerfd_create(int clockid, int flags)
+ int timerfd_settime(int fd, int flags, const itimerspec *new_value, itimerspec *old_value)
+ int timerfd_gettime(int fd, itimerspec *curr_value)
+
+
+cdef int _os_timerfd_create(int clockid, int flags=0) except -1:
+ fd = timerfd_create(clockid, flags)
+ if fd == -1:
+ _raise_oserr()
+ return fd
+
+cdef _os_timerfd_settime_ns(int fd, flags=0, initial=0, interval=0):
+ cdef itimerspec its
+ its.it_value .tv_sec = initial // 1000000000 # 1e9
+ its.it_value .tv_nsec = initial % 1000000000
+ its.it_interval .tv_sec = interval // 1000000000
+ its.it_interval .tv_nsec = interval % 1000000000
+ err = timerfd_settime(fd, flags, &its, NULL)
+ if err == -1:
+ _raise_oserr()
+
+cdef _os_timerfd_gettime_ns(int fd): # -> (next_expiration, interval)
+ cdef itimerspec its
+ err = timerfd_gettime(fd, &its)
+ if err == -1:
+ _raise_oserr()
+ cdef object t_next = 0L # py long to avoid int overflow
+ cdef object t_interval = 0L
+ t_next += its.it_value.tv_sec
+ t_next *= 1000000000 # 1e9
+ t_next += its.it_value.tv_nsec
+ t_interval += its.it_interval.tv_sec
+ t_interval *= 1000000000 # 1e9
+ t_interval += its.it_interval.tv_nsec
+ return (t_next, t_interval)

To view, visit change 40092. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: newchange
Gerrit-Project: osmocom-bb
Gerrit-Branch: master
Gerrit-Change-Id: I39e4e05ba65fcb3e07bcfe19a3ef95201aaa40d0
Gerrit-Change-Number: 40092
Gerrit-PatchSet: 1
Gerrit-Owner: kirr <kirr@nexedi.com>
Gerrit-CC: fixeria <vyanitskiy@sysmocom.de>
Gerrit-CC: osmith <osmith@sysmocom.de>
Gerrit-CC: pespin <pespin@sysmocom.de>