From 4a871a65b76ad2cf1fef3c16a1c43c200fec6976 Mon Sep 17 00:00:00 2001 From: changtengfei Date: Fri, 5 Jul 2019 13:14:48 +0200 Subject: [PATCH] OV-27. use semaphore to protect the read consistency between timeLine module and BspUart module. --- bin/openVisualizerApp.py | 8 ++++++-- openvisualizer/BspEmulator/BspUart.py | 7 ++++++- openvisualizer/SimEngine/MoteHandler.py | 7 ++++--- openvisualizer/SimEngine/SimEngine.py | 5 +++-- openvisualizer/SimEngine/TimeLine.py | 16 ++++++++++++++-- 5 files changed, 33 insertions(+), 10 deletions(-) diff --git a/bin/openVisualizerApp.py b/bin/openVisualizerApp.py index 24fcb0ea..f10e54fb 100644 --- a/bin/openVisualizerApp.py +++ b/bin/openVisualizerApp.py @@ -12,6 +12,7 @@ import os import logging import json +import threading from openvisualizer.OVtracer import OVtracer @@ -65,7 +66,10 @@ def __init__(self,confdir,datadir,logdir,simulatorMode,numMotes,trace,debug,useP if self.simulatorMode: from openvisualizer.SimEngine import SimEngine, MoteHandler - self.simengine = SimEngine.SimEngine(simTopology) + # create semaphore for reading the currentTime + self.currentTime_semaphore = threading.Semaphore() + + self.simengine = SimEngine.SimEngine(simTopology=simTopology, currentTime_semaphore=self.currentTime_semaphore) self.simengine.start() # import the number of motes from json file given by user (if the pathTopo option is enabled) @@ -89,7 +93,7 @@ def __init__(self,confdir,datadir,logdir,simulatorMode,numMotes,trace,debug,useP MoteHandler.readNotifIds(os.path.join(self.datadir, 'sim_files', 'openwsnmodule_obj.h')) self.moteProbes = [] for _ in range(self.numMotes): - moteHandler = MoteHandler.MoteHandler(oos_openwsn.OpenMote()) + moteHandler = MoteHandler.MoteHandler(oos_openwsn.OpenMote(), self.currentTime_semaphore) self.simengine.indicateNewMote(moteHandler) self.moteProbes += [moteProbe.moteProbe(mqtt_broker_address, emulatedMote=moteHandler)] elif self.iotlabmotes: diff --git a/openvisualizer/BspEmulator/BspUart.py b/openvisualizer/BspEmulator/BspUart.py index 7d292c6c..267d4466 100644 --- a/openvisualizer/BspEmulator/BspUart.py +++ b/openvisualizer/BspEmulator/BspUart.py @@ -24,11 +24,12 @@ class BspUart(BspModule.BspModule): XONXOFF_ESCAPE = 0x12 XONXOFF_MASK = 0x10 - def __init__(self,motehandler): + def __init__(self,motehandler, currentTime_semaphore): # store params self.engine = SimEngine.SimEngine() self.motehandler = motehandler + self.ct_semaphore = currentTime_semaphore # local variables self.timeline = self.engine.timeline @@ -357,9 +358,13 @@ def intr_rx(self): #======================== private ========================================= def _scheduleNextTx(self): + + self.ct_semaphore.acquire() # calculate time at which byte will get out timeNextTx = self.timeline.getCurrentTime()+float(1.0/float(self.BAUDRATE)) + + self.ct_semaphore.release() # schedule that event self.timeline.scheduleEvent( diff --git a/openvisualizer/SimEngine/MoteHandler.py b/openvisualizer/SimEngine/MoteHandler.py index 30a280fa..cf03b312 100644 --- a/openvisualizer/SimEngine/MoteHandler.py +++ b/openvisualizer/SimEngine/MoteHandler.py @@ -56,11 +56,12 @@ def notifId(s): class MoteHandler(threading.Thread): - def __init__(self,mote): + def __init__(self,mote, currentTime_semaphore): # store params - self.engine = SimEngine.SimEngine() + self.engine = SimEngine.SimEngine(currentTime_semaphore) self.mote = mote + self.ct_semaphore = currentTime_semaphore #=== local variables self.loghandler = self.engine.loghandler @@ -81,7 +82,7 @@ def __init__(self,mote): self.bspLeds = BspLeds.BspLeds(self) self.bspSctimer = BspSctimer.BspSctimer(self) self.bspRadio = BspRadio.BspRadio(self) - self.bspUart = BspUart.BspUart(self) + self.bspUart = BspUart.BspUart(self, self.ct_semaphore) # status self.booted = False self.cpuRunning = threading.Lock() diff --git a/openvisualizer/SimEngine/SimEngine.py b/openvisualizer/SimEngine/SimEngine.py index 3af6299f..7da8c311 100644 --- a/openvisualizer/SimEngine/SimEngine.py +++ b/openvisualizer/SimEngine/SimEngine.py @@ -52,7 +52,7 @@ def __new__(cls, *args, **kwargs): #======================== main ============================================ - def __init__(self,simTopology='',loghandler=logging.NullHandler()): + def __init__(self,simTopology='',loghandler=logging.NullHandler(), currentTime_semaphore=None): # don't re-initialize an instance (singleton pattern) if self._init: @@ -61,10 +61,11 @@ def __init__(self,simTopology='',loghandler=logging.NullHandler()): # store params self.loghandler = loghandler + self.ct_semaphore = currentTime_semaphore # local variables self.moteHandlers = [] - self.timeline = TimeLine.TimeLine() + self.timeline = TimeLine.TimeLine(self.ct_semaphore) self.propagation = Propagation.Propagation(simTopology) self.idmanager = IdManager.IdManager() self.locationmanager = LocationManager.LocationManager() diff --git a/openvisualizer/SimEngine/TimeLine.py b/openvisualizer/SimEngine/TimeLine.py index 1af8a3b7..2c1e083f 100644 --- a/openvisualizer/SimEngine/TimeLine.py +++ b/openvisualizer/SimEngine/TimeLine.py @@ -37,13 +37,15 @@ class TimeLine(threading.Thread): The timeline of the engine. ''' - def __init__(self): + def __init__(self,ct_semaphore): # store params - self.engine = SimEngine.SimEngine() + self.engine = SimEngine.SimEngine(ct_semaphore) + self.ct_semaphore = ct_semaphore # local variables self.currentTime = 0 # current time + self.currentTimeLock = threading.Lock() self.timeline = [] # list of upcoming events self.firstEventPassed = False self.firstEvent = threading.Lock() @@ -94,7 +96,15 @@ def run(self): output += ' - currentTime='+str(self.getCurrentTime())+'\n' self.log.warning(output) raise StopIteration(output) + + ''' + use semaphore to resolve the inconsistant reading of currentTime + - acquire right before a pop the next event + - release right after the currentTime is assigned. + ''' + self.ct_semaphore.acquire() + # pop the event at the head of the timeline event = self.timeline.pop(0) @@ -103,6 +113,8 @@ def run(self): # record the current time self.currentTime = event.atTime + + self.ct_semaphore.release() # log if self.log.isEnabledFor(logging.DEBUG):