beremiz

Try using a semaphore instead of pthread_cond.
svghmi
2019-12-09, Edouard Tisserant
8cc70f7f525a
Parents 7825a76f5ffb
Children af68c0d6dcbe
Try using a semaphore instead of pthread_cond.
Finally crash when (non-python, cobalt-pthread_created) thread calls callback.
  • +39 -17
    svghmi/svghmi.c
  • --- a/svghmi/svghmi.c Mon Dec 09 09:42:07 2019 +0100
    +++ b/svghmi/svghmi.c Mon Dec 09 09:45:40 2019 +0100
    @@ -1,6 +1,6 @@
    #include <pthread.h>
    #include <errno.h>
    -#include <pthread.h>
    +#include <semaphore.h>
    #include "iec_types_all.h"
    #include "POUS.h"
    #include "config.h"
    @@ -82,6 +82,8 @@
    static int write_iterator(uint32_t index, hmi_tree_item_t *dsc)
    {
    +
    + printf("write %%d \n",ticktime_ms );
    if(AtomicCompareExchange(&dsc->wlock, 0, 1) == 0)
    {
    if(dsc->wstate == buf_set){
    @@ -106,6 +108,7 @@
    if(dsc->wstate == buf_new || memcmp(dest_p, visible_value_p, sz) != 0){
    /* copy and flag as set */
    memcpy(dest_p, visible_value_p, sz);
    + printf("change or new %%d \n", dsc->wstate);
    if(dsc->wstate == buf_new || dsc->wstate == buf_free) {
    if(dsc->wstate == buf_new || ticktime_ms > dsc->refresh_period_ms){
    dsc->wstate = buf_tosend;
    @@ -174,6 +177,7 @@
    void update_refresh_period(hmi_tree_item_t *dsc, uint16_t refresh_period_ms)
    {
    while(AtomicCompareExchange(&dsc->wlock, 0, 1)) sched_yield();
    + printf("subsc \n");
    dsc->refresh_period_ms = refresh_period_ms;
    if(refresh_period_ms) {
    /* TODO : maybe only if was null before for optimization */
    @@ -190,8 +194,9 @@
    return 0;
    }
    -static pthread_cond_t svghmi_send_WakeCond = PTHREAD_COND_INITIALIZER;
    -static pthread_mutex_t svghmi_send_WakeCondLock = PTHREAD_MUTEX_INITIALIZER;
    +static sem_t svghmi_send_WakeSem;
    +// static pthread_cond_t svghmi_send_WakeCond = PTHREAD_COND_INITIALIZER;
    +// static pthread_mutex_t svghmi_send_WakeCondLock = PTHREAD_MUTEX_INITIALIZER;
    static pthread_mutex_t svghmi_send_collect_callback_lock = PTHREAD_MUTEX_INITIALIZER;
    pthread_t svghmi_send_collect_thread;
    @@ -204,18 +209,23 @@
    {
    while(1){
    int do_collect;
    - int ret = pthread_mutex_lock(&svghmi_send_WakeCondLock);
    - if(continue_collect) {
    - ret = pthread_cond_wait(&svghmi_send_WakeCond, &svghmi_send_WakeCondLock);
    - do_collect = continue_collect; // continue_collect might have changed
    - }else{
    - do_collect = 0;
    - }
    + printf("Yelllllo\n");
    + sem_wait(&svghmi_send_WakeSem);
    + while(sem_trywait(&svghmi_send_WakeSem) == 0);
    + // int ret = pthread_mutex_lock(&svghmi_send_WakeCondLock);
    + // printf("mutex lock %%d \n ",ret);
    + // if(continue_collect) {
    + // // ret = pthread_cond_wait(&svghmi_send_WakeCond, &svghmi_send_WakeCondLock);
    + // // printf("condwait %%d \n",ret);
    + // do_collect = continue_collect; // continue_collect might have changed
    + // }else{
    + // do_collect = 0;
    + // }
    - pthread_mutex_unlock(&svghmi_send_WakeCondLock);
    + // pthread_mutex_unlock(&svghmi_send_WakeCondLock);
    - if(do_collect) {
    + if(continue_collect) {
    pthread_mutex_lock(&svghmi_send_collect_callback_lock);
    if(svghmi_send_collect_callback) {
    int res;
    @@ -226,7 +236,7 @@
    memcpy(&sbuf[0], &hmi_hash[0], HMI_HASH_SIZE);
    char *ptr = &sbuf[0];
    uint32_t size = sbufidx;
    - svghmi_send_collect_callback(size, ptr);
    + //svghmi_send_collect_callback(size, ptr);
    }
    }
    }
    @@ -243,12 +253,16 @@
    {
    bzero(rbuf,sizeof(rbuf));
    bzero(wbuf,sizeof(wbuf));
    +
    + sem_init(&svghmi_send_WakeSem, 0, 0);
    +
    continue_collect = 1;
    int res = pthread_create(&svghmi_send_collect_thread,
    NULL,
    (void*) &svghmi_send_collect_thread_proc,
    NULL);
    + printf("res %%d\n",res);
    return 0;
    }
    @@ -256,12 +270,14 @@
    void __cleanup_svghmi()
    {
    - pthread_mutex_lock(&svghmi_send_WakeCondLock);
    + // pthread_mutex_lock(&svghmi_send_WakeCondLock);
    continue_collect = 0;
    - pthread_cond_signal(&svghmi_send_WakeCond);
    - pthread_mutex_unlock(&svghmi_send_WakeCondLock);
    + // pthread_cond_signal(&svghmi_send_WakeCond);
    + // pthread_mutex_unlock(&svghmi_send_WakeCondLock);
    + sem_post(&svghmi_send_WakeSem);
    pthread_join(svghmi_send_collect_thread, NULL);
    + sem_destroy(&svghmi_send_WakeSem);
    }
    void __retrieve_svghmi()
    @@ -274,7 +290,10 @@
    global_write_dirty = 0;
    traverse_hmi_tree(write_iterator);
    if(global_write_dirty) {
    - pthread_cond_signal(&svghmi_send_WakeCond);
    + printf("got dirty\n");
    + sem_post(&svghmi_send_WakeSem);
    + //int res = pthread_cond_signal(&svghmi_send_WakeCond);
    + //printf("dirty %%d\n", res);
    }
    }
    @@ -287,6 +306,7 @@
    pthread_mutex_unlock(&svghmi_send_collect_callback_lock);
    }
    +
    typedef enum {
    setval = 0,
    reset = 1,
    @@ -298,6 +318,8 @@
    const uint8_t* end = ptr + size;
    + printf("svghmi_recv_dispatch !!\n");
    +
    /* match hmitree fingerprint */
    if(size <= HMI_HASH_SIZE || memcmp(ptr, hmi_hash, HMI_HASH_SIZE) != 0)
    {