Merge pull request #2810 from kumpera/fix_hazard_free
authormonojenkins <jo.shields+jenkins@xamarin.com>
Thu, 31 Mar 2016 19:00:19 +0000 (20:00 +0100)
committermonojenkins <jo.shields+jenkins@xamarin.com>
Thu, 31 Mar 2016 19:00:19 +0000 (20:00 +0100)
commit58e8a9f85176c9607e605b888ef45db01a0f6997
tree7fa066d2c9d1d1eb8b3b3e84fc1918af625a353c
parent5275f3f3c638856c811a3b842e0f0b0d0fce4b43
parent2ad72ecc3a4c547e3aeab26dba0f03a7396bfa1c
Merge pull request #2810 from kumpera/fix_hazard_free

Fix hazard free

Replace usage of mono_thread_hazardous_free_or_queue and remove it.

    mono_thread_hazardous_free_or_queue has a fundamentally broken design.

    It allows arbitrary free code to run in the context of its caller.

    The sync/async split on where it's called is not enough to know whether
    we can run free'ing code or not.

    Since in sync context we called free functions that could take locks,
    it happened that those locks conflicted with the ones already taken.

    In particular, mono_jit_info_table_free did take a domain lock and
    quite a few of the sync context calls would hold locks that must
    not be held when taking a domain lock.

    This, is practice, means that we'd need to partition the free calls
    into 3 groups: async context, reentrant context (no runtime locks held)
    and sync context (maybe some locks held).

    There was no case where reentrant context would be usable meaning,
    in practice, that all calls happens in what effectively is async context
    where free functions can't be called.

    The new design is a lot more straightforward:

    - No implicit free queue pumping
    - A pair of free functions with well defined behavior.
     mono_thread_hazardous_try_free - to be used where the caller expects the free function to be called
     mono_thread_hazardous_queue_free - to be used where the caller don't expect the free function to be called [1]
    - Explicit pumping on places that known to be ok
     Thread detach
     Finalizer thread

    [1] This might sound like a weird condition, but a lot of lock-free code
    have compensation logic that trigger free'ing during lookups.
mono/metadata/gc.c
mono/metadata/jit-info.c
mono/sgen/sgen-gc.c
mono/utils/hazard-pointer.c
mono/utils/hazard-pointer.h
mono/utils/lock-free-alloc.c
mono/utils/mono-threads.c