# HG changeset patch # User greg # Date 1220774603 -7200 # Node ID 85e92d9e34a8fb1040fd8c07ca83b810688d95cd # Parent 90db933fe9560cb341e21ae720708bf472b2e173 fixed : bug in debugthreadproc (plugger.py) changes in plc_win32_main.c and plc_debug diff -r 90db933fe956 -r 85e92d9e34a8 plugger.py --- a/plugger.py Fri Sep 05 18:15:18 2008 +0200 +++ b/plugger.py Sun Sep 07 10:03:23 2008 +0200 @@ -1358,19 +1358,14 @@ self.ReArmDebugRegisterTimer() - def DebugCallerFunc(self, weakcallable, value, *args, **kwargs): - # do the call - weakcallable.SetValue(value, *args, **kwargs) - # will unlock debug thread - self.DebugThreadSlowDownLock.release() - def DebugThreadProc(self): """ This thread waid PLC debug data, and dispatch them to subscribers """ # This lock is used to avoid flooding wx event stack calling callafter self.DebugThreadSlowDownLock = Semaphore(0) - while self._connector is not None: + _break = False + while not _break and self._connector is not None: debug_tick, debug_vars = self._connector.GetTraceVariables() #print debug_tick, debug_vars self.IECdebug_lock.acquire() @@ -1383,9 +1378,9 @@ data_log.append((debug_tick, value)) for weakcallable,(args,kwargs) in WeakCallableDict.iteritems(): # delegate call to wx event loop - wx.CallAfter(self.DebugCallerFunc, weakcallable, value, *args, **kwargs) + #print weakcallable, value, args, kwargs + wx.CallAfter(weakcallable.SetValue, value, *args, **kwargs) # This will block thread if more than one call is waiting - self.DebugThreadSlowDownLock.acquire() elif debug_vars is not None: wx.CallAfter(self.logger.write_warning, "debug data not coherent %d != %d"%(len(debug_vars), len(self.TracedIECPath))) @@ -1394,8 +1389,10 @@ pass else: wx.CallAfter(self.logger.write, "Debugger disabled\n") - break + _break = True self.IECdebug_lock.release() + wx.CallAfter(self.DebugThreadSlowDownLock.release) + self.DebugThreadSlowDownLock.acquire() def _Debug(self): """ @@ -1424,9 +1421,9 @@ # for IEC_Path, idx in self._IECPathToIdx.iteritems(): # class tmpcls: # def __init__(_self): -# self.buf = None +# _self.buf = None # def setbuf(_self,buf): -# self.buf = buf +# _self.buf = buf # def SetValue(_self, value, idx, name): # self.logger.write("debug call: %s %d %s\n"%(repr(value), idx, name)) # #self.logger.write("debug call: %s %d %s %s\n"%(repr(value), idx, name, repr(self.buf))) diff -r 90db933fe956 -r 85e92d9e34a8 targets/Win32/plc_Win32_main.c --- a/targets/Win32/plc_Win32_main.c Fri Sep 05 18:15:18 2008 +0200 +++ b/targets/Win32/plc_Win32_main.c Sun Sep 07 10:03:23 2008 +0200 @@ -3,7 +3,7 @@ #include #include -long AtomicCompareExchange(long* atomicvar,long exchange, long compared) +long AtomicCompareExchange(long* atomicvar, long compared, long exchange) { return InterlockedCompareExchange(atomicvar, exchange, compared); } @@ -62,8 +62,10 @@ } } -HANDLE DebugLock; HANDLE PLC_thread; +HANDLE debug_sem; +HANDLE wait_sem; +#define MAX_SEM_COUNT 10 int startPLC(int argc,char **argv) { @@ -71,12 +73,24 @@ /* Translate PLC's microseconds to Ttick nanoseconds */ Ttick = 1000000 * maxval(common_ticktime__,1); - DebugLock = CreateMutex( - NULL, // default security attributes - FALSE, // initially not owned - NULL); // unnamed mutex + debug_sem = CreateSemaphore( + NULL, // default security attributes + 1, // initial count + MAX_SEM_COUNT, // maximum count + NULL); // unnamed semaphore + if (debug_sem == NULL) + { + printf("CreateMutex error: %d\n", GetLastError()); + return; + } + + wait_sem = CreateSemaphore( + NULL, // default security attributes + 0, // initial count + MAX_SEM_COUNT, // maximum count + NULL); // unnamed semaphore - if (DebugLock == NULL) + if (wait_sem == NULL) { printf("CreateMutex error: %d\n", GetLastError()); return; @@ -99,30 +113,60 @@ } return 0; } +static int __debug_tick; + +int TryEnterDebugSection(void) +{ + //printf("TryEnterDebugSection\n"); + return WaitForSingleObject(debug_sem, 0) == WAIT_OBJECT_0; +} + +void LeaveDebugSection(void) +{ + ReleaseSemaphore(debug_sem, 1, NULL); + //printf("LeaveDebugSection\n"); +} int stopPLC() { runplcloop = 0; WaitForSingleObject(PLC_thread, INFINITE); + __cleanup(); + __debug_tick = -1; + ReleaseSemaphore(wait_sem, 1, NULL); + CloseHandle(debug_sem); + CloseHandle(wait_sem); + CloseHandle(PLC_timer); CloseHandle(PLC_thread); - CloseHandle(DebugLock); - CloseHandle(PLC_timer); - __cleanup(); } /* from plc_debugger.c */ -void WaitDebugData() +int WaitDebugData() { - DWORD dwWaitResult; - dwWaitResult = WaitForSingleObject( - DebugLock, // handle to mutex - INFINITE); // no time-out interval + WaitForSingleObject(wait_sem, INFINITE); + return __debug_tick; } /* Called by PLC thread when debug_publish finished * This is supposed to unlock debugger thread in WaitDebugData*/ void InitiateDebugTransfer() { - /* signal debugger thread to continue*/ - ReleaseMutex(DebugLock); + /* Leave debugger section */ + ReleaseSemaphore(debug_sem, 1, NULL); + /* remember tick */ + __debug_tick = __tick; + /* signal debugger thread it can read data */ + ReleaseSemaphore(wait_sem, 1, NULL); } + +void suspendDebug() +{ + /* Prevent PLC to enter debug code */ + WaitForSingleObject(debug_sem, INFINITE); +} + +void resumeDebug() +{ + /* Let PLC enter debug code */ + ReleaseSemaphore(debug_sem, 1, NULL); +} diff -r 90db933fe956 -r 85e92d9e34a8 targets/plc_debug.c --- a/targets/plc_debug.c Fri Sep 05 18:15:18 2008 +0200 +++ b/targets/plc_debug.c Sun Sep 07 10:03:23 2008 +0200 @@ -53,7 +53,11 @@ void __init_debug() { %(variables_pointer_type_table_initializer)s -}; +AtomicCompareExchange( + &buffer_state, + BUFFER_BUSY, + BUFFER_FREE); +} void __cleanup_debug() {