ObjectSynchronizer iterate only in-use monitors?
Carsten Varming
varming at gmail.com
Tue May 16 13:53:24 UTC 2017
Dear Roman,
I didn't do anything to extend it to work with MonitorInUseLists (it wasn't
on by default at the time). If MonitorInUseLists is enabled, then my patch
is a noop. MonitorInUseLists makes every java thread do more work when
inflating locks. That work is thread local and trying to get it to work in
the presence of a deflater thread might not be productive.
Re races:
1. To avoid endless inflation / deflation cycles I only attempt to deflate
a monitor the second time I see it: If the service thread (the only thread
deflating monitors) see a monitor in state New, then mark it as Old and
move on. So there is little interaction between a thread inflating a lock
to a monitor and the deflating thread (the service thread), the inflating
thread just have to make sure the monitor is marked New and this marker is
published using appropriate barriers. The code already does the right thing
as the displaced mark word has to be correctly published for the hashcode
races to be resolved.
2. An interesting race is between a thread acquiring the monitor and the
service thread trying to deflate the monitor. The the monitor is free
(_owner == NULL), then the service thread installs -1 in _owner to let
everyone else know that it will attempt to deflate the monitor. This causes
other threads to use the slow path on this monitor, but otherwise general
threads do not make a difference between _owner == -1 and _owner == NULL.
The -1 marker is used to ensure that no other thread has acquired the
monitor while we read _count and _waiters. If the deflater thread manage to
install -1 in _owner, read _waiters == 0, and make _count very negative if
_count == 0, and _owner is still -1, then _waiters must still be 0 as other
threads has to acquire the monitor to increase _waiters, and _count is
still negative (I displaced _count by a very large amount). That the is the
signal to other threads deflation is in progress. The actual deflation
(installing the displaced mark word in java object) is an idempotent
operation and both deflater thread and general threads will attempt to
complete the deflation. If any of the conditions mentioned above are not
true, then the monitor is in use. In that case we restore _count if needed.
If the deflating thread managed to install -1 in _owner, but fail to make
_count negative, then the next thread writing to _owner (acquiring the
lock), erases the -1 installed by the deflater thread.
3. Installing the displaced mark word in the java object might also race
with a thread writing the hashcode. This race was pretty simple to sort out
as it is very similar to two thread both trying to install a hashcode.
Finally, do we really want monitors on the C-heap? We could store monitors
in the java heap. It wouldn't be that hard to teach the GCs to check if the
mark word is a pointer into the java heap, and potentially copy the monitor
object and update the pointer in the mark word. This would avoid treating
monitors as roots in the first place. When should monitors be deflated? In
such a scheme I propose to deflate monitors when a java thread releases the
lock using a simpler approach than outlined in my patch (since the thread
owns the monitor is just have to make _count very negative to signal that
this monitor is being deflated), the safepoint counter could be used to
prevent more than one deflation per safepoint. WDYT?
Carsten
On Tue, May 16, 2017 at 8:05 AM, Roman Kennke <rkennke at redhat.com> wrote:
> Am 16.05.2017 um 13:37 schrieb Carsten Varming:
>
> FYI. Last year I wrote a small patch[1] against JDK9 that enables monitor
> deflation to happen outside a safepoint. There was little interest then, so
> I never proposed it as a patch. The JDK9 code has moved on a little bit, so
> the patch probably doesn't apply cleanly, but the patch shows one way to
> complete the life of a monitor without going through a safepoint.
>
>
> Wow, now that is interesting!
>
> Can you give me a quick summary-description how you avoid racing with
> other threads that might inflate the monitor? As far as I know, monitor
> deflation (currently) requires that all Java threads stand still at a
> safepoint.
>
> Can it also be made to work with MonitorInUseLists?
>
> Roman
>
>
> Carsten
>
> [1] http://cr.openjdk.java.net/~cvarming/monitor_deflate_conc/0/
>
> On Tue, May 16, 2017 at 6:32 AM, Roman Kennke <rkennke at redhat.com> wrote:
>
>> Am 16.05.2017 um 11:48 schrieb Robbin Ehn:
>> > Correction,
>> >
>> > On 05/16/2017 11:45 AM, Robbin Ehn wrote:
>> >> Yes, but since we are at a safepoint you should be able to use gc
>> >> worker in that case also?
>> >
>> > or the java thread. And scratch 'also' :)
>>
>> This clearly requires co-operation from the GC.
>>
>> Also, I noticed that some GCs cannot do deflation during root scanning,
>> because they stow away mark words during marking, and temporarily store
>> forwarding pointers into the mark words, and only restore mark words
>> after GC. This obviously conflicts with monitor deflation. Which means
>> we need some GC cooperation there too... I will figure something out.
>>
>> Roman
>>
>>
>
>
More information about the hotspot-runtime-dev
mailing list