[sgen] Fix hazard pointer free deadlock problem. Fixes #9828.
authorMark Probst <mark.probst@gmail.com>
Fri, 1 Feb 2013 15:46:33 +0000 (07:46 -0800)
committerMark Probst <mark.probst@gmail.com>
Sun, 3 Feb 2013 00:52:40 +0000 (16:52 -0800)
commit56a6ae2bd0ac3b9ebf8ad9daec6aca484b7e487b
tree93be81daaeb2dd87db2f65696bc9cd488fb36a58
parent22d18ea249abcc4813efb853e3c0a53e345781b3
[sgen] Fix hazard pointer free deadlock problem.  Fixes #9828.

The hazard pointer code, which assists in lock free algorithms, tries
to free some data it had to keep around (because other threads were
still using it) whenever it is invoked.  Obviously, the code that frees
data must never lock, or else the code that uses hazard pointers might
lock, as well.

The JIT info table pointer code uses malloc/free to allocate its memory,
so its free function uses free(), which might lock.  Even worse, it takes
the domain lock.  (The JIT info table is lock-free for readers, not for writers,
which explains why it uses hazard pointers.)

To solve the problem we separate hazard pointers into those whose free
functions might lock, and those who will not, and we provide the information
on whether we're currently in a context where locking is permissible.  If it isn't,
no free function which might lock must be called.  To make sure they are
called eventually we try to free a few after restarting the world in SGen, at
which point locking is allowed.
mono/metadata/domain.c
mono/metadata/sgen-stw.c
mono/utils/hazard-pointer.c
mono/utils/hazard-pointer.h
mono/utils/lock-free-alloc.c
mono/utils/lock-free-queue.c
mono/utils/mono-linked-list-set.c
mono/utils/mono-threads.c