Okay, here's an almost correct example (except for the usual
return-after-removal, plus an unlikely data race described
below). foo_1 runs first:
foo_1(...)
{
MOD_INC_USE_COUNT;
...
initiate_asynchronous_execution_of(foo_2);
rendezvous(foo_a);
/* wait until foo_2 has incremented the use count */
...
MOD_DEC_USE_COUNT;
...
rendezvous(foo_b); /* release foo_2 */
/* cool return-after-removal race */
}
foo_2(...)
{
MOD_INC_USE_COUNT;
rendezvous(foo_a);
rendezvous(foo_b);
MOD_DEC_USE_COUNT;
}
(The pseudo-primitive redezvous(X) stops execution until all
"threads" have reached that point, then they all continue.)
I think the easiest solution is to simply declare such constructs
illegal.
Note that I'm using "return" loosely - whatever is used to implement
rendezvous() may execute instructions after unblocking, which would
race with removal too. Also note that in this case, we may, at least
theoretically, data race with removal if accessing foo_b after
unblocking foo_2.
- Werner
-- _________________________________________________________________________ / Werner Almesberger, Buenos Aires, Argentina wa@almesberger.net / /_http://icapeople.epfl.ch/almesber/_____________________________________/ - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/