fixed : bug in debugthreadproc (plugger.py)
authorgreg
Sun, 07 Sep 2008 10:03:23 +0200
changeset 244 85e92d9e34a8
parent 243 90db933fe956
child 245 60a221d72152
fixed : bug in debugthreadproc (plugger.py)
changes in plc_win32_main.c and plc_debug
plugger.py
targets/Win32/plc_Win32_main.c
targets/plc_debug.c
--- 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)))
--- 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 <time.h>
 #include <windows.h>
 
-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);
+}
--- 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()
 {