Runtime+SVGHMI: Add generic wakeup of threads from PLC thread to windows implementation of plc_main.c. Also added nRT_reschedule to abstract sched_yield. svghmi
authorEdouard Tisserant <edouard.tisserant@gmail.com>
Tue, 17 Aug 2021 12:29:36 +0200
branchsvghmi
changeset 3295 0375d801fff7
parent 3294 e3db472b0dfb
child 3296 3bcd5ec67521
Runtime+SVGHMI: Add generic wakeup of threads from PLC thread to windows implementation of plc_main.c. Also added nRT_reschedule to abstract sched_yield.
svghmi/svghmi.c
targets/Linux/plc_Linux_main.c
targets/Win32/plc_Win32_main.c
targets/Xenomai/plc_Xenomai_main.c
targets/beremiz.h
--- a/svghmi/svghmi.c	Mon Aug 16 22:49:08 2021 +0200
+++ b/svghmi/svghmi.c	Tue Aug 17 12:29:36 2021 +0200
@@ -137,7 +137,8 @@
 static uint32_t send_session_index;
 static int send_iterator(uint32_t index, hmi_tree_item_t *dsc)
 {
-    while(AtomicCompareExchange(&dsc->wlock, 0, 1)) sched_yield();
+    while(AtomicCompareExchange(&dsc->wlock, 0, 1))
+        nRT_reschedule();
 
     if(dsc->wstate[send_session_index] == buf_tosend)
     {
@@ -188,7 +189,9 @@
 
 void update_refresh_period(hmi_tree_item_t *dsc, uint32_t session_index, uint16_t refresh_period_ms)
 {
-    while(AtomicCompareExchange(&dsc->wlock, 0, 1)) sched_yield();
+    while(AtomicCompareExchange(&dsc->wlock, 0, 1)) 
+        nRT_reschedule();
+
     if(refresh_period_ms) {
         if(!dsc->refresh_period_ms[session_index])
         {
@@ -224,8 +227,8 @@
 
 int __init_svghmi()
 {
-    bzero(rbuf,sizeof(rbuf));
-    bzero(wbuf,sizeof(wbuf));
+    memset(rbuf,0,sizeof(rbuf));
+    memset(wbuf,0,sizeof(wbuf));
 
     svghmi_continue_collect = 1;
 
@@ -347,7 +350,8 @@
                     if((valptr + sz) <= end)
                     {
                         // rescheduling spinlock until free
-                        while(AtomicCompareExchange(&dsc->rlock, 0, 1)) sched_yield();
+                        while(AtomicCompareExchange(&dsc->rlock, 0, 1)) 
+                            nRT_reschedule();
 
                         memcpy(dst_p, valptr, sz);
                         dsc->rstate = buf_set;
--- a/targets/Linux/plc_Linux_main.c	Mon Aug 16 22:49:08 2021 +0200
+++ b/targets/Linux/plc_Linux_main.c	Tue Aug 17 12:29:36 2021 +0200
@@ -236,9 +236,6 @@
     pthread_mutex_lock(&python_mutex);
 }
 
-static pthread_cond_t svghmi_send_WakeCond = PTHREAD_COND_INITIALIZER;
-static pthread_mutex_t svghmi_send_WakeCondLock = PTHREAD_MUTEX_INITIALIZER;
-
 struct RT_to_nRT_signal_s {
     pthread_cond_t WakeCond;
     pthread_mutex_t WakeCondLock;
@@ -289,3 +286,6 @@
     return pthread_cond_signal(&sig->WakeCond);
 }
 
+void nRT_reschedule(void){
+    sched_yield();
+}
--- a/targets/Win32/plc_Win32_main.c	Mon Aug 16 22:49:08 2021 +0200
+++ b/targets/Win32/plc_Win32_main.c	Tue Aug 17 12:29:36 2021 +0200
@@ -262,3 +262,63 @@
     DeleteCriticalSection(&Atomic64CS);
 }
 
+struct RT_to_nRT_signal_s {
+    HANDLE sem;
+};
+
+typedef struct RT_to_nRT_signal_s RT_to_nRT_signal_t;
+
+#define _LogAndReturnNull(text) \
+    {\
+    	char mstr[256] = text " for ";\
+        strncat(mstr, name, 255);\
+        LogMessage(LOG_CRITICAL, mstr, strlen(mstr));\
+        return NULL;\
+    }
+
+void *create_RT_to_nRT_signal(char* name){
+    RT_to_nRT_signal_t *sig = (RT_to_nRT_signal_t*)malloc(sizeof(RT_to_nRT_signal_t));
+
+    if(!sig) 
+    	_LogAndReturnNull("Failed allocating memory for RT_to_nRT signal");
+
+    sig->sem = CreateSemaphore(
+                            NULL,           // default security attributes
+                            1,  			// initial count
+                            1,  			// maximum count
+                            NULL);          // unnamed semaphore
+
+    if(sig->sem == NULL)
+    {
+    	char mstr[256];
+        snprintf(mstr, 255, "startPLC CreateSemaphore %s error: %d\n", name, GetLastError());
+        LogMessage(LOG_CRITICAL, mstr, strlen(mstr));
+        return NULL;
+    }
+
+    return (void*)sig;
+}
+
+void delete_RT_to_nRT_signal(void* handle){
+    RT_to_nRT_signal_t *sig = (RT_to_nRT_signal_t*)handle;
+
+    CloseHandle(python_sem);
+
+    free(sig);
+}
+
+int wait_RT_to_nRT_signal(void* handle){
+    int ret;
+    RT_to_nRT_signal_t *sig = (RT_to_nRT_signal_t*)handle;
+	return WaitForSingleObject(sig->sem, INFINITE);
+}
+
+int unblock_RT_to_nRT_signal(void* handle){
+    RT_to_nRT_signal_t *sig = (RT_to_nRT_signal_t*)handle;
+	return ReleaseSemaphore(sig->sem, 1, NULL);
+}
+
+void nRT_reschedule(void){
+    SwitchToThread();
+}
+
--- a/targets/Xenomai/plc_Xenomai_main.c	Mon Aug 16 22:49:08 2021 +0200
+++ b/targets/Xenomai/plc_Xenomai_main.c	Tue Aug 17 12:29:36 2021 +0200
@@ -185,6 +185,10 @@
     return (ret == 1) ? 0 : ((ret == 0) ? EINVAL : -ret);
 }
 
+void nRT_reschedule(void){
+    sched_yield();
+}
+
 void PLC_cleanup_all(void)
 {
     if (PLC_state & PLC_STATE_TASK_CREATED) {
--- a/targets/beremiz.h	Mon Aug 16 22:49:08 2021 +0200
+++ b/targets/beremiz.h	Tue Aug 17 12:29:36 2021 +0200
@@ -30,5 +30,6 @@
 void delete_RT_to_nRT_signal(void* handle);
 int wait_RT_to_nRT_signal(void* handle);
 int unblock_RT_to_nRT_signal(void* handle);
+void nRT_reschedule(void);
 
 #endif