7 Replies Latest reply on May 9, 2016 7:11 AM by AxLi_1746341

    Are the Queue APIs thread-safe?

      I just wanted to know if these APIs are guaranteed thread safe by the ThreadX RTOS?

       

      /** @} */

      /*****************************************************************************/

      /** @addtogroup queues       Queues

      *  @ingroup rtos

      *

      * Queue management functionss

      *

      *

      *  @{

      */

      /*****************************************************************************/

       

       

      /** Initialises a queue

      *

      * Initialises a FIFO queue

      *

      * @param queue : a pointer to the queue handle to be initialised

      * @param name  : a text string name for the queue (NULL is allowed)

      * @param message_size : size in bytes of objects that will be held in the queue

      * @param number_of_messages : depth of the queue - i.e. max number of objects in the queue

      *

      * @return    WICED_SUCCESS : on success.

      * @return    WICED_ERROR   : if an error occurred

      */

      wiced_result_t wiced_rtos_init_queue( wiced_queue_t* queue, const char* name, uint32_t message_size, uint32_t number_of_messages );

       

       

       

       

      /** Pushes an object onto a queue

      *

      * Pushes an object onto a queue

      *

      * @param queue : a pointer to the queue handle

      * @param message : the object to be added to the queue. Size is assumed to be

      *                  the size specified in @ref wiced_rtos_init_queue

      * @param timeout_ms: the number of milliseconds to wait before returning

      *

      * @return    WICED_SUCCESS : on success.

      * @return    WICED_ERROR   : if an error or timeout occurred

      */

      wiced_result_t wiced_rtos_push_to_queue( wiced_queue_t* queue, void* message, uint32_t timeout_ms );

       

       

       

       

      /** Pops an object off a queue

      *

      * Pops an object off a queue

      *

      * @param queue : a pointer to the queue handle

      * @param message : pointer to a buffer that will receive the object being

      *                  popped off the queue. Size is assumed to be

      *                  the size specified in @ref wiced_rtos_init_queue , hence

      *                  you must ensure the buffer is long enough or memory

      *                  corruption will result

      * @param timeout_ms: the number of milliseconds to wait before returning

      *

      * @return    WICED_SUCCESS : on success.

      * @return    WICED_ERROR   : if an error or timeout occurred

      */

      wiced_result_t wiced_rtos_pop_from_queue( wiced_queue_t* queue, void* message, uint32_t timeout_ms );

       

       

       

       

      /** De-initialise a queue

      *

      * Deletes a queue created with @ref wiced_rtos_init_queue

      *

      * @param queue : a pointer to the queue handle

      *

      * @return    WICED_SUCCESS : on success.

      * @return    WICED_ERROR   : if an error occurred

      */

      wiced_result_t wiced_rtos_deinit_queue( wiced_queue_t* queue );

       

       

       

       

      /** Check if a queue is empty

      *

      * @param queue : a pointer to the queue handle

      *

      * @return    WICED_SUCCESS : queue is empty.

      * @return    WICED_ERROR   : queue is not empty.

      */

      wiced_result_t wiced_rtos_is_queue_empty( wiced_queue_t* queue );

       

       

       

       

      /** Check if a queue is full

      *

      * @param queue : a pointer to the queue handle

      *

      * @return    WICED_SUCCESS : queue is full.

      * @return    WICED_ERROR   : queue is not full.

      */

      wiced_result_t wiced_rtos_is_queue_full( wiced_queue_t* queue );

       

       

       

       

      /** Get the queue occupancy

      *

      * @param queue : a pointer to the queue handle

      * @param count : pointer to integer for storing occupancy count

      *

      * @return    WICED_SUCCESS : on success.

      * @return    WICED_ERROR   : if an error occurred

      */

      wiced_result_t wiced_rtos_get_queue_occupancy( wiced_queue_t* queue, uint32_t *count );

        • 1. Re: Are the Queue APIs thread-safe?

          AFAIK they are. From ThreadX user guide:

          Message queues are the primary means of inter- thread communication in ThreadX.

          Messages are copied to a queue by tx_queue_send and are copied from a queue by tx_queue_receive. The only exception to this is when a thread is suspended while waiting for a message on an empty queue. In this case, the next message sent to the queue is placed directly into the thread’s destination area.

          I never experienced race-conditions while using queues.

          1 of 1 people found this helpful
          • 2. Re: Are the Queue APIs thread-safe?

            Thanks Olivier.

            • 3. Re: Are the Queue APIs thread-safe?
              AxLi_1746341

              Can you explain why the pointer dereference without any protection is thread safe?

               

              e.g.

              wiced_result_t wiced_rtos_get_queue_occupancy( wiced_queue_t* queue, uint32_t *count )

              {

                  *count = queue->handle.tx_queue_enqueued;

                  return WICED_SUCCESS;

              }

              • 4. Re: Are the Queue APIs thread-safe?

                Well it isn't, but that's not ThreadX API. I suppose to have a "safer" implementation, we'd need to call tx_queue_info_get and retrieve available_storage value.

                • 5. Re: Are the Queue APIs thread-safe?
                  AxLi_1746341

                  olivierdufour wrote:

                   

                  Well it isn't, but that's not ThreadX API. I suppose to have a "safer" implementation, we'd need to call tx_queue_info_get and retrieve available_storage value.

                  The ThreadX's APIs are supposed to be thread safe.

                  However, WICED's API implementation does not.

                  • 6. Re: Are the Queue APIs thread-safe?

                    I don't totally agree with you. For other functions, calls are direct to ThreadX API, so there shouldn't be any issue.

                    For the sole example of get_queue_occupancy, there might be an issue, but I'm not convinced.

                    The value you will get might be good, or greater than the actual value, but that shouldn't be a problem (you're only reading it, not writing it).

                    Since it's a single word read, there is no chance the data will be partially wrong, but it could be outdated when you process it.

                    • 7. Re: Are the Queue APIs thread-safe?
                      AxLi_1746341

                      Assume the push to queue has below logic:

                       

                      lock

                      do the real work of handling push queue

                      set queue->handle.tx_queue_enqueued

                      unlock

                       

                      Now you have a implementation of wiced_rtos_get_queue_occupancy

                      by just getting  queue->handle.tx_queue_enqueued without locking.

                      It's possible you got wrong value while the

                      "real work of handling push queue" is in progress but

                      queue->handle.tx_queue_enqueued is not updated.

                       

                      So you don't get a partially wrong value, you just get a wrong value.

                      1 of 1 people found this helpful