Art threads suspension causes deadlock
canyie opened this issue · comments
(This problem is also described in the README.)
Background:
- In the bridge_jump_trampoline, we modified some registers to save our own values, so we have to save the original values from these registers; we can't allocate memory (stack and heap) here, so we use pre-allocated memory; but when multiple threads execute concurrently, because the memory is shared, its value may be erased by other threads, so we designed a spin lock, the thread executing here will block until it successfully acquires the lock.
- In some cases, art needs to suspend the execution of all threads (such as GC). When the thread executes to the checkpoint, it will be suspended. When all threads are suspended, the GC can begin.
Imagine this situation:
- Thread A and thread B acquire the lock at the same time, A acquires the lock and continues to execute, B blocks here until A releases the lock.
- At this time, art needs to suspend all threads. When A executes to checkpoint, it is blocked, waiting for B to execute checkpoint.
- A waits for B to execute the checkpoint and B waits for A to release the lock. They cannot continue to execute; and because other threads are also suspended, the runtime cannot continue to work.
We have three ways to solve it:
When the thread fails to acquire the lock, explicitly check whether the thread needs to be suspended and actively enter the checkpoint.Tested and failed, the thread crashes at Thread::VerifyStack().- Since the thread waiting for the lock has actually been suspended, we can hook certain system functions and make it ignore the thread; however, this method is hard to implement and may cause unknown problems.
- Prevent the thread holding the lock from being suspended until it releases the lock. This can be achieved by hooking certain system functions.
We will try to solve the problem, and suggestions are welcome!
has this been solved yet? @canyie
https://juejin.cn/post/7372126591215222835
这里有篇文章说了这个问题,不知道有没有帮助.
https://juejin.cn/post/7372126591215222835 这里有篇文章说了这个问题,不知道有没有帮助.
这篇文章我看过的,但是要实现这种解决方法需要我把这部分逻辑几乎重写一遍,而且从 Android 4.4 ~ 15,每个版本的实现都需要重新追一遍以确保兼容性,我现在的心力不足以支撑我这样做