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 -
WFE
is 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
SEV
is send an event. It is not the global monitor.To clear the global monitor, it is
clrex
. Aldrex
reserves the global monitor and anstrex
commits 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, thestrex
will fail if another core has reserved and committed the same memory. It is normal to re-issue anldrex
to retrieve the updated memory copy whenstrex
fails.An issue comes when a core supports pre-emption and/or interrupts. One context on the core may issue an
ldrex
and then be pre-empted by a successfulldrex/strex
pair. When the context returns, the priorldrex
is not reserving anything and thestrex
is undefined. In this case, the OS (or interrupt code) must issue aclrex
to force the original pairedstrex
to fail and retry. For a Cortex-M, the system often does an intrinsicclrex
on 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/SEV
with 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/strex
for fairness between cores.Specifically, it is valuable for a semaphore (simple flag). The 'semTake()' will do a
WFE
to sleep when it fails. The 'semGive()' will issue aSEV
to 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/strex
to 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).