hotspot/src/share/vm/utilities/workgroup.cpp
author minqi
Mon, 12 Nov 2012 14:03:53 -0800
changeset 14477 95e66ea71f71
parent 13963 e5b53c306fb5
child 17026 72b2233861f1
permissions -rw-r--r--
6830717: replay of compilations would help with debugging Summary: When java process crashed in compiler thread, repeat the compilation process will help finding root cause. This is done with using SA dump application class data and replay data from core dump, then use debug version of jvm to recompile the problematic java method. Reviewed-by: kvn, twisti, sspitsyn Contributed-by: yumin.qi@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
13963
e5b53c306fb5 7197424: update copyright year to match last edit in jdk8 hotspot repository
mikael
parents: 13195
diff changeset
     2
 * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1374
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1374
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1374
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6759
diff changeset
    25
#include "precompiled.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6759
diff changeset
    26
#include "memory/allocation.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6759
diff changeset
    27
#include "memory/allocation.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6759
diff changeset
    28
#include "runtime/os.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6759
diff changeset
    29
#include "utilities/workgroup.hpp"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
// Definitions of WorkGang methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
AbstractWorkGang::AbstractWorkGang(const char* name,
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
    34
                                   bool  are_GC_task_threads,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
    35
                                   bool  are_ConcurrentGC_threads) :
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
  _name(name),
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
    37
  _are_GC_task_threads(are_GC_task_threads),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
    38
  _are_ConcurrentGC_threads(are_ConcurrentGC_threads) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
    39
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
    40
  assert(!(are_GC_task_threads && are_ConcurrentGC_threads),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
    41
         "They cannot both be STW GC and Concurrent threads" );
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
    42
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
  // Other initialization.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
  _monitor = new Monitor(/* priority */       Mutex::leaf,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
                         /* name */           "WorkGroup monitor",
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
    46
                         /* allow_vm_block */ are_GC_task_threads);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
  assert(monitor() != NULL, "Failed to allocate monitor");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
  _terminate = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
  _task = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
  _sequence_number = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
  _started_workers = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
  _finished_workers = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
WorkGang::WorkGang(const char* name,
11396
917d8673b5ef 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 11174
diff changeset
    56
                   uint        workers,
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
    57
                   bool        are_GC_task_threads,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
    58
                   bool        are_ConcurrentGC_threads) :
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    59
  AbstractWorkGang(name, are_GC_task_threads, are_ConcurrentGC_threads) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
  _total_workers = workers;
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    61
}
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    62
11396
917d8673b5ef 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 11174
diff changeset
    63
GangWorker* WorkGang::allocate_worker(uint which) {
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    64
  GangWorker* new_worker = new GangWorker(this, which);
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    65
  return new_worker;
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    66
}
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    67
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    68
// The current implementation will exit if the allocation
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    69
// of any worker fails.  Still, return a boolean so that
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    70
// a future implementation can possibly do a partial
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    71
// initialization of the workers and report such to the
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    72
// caller.
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    73
bool WorkGang::initialize_workers() {
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
    74
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
  if (TraceWorkGang) {
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    76
    tty->print_cr("Constructing work gang %s with %d threads",
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    77
                  name(),
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    78
                  total_workers());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
  }
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 11396
diff changeset
    80
  _gang_workers = NEW_C_HEAP_ARRAY(GangWorker*, total_workers(), mtInternal);
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
    81
  if (gang_workers() == NULL) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
    82
    vm_exit_out_of_memory(0, "Cannot create GangWorker array.");
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    83
    return false;
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    84
  }
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    85
  os::ThreadType worker_type;
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    86
  if (are_ConcurrentGC_threads()) {
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    87
    worker_type = os::cgc_thread;
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    88
  } else {
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    89
    worker_type = os::pgc_thread;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
    90
  }
