Problems with ADL semaphores


#1

Hi all,

I’ve got a problem with ADL semaphores. A little background: I connect a small RS232-capable sensor to UART1 of my Fastrack Supreme 20.
This sensor is polled automatically by the modem to generate alarm notifications when necessary. Additionally, the sensor can be queried interactively by using self-written AT commands via the USB serial interface of the modem. Communication with the sensor always involves sending a query and receiving a response. So far, so good.

The task setup in my OpenAT application is as follows:

  • Task #0: AT command processing, etc
  • Task #1: processing of asynchronous UART1 I/O
  • Task #2: periodic query of the sensor

I use a semaphore (that simulates a mutex) to block sensor requests while a different request is currently being processed. This should work well because (a) requests originate from different tasks, so there should be no deadlock, and (b) requests from one task can’t be issued recursively, this is assured.

Processing a single sensor request involves the following steps:

  • the calling task consumes the semaphore
  • the calling tasks writes bytes to the UART (asynchronously)
  • Task #1 receives indication that write is completed (via message queue)
  • Task #1 programs a timeout for the response
  • Task #1 receives indication about response received (or timeout) via message queue
  • Task #1 does post-processing and produces the semaphore

This scheme works extremely well as long as there are no concurrent requests involved. The problem I see is that this scheme somehow deadlocks in the following situation:

  • Task #2 consumes the semaphore
  • Task #2 writes data to the UART
  • Task #1 is notified that write is completed
  • Task #0 tries to consume the semaphore and is suspended
  • the on_receive_complete UART callback is invoked and sends a message to Task #1
  • Task #1 never wakes up and cannot procuce the semaphore

I would expect Task #0 to be suspended by adl_semConsume[Delay] so that there’s no reason why Task #1 should be unable to run. However, (verified by traces), this is exactly what I DO see. Am I doing something wrong?

I would love to stick with the semaphore (instead of, say, having a third process that just serializes sensor requests), because the semaphore gives an effective rate-limiting at the request-producer side, which may be important if the sensor is not responding and we have to wait for the timeouts to occur and requests arrive faster than we can process them.


#2

Hi,

During using semaphore service,sometimes “priority inversion” comes into picture and should be handled at the application level.

Task priority and the sequence to use semaphore should be properly handled.

Thanks.


#3

Hi,

I have not yet figured out why a priority inversion could happen in my case, since I don’t have an obvious two-lock situation here. It’s just that my Task #1 doesn’t wake up when a message is sent to it and Task #0 is concurrently waiting on the semaphore. The only explanation I have is that maybe task #0 is somehow required for dispatching messages between tasks (which isn’t stated anywhere in the documentation).

If this is the case, I would kindly request to clearly state in the documentation that semaphores are NOT to be consumed by task #0 (this has already been done for the events service, which also isn’t usable from task #0).

Best regards,