On 9/20/19 9:07 PM, Daniel D. Daugherty wrote:
On 9/20/19 7:15 PM, serguei.spit...@oracle.com wrote:
Hi Dan,

Please, find a minor correction below.


On 9/20/19 2:59 PM, Daniel D. Daugherty wrote:
Daniil,

Thanks for sticking with this project through the many versions.
Sorry this review is late...


On 9/19/19 8:30 PM, Daniil Titov wrote:
Hi David and Serguei,

Please review new version of the fix that includes the changes Serguei suggested:   1. If racing threads initialize the thread table only one of these threads will populate the table with the threads from the thread list   2. The code that adds the thread to the tread table is put inside Threads_lock to ensure that we cannot accidentally add the thread       that has just passed the removal point in ThreadsSMRSupport::remove_thread()

The changes are in ThreadTable::lazy_initialize() method only.

Testing:  Mach5 tier1, tier2, tier3, tier4, and tier5 tests successfully passed.

Webrev: https://cr.openjdk.java.net/~dtitov/8185005/webrev.07/
. . .
L93: void ThreadTable::lazy_initialize(const ThreadsList *threads) {
        Re: discussion about lazy_initialize() racing with
            ThreadsList::find_JavaThread_from_java_tid()

        There's a couple of aspects to these two pieces of code racing
        with each other and racing with new thread creation. Racing with
        new thread creation is the easy one:

          If a new thread isn't added to the ThreadTable by
          ThreadsSMRSupport::add_thread() calling ThreadTable::add_thread(),
          then the point in the future where someone calls
          find_JavaThread_from_java_tid() will add it to the table due to
          the linear search when ThreadTable::find_thread_by_tid()
          returns NULL.

       As for multi-threads calling ThreadsList::find_JavaThread_from_java_tid()        at the same time which results in multi-threads in lazy_initialize()
       at the same time...

       - ThreadTable creation will be linear due to ThreadTableCreate_lock.
         After _is_initialized is set to true, then no more callers to
         lazy_initialize() will be in the "if (!_is_initialized)" block.
       - Once the ThreadTable is created, then multi-threads can be
         executing the for-loop to add their ThreadsList entries to
         the ThreadTable.

I guess, there is a confusion here.
The lines 97-101 were recently added into the latest webrev:

  93 void ThreadTable::lazy_initialize(const ThreadsList *threads) {
  94   if (!_is_initialized) {
  95     {
  96       MutexLocker ml(ThreadTableCreate_lock);
  97       if (_is_initialized) {
  98         // There is no obvious benefits in allowing the thread table
  99         // being concurently populated during the initalization.
 100         return;
 101       }

It prevents multi-threads executing the for-loop to add their
ThreadsList entries to the ThreadTable.
Instead, these threads may not find the requested threads in the
ThreadTable and so, will start linear search in their ThreadsList
to add them into the ThreadTable.

I should have read your comment more carefully...

Yes, you are right about the early cut out on L97-100 causing
the for-loop to be skipped by any thread that saw (!_is_initialized)
and was blocked on the ThreadTableCreate_lock.

So my response below is wrong...

Sorry about the noise.

Dan


The ThreadTableCreate_lock is only held from here:

  L95:     {
  L96:       MutexLocker ml(ThreadTableCreate_lock);

to here:

  L103:       _is_initialized = true;
  L104:     }

and the for-loop starts here:

  L105:     for (uint i = 0; i < threads->length(); i++) {

so the ThreadTable_Create_lock does not linearize the
for-loop.

I'm quoting webrev.07... which I believe is the latest.

Dan



. . .
Short version: Thumbs up.

Longer version: I don't think I've spotted anything other than nits here.
Mostly I've just looked for multi-threaded races, proper usage of the
Thread-SMR stuff, and minimal impact in the case where the new
ThreadsTable is never needed.

Dan

P.S.
ThreadTable is a bit of misnomer. What you really have here is
a ThreadIdTable, but I'm really late to the code review flow
with that comment...

Agreed, ThreadIdTable is better name for this table.

Thanks,
Serguei




Bug : https://bugs.openjdk.java.net/browse/JDK-8185005

Thank you!
--Daniil




Reply via email to