11396
917d8673b5ef 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 11174
diff changeset
    91
  for (uint worker = 0; worker < total_workers(); worker += 1) {
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    92
    GangWorker* new_worker = allocate_worker(worker);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
    assert(new_worker != NULL, "Failed to allocate GangWorker");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
    _gang_workers[worker] = new_worker;
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    95
    if (new_worker == NULL || !os::create_thread(new_worker, worker_type)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
      vm_exit_out_of_memory(0, "Cannot create worker GC thread. Out of system resources.");
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    97
      return false;
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    98
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
    if (!DisableStartThread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
      os::start_thread(new_worker);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
  }
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   103
  return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
AbstractWorkGang::~AbstractWorkGang() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
  if (TraceWorkGang) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
    tty->print_cr("Destructing work gang %s", name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
  stop();   // stop all the workers
11396
917d8673b5ef 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 11174
diff changeset
   111
  for (uint worker = 0; worker < total_workers(); worker += 1) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
    delete gang_worker(worker);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
  delete gang_workers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
  delete monitor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
11396
917d8673b5ef 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 11174
diff changeset
   118
GangWorker* AbstractWorkGang::gang_worker(uint i) const {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
  // Array index bounds checking.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
  GangWorker* result = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
  assert(gang_workers() != NULL, "No workers for indexing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
  assert(((i >= 0) && (i < total_workers())), "Worker index out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  result = _gang_workers[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
  assert(result != NULL, "Indexing to null worker");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
void WorkGang::run_task(AbstractGangTask* task) {
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   129
  run_task(task, total_workers());
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   130
}
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   131
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   132
void WorkGang::run_task(AbstractGangTask* task, uint no_of_parallel_workers) {
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   133
  task->set_for_termination(no_of_parallel_workers);
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   134
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
  // This thread is executed by the VM thread which does not block
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
  // on ordinary MutexLocker's.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
  MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
  if (TraceWorkGang) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
    tty->print_cr("Running work gang %s task %s", name(), task->name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
  // Tell all the workers to run a task.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
  assert(task != NULL, "Running a null task");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
  // Initialize.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
  _task = task;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
  _sequence_number += 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  _started_workers = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
  _finished_workers = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
  // Tell the workers to get to work.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  monitor()->notify_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
  // Wait for them to be finished
11396
917d8673b5ef 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 11174
diff changeset
   151
  while (finished_workers() < no_of_parallel_workers) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
    if (TraceWorkGang) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
      tty->print_cr("Waiting in work gang %s: %d/%d finished sequence %d",
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   154
                    name(), finished_workers(), no_of_parallel_workers,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
                    _sequence_number);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
    monitor()->wait(/* no_safepoint_check */ true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
  _task = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
  if (TraceWorkGang) {
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   161
    tty->print_cr("\nFinished work gang %s: %d/%d sequence %d",
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   162
                  name(), finished_workers(), no_of_parallel_workers,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
                  _sequence_number);
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   164
    Thread* me = Thread::current();
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   165
    tty->print_cr("  T: 0x%x  VM_thread: %d", me, me->is_VM_thread());
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 7397
diff changeset
   166
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   169
void FlexibleWorkGang::run_task(AbstractGangTask* task) {
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   170
  // If active_workers() is passed, _finished_workers
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   171
  // must only be incremented for workers that find non_null
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   172
  // work (as opposed to all those that just check that the
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   173
  // task is not null).
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   174
  WorkGang::run_task(task, (uint) active_workers());
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   175
}
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   176
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
void AbstractWorkGang::stop() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
  // Tell all workers to terminate, then wait for them to become inactive.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
  MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
  if (TraceWorkGang) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
    tty->print_cr("Stopping work gang %s task %s", name(), task()->name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
  _task = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
  _terminate = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
  monitor()->notify_all();
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   186
  while (finished_workers() < active_workers()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
    if (TraceWorkGang) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
      tty->print_cr("Waiting in work gang %s: %d/%d finished",
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   189
                    name(), finished_workers(), active_workers());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
    monitor()->wait(/* no_safepoint_check */ true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
void AbstractWorkGang::internal_worker_poll(WorkData* data) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
  assert(monitor()->owned_by_self(), "worker_poll is an internal method");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
  assert(data != NULL, "worker data is null");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
  data->set_terminate(terminate());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
  data->set_task(task());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
  data->set_sequence_number(sequence_number());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
void AbstractWorkGang::internal_note_start() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
  assert(monitor()->owned_by_self(), "note_finish is an internal method");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
  _started_workers += 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
void AbstractWorkGang::internal_note_finish() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
  assert(monitor()->owned_by_self(), "note_finish is an internal method");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
  _finished_workers += 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
void AbstractWorkGang::print_worker_threads_on(outputStream* st) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
  uint    num_thr = total_workers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
  for (uint i = 0; i < num_thr; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
    gang_worker(i)->print_on(st);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
    st->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
void AbstractWorkGang::threads_do(ThreadClosure* tc) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
  assert(tc != NULL, "Null ThreadClosure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
  uint num_thr = total_workers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
  for (uint i = 0; i < num_thr; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
    tc->do_thread(gang_worker(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
// GangWorker methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
GangWorker::GangWorker(AbstractWorkGang* gang, uint id) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
  _gang = gang;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
  set_id(id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
  set_name("Gang worker#%d (%s)", id, gang->name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
void GangWorker::run() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
  initialize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
  loop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
void GangWorker::initialize() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
  this->initialize_thread_local_storage();
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 11396
diff changeset
   244
  this->record_stack_base_and_size();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
  assert(_gang != NULL, "No gang to run in");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
  os::set_priority(this, NearMaxPriority);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
  if (TraceWorkGang) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
    tty->print_cr("Running gang worker for gang %s id %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
                  gang()->name(), id());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
  // The VM thread should not execute here because MutexLocker's are used
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
  // as (opposed to MutexLockerEx's).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
  assert(!Thread::current()->is_VM_thread(), "VM thread should not be part"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
         " of a work gang");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
void GangWorker::loop() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
  int previous_sequence_number = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
  Monitor* gang_monitor = gang()->monitor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
  for ( ; /* !terminate() */; ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
    WorkData data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
    int part;  // Initialized below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
      // Grab the gang mutex.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
      MutexLocker ml(gang_monitor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
      // Wait for something to do.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
      // Polling outside the while { wait } avoids missed notifies
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
      // in the outer loop.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
      gang()->internal_worker_poll(&data);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
      if (TraceWorkGang) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
        tty->print("Polled outside for work in gang %s worker %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
                   gang()->name(), id());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
        tty->print("  terminate: %s",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
                   data.terminate() ? "true" : "false");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
        tty->print("  sequence: %d (prev: %d)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
                   data.sequence_number(), previous_sequence_number);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
        if (data.task() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
          tty->print("  task: %s", data.task()->name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
          tty->print("  task: NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
        tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
      for ( ; /* break or return */; ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
        // Terminate if requested.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
        if (data.terminate()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
          gang()->internal_note_finish();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
          gang_monitor->notify_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
        // Check for new work.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
        if ((data.task() != NULL) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
            (data.sequence_number() != previous_sequence_number)) {
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   294
          if (gang()->needs_more_workers()) {
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   295
            gang()->internal_note_start();
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   296
            gang_monitor->notify_all();
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   297
            part = gang()->started_workers() - 1;
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   298
            break;
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   299
          }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
        // Nothing to do.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
        gang_monitor->wait(/* no_safepoint_check */ true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
        gang()->internal_worker_poll(&data);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
        if (TraceWorkGang) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
          tty->print("Polled inside for work in gang %s worker %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
                     gang()->name(), id());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
          tty->print("  terminate: %s",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
                     data.terminate() ? "true" : "false");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
          tty->print("  sequence: %d (prev: %d)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
                     data.sequence_number(), previous_sequence_number);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
          if (data.task() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
            tty->print("  task: %s", data.task()->name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
          } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
            tty->print("  task: NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
          tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
      // Drop gang mutex.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
    if (TraceWorkGang) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
      tty->print("Work for work gang %s id %d task %s part %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
                 gang()->name(), id(), data.task()->name(), part);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
    assert(data.task() != NULL, "Got null task");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
    data.task()->work(part);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
      if (TraceWorkGang) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
        tty->print("Finish for work gang %s id %d task %s part %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
                   gang()->name(), id(), data.task()->name(), part);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
      // Grab the gang mutex.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
      MutexLocker ml(gang_monitor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
      gang()->internal_note_finish();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
      // Tell the gang you are done.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
      gang_monitor->notify_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
      // Drop the gang mutex.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
    previous_sequence_number = data.sequence_number();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
bool GangWorker::is_GC_task_thread() const {
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   344
  return gang()->are_GC_task_threads();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   345
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   346
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   347
bool GangWorker::is_ConcurrentGC_thread() const {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   348
  return gang()->are_ConcurrentGC_threads();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
void GangWorker::print_on(outputStream* st) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
  st->print("\"%s\" ", name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
  Thread::print_on(st);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
  st->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
// Printing methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
const char* AbstractWorkGang::name() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
  return _name;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
const char* AbstractGangTask::name() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
  return _name;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
#endif /* PRODUCT */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   371
// FlexibleWorkGang
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   372
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 8688
diff changeset
   373
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
// *** WorkGangBarrierSync
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
WorkGangBarrierSync::WorkGangBarrierSync()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
  : _monitor(Mutex::safepoint, "work gang barrier sync", true),
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   378
    _n_workers(0), _n_completed(0), _should_reset(false) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
11396
917d8673b5ef 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 11174
diff changeset
   381
WorkGangBarrierSync::WorkGangBarrierSync(uint n_workers, const char* name)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
  : _monitor(Mutex::safepoint, name, true),
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   383
    _n_workers(n_workers), _n_completed(0), _should_reset(false) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
11396
917d8673b5ef 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 11174
diff changeset
   386
void WorkGangBarrierSync::set_n_workers(uint n_workers) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
  _n_workers   = n_workers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
  _n_completed = 0;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   389
  _should_reset = false;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
void WorkGangBarrierSync::enter() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
  MutexLockerEx x(monitor(), Mutex::_no_safepoint_check_flag);
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   394
  if (should_reset()) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   395
    // The should_reset() was set and we are the first worker to enter
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   396
    // the sync barrier. We will zero the n_completed() count which
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   397
    // effectively resets the barrier.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   398
    zero_completed();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   399
    set_should_reset(false);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   400
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
  inc_completed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
  if (n_completed() == n_workers()) {
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   403
    // At this point we would like to reset the barrier to be ready in
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   404
    // case it is used again. However, we cannot set n_completed() to
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   405
    // 0, even after the notify_all(), given that some other workers
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   406
    // might still be waiting for n_completed() to become ==
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   407
    // n_workers(). So, if we set n_completed() to 0, those workers
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   408
    // will get stuck (as they will wake up, see that n_completed() !=
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   409
    // n_workers() and go back to sleep). Instead, we raise the
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   410
    // should_reset() flag and the barrier will be reset the first
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   411
    // time a worker enters it again.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   412
    set_should_reset(true);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
    monitor()->notify_all();
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   414
  } else {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
    while (n_completed() != n_workers()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
      monitor()->wait(/* no_safepoint_check */ true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
// SubTasksDone functions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
11396
917d8673b5ef 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 11174
diff changeset
   423
SubTasksDone::SubTasksDone(uint n) :
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
  _n_tasks(n), _n_threads(1), _tasks(NULL) {
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 11396
diff changeset
   425
  _tasks = NEW_C_HEAP_ARRAY(uint, n, mtInternal);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
  guarantee(_tasks != NULL, "alloc failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
  clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
bool SubTasksDone::valid() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
  return _tasks != NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
11396
917d8673b5ef 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 11174
diff changeset
   434
void SubTasksDone::set_n_threads(uint t) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
  assert(_claimed == 0 || _threads_completed == _n_threads,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
         "should not be called while tasks are being processed!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
  _n_threads = (t == 0 ? 1 : t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
void SubTasksDone::clear() {
11396
917d8673b5ef 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 11174
diff changeset
   441
  for (uint i = 0; i < _n_tasks; i++) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
    _tasks[i] = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
  _threads_completed = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
  _claimed = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
11396
917d8673b5ef 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 11174
diff changeset
   450
bool SubTasksDone::is_task_claimed(uint t) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
  assert(0 <= t && t < _n_tasks, "bad task id.");
11396
917d8673b5ef 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 11174
diff changeset
   452
  uint old = _tasks[t];
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
  if (old == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
    old = Atomic::cmpxchg(1, &_tasks[t], 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
  assert(_tasks[t] == 1, "What else?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
  bool res = old != 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
  if (!res) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
    assert(_claimed < _n_tasks, "Too many tasks claimed; missing clear?");
11396
917d8673b5ef 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 11174
diff changeset
   461
    Atomic::inc((volatile jint*) &_claimed);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
void SubTasksDone::all_tasks_completed() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
  jint observed = _threads_completed;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
  jint old;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
  do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
    old = observed;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
    observed = Atomic::cmpxchg(old+1, &_threads_completed, old);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
  } while (observed != old);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
  // If this was the last thread checking in, clear the tasks.
11396
917d8673b5ef 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 11174
diff changeset
   475
  if (observed+1 == (jint)_n_threads) clear();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
SubTasksDone::~SubTasksDone() {
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 11396
diff changeset
   480
  if (_tasks != NULL) FREE_C_HEAP_ARRAY(jint, _tasks, mtInternal);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
// *** SequentialSubTasksDone
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
void SequentialSubTasksDone::clear() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
  _n_tasks   = _n_claimed   = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
  _n_threads = _n_completed = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
bool SequentialSubTasksDone::valid() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
  return _n_threads > 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
11396
917d8673b5ef 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 11174
diff changeset
   494
bool SequentialSubTasksDone::is_task_claimed(uint& t) {
917d8673b5ef 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 11174
diff changeset
   495
  uint* n_claimed_ptr = &_n_claimed;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
  t = *n_claimed_ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
  while (t < _n_tasks) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
    jint res = Atomic::cmpxchg(t+1, n_claimed_ptr, t);
11396
917d8673b5ef 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 11174
diff changeset
   499
    if (res == (jint)t) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
    t = *n_claimed_ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
bool SequentialSubTasksDone::all_tasks_completed() {
11396
917d8673b5ef 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 11174
diff changeset
   508
  uint* n_completed_ptr = &_n_completed;
917d8673b5ef 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 11174
diff changeset
   509
  uint  complete        = *n_completed_ptr;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
  while (true) {
11396
917d8673b5ef 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 11174
diff changeset
   511
    uint res = Atomic::cmpxchg(complete+1, n_completed_ptr, complete);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
    if (res == complete) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
    complete = res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
  if (complete+1 == _n_threads) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
    clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
}
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   523
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   524
bool FreeIdSet::_stat_init = false;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   525
FreeIdSet* FreeIdSet::_sets[NSets];
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   526
bool FreeIdSet::_safepoint;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   527
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   528
FreeIdSet::FreeIdSet(int sz, Monitor* mon) :
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   529
  _sz(sz), _mon(mon), _hd(0), _waiters(0), _index(-1), _claimed(0)
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   530
{
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   531
  _ids = new int[sz];
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   532
  for (int i = 0; i < sz; i++) _ids[i] = i+1;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   533
  _ids[sz-1] = end_of_list; // end of list.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   534
  if (_stat_init) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   535
    for (int j = 0; j < NSets; j++) _sets[j] = NULL;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   536
    _stat_init = true;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   537
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   538
  // Add to sets.  (This should happen while the system is still single-threaded.)
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   539
  for (int j = 0; j < NSets; j++) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   540
    if (_sets[j] == NULL) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   541
      _sets[j] = this;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   542
      _index = j;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   543
      break;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   544
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   545
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   546
  guarantee(_index != -1, "Too many FreeIdSets in use!");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   547
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   548
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   549
FreeIdSet::~FreeIdSet() {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   550
  _sets[_index] = NULL;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   551
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   552
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   553
void FreeIdSet::set_safepoint(bool b) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   554
  _safepoint = b;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   555
  if (b) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   556
    for (int j = 0; j < NSets; j++) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   557
      if (_sets[j] != NULL && _sets[j]->_waiters > 0) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   558
        Monitor* mon = _sets[j]->_mon;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   559
        mon->lock_without_safepoint_check();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   560
        mon->notify_all();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   561
        mon->unlock();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   562
      }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   563
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   564
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   565
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   566
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   567
#define FID_STATS 0
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   568
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   569
int FreeIdSet::claim_par_id() {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   570
#if FID_STATS
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   571
  thread_t tslf = thr_self();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   572
  tty->print("claim_par_id[%d]: sz = %d, claimed = %d\n", tslf, _sz, _claimed);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   573
#endif
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   574
  MutexLockerEx x(_mon, Mutex::_no_safepoint_check_flag);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   575
  while (!_safepoint && _hd == end_of_list) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   576
    _waiters++;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   577
#if FID_STATS
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   578
    if (_waiters > 5) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   579
      tty->print("claim_par_id waiting[%d]: %d waiters, %d claimed.\n",
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   580
                 tslf, _waiters, _claimed);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   581
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   582
#endif
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   583
    _mon->wait(Mutex::_no_safepoint_check_flag);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   584
    _waiters--;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   585
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   586
  if (_hd == end_of_list) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   587
#if FID_STATS
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   588
    tty->print("claim_par_id[%d]: returning EOL.\n", tslf);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   589
#endif
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   590
    return -1;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   591
  } else {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   592
    int res = _hd;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   593
    _hd = _ids[res];
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   594
    _ids[res] = claimed;  // For debugging.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   595
    _claimed++;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   596
#if FID_STATS
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   597
    tty->print("claim_par_id[%d]: returning %d, claimed = %d.\n",
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   598
               tslf, res, _claimed);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   599
#endif
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   600
    return res;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   601
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   602
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   603
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   604
bool FreeIdSet::claim_perm_id(int i) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   605
  assert(0 <= i && i < _sz, "Out of range.");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   606
  MutexLockerEx x(_mon, Mutex::_no_safepoint_check_flag);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   607
  int prev = end_of_list;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   608
  int cur = _hd;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   609
  while (cur != end_of_list) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   610
    if (cur == i) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   611
      if (prev == end_of_list) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   612
        _hd = _ids[cur];
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   613
      } else {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   614
        _ids[prev] = _ids[cur];
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   615
      }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   616
      _ids[cur] = claimed;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   617
      _claimed++;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   618
      return true;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   619
    } else {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   620
      prev = cur;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   621
      cur = _ids[cur];
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   622
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   623
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   624
  return false;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   625
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   626
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   627
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   628
void FreeIdSet::release_par_id(int id) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   629
  MutexLockerEx x(_mon, Mutex::_no_safepoint_check_flag);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   630
  assert(_ids[id] == claimed, "Precondition.");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   631
  _ids[id] = _hd;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   632
  _hd = id;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   633
  _claimed--;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   634
#if FID_STATS
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   635
  tty->print("[%d] release_par_id(%d), waiters =%d,  claimed = %d.\n",
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   636
             thr_self(), id, _waiters, _claimed);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   637
#endif
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   638
  if (_waiters > 0)
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   639
    // Notify all would be safer, but this is OK, right?
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   640
    _mon->notify_all();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   641
}