Skip to content

Not calling unblock from monitor exit can cause threads to block in monitor entry, potentially permanently #7859

@JamesKingdon

Description

@JamesKingdon

A customer presented a case where they reproducibly experience a JVM hang during shutdown. After several iterations of test builds the behaviour leading up to the hang was found to be that one or more threads were in monitor enter and transitioned from spinning to blocking at the time that another thread was running in monitor exit. In monitor exit there is a test for monitor->spinThreads which gates the call to unblock_spinlock_threads, see

omr/thread/common/omrthread.c

Lines 4363 to 4365 in d2c93b8

if (0 == monitor->spinThreads) {
unblock_spinlock_threads(self, monitor);
}

At this test the value of spinThreads was 1, so unblock_spinlock_threads was not called. At this point there were two threads blocked in monitor enter.

No further events occurred on this monitor (since the system was shutting down) and the two blocked threads prevented the shutdown from completing.

I created a testfix that disabled the test for non-zero spinThreads so that the unblock' function is always called and the customer reported no further hangs.

It appears that the test is an optimization to avoid calling unblock_spinlock_threads on the basis that a spinning thread will acquire the monitor without the cost of waking a blocked thread. Unfortunately this appears to introduce a race condition between the last iteration in omrthread_spinlock_acquire and the point where spinThreads is decremented.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions