Getting event SF_MESSAGE_EVENT_UNUSED (0) when pending for an event

Hi one and all
In a system with s5D9 ssp 1.6.3 and ThreadX I have 13 threads.
Of these threads one could say that 8 are working "all the time" and the other has very low execution rate.
To get a quick throughput in the system we do not sleep in the end of the threads except for the sensor data feeders.
Anyway, without going into any more details, we are getting 0 as event sometimes.
Anyone who have a lead what might be wrong?
I suspect that it might ave something to do with how the message pool is being synchronized when releasing buffers.

Thank you 

  • Hi aarne,

    >Of these threads one could say that 8 are working "all the time" and the other has very low execution rate.
    >To get a quick throughput in the system we do not sleep in the end of the threads except for the sensor data feeders.
    I regret to inform you that you try to do wrong approach.
    To get best performance in multi-thread system, each thread should be suspended except it processes some works.
    So calling pend() funtion with infinite wait time is usually the best.

    I recommend you that you improve the performances of other threads.
    Maybe you use multiple objects in one of them and wait no time for a take like below?


    ---------------------------------------------
    void my_thread_entry()
    {
    UINT err;
    queue_item_t item;
    ULONG flags;

        while(1)
        {
            err = tx_queue_receive(&some_queue, TX_QUEUE *queue_ptr, (VOID *)&item, TX_NO_WAIT);
            if(err == TX_SUCCESS)
            {
                <<<codes for queue processing>>>
            }
            if(err == TX_QUEUE_EMPTY)
            {
                err = tx_event_flags_get(&_some_event_flags, 0x01, TX_OR_CLEAR, &flags, TX_NO_WAIT);
                if(err == TX_SUCCESS)
                {
                    <<<codes for event flags processing>>>
                }
            }
        }

    }
    ---------------------------------------------

  • Hi tenballs
    We are using error = g_sf_message0.p_api->pend… in all threads.
    However , after releasing the buffer after processing, there is no delay ( tx_thread_sleep (X);)
    Instead we are back at the beginning waiting for a new message.
  • In reply to aarne:

    >We are using error = g_sf_message0.p_api->pend… in all threads.
    >However , after releasing the buffer after processing, there is no delay ( tx_thread_sleep (X);)
    >Instead we are back at the beginning waiting for a new message.
    I see.

    No delay is needed for message processing.

    However arm cpu sometimes doesn't process codes in the right order for optimization.

    maybe it occurs this problem.

    Give it a try barrier instruction such as __ISB(), __DSB() and __DMB().

     

    But I have no idea why you don't wait message forever.
    Some threads have to do works even the period of no message is receved?

    Usually I use messaging framework with several kind messages like this.

    --------------------------------------------------------------
    while(1)
    {
        err = g_sf_message0.p_api->pend(g_sf_message0.p_ctrl, &main_thread_message_queue, (sf_message_header_t **) &p_message, TX_WAIT_FOREVER);
        if (err)
        {
              /** TODO: Handle error. */
         }

         switch (p_message->event_b.class_code)

         {

              case SF_MESSAGE_EVENT_NEW_DATA:

         switch (p_message->event_b.code)

              {

              case SF_MESSAGE_EVENT_CLASS_A:

                        do_class_a();

                        break;

              case SF_MESSAGE_EVENT_CLASS_B:

                        do_class_b();

                        break;

              }

         }

    }

     

     

    -------------------------------------------------------------

     

    If one thread has 3 tasks, I define 3 different messages instead of nonstop waiting messages.

    Each thread can take a break if it has no works.

    By doing so, you can get the best performance.

  • In reply to aarne:

    I'm using TX_WAIT_FOREVER also when pending.
    But the system is even so quite heavely loaded since the messages arrives at high speed. Sorry being unclear at start of this discussion.
  • In reply to aarne:

    >Sorry being unclear at start of this discussion.

    Not at all.

    Give it a try inhibiting thread preemption during buffer acquire/release.

    ------------------------------------------
    TX_THREAD *own_thread;
    UINT old_priority, dummy;
    UINT err;

    own_thread = tx_thread_identify();
    err = tx_thread_priority_change(own_thread, 0, &old_priority);
    if(err)
    __BKPT();
    << Code for buffer acquire/release >>
    err = tx_thread_priority_change(own_thread, old_priority, &dummy);
    if(err)
    __BKPT();
    ------------------------------------------

  • In reply to aarne:

    If you don't want to stop intterrupt, you can use tx_thread_preemption_change() function instead of tx_thread_priority_change().

    ------------------------------------------
    TX_THREAD *own_thread;
    UINT old_threshold, dummy;
    UINT err;

    own_thread = tx_thread_identify();
    err = tx_thread_preemption_change(own_thread, 0, &old_threshold);
    if(err)
    __BKPT();
    << Code for buffer acquire/release >>
    err = tx_thread_preemption_change(own_thread, old_threshold, &dummy);
    if(err)
    __BKPT();
    ------------------------------------------