--- a/svghmi/svghmi.c Tue Oct 26 11:41:03 2021 +0200
+++ b/svghmi/svghmi.c Fri Oct 29 09:45:39 2021 +0200
@@ -39,6 +39,8 @@
static int global_write_dirty = 0;
+static long hmitree_rlock = 0; +static long hmitree_wlock = 0; @@ -46,7 +48,6 @@
buf_state_t wstate[MAX_CONNECTIONS];
/* zero means not subscribed */
@@ -54,7 +55,6 @@
uint16_t age_ms[MAX_CONNECTIONS];
@@ -83,17 +83,13 @@
static int write_iterator(uint32_t index, hmi_tree_item_t *dsc)
- uint32_t session_index = 0;
- if(AtomicCompareExchange(&dsc->wlock, 0, 1) == 0) {
- void *dest_p = &wbuf[dsc->buf_index];
+ uint32_t session_index = 0; void *real_value_p = NULL;
- void *visible_value_p = UnpackVar(dsc, &real_value_p, &flags);
- USINT sz = __get_type_enum_size(dsc->type);
- if(__Is_a_string(dsc)){
- sz = ((STRING*)visible_value_p)->len + 1;
+ void *visible_value_p = NULL; while(session_index < MAX_CONNECTIONS) {
if(dsc->wstate[session_index] == buf_set){
/* if being subscribed */
@@ -107,13 +103,39 @@
- if(dsc->wstate[session_index] == buf_new /* just subscribed
- or already subscribed having value change */
- || (dsc->refresh_period_ms[session_index] > 0
- && (value_changed || (value_changed=memcmp(dest_p, visible_value_p, sz))) != 0)){
- /* if not already marked/signaled, do it */
+ /* variable is sample only if just subscribed + or already subscribed and having value change */ + int just_subscribed = dsc->wstate[session_index] == buf_new; + int already_subscribed = dsc->refresh_period_ms[session_index] > 0; + if(already_subscribed){ + visible_value_p = UnpackVar(dsc, &real_value_p, &flags); + if(__Is_a_string(dsc)){ + sz = ((STRING*)visible_value_p)->len + 1; + sz = __get_type_enum_size(dsc->type); + dest_p = &wbuf[dsc->buf_index]; + value_changed = memcmp(dest_p, visible_value_p, sz) != 0; + do_sample = value_changed; if(dsc->wstate[session_index] != buf_set && dsc->wstate[session_index] != buf_tosend) {
- if(dsc->wstate[session_index] == buf_new || ticktime_ms > dsc->refresh_period_ms[session_index]){
+ if(dsc->wstate[session_index] == buf_new \ + || ticktime_ms > dsc->refresh_period_ms[session_index]){ dsc->wstate[session_index] = buf_tosend;
@@ -128,7 +150,6 @@
/* copy value if changed (and subscribed) */
memcpy(dest_p, visible_value_p, sz);
- AtomicCompareExchange(&dsc->wlock, 1, 0);
// else ... : PLC can't wait, variable will be updated next turn
@@ -137,9 +158,6 @@
static uint32_t send_session_index;
static int send_iterator(uint32_t index, hmi_tree_item_t *dsc)
- while(AtomicCompareExchange(&dsc->wlock, 0, 1))
if(dsc->wstate[send_session_index] == buf_tosend)
uint32_t sz = __get_type_enum_size(dsc->type);
@@ -159,39 +177,29 @@
printf("BUG!!! %%d + %%ld + %%d > %%ld \n", sbufidx, sizeof(uint32_t), sz, sizeof(sbuf));
- AtomicCompareExchange(&dsc->wlock, 1, 0);
- AtomicCompareExchange(&dsc->wlock, 1, 0);
static int read_iterator(uint32_t index, hmi_tree_item_t *dsc)
- if(AtomicCompareExchange(&dsc->rlock, 0, 1) == 0)
+ if(dsc->rstate == buf_set) - if(dsc->rstate == buf_set)
- void *src_p = &rbuf[dsc->buf_index];
- void *real_value_p = NULL;
- void *visible_value_p = UnpackVar(dsc, &real_value_p, &flags);
- memcpy(real_value_p, src_p, __get_type_enum_size(dsc->type));
- dsc->rstate = buf_free;
- AtomicCompareExchange(&dsc->rlock, 1, 0);
+ void *src_p = &rbuf[dsc->buf_index]; + void *real_value_p = NULL; + void *visible_value_p = UnpackVar(dsc, &real_value_p, &flags); + memcpy(real_value_p, src_p, __get_type_enum_size(dsc->type)); + dsc->rstate = buf_free; - // else ... : PLC can't wait, variable will be updated next turn
void update_refresh_period(hmi_tree_item_t *dsc, uint32_t session_index, uint16_t refresh_period_ms)
- while(AtomicCompareExchange(&dsc->wlock, 0, 1))
if(!dsc->refresh_period_ms[session_index])
@@ -201,7 +209,6 @@
dsc->wstate[session_index] = buf_free;
dsc->refresh_period_ms[session_index] = refresh_period_ms;
- AtomicCompareExchange(&dsc->wlock, 1, 0);
static uint32_t reset_session_index;
@@ -250,13 +257,19 @@
- traverse_hmi_tree(read_iterator);
+ if(AtomicCompareExchange(&hmitree_rlock, 0, 1) == 0) { + traverse_hmi_tree(read_iterator); + AtomicCompareExchange(&hmitree_rlock, 1, 0); - traverse_hmi_tree(write_iterator);
+ if(AtomicCompareExchange(&hmitree_wlock, 0, 1) == 0) { + traverse_hmi_tree(write_iterator); + AtomicCompareExchange(&hmitree_wlock, 1, 0); SVGHMI_WakeupFromRTThread();
@@ -274,17 +287,25 @@
send_session_index = session_index;
+ while(AtomicCompareExchange(&hmitree_wlock, 0, 1)){ if((res = traverse_hmi_tree(send_iterator)) == 0)
if(sbufidx > HMI_HASH_SIZE){
memcpy(&sbuf[0], &hmi_hash[0], HMI_HASH_SIZE);
+ AtomicCompareExchange(&hmitree_wlock, 1, 0); + AtomicCompareExchange(&hmitree_wlock, 1, 0); // printf("collected BAD result %%d\n", res);
+ AtomicCompareExchange(&hmitree_wlock, 1, 0); @@ -294,6 +315,7 @@
@@ -320,10 +342,29 @@
+ cmd_from_JS cmd_old = unset; + cmd_from_JS cmd = unset; - cmd_from_JS cmd = *(cursor++);
+ AtomicCompareExchange(&hmitree_wlock, 1, 0); + AtomicCompareExchange(&hmitree_rlock, 1, 0); @@ -350,23 +391,28 @@
// rescheduling spinlock until free
- while(AtomicCompareExchange(&dsc->rlock, 0, 1))
+ while(AtomicCompareExchange(&hmitree_rlock, 0, 1)){ memcpy(dst_p, valptr, sz);
- AtomicCompareExchange(&dsc->rlock, 1, 0);
progress = sz + sizeof(uint32_t) /* index */;
@@ -375,6 +421,12 @@
reset_session_index = session_index;
+ while(AtomicCompareExchange(&hmitree_wlock, 0, 1)){ traverse_hmi_tree(reset_iterator);
@@ -386,12 +438,19 @@
if(index < HMI_ITEM_COUNT)
+ while(AtomicCompareExchange(&hmitree_wlock, 0, 1)){ hmi_tree_item_t *dsc = &hmi_tree_item[index];
update_refresh_period(dsc, session_index, refresh_period_ms);
progress = sizeof(uint32_t) /* index */ +
@@ -404,6 +463,17 @@
+ AtomicCompareExchange(&hmitree_wlock, 1, 0); + AtomicCompareExchange(&hmitree_rlock, 1, 0);