This is for Ralf and any other MIPS/Linux kernel
hackers who may be on the list.
Some time ago, I fixed the assembler macros
for waking_non_zero_interruptable and down_trylock
to be correct(ish) for MIPSEL and MIPSEB, but
there remained the issue of their requiring the use
of 64-bit instructions to work - they "cheat" by using
the same ll/sc pair to update both the count and the
waking field of the semaphore.
To make it work on 32-bit CPUs, I looked at using
the x386 model, but that one uses interrupt disables
and is intrinsically SMP-unsafe. Now, looking at
the comments and studying the code a bit,
it *seems* that the issue is not so much a race
condition between updates of the waking and
count fields, but a race with other functions that
may be updating the waking field. CAN ANYONE
CONFIRM OR DENY THAT?
If it's true, it looks to me that by inventing one
new primitive in atomic.h, atomic_sub_and_return_if_gtz(),
a) Eliminate the need for an assembly macro dedicated
to waking_non_zero, which maps directly to the new macro.
b) Make it possible to do waking_non_zero_interruptible in
C, as all the examinations/updates of sem->waking can
be made atomic
c) Likewise simplify down_trylock() and
d) Make waking_non_zero_trylock() SMP safe.
I've coded this up for experimentation, and will provide
the sources (at least relative to 2.2.12) to any interested
parties, but I'd really like someone who has worked
intimately with the kernel semaphores to tell me if
there really are races between updates of sem->waking
and sem->count, and if they exist, what they are!
Kevin D. Kissell
MIPS Technologies European Architecture Lab