# HG changeset patch # User Edouard Tisserant # Date 1629196176 -7200 # Node ID 0375d801fff72b03b46a6e582168a6c1d2b28827 # Parent e3db472b0dfb219b83685552998e470c97283045 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. diff -r e3db472b0dfb -r 0375d801fff7 svghmi/svghmi.c --- 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; diff -r e3db472b0dfb -r 0375d801fff7 targets/Linux/plc_Linux_main.c --- 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(); +} diff -r e3db472b0dfb -r 0375d801fff7 targets/Win32/plc_Win32_main.c --- 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(); +} + diff -r e3db472b0dfb -r 0375d801fff7 targets/Xenomai/plc_Xenomai_main.c --- 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) { diff -r e3db472b0dfb -r 0375d801fff7 targets/beremiz.h --- 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