Change in osmocom-bb[master]: trx_toolkit/clck_gen.py: refactor CLCKGen to use a single thread

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

fixeria gerrit-no-reply at lists.osmocom.org
Sat Nov 23 19:25:21 UTC 2019


fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmocom-bb/+/16177 )


Change subject: trx_toolkit/clck_gen.py: refactor CLCKGen to use a single thread
......................................................................

trx_toolkit/clck_gen.py: refactor CLCKGen to use a single thread

The previous approach was based on threading.Timer, so on each clock
iteration one thread spawned another new thread.  So far it worked
well, but such frequent spawning involves an additional overhead.

After this change, CLCKGen.start() allocates and starts a new thread,
that periodically sends clock indications and sleep()s during the
indication intervals.  The CLCKGen.stop() in its turn terminates
that thread and frees the memory.

Change-Id: Ibe477eb0a1ee2193c1ff16452a407be7e858b2ef
---
M src/target/trx_toolkit/clck_gen.py
M src/target/trx_toolkit/transceiver.py
2 files changed, 41 insertions(+), 22 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/77/16177/1

diff --git a/src/target/trx_toolkit/clck_gen.py b/src/target/trx_toolkit/clck_gen.py
index c58d8bd..92ca217 100755
--- a/src/target/trx_toolkit/clck_gen.py
+++ b/src/target/trx_toolkit/clck_gen.py
@@ -4,7 +4,7 @@
 # TRX Toolkit
 # Simple TDMA frame clock generator
 #
-# (C) 2017-2018 by Vadim Yanitskiy <axilirator at gmail.com>
+# (C) 2017-2019 by Vadim Yanitskiy <axilirator at gmail.com>
 #
 # All Rights Reserved
 #
@@ -22,13 +22,14 @@
 # with this program; if not, write to the Free Software Foundation, Inc.,
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
-APP_CR_HOLDERS = [("2017-2018", "Vadim Yanitskiy <axilirator at gmail.com>")]
+APP_CR_HOLDERS = [("2017-2019", "Vadim Yanitskiy <axilirator at gmail.com>")]
 
 import logging as log
+import threading
 import signal
+import time
 
 from app_common import ApplicationBase
-from threading import Timer
 from udp_link import UDPLink
 from gsm_shared import *
 
@@ -40,32 +41,54 @@
 	# Average loop back delay
 	LO_DELAY_US = 90.0
 
-	# State variables
-	timer = None
-
 	def __init__(self, clck_links, clck_start = 0, ind_period = 102):
+		# This event is needed to control the thread
+		self._breaker = threading.Event()
+		self._thread = None
+
 		self.clck_links = clck_links
 		self.ind_period = ind_period
 		self.clck_start = clck_start
-		self.clck_src = clck_start
 
 		# Calculate counter time
 		self.ctr_interval  = self.GSM_FRAME_US - self.LO_DELAY_US
 		self.ctr_interval /= self.SEC_DELAY_US
 		self.ctr_interval *= self.ind_period
 
+	@property
+	def running(self):
+		if self._thread is None:
+			return False
+		return self._thread.isAlive()
+
 	def start(self):
-		# Send the first indication
-		self.send_clck_ind()
+		# Make sure we won't start two threads
+		assert(self._thread is None)
+
+		# (Re)set the clock counter
+		self.clck_src = self.clck_start
+
+		# Initialize and start a new thread
+		self._thread = threading.Thread(target = self._worker)
+		self._thread.start()
 
 	def stop(self):
-		# Stop pending timer
-		if self.timer is not None:
-			self.timer.cancel()
-			self.timer = None
+		# No thread, no problem ;)
+		if self._thread is None:
+			return
 
-		# Reset the clock source
-		self.clck_src = self.clck_start
+		# Stop the thread first
+		self._breaker.set()
+		self._thread.join()
+
+		# Free memory, reset breaker
+		del self._thread
+		self._thread = None
+		self._breaker.clear()
+
+	def _worker(self):
+		while not self._breaker.wait(self.ctr_interval):
+			self.send_clck_ind()
 
 	def send_clck_ind(self):
 		# Keep clock cycle
@@ -87,10 +110,6 @@
 		# Increase frame count
 		self.clck_src += self.ind_period
 
-		# Schedule a new indication
-		self.timer = Timer(self.ctr_interval, self.send_clck_ind)
-		self.timer.start()
-
 # Just a wrapper for independent usage
 class Application(ApplicationBase):
 	def __init__(self):
@@ -102,7 +121,7 @@
 
 		# Configure logging
 		log.basicConfig(level = log.DEBUG,
-			format = "[%(levelname)s] %(filename)s:%(lineno)d %(message)s")
+			format = "[%(levelname)s] TID#%(thread)s %(filename)s:%(lineno)d %(message)s")
 
 	def run(self):
 		self.link = UDPLink("127.0.0.1", 5800, "0.0.0.0", 5700)
diff --git a/src/target/trx_toolkit/transceiver.py b/src/target/trx_toolkit/transceiver.py
index 37680e7..b1a5c11 100644
--- a/src/target/trx_toolkit/transceiver.py
+++ b/src/target/trx_toolkit/transceiver.py
@@ -172,10 +172,10 @@
 				# Transceiver was started
 				clck_links.append(self.clck_if)
 
-			if not self.clck_gen.timer and len(clck_links) > 0:
+			if not self.clck_gen.running and len(clck_links) > 0:
 				log.info("Starting clock generator")
 				self.clck_gen.start()
-			elif self.clck_gen.timer and not clck_links:
+			elif self.clck_gen.running and not clck_links:
 				log.info("Stopping clock generator")
 				self.clck_gen.stop()
 

-- 
To view, visit https://gerrit.osmocom.org/c/osmocom-bb/+/16177
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmocom-bb
Gerrit-Branch: master
Gerrit-Change-Id: Ibe477eb0a1ee2193c1ff16452a407be7e858b2ef
Gerrit-Change-Number: 16177
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <axilirator at gmail.com>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20191123/3d0e92c5/attachment.htm>


More information about the gerrit-log mailing list