This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

sd_mutex implementation question

I am using a mutex to protect a serial debug printout.

Is it safe to use sd_mutex_acquire in a blocking manner, provided it is only called from main and softdevice callbacks  (interrupt pri level 3), or is there a scenario in which this could cause a problem?

What happens if a softdevice callback functions needs a mutex-protected resource that main currently has locked; will the callback task be suspended and main (eventually) scheduled?

  • When you say blocking manner, i am assuming you say that you loop until you get it, right? I think this is safe to do in main context. In the softdevice callback, which is the SWI2 interrupt handler, you should not do this because if you wait long enough, then your program will miss other incoming SWI2 events from softdevice. This could result that if you are using sd_app_evt_wait() hoping to get an event, then your system could sleep for ever as that event was notified by softdevice but just was lost in the blocking wait.

    This is something I could think of, maybe others will add more reasons, but It is recommended not to do this in any interrupt context with priority higher than or equal to APP_PRIORITY_LOW (3).

  • The answer to the second paragraph is no. There's no operating system or preemptive scheduling here, if main (thread mode) is running, acquires the mutex, and is holding it whilst it's doing something, and anything of higher priority interrupts it, that handler mode code will run to completion before control returns to main. If the handler mode code spins waiting to get the mutex, it will spin forever because main will never get to run and release it again.

    There's not much you can do there, you can't yield or sleep and wait for the mutex, you have to exit the interrupt routine and schedule some way to go return to it later after the code holding it has released it. That's not easy either, if you just re-raise the interrupt, then you'll just instantly be called again and the other code still won't get a chance to run

    Spinlocks don't work on cortex processors (without RTXs)

    Thinking about it more, if you are using a mutex for the usual case, grabbing it, doing a small amount of work, and then releasing it again; if you ever find the mutex locked when you need it, it must be currently owned by something of lower priority than you, because if it wasn't, you wouldn't be running, the other piece of code would be.

    This makes mutexes less useful than you'd immediately think. The only real use case I can think of is a process which runs periodically and can defer work to the next 'tick'. if it doesn't get the mutex, it exits and tries again the next time. When it eventually does get it, it runs all the work it has available.

  • RK, you and I understood the question in a different way. I thought that the question is not regarding the mutex deadlock case, but rather about the side effects of blocking wait on a mutex in interrupt context. But now ned has got information with everything covered :)

  • OK, I imagined there was some sort of preemptive scheduling involved since there was a mutex implementation. But if the callbacks are handled strictly by the SWI2 interrupt handler I understand why using the mutex is not a viable solution.

    Thanks a lot for the thorough answers guys!

Related