--- 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()
{