Am implementing a global monitor for exclusive access (for ARM cores).
Query- if a particular exclusive transaction is successful, should I signal a clear on the global monitor?
In the case above is required, a concern is this would cause other cores which are in the WFE state to be unnecessarily woken up, even if they have nothing to do with a different core's successful exclusive transaction.
TL;DR -
WFEis wait for event. Events and the global monitor are different orthogonal concepts. They have synergy when used together, but are completely seperate.No, this case is successful and the global monitor is automatically cleared. The 'WFE' is different from the global monitor for exclusive access. The
SEVis send an event. It is not the global monitor.To clear the global monitor, it is
clrex. Aldrexreserves the global monitor and anstrexcommits the global monitor if successful. The monitor itself is on the ''global'' state of memory. Each CPU/core can have different working copies of the memory to update. Normally, thestrexwill fail if another core has reserved and committed the same memory. It is normal to re-issue anldrexto retrieve the updated memory copy whenstrexfails.An issue comes when a core supports pre-emption and/or interrupts. One context on the core may issue an
ldrexand then be pre-empted by a successfulldrex/strexpair. When the context returns, the priorldrexis not reserving anything and thestrexis undefined. In this case, the OS (or interrupt code) must issue aclrexto force the original pairedstrexto fail and retry. For a Cortex-M, the system often does an intrinsicclrexon a return from interrupt, but you need to read your system documentation. For some Cortex-A systems, you need aclrex(and the same for normal/secure worlds).What is your use case for using
WFE/SEVwith theldrex/strex? I think it needs to be a simple flag as oppose to some lock free data structure. I guess the WFE/SEV could augment the plainldrex/strexfor fairness between cores.Specifically, it is valuable for a semaphore (simple flag). The 'semTake()' will do a
WFEto sleep when it fails. The 'semGive()' will issue aSEVto wake all sleepers in a 'semTake()'. If a core has gained access to the semaphore, having the other cores sleep will result in a fasterldrex/strexto put the semaphore to it's free state as well as save power on the blocked cores. (Rosetta, vxWorks/Posix:semGive/sem_post,semTake/sem_wait. The vxWorks names seem best for a binary semaphore or mutex depending on pendatics... but these are the ARM primitives).