kirr has uploaded this change for review. (
https://gerrit.osmocom.org/c/osmocom-bb/+/40062?usp=email )
Change subject: trx_toolkit/_clck_gen: Optimize timerfd read
......................................................................
trx_toolkit/_clck_gen: Optimize timerfd read
As can be seen from
http://navytux.spb.ru/~kirr/osmo/fake_trx/pyx-base.html
(CLCKGen_11tick)
the system is spending just a bit of time doing os.read. But it is also
the fact that os.read releases/reacquires gil which, as
Iaa675c95059ec8ccfad667f69984d5a7f608c249 (trx_toolkit/clck_gen: Don't
use threads because Python GIL is latency killer) shows can have
dramatic effect.
-> Avoid both py wrapper overhead and potential gil ping-pong
performance penalty by doing read from ._timerfd ourselves.
Change-Id: I23d5fc2b7209592c62a4655c42004777b8bb31a8
---
M src/target/trx_toolkit/_clck_gen.pyx
1 file changed, 12 insertions(+), 3 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/62/40062/1
diff --git a/src/target/trx_toolkit/_clck_gen.pyx b/src/target/trx_toolkit/_clck_gen.pyx
index 46e28c1..e63eacb 100644
--- a/src/target/trx_toolkit/_clck_gen.pyx
+++ b/src/target/trx_toolkit/_clck_gen.pyx
@@ -22,8 +22,11 @@
import os
import sys
+from udp_link cimport _raise_oserr
from cython cimport final
+from libc.stdint cimport uint64_t
+from posix.unistd cimport read
import gsm_shared
cdef int GSM_HYPERFRAME = gsm_shared.GSM_HYPERFRAME
@@ -88,9 +91,15 @@
# run .send_clck_ind() every .ctr_interval
# NOTE timerfd is careful not to accumulate timing error when organizing the clock
loop
- _ = os.read(self._timerfd, 8)
- assert len(_) == 8, len(_)
- ticks = int.from_bytes(_, byteorder=sys.byteorder)
+ cdef uint64_t ticks
+ # NOTE we do not release/reacquire gil to save us from gil ping-pong performance
penalty
+ # we can do that because fake_trx is single-threaded and invokes us here then
.timerfd is ready
+ # for standalone usage the worst that would happen is 1 GSM frame pause.
+ # But standalone-usage in clck_gen.py is single-threaded as well, so that is also
ok.
+ n = read(self._timerfd, &ticks, sizeof(ticks))
+ if n == -1:
+ _raise_oserr()
+ assert n == 8, n
assert ticks > 0, ticks
if ticks > 1:
log.warning("CLCKGen: time overrun by %dus; resetting the clock" %
((ticks-1)*self._t_tick * ns // us))
--
To view, visit
https://gerrit.osmocom.org/c/osmocom-bb/+/40062?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: osmocom-bb
Gerrit-Branch: master
Gerrit-Change-Id: I23d5fc2b7209592c62a4655c42004777b8bb31a8
Gerrit-Change-Number: 40062
Gerrit-PatchSet: 1
Gerrit-Owner: kirr <kirr(a)nexedi.com>
Gerrit-CC: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-CC: osmith <osmith(a)sysmocom.de>
Gerrit-CC: pespin <pespin(a)sysmocom.de>