kirr has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmocom-bb/+/40068?usp=email )
Change subject: trx_toolkit/_fake_trx: No need to initialize .rf_muted in FakeTRX
......................................................................
trx_toolkit/_fake_trx: No need to initialize .rf_muted in FakeTRX
Because .rf_muted is attribute of Transceiver and is initialized to that
value in Transceiver.__cinit__ .
Change-Id: Ibd6b5dd7fa65e42cc864be0153fa9906dd3ddf7e
---
M src/target/trx_toolkit/_fake_trx.pyx
1 file changed, 0 insertions(+), 2 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/68/40068/1
diff --git a/src/target/trx_toolkit/_fake_trx.pyx b/src/target/trx_toolkit/_fake_trx.pyx
index e49d056..7c0fd35 100644
--- a/src/target/trx_toolkit/_fake_trx.pyx
+++ b/src/target/trx_toolkit/_fake_trx.pyx
@@ -113,8 +113,6 @@
# When disabled, RSSI is calculated based on Tx power and Rx path loss
self.fake_rssi_enabled = False
- self.rf_muted = False
-
# Actual ToA, RSSI, C/I, TA values
self.tx_power_base = self.NOMINAL_TX_POWER_DEFAULT
self.tx_att_base = self.TX_ATT_DEFAULT
--
To view, visit https://gerrit.osmocom.org/c/osmocom-bb/+/40068?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: Ibd6b5dd7fa65e42cc864be0153fa9906dd3ddf7e
Gerrit-Change-Number: 40068
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>
kirr has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmocom-bb/+/40071?usp=email )
Change subject: trx_toolkit/data_msg: Replace `from gsm_shared import *` with explicit import and at C level
......................................................................
trx_toolkit/data_msg: Replace `from gsm_shared import *` with explicit import and at C level
gsm_shared is currently pure-py module, but still we can import needed
constants and set them to C-level typed variables. It is both goods: all
imports are explicit, and access to the constant now go faster instead
of going through py-level module dict lookup.
Change-Id: Ica8c73d6136053845415bdece48b24a7df6520be
---
M src/target/trx_toolkit/data_msg.pyx
1 file changed, 5 insertions(+), 1 deletion(-)
git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/71/40071/1
diff --git a/src/target/trx_toolkit/data_msg.pyx b/src/target/trx_toolkit/data_msg.pyx
index af0aac6..0da4f7c 100644
--- a/src/target/trx_toolkit/data_msg.pyx
+++ b/src/target/trx_toolkit/data_msg.pyx
@@ -25,7 +25,11 @@
from typing import List
from enum import Enum
from array import array
-from gsm_shared import *
+
+import gsm_shared
+cdef int GMSK_BURST_LEN = gsm_shared.GMSK_BURST_LEN
+cdef int EDGE_BURST_LEN = gsm_shared.EDGE_BURST_LEN
+cdef int GSM_HYPERFRAME = gsm_shared.GSM_HYPERFRAME
# _bu2s converts unsigned byte to signed.
def _bu2s(x):
--
To view, visit https://gerrit.osmocom.org/c/osmocom-bb/+/40071?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: Ica8c73d6136053845415bdece48b24a7df6520be
Gerrit-Change-Number: 40071
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>
kirr has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmocom-bb/+/40073?usp=email )
Change subject: trx_toolkit/data_msg: Factor constants out of *Msg classes
......................................................................
trx_toolkit/data_msg: Factor constants out of *Msg classes
Accessing those constants via either self.CONSTANT, or e.g. RxMsg.CONSTANT
always do dict lookup on class .__dict__ and there is no way to change
that even with switching to cdef class. Dict lookups are slow.
-> Fix that with factoring constants to be module-level cdef globals which
are now accessed statically and quickly.
Change-Id: Ia117e2aa04bf7dce20bef61af56d66a07fe24778
---
M src/target/trx_toolkit/data_msg.pyx
1 file changed, 44 insertions(+), 40 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/73/40073/1
diff --git a/src/target/trx_toolkit/data_msg.pyx b/src/target/trx_toolkit/data_msg.pyx
index 81f93ca..ccbdd71 100644
--- a/src/target/trx_toolkit/data_msg.pyx
+++ b/src/target/trx_toolkit/data_msg.pyx
@@ -68,12 +68,14 @@
ModAQPSK = Modulation(0b1100, 2 * GMSK_BURST_LEN)
+cdef int KNOWN_VERSION_MAX = 1 # 0, 1
+
class Msg(abc.ABC):
''' TRXD (DATA) message coding API (common part). '''
# NOTE: up to 16 versions can be encoded
CHDR_VERSION_MAX = 0b1111
- KNOWN_VERSIONS = (0, 1)
+ KNOWN_VERSIONS = tuple(range(KNOWN_VERSION_MAX+1))
def __init__(self, fn = None, tn = None, burst = None, ver = 0):
self.burst = burst # bytes|bytearray for ubit, array[b] for sbit, array[B] for usbit
@@ -166,7 +168,7 @@
def validate(self):
''' Validate the message fields (throws ValueError). '''
- if not self.ver in self.KNOWN_VERSIONS:
+ if not (0 <= self.ver <= KNOWN_VERSION_MAX):
raise ValueError("Unknown TRXD header version %d" % self.ver)
if self.fn is None:
@@ -219,7 +221,7 @@
# Parse the header version first
self.ver = (msg[0] >> 4)
- if not self.ver in self.KNOWN_VERSIONS:
+ if not (0 <= self.ver <= KNOWN_VERSION_MAX):
raise ValueError("Unknown TRXD header version %d" % self.ver)
# Parse TDMA TN and FN
@@ -241,13 +243,14 @@
msg_burst = memoryview(msg)[self.HDR_LEN:]
self.parse_burst(msg_burst)
+
+# Constants
+cdef int PWR_MIN = 0x00
+cdef int PWR_MAX = 0xff
+
class TxMsg(Msg):
''' Tx (L1 -> TRX) message coding API. '''
- # Constants
- PWR_MIN = 0x00
- PWR_MAX = 0xff
-
# Specific message fields
pwr = None
@@ -275,7 +278,7 @@
if self.pwr is None:
raise ValueError("Tx Attenuation level is not set")
- if self.pwr < self.PWR_MIN or self.pwr > self.PWR_MAX:
+ if self.pwr < PWR_MIN or self.pwr > PWR_MAX:
raise ValueError("Tx Attenuation %d is out of range" % self.pwr)
# FIXME: properly handle IDLE / NOPE indications
@@ -290,10 +293,10 @@
''' Generate a random power level. '''
if min is None:
- min = self.PWR_MIN
+ min = PWR_MIN
if max is None:
- max = self.PWR_MAX
+ max = PWR_MAX
return random.randint(min, max)
@@ -367,27 +370,28 @@
return msg
+
+# rxlev2dbm(0..63) gives us [-110..-47], plus -10 dbm for noise
+cdef int RSSI_MIN = -120
+cdef int RSSI_MAX = -47
+
+# Min and max values of int16_t
+cdef int TOA256_MIN = -32768
+cdef int TOA256_MAX = 32767
+
+# TSC (Training Sequence Code) range is [0, 7]
+cdef int TSC_MAX = 7
+
+# C/I range (in centiBels)
+cdef int CI_MIN = -1280
+cdef int CI_MAX = 1280
+
+# IDLE frame / nope detection indicator
+cdef int NOPE_IND = (1 << 7)
+
class RxMsg(Msg):
''' Rx (TRX -> L1) message coding API. '''
- # rxlev2dbm(0..63) gives us [-110..-47], plus -10 dbm for noise
- RSSI_MIN = -120
- RSSI_MAX = -47
-
- # Min and max values of int16_t
- TOA256_MIN = -32768
- TOA256_MAX = 32767
-
- # TSC (Training Sequence Code) range
- TSC_RANGE = range(0, 8)
-
- # C/I range (in centiBels)
- CI_MIN = -1280
- CI_MAX = 1280
-
- # IDLE frame / nope detection indicator
- NOPE_IND = (1 << 7)
-
# Specific message fields
rssi = None
toa256 = None
@@ -459,13 +463,13 @@
if self.rssi is None:
raise ValueError("RSSI is not set")
- if self.rssi < self.RSSI_MIN or self.rssi > self.RSSI_MAX:
+ if self.rssi < RSSI_MIN or self.rssi > RSSI_MAX:
raise ValueError("RSSI %d is out of range" % self.rssi)
if self.toa256 is None:
raise ValueError("ToA256 is not set")
- if self.toa256 < self.TOA256_MIN or self.toa256 > self.TOA256_MAX:
+ if self.toa256 < TOA256_MIN or self.toa256 > TOA256_MAX:
raise ValueError("ToA256 %d is out of range" % self.toa256)
# Version specific parameters (omited for NOPE.ind)
@@ -486,7 +490,7 @@
if self.tsc is None:
raise ValueError("TSC is not set")
- if self.tsc not in self.TSC_RANGE:
+ if not (0 <= self.tsc <= TSC_MAX):
raise ValueError("TSC %d is out of range" % self.tsc)
# Version specific parameters (also present in NOPE.ind)
@@ -494,7 +498,7 @@
if self.ci is None:
raise ValueError("C/I is not set")
- if self.ci < self.CI_MIN or self.ci > self.CI_MAX:
+ if self.ci < CI_MIN or self.ci > CI_MAX:
raise ValueError("C/I %d is out of range" % self.ci)
self.validate_burst()
@@ -503,10 +507,10 @@
''' Generate a random RSSI value. '''
if min is None:
- min = self.RSSI_MIN
+ min = RSSI_MIN
if max is None:
- max = self.RSSI_MAX
+ max = RSSI_MAX
return random.randint(min, max)
@@ -514,10 +518,10 @@
''' Generate a random ToA (Time of Arrival) value. '''
if min is None:
- min = self.TOA256_MIN
+ min = TOA256_MIN
if max is None:
- max = self.TOA256_MAX
+ max = TOA256_MAX
return random.randint(min, max)
@@ -534,10 +538,10 @@
self.tsc_set = random.randint(0, 3)
else:
self.tsc_set = random.randint(0, 1)
- self.tsc = random.choice(self.TSC_RANGE)
+ self.tsc = random.randint(0, TSC_MAX)
# C/I: Carrier-to-Interference ratio
- self.ci = random.randint(self.CI_MIN, self.CI_MAX)
+ self.ci = random.randint(CI_MIN, CI_MAX)
def desc_hdr(self):
''' Generate human-readable header description. '''
@@ -572,7 +576,7 @@
# IDLE / nope indication has no MTS info
if self.nope_ind:
- return self.NOPE_IND
+ return NOPE_IND
# TSC: . . . . . X X X
mts = self.tsc & 0b111
@@ -587,7 +591,7 @@
''' Parse Modulation and Training Sequence info. '''
# IDLE / nope indication has no MTS info
- self.nope_ind = (mts & self.NOPE_IND) > 0
+ self.nope_ind = (mts & NOPE_IND) > 0
if self.nope_ind:
self.mod_type = None
self.tsc_set = None
--
To view, visit https://gerrit.osmocom.org/c/osmocom-bb/+/40073?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: Ia117e2aa04bf7dce20bef61af56d66a07fe24778
Gerrit-Change-Number: 40073
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>
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>
kirr has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmocom-bb/+/40063?usp=email )
Change subject: trx_toolkit/_fake_trx: Invoke CLCKGen.tick via C
......................................................................
trx_toolkit/_fake_trx: Invoke CLCKGen.tick via C
As can be seen from http://navytux.spb.ru/~kirr/osmo/fake_trx/pyx-base.html (Runner_5loop)
there is a lot of overhead to invoke things via py-level.
-> Avoid that for invoking CLCK_gen.tick by switching to use C-level for
this call.
We will deal with switching other things to C later.
Change-Id: I19a7a90cd420b481c555f37f3fb7f2ebb513d6e8
---
M src/target/trx_toolkit/_clck_gen.pxd
M src/target/trx_toolkit/_clck_gen.pyx
M src/target/trx_toolkit/_fake_trx.pyx
3 files changed, 4 insertions(+), 1 deletion(-)
git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/63/40063/1
diff --git a/src/target/trx_toolkit/_clck_gen.pxd b/src/target/trx_toolkit/_clck_gen.pxd
index f4de595..447d0be 100644
--- a/src/target/trx_toolkit/_clck_gen.pxd
+++ b/src/target/trx_toolkit/_clck_gen.pxd
@@ -19,4 +19,5 @@
cdef int _t_tick
+ cdef _tick(self)
cdef send_clck_ind(self)
diff --git a/src/target/trx_toolkit/_clck_gen.pyx b/src/target/trx_toolkit/_clck_gen.pyx
index e63eacb..3a6bfc7 100644
--- a/src/target/trx_toolkit/_clck_gen.pyx
+++ b/src/target/trx_toolkit/_clck_gen.pyx
@@ -88,6 +88,8 @@
# - client code can also poll/select on ._timerfd to wait for GSM frame.
# After ._timerfd becomes ready it is guaranteed that the next .tick call will not block.
def tick(self):
+ self._tick()
+ cdef _tick(self):
# run .send_clck_ind() every .ctr_interval
# NOTE timerfd is careful not to accumulate timing error when organizing the clock loop
diff --git a/src/target/trx_toolkit/_fake_trx.pyx b/src/target/trx_toolkit/_fake_trx.pyx
index 8803b24..f4cf7f6 100644
--- a/src/target/trx_toolkit/_fake_trx.pyx
+++ b/src/target/trx_toolkit/_fake_trx.pyx
@@ -408,7 +408,7 @@
# clock is priority
if self.clck_gen._timerfd in r_event:
- self.clck_gen.tick()
+ self.clck_gen._tick()
# Iterate over all transceivers
for trx in self.trx_list:
--
To view, visit https://gerrit.osmocom.org/c/osmocom-bb/+/40063?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: I19a7a90cd420b481c555f37f3fb7f2ebb513d6e8
Gerrit-Change-Number: 40063
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>
kirr has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmocom-bb/+/40064?usp=email )
Change subject: trx_toolkit/_fake_trx: Optimize IO loop fd polling
......................................................................
trx_toolkit/_fake_trx: Optimize IO loop fd polling
As can be seen from http://navytux.spb.ru/~kirr/osmo/fake_trx/pyx-base.html (Runner_5loop)
the system spends more in py select wrapper compared to select system
call itself. And also the wrapper 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. It is also known that select inside the kernel is doing
useless work at every call by registering/deregistering each fd every
time.
-> Avoid all that overhead by switching to epoll and doing epoll_wait
ourselves and without releasing/reacquiring the gil. We can do that
because fake_trx is single-threaded and because clck_gen._timerfd is
setup to do ~ 200 Hz regular wakeup.
Change-Id: I748810871601178cc97bcdaba41419949078c29d
---
M src/target/trx_toolkit/_fake_trx.pyx
1 file changed, 111 insertions(+), 18 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/64/40064/1
diff --git a/src/target/trx_toolkit/_fake_trx.pyx b/src/target/trx_toolkit/_fake_trx.pyx
index f4cf7f6..e540e14 100644
--- a/src/target/trx_toolkit/_fake_trx.pyx
+++ b/src/target/trx_toolkit/_fake_trx.pyx
@@ -25,6 +25,7 @@
from _clck_gen cimport CLCKGen
from transceiver import Transceiver
from data_msg import Modulation
+from udp_link cimport _raise_oserr
from gsm_shared import *
@@ -373,6 +374,30 @@
return None
+# ----------------------------------------
+
+from libc.stdint cimport int64_t, uint32_t, uint64_t
+from libc.stdlib cimport calloc, free
+
+cdef extern from "<sys/epoll.h>":
+ union epoll_data_t:
+ void *ptr
+ int fd
+ uint32_t u32
+ uint64_t u64
+
+ struct epoll_event:
+ uint32_t events
+ epoll_data_t data
+
+ enum:
+ EPOLL_CTL_ADD
+ EPOLLIN
+
+ int epoll_ctl(int epfd, int op, int fd, epoll_event *event)
+ int epoll_wait(int epfd, epoll_event *events, int maxevents, int timeout)
+
+
# Runner organizes execution of several FakeTRX instances with common clock.
cdef class Runner:
cdef CLCKGen clck_gen
@@ -396,26 +421,94 @@
# loops runs IO loop on specified CLCKGen and TRXes forever.
def loop(self):
- sock_list = [self.clck_gen._timerfd]
+ epoll = select.epoll()
+ cdef int epoll_fd = epoll.fileno()
+
+ cdef epoll_event ee
+ ee = _heventdef(_Handler(_RxTimer, None))
+ xepoll_ctl(epoll_fd, EPOLL_CTL_ADD, self.clck_gen._timerfd, &ee)
+
for trx in self.trx_list:
- sock_list.append(trx.ctrl_if.sock)
- sock_list.append(trx.data_if.sock)
+ ee = _heventdef(_Handler(_RxTRXCtrl, trx))
+ xepoll_ctl(epoll_fd, EPOLL_CTL_ADD, trx.ctrl_if.sock.fileno(), &ee)
- # Enter main loop
- while True:
- # Wait until we get any data on any socket
- r_event, _, _ = select.select(sock_list, [], [])
+ ee = _heventdef(_Handler(_RxTRXData, trx))
+ xepoll_ctl(epoll_fd, EPOLL_CTL_ADD, trx.data_if.sock.fileno(), &ee)
- # clock is priority
- if self.clck_gen._timerfd in r_event:
- self.clck_gen._tick()
- # Iterate over all transceivers
- for trx in self.trx_list:
- # DATA interface
- if trx.data_if.sock in r_event:
- trx.recv_data_msg()
+ cdef int maxevents = 1 + 2*len(self.trx_list)
+ cdef epoll_event *events = <epoll_event*>calloc(maxevents, sizeof(events[0]))
+ if events == NULL:
+ raise MemoryError()
- # CTRL interface
- if trx.ctrl_if.sock in r_event:
- trx.ctrl_if.handle_rx()
+ try:
+
+ # Enter main loop
+ while True:
+ # Wait until we get any data on any socket
+ #
+ # 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 because clck_gen._timerfd
+ # is setup to do ~ 200 Hz regular wakeup.
+ n = epoll_wait(epoll_fd, &events[0], maxevents, -1)
+ if n == -1:
+ _raise_oserr()
+
+ # clock is priority
+ for i in range(n):
+ h = <_Handler>events[i].data.ptr
+ if h.kind == _RxTimer:
+ self.clck_gen._tick()
+
+ # data / ctrl
+ for i in range(n):
+ h = <_Handler>events[i].data.ptr
+ if h.kind == _RxTRXData:
+ h.trx.recv_data_msg()
+
+ elif h.kind == _RxTRXCtrl:
+ h.trx.ctrl_if.handle_rx()
+
+ elif h.kind == _RxTimer:
+ pass
+
+ else:
+ raise AssertionError('bug')
+
+ finally:
+ free(events)
+
+
+# _Handler represents how POLLIN event on an fd should be handled.
+cdef class _Handler:
+ cdef _HandlerKind kind
+ cdef object trx # Tranceiver | None
+
+ def __cinit__(self, _HandlerKind kind, trx):
+ self.kind = kind
+ self.trx = trx
+ _hkeepalive.append(self) # so that _heventdef works without special care
+
+cdef enum _HandlerKind:
+ _RxTimer
+ _RxTRXCtrl
+ _RxTRXData
+
+cdef list _hkeepalive = []
+
+
+# _heventdef returns epoll_event suitable for registering that links to specified _Handler.
+#
+# NOTE the caller must make sure to keep handler object alive during epoll loop run.
+cdef epoll_event _heventdef(_Handler h):
+ cdef epoll_event e
+ e.events = EPOLLIN
+ e.data.ptr = <void*>h
+ return e
+
+
+# xepoll_ctl invokes epoll_ctl and raises exception on error.
+cdef xepoll_ctl(int efd, int op, int fd, epoll_event* event):
+ err = epoll_ctl(efd, op, fd, event)
+ if err == -1:
+ _raise_oserr()
--
To view, visit https://gerrit.osmocom.org/c/osmocom-bb/+/40064?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: I748810871601178cc97bcdaba41419949078c29d
Gerrit-Change-Number: 40064
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>
kirr has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmocom-bb/+/40065?usp=email )
Change subject: trx_toolkit/burst_fwd: Switch BurstForwarder to cdef class
......................................................................
trx_toolkit/burst_fwd: Switch BurstForwarder to cdef class
- Put fields into the object struct; fields are now accessed directly
via that C-level struct instead of via __dict__ lookup
- cimport instead of import BurstForwarder at the users
- switch to invoke BurstForwarder.forward_msg via C-level as that function is
the only public function of BurstForwarder and is used only in one
place in Tansceiver.clck_tick . Add corresponding type annotation
there to make that C-calling possible.
Change-Id: I8e5fe20ff5a9a0fbbb8ce82a7776837de1219e13
---
M src/target/trx_toolkit/_fake_trx.pyx
A src/target/trx_toolkit/burst_fwd.pxd
M src/target/trx_toolkit/burst_fwd.pyx
M src/target/trx_toolkit/transceiver.pyx
4 files changed, 13 insertions(+), 6 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/65/40065/1
diff --git a/src/target/trx_toolkit/_fake_trx.pyx b/src/target/trx_toolkit/_fake_trx.pyx
index e540e14..102a8d1 100644
--- a/src/target/trx_toolkit/_fake_trx.pyx
+++ b/src/target/trx_toolkit/_fake_trx.pyx
@@ -21,7 +21,7 @@
import random
import select
-from burst_fwd import BurstForwarder
+from burst_fwd cimport BurstForwarder
from _clck_gen cimport CLCKGen
from transceiver import Transceiver
from data_msg import Modulation
@@ -401,7 +401,7 @@
# Runner organizes execution of several FakeTRX instances with common clock.
cdef class Runner:
cdef CLCKGen clck_gen
- cdef object burst_fwd # BurstForwarder
+ cdef BurstForwarder burst_fwd
cdef list[Transceiver] trx_list
def __init__(self, clck_gen, trx_list):
diff --git a/src/target/trx_toolkit/burst_fwd.pxd b/src/target/trx_toolkit/burst_fwd.pxd
new file mode 100644
index 0000000..eb3d60b
--- /dev/null
+++ b/src/target/trx_toolkit/burst_fwd.pxd
@@ -0,0 +1,6 @@
+# cython: language_level=3
+
+cdef class BurstForwarder:
+ cdef list trx_list # [] of Transceiver
+
+ cdef forward_msg(self, src_trx, rx_msg)
diff --git a/src/target/trx_toolkit/burst_fwd.pyx b/src/target/trx_toolkit/burst_fwd.pyx
index 36e5095..2c63187 100644
--- a/src/target/trx_toolkit/burst_fwd.pyx
+++ b/src/target/trx_toolkit/burst_fwd.pyx
@@ -21,7 +21,7 @@
import logging as log
-class BurstForwarder:
+cdef class BurstForwarder:
""" Performs burst forwarding between transceivers.
BurstForwarder distributes bursts between the list of given
@@ -40,10 +40,10 @@
"""
- def __init__(self, trx_list):
+ def __cinit__(self, list trx_list):
self.trx_list = trx_list
- def forward_msg(self, src_trx, rx_msg):
+ cdef forward_msg(self, src_trx, rx_msg):
# Originating Transceiver may use frequency hopping,
# so let's precalculate its Tx frequency in advance
tx_freq = src_trx.get_tx_freq(rx_msg.fn)
diff --git a/src/target/trx_toolkit/transceiver.pyx b/src/target/trx_toolkit/transceiver.pyx
index a11a319..2918d54 100644
--- a/src/target/trx_toolkit/transceiver.pyx
+++ b/src/target/trx_toolkit/transceiver.pyx
@@ -23,6 +23,7 @@
from ctrl_if_trx import CTRLInterfaceTRX
from data_if cimport DATAInterface
+from burst_fwd cimport BurstForwarder
from udp_link cimport UDPLink
from trx_list import TRXList
@@ -295,7 +296,7 @@
# TODO: make legacy mode configurable (via argv?)
self.data_if.send_msg(msg, legacy = True)
- def clck_tick(self, fwd, fn):
+ def clck_tick(self, BurstForwarder fwd, fn):
if not self.running:
return
--
To view, visit https://gerrit.osmocom.org/c/osmocom-bb/+/40065?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: I8e5fe20ff5a9a0fbbb8ce82a7776837de1219e13
Gerrit-Change-Number: 40065
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>