Can Semaphore lose data?

We use some serial devices for RS-485 and Modbus communication as well as UDP and TCP. To handle all these in a sane way we use the ISR mechanics available for sockets and the serial devices. The ISR handlers will basically just set some flags and call Semaphore.release(). In the other end of the semaphore is a thread that just sits and waits doing Semaphore.acquire() and then handles whatever task needs to be handled. This works very and allows the ISR handlers to be extremely simple and not do anything dangerous.

However, we now see that sometimes calling release() on the semaphore does not lead to the worker thread’s acquire() to succeed, the thread simply sits there forever and no releasing will get it to do anything anymore. To trigger this the application needs to run for hours or days. In my latest tests it’s taken about 24h to trigger it, which makes debugging somewhat interesting.

Is there something inherently bad with this approach? Normally I would protect everything with a Mutex, but it can’t be used in an ISR context. I would assume that there should be errors way faster if the whole approach was wrong (there is a fair deal of data flowing constantly). It feels a bit as if the semaphore somehow dies internally, but without crashing.

Would event flags be better or more safe here or can anyone recommend some better pattern for having an ISR offload work to a thread? Our memory is extremely tight, so preferably nothing too elaborate or which requires dynamic memory allocation.

We’re using MBed 5.15.5 on an LPC1768.