src/hotspot/share/gc/parallel/gcTaskManager.cpp
author coleenp
Mon, 29 Apr 2019 16:01:52 -0400
changeset 54645 05aaccf7d558
parent 54623 1126f0607c70
permissions -rw-r--r--
8222988: Use MonitorLocker rather than MutexLocker when wait/notify used Summary: fixed use cases in code except CMS. Reviewed-by: rehn, dcubed
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
54623
1126f0607c70 8222811: Consolidate MutexLockerEx and MutexLocker
coleenp
parents: 52904
diff changeset
     2
 * Copyright (c) 2002, 2019, 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: 1
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
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: 1
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: 5547
diff changeset
    25
#include "precompiled.hpp"
30764
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 29798
diff changeset
    26
#include "gc/parallel/gcTaskManager.hpp"
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 29798
diff changeset
    27
#include "gc/parallel/gcTaskThread.hpp"
33126
260ff671354b 8138707: TestPromotionEventWithParallelScavenge.java crashes using undefined GC id.
brutisso
parents: 33125
diff changeset
    28
#include "gc/shared/gcId.hpp"
38216
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
    29
#include "gc/shared/workerManager.hpp"
52904
d2f118d3f8e7 8213224: Move code related to GC threads calculation out of AdaptiveSizePolicy
manc
parents: 51332
diff changeset
    30
#include "gc/shared/workerPolicy.hpp"
35061
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33126
diff changeset
    31
#include "logging/log.hpp"
46701
f559541c0daa 8181917: Refactor UL LogStreams to avoid using resource area
stuefe
parents: 40096
diff changeset
    32
#include "logging/logStream.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    33
#include "memory/allocation.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    34
#include "memory/allocation.inline.hpp"
37224
fd3320bf6413 8153186: Convert TraceGCTaskThread to use unified logging
brutisso
parents: 35061
diff changeset
    35
#include "memory/resourceArea.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    36
#include "runtime/mutex.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    37
#include "runtime/mutexLocker.hpp"
50429
83aec1d357d4 8204301: Make OrderAccess functions available to hpp rather than inline.hpp files
coleenp
parents: 47216
diff changeset
    38
#include "runtime/orderAccess.hpp"
38216
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
    39
#include "runtime/os.hpp"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
// GCTask
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
const char* GCTask::Kind::to_string(kind value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
  const char* result = "unknown GCTask kind";
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
  switch (value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
  default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
    result = "unknown GCTask kind";
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
  case unknown_task:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
    result = "unknown task";
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
  case ordinary_task:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
    result = "ordinary task";
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
    break;
33124
e256f7a94c38 8138862: Remove some unused code and subclasses in gcTaskManager.hpp/cpp
brutisso
parents: 33105
diff changeset
    57
  case wait_for_barrier_task:
e256f7a94c38 8138862: Remove some unused code and subclasses in gcTaskManager.hpp/cpp
brutisso
parents: 33105
diff changeset
    58
    result = "wait for barrier task";
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
  case noop_task:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
    result = "noop task";
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
    break;
11208
101816314520 7119584: UseParallelGC barrier task can be overwritten.
jmasa
parents: 11174
diff changeset
    63
  case idle_task:
101816314520 7119584: UseParallelGC barrier task can be overwritten.
jmasa
parents: 11174
diff changeset
    64
    result = "idle task";
101816314520 7119584: UseParallelGC barrier task can be overwritten.
jmasa
parents: 11174
diff changeset
    65
    break;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
33126
260ff671354b 8138707: TestPromotionEventWithParallelScavenge.java crashes using undefined GC id.
brutisso
parents: 33125
diff changeset
    70
GCTask::GCTask() {
260ff671354b 8138707: TestPromotionEventWithParallelScavenge.java crashes using undefined GC id.
brutisso
parents: 33125
diff changeset
    71
  initialize(Kind::ordinary_task, GCId::current());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
33126
260ff671354b 8138707: TestPromotionEventWithParallelScavenge.java crashes using undefined GC id.
brutisso
parents: 33125
diff changeset
    74
GCTask::GCTask(Kind::kind kind) {
260ff671354b 8138707: TestPromotionEventWithParallelScavenge.java crashes using undefined GC id.
brutisso
parents: 33125
diff changeset
    75
  initialize(kind, GCId::current());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
33126
260ff671354b 8138707: TestPromotionEventWithParallelScavenge.java crashes using undefined GC id.
brutisso
parents: 33125
diff changeset
    78
GCTask::GCTask(Kind::kind kind, uint gc_id) {
260ff671354b 8138707: TestPromotionEventWithParallelScavenge.java crashes using undefined GC id.
brutisso
parents: 33125
diff changeset
    79
  initialize(kind, gc_id);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
33126
260ff671354b 8138707: TestPromotionEventWithParallelScavenge.java crashes using undefined GC id.
brutisso
parents: 33125
diff changeset
    82
void GCTask::initialize(Kind::kind kind, uint gc_id) {
260ff671354b 8138707: TestPromotionEventWithParallelScavenge.java crashes using undefined GC id.
brutisso
parents: 33125
diff changeset
    83
  _kind = kind;
260ff671354b 8138707: TestPromotionEventWithParallelScavenge.java crashes using undefined GC id.
brutisso
parents: 33125
diff changeset
    84
  _affinity = GCTaskManager::sentinel_worker();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
  _older = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
  _newer = NULL;
33126
260ff671354b 8138707: TestPromotionEventWithParallelScavenge.java crashes using undefined GC id.
brutisso
parents: 33125
diff changeset
    87
  _gc_id = gc_id;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
void GCTask::destruct() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
  assert(older() == NULL, "shouldn't have an older task");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
  assert(newer() == NULL, "shouldn't have a newer task");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
  // Nothing to do.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
void GCTask::print(const char* message) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
  tty->print(INTPTR_FORMAT " <- " INTPTR_FORMAT "(%u) -> " INTPTR_FORMAT,
29798
451c73fdf690 8076071: parallelScavenge: PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC needs to be removed from source files
david
parents: 28163
diff changeset
    99
             p2i(newer()), p2i(this), affinity(), p2i(older()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
// GCTaskQueue
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
GCTaskQueue* GCTaskQueue::create() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
  GCTaskQueue* result = new GCTaskQueue(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
  if (TraceGCTaskQueue) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
    tty->print_cr("GCTaskQueue::create()"
29798
451c73fdf690 8076071: parallelScavenge: PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC needs to be removed from source files
david
parents: 28163
diff changeset
   111
                  " returns " INTPTR_FORMAT, p2i(result));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
GCTaskQueue* GCTaskQueue::create_on_c_heap() {
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 11208
diff changeset
   117
  GCTaskQueue* result = new(ResourceObj::C_HEAP, mtGC) GCTaskQueue(true);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
  if (TraceGCTaskQueue) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
    tty->print_cr("GCTaskQueue::create_on_c_heap()"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
                  " returns " INTPTR_FORMAT,
29798
451c73fdf690 8076071: parallelScavenge: PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC needs to be removed from source files
david
parents: 28163
diff changeset
   121
                  p2i(result));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
GCTaskQueue::GCTaskQueue(bool on_c_heap) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  _is_c_heap_obj(on_c_heap) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
  initialize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
  if (TraceGCTaskQueue) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
    tty->print_cr("[" INTPTR_FORMAT "]"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
                  " GCTaskQueue::GCTaskQueue() constructor",
29798
451c73fdf690 8076071: parallelScavenge: PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC needs to be removed from source files
david
parents: 28163
diff changeset
   132
                  p2i(this));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
void GCTaskQueue::destruct() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
  // Nothing to do.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
void GCTaskQueue::destroy(GCTaskQueue* that) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
  if (TraceGCTaskQueue) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
    tty->print_cr("[" INTPTR_FORMAT "]"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
                  " GCTaskQueue::destroy()"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
                  "  is_c_heap_obj:  %s",
29798
451c73fdf690 8076071: parallelScavenge: PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC needs to be removed from source files
david
parents: 28163
diff changeset
   145
                  p2i(that),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
                  that->is_c_heap_obj() ? "true" : "false");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
  // That instance may have been allocated as a CHeapObj,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  // in which case we have to free it explicitly.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
  if (that != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
    that->destruct();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
    assert(that->is_empty(), "should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
    if (that->is_c_heap_obj()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
      FreeHeap(that);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
void GCTaskQueue::initialize() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
  set_insert_end(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
  set_remove_end(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
  set_length(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
// Enqueue one task.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
void GCTaskQueue::enqueue(GCTask* task) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
  if (TraceGCTaskQueue) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
    tty->print_cr("[" INTPTR_FORMAT "]"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
                  " GCTaskQueue::enqueue(task: "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
                  INTPTR_FORMAT ")",
29798
451c73fdf690 8076071: parallelScavenge: PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC needs to be removed from source files
david
parents: 28163
diff changeset
   171
                  p2i(this), p2i(task));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
    print("before:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
  assert(task != NULL, "shouldn't have null task");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
  assert(task->older() == NULL, "shouldn't be on queue");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
  assert(task->newer() == NULL, "shouldn't be on queue");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
  task->set_newer(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
  task->set_older(insert_end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
  if (is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
    set_remove_end(task);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
    insert_end()->set_newer(task);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
  set_insert_end(task);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
  increment_length();
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   186
  verify_length();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
  if (TraceGCTaskQueue) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
    print("after:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
// Enqueue a whole list of tasks.  Empties the argument list.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
void GCTaskQueue::enqueue(GCTaskQueue* list) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
  if (TraceGCTaskQueue) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
    tty->print_cr("[" INTPTR_FORMAT "]"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
                  " GCTaskQueue::enqueue(list: "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
                  INTPTR_FORMAT ")",
29798
451c73fdf690 8076071: parallelScavenge: PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC needs to be removed from source files
david
parents: 28163
diff changeset
   198
                  p2i(this), p2i(list));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
    print("before:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
    list->print("list:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
  if (list->is_empty()) {
22551
9bf46d16dcc6 8025856: Fix typos in the GC code
jwilhelm
parents: 13963
diff changeset
   203
    // Enqueueing the empty list: nothing to do.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
  uint list_length = list->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
  if (is_empty()) {
22551
9bf46d16dcc6 8025856: Fix typos in the GC code
jwilhelm
parents: 13963
diff changeset
   208
    // Enqueueing to empty list: just acquire elements.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
    set_insert_end(list->insert_end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
    set_remove_end(list->remove_end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
    set_length(list_length);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
    // Prepend argument list to our queue.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
    list->remove_end()->set_older(insert_end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
    insert_end()->set_newer(list->remove_end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
    set_insert_end(list->insert_end());
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   217
    set_length(length() + list_length);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
    // empty the argument list.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
  list->initialize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
  if (TraceGCTaskQueue) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
    print("after:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
    list->print("list:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
  }
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   225
  verify_length();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
// Dequeue one task.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
GCTask* GCTaskQueue::dequeue() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
  if (TraceGCTaskQueue) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
    tty->print_cr("[" INTPTR_FORMAT "]"
29798
451c73fdf690 8076071: parallelScavenge: PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC needs to be removed from source files
david
parents: 28163
diff changeset
   232
                  " GCTaskQueue::dequeue()", p2i(this));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
    print("before:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
  assert(!is_empty(), "shouldn't dequeue from empty list");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
  GCTask* result = remove();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
  assert(result != NULL, "shouldn't have NULL task");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
  if (TraceGCTaskQueue) {
29798
451c73fdf690 8076071: parallelScavenge: PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC needs to be removed from source files
david
parents: 28163
diff changeset
   239
    tty->print_cr("    return: " INTPTR_FORMAT, p2i(result));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
    print("after:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
// Dequeue one task, preferring one with affinity.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
GCTask* GCTaskQueue::dequeue(uint affinity) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
  if (TraceGCTaskQueue) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
    tty->print_cr("[" INTPTR_FORMAT "]"
29798
451c73fdf690 8076071: parallelScavenge: PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC needs to be removed from source files
david
parents: 28163
diff changeset
   249
                  " GCTaskQueue::dequeue(%u)", p2i(this), affinity);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
    print("before:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
  assert(!is_empty(), "shouldn't dequeue from empty list");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
  // Look down to the next barrier for a task with this affinity.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
  GCTask* result = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
  for (GCTask* element = remove_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
       element != NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
       element = element->newer()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
    if (element->is_barrier_task()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
      // Don't consider barrier tasks, nor past them.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
      result = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
    if (element->affinity() == affinity) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
      result = remove(element);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
  // If we didn't find anything with affinity, just take the next task.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
  if (result == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
    result = remove();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
  if (TraceGCTaskQueue) {
29798
451c73fdf690 8076071: parallelScavenge: PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC needs to be removed from source files
david
parents: 28163
diff changeset
   273
    tty->print_cr("    return: " INTPTR_FORMAT, p2i(result));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
    print("after:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
GCTask* GCTaskQueue::remove() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
  // Dequeue from remove end.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
  GCTask* result = remove_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
  assert(result != NULL, "shouldn't have null task");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
  assert(result->older() == NULL, "not the remove_end");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
  set_remove_end(result->newer());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
  if (remove_end() == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
    assert(insert_end() == result, "not a singleton");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
    set_insert_end(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
    remove_end()->set_older(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
  result->set_newer(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
  decrement_length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
  assert(result->newer() == NULL, "shouldn't be on queue");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
  assert(result->older() == NULL, "shouldn't be on queue");
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   295
  verify_length();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
GCTask* GCTaskQueue::remove(GCTask* task) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
  // This is slightly more work, and has slightly fewer asserts
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
  // than removing from the remove end.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
  assert(task != NULL, "shouldn't have null task");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
  GCTask* result = task;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
  if (result->newer() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
    result->newer()->set_older(result->older());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
    assert(insert_end() == result, "not youngest");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
    set_insert_end(result->older());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
  if (result->older() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
    result->older()->set_newer(result->newer());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
    assert(remove_end() == result, "not oldest");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
    set_remove_end(result->newer());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
  result->set_newer(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
  result->set_older(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
  decrement_length();
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   319
  verify_length();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
NOT_PRODUCT(
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   324
// Count the elements in the queue and verify the length against
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   325
// that count.
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   326
void GCTaskQueue::verify_length() const {
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   327
  uint count = 0;
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   328
  for (GCTask* element = insert_end();
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   329
       element != NULL;
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   330
       element = element->older()) {
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   331
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   332
    count++;
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   333
  }
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   334
  assert(count == length(), "Length does not match queue");
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   335
}
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   336
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
void GCTaskQueue::print(const char* message) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
  tty->print_cr("[" INTPTR_FORMAT "] GCTaskQueue:"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
                "  insert_end: " INTPTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
                "  remove_end: " INTPTR_FORMAT
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   341
                "  length:       %d"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
                "  %s",
29798
451c73fdf690 8076071: parallelScavenge: PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC needs to be removed from source files
david
parents: 28163
diff changeset
   343
                p2i(this), p2i(insert_end()), p2i(remove_end()), length(), message);
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   344
  uint count = 0;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
  for (GCTask* element = insert_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
       element != NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
       element = element->older()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
    element->print("    ");
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   349
    count++;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
    tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
  }
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   352
  tty->print("Total tasks: %d", count);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
// SynchronizedGCTaskQueue
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
SynchronizedGCTaskQueue::SynchronizedGCTaskQueue(GCTaskQueue* queue_arg,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
                                                 Monitor *       lock_arg) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
  _unsynchronized_queue(queue_arg),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
  _lock(lock_arg) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
  assert(unsynchronized_queue() != NULL, "null queue");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
  assert(lock() != NULL, "null lock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
SynchronizedGCTaskQueue::~SynchronizedGCTaskQueue() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
  // Nothing to do.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
// GCTaskManager
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
GCTaskManager::GCTaskManager(uint workers) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
  _workers(workers),
51332
c25572739e7c 8208669: GC changes to allow enabling -Wreorder
tschatzl
parents: 50429
diff changeset
   377
  _created_workers(0),
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   378
  _active_workers(0),
51332
c25572739e7c 8208669: GC changes to allow enabling -Wreorder
tschatzl
parents: 50429
diff changeset
   379
  _idle_workers(0) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
  initialize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
38216
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   383
GCTaskThread* GCTaskManager::install_worker(uint t) {
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   384
  GCTaskThread* new_worker = GCTaskThread::create(this, t, _processor_assignment[t]);
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   385
  set_thread(t, new_worker);
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   386
  return new_worker;
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   387
}
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   388
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   389
void GCTaskManager::add_workers(bool initializing) {
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   390
  os::ThreadType worker_type = os::pgc_thread;
39704
157f39705057 8157240: GC task trace logging is incomprehensible
jmasa
parents: 38216
diff changeset
   391
  uint previous_created_workers = _created_workers;
157f39705057 8157240: GC task trace logging is incomprehensible
jmasa
parents: 38216
diff changeset
   392
38216
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   393
  _created_workers = WorkerManager::add_workers(this,
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   394
                                                _active_workers,
39704
157f39705057 8157240: GC task trace logging is incomprehensible
jmasa
parents: 38216
diff changeset
   395
                                                _workers,
38216
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   396
                                                _created_workers,
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   397
                                                worker_type,
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   398
                                                initializing);
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   399
  _active_workers = MIN2(_created_workers, _active_workers);
39704
157f39705057 8157240: GC task trace logging is incomprehensible
jmasa
parents: 38216
diff changeset
   400
157f39705057 8157240: GC task trace logging is incomprehensible
jmasa
parents: 38216
diff changeset
   401
  WorkerManager::log_worker_creation(this, previous_created_workers, _active_workers, _created_workers, initializing);
157f39705057 8157240: GC task trace logging is incomprehensible
jmasa
parents: 38216
diff changeset
   402
}
157f39705057 8157240: GC task trace logging is incomprehensible
jmasa
parents: 38216
diff changeset
   403
157f39705057 8157240: GC task trace logging is incomprehensible
jmasa
parents: 38216
diff changeset
   404
const char* GCTaskManager::group_name() {
157f39705057 8157240: GC task trace logging is incomprehensible
jmasa
parents: 38216
diff changeset
   405
  return "ParGC Thread";
38216
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   406
}
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   407
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
void GCTaskManager::initialize() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
  if (TraceGCTaskManager) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
    tty->print_cr("GCTaskManager::initialize: workers: %u", workers());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
  assert(workers() != 0, "no workers");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
  _monitor = new Monitor(Mutex::barrier,                // rank
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
                         "GCTaskManager monitor",       // name
28163
322d55d167be 8047290: Make Mutex::_no_safepoint_check_flag locks verify that this lock never checks for safepoint
coleenp
parents: 27880
diff changeset
   415
                         Mutex::_allow_vm_block_flag,   // allow_vm_block
322d55d167be 8047290: Make Mutex::_no_safepoint_check_flag locks verify that this lock never checks for safepoint
coleenp
parents: 27880
diff changeset
   416
                         Monitor::_safepoint_check_never);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
  // The queue for the GCTaskManager must be a CHeapObj.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
  GCTaskQueue* unsynchronized_queue = GCTaskQueue::create_on_c_heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
  _queue = SynchronizedGCTaskQueue::create(unsynchronized_queue, lock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
  _noop_task = NoopGCTask::create_on_c_heap();
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 11208
diff changeset
   421
  _resource_flag = NEW_C_HEAP_ARRAY(bool, workers(), mtGC);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
    // Set up worker threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
    //     Distribute the workers among the available processors,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
    //     unless we were told not to, or if the os doesn't want to.
38216
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   426
    _processor_assignment = NEW_C_HEAP_ARRAY(uint, workers(), mtGC);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
    if (!BindGCTaskThreadsToCPUs ||
38216
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   428
        !os::distribute_processes(workers(), _processor_assignment)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
      for (uint a = 0; a < workers(); a += 1) {
38216
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   430
        _processor_assignment[a] = sentinel_worker();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
    }
38216
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   433
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 11208
diff changeset
   434
    _thread = NEW_C_HEAP_ARRAY(GCTaskThread*, workers(), mtGC);
38216
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   435
    _active_workers = ParallelGCThreads;
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   436
    if (UseDynamicNumberOfGCThreads && !FLAG_IS_CMDLINE(ParallelGCThreads)) {
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   437
      _active_workers = 1U;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
    }
38216
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   439
37242
91e5f98fff6f 8152632: Rename LogHandle(...) to Log(...)
stefank
parents: 37224
diff changeset
   440
    Log(gc, task, thread) log;
37224
fd3320bf6413 8153186: Convert TraceGCTaskThread to use unified logging
brutisso
parents: 35061
diff changeset
   441
    if (log.is_trace()) {
46701
f559541c0daa 8181917: Refactor UL LogStreams to avoid using resource area
stuefe
parents: 40096
diff changeset
   442
      LogStream ls(log.trace());
f559541c0daa 8181917: Refactor UL LogStreams to avoid using resource area
stuefe
parents: 40096
diff changeset
   443
      ls.print("GCTaskManager::initialize: distribution:");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
      for (uint t = 0; t < workers(); t += 1) {
46701
f559541c0daa 8181917: Refactor UL LogStreams to avoid using resource area
stuefe
parents: 40096
diff changeset
   445
        ls.print("  %u", _processor_assignment[t]);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
      }
46701
f559541c0daa 8181917: Refactor UL LogStreams to avoid using resource area
stuefe
parents: 40096
diff changeset
   447
      ls.cr();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
  reset_busy_workers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
  set_unblocked();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
  for (uint w = 0; w < workers(); w += 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
    set_resource_flag(w, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
  reset_delivered_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
  reset_completed_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
  reset_barriers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
  reset_emptied_queue();
38216
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   459
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   460
  add_workers(true);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
GCTaskManager::~GCTaskManager() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
  assert(busy_workers() == 0, "still have busy workers");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
  assert(queue()->is_empty(), "still have queued work");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
  NoopGCTask::destroy(_noop_task);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
  _noop_task = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
  if (_thread != NULL) {
38216
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   469
    for (uint i = 0; i < created_workers(); i += 1) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
      GCTaskThread::destroy(thread(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
      set_thread(i, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
    }
27880
afb974a04396 8060074: os::free() takes MemoryTrackingLevel but doesn't need it
coleenp
parents: 24424
diff changeset
   473
    FREE_C_HEAP_ARRAY(GCTaskThread*, _thread);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
    _thread = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
  }
38216
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   476
  if (_processor_assignment != NULL) {
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   477
    FREE_C_HEAP_ARRAY(uint, _processor_assignment);
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   478
    _processor_assignment = NULL;
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   479
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
  if (_resource_flag != NULL) {
27880
afb974a04396 8060074: os::free() takes MemoryTrackingLevel but doesn't need it
coleenp
parents: 24424
diff changeset
   481
    FREE_C_HEAP_ARRAY(bool, _resource_flag);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
    _resource_flag = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
  if (queue() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
    GCTaskQueue* unsynchronized_queue = queue()->unsynchronized_queue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
    GCTaskQueue::destroy(unsynchronized_queue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
    SynchronizedGCTaskQueue::destroy(queue());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
    _queue = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
  if (monitor() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
    delete monitor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
    _monitor = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   496
void GCTaskManager::set_active_gang() {
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   497
  _active_workers =
52904
d2f118d3f8e7 8213224: Move code related to GC threads calculation out of AdaptiveSizePolicy
manc
parents: 51332
diff changeset
   498
    WorkerPolicy::calc_active_workers(workers(),
d2f118d3f8e7 8213224: Move code related to GC threads calculation out of AdaptiveSizePolicy
manc
parents: 51332
diff changeset
   499
                                      active_workers(),
d2f118d3f8e7 8213224: Move code related to GC threads calculation out of AdaptiveSizePolicy
manc
parents: 51332
diff changeset
   500
                                      Threads::number_of_non_daemon_threads());
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   501
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   502
  assert(!all_workers_active() || active_workers() == ParallelGCThreads,
33105
294e48b4f704 8080775: Better argument formatting for assert() and friends
david
parents: 31330
diff changeset
   503
         "all_workers_active() is  incorrect: "
294e48b4f704 8080775: Better argument formatting for assert() and friends
david
parents: 31330
diff changeset
   504
         "active %d  ParallelGCThreads %u", active_workers(),
294e48b4f704 8080775: Better argument formatting for assert() and friends
david
parents: 31330
diff changeset
   505
         ParallelGCThreads);
38216
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   506
  _active_workers = MIN2(_active_workers, _workers);
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   507
  // "add_workers" does not guarantee any additional workers
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   508
  add_workers(false);
35061
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33126
diff changeset
   509
  log_trace(gc, task)("GCTaskManager::set_active_gang(): "
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33126
diff changeset
   510
                      "all_workers_active()  %d  workers %d  "
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33126
diff changeset
   511
                      "active  %d  ParallelGCThreads %u",
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33126
diff changeset
   512
                      all_workers_active(), workers(),  active_workers(),
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33126
diff changeset
   513
                      ParallelGCThreads);
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   514
}
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   515
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   516
// Create IdleGCTasks for inactive workers.
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   517
// Creates tasks in a ResourceArea and assumes
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   518
// an appropriate ResourceMark.
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   519
void GCTaskManager::task_idle_workers() {
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   520
  {
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   521
    int more_inactive_workers = 0;
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   522
    {
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   523
      // Stop any idle tasks from exiting their IdleGCTask's
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   524
      // and get the count for additional IdleGCTask's under
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   525
      // the GCTaskManager's monitor so that the "more_inactive_workers"
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   526
      // count is correct.
54623
1126f0607c70 8222811: Consolidate MutexLockerEx and MutexLocker
coleenp
parents: 52904
diff changeset
   527
      MutexLocker ml(monitor(), Mutex::_no_safepoint_check_flag);
33125
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   528
      _wait_helper.set_should_wait(true);
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   529
      // active_workers are a number being requested.  idle_workers
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   530
      // are the number currently idle.  If all the workers are being
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   531
      // requested to be active but some are already idle, reduce
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   532
      // the number of active_workers to be consistent with the
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   533
      // number of idle_workers.  The idle_workers are stuck in
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   534
      // idle tasks and will no longer be release (since a new GC
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   535
      // is starting).  Try later to release enough idle_workers
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   536
      // to allow the desired number of active_workers.
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   537
      more_inactive_workers =
38216
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   538
        created_workers() - active_workers() - idle_workers();
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   539
      if (more_inactive_workers < 0) {
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   540
        int reduced_active_workers = active_workers() + more_inactive_workers;
40096
246c62cd9180 8159073: : Error handling incomplete when creating GC threads lazily
jmasa
parents: 39704
diff changeset
   541
        update_active_workers(reduced_active_workers);
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   542
        more_inactive_workers = 0;
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   543
      }
35061
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33126
diff changeset
   544
      log_trace(gc, task)("JT: %d  workers %d  active  %d  idle %d  more %d",
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33126
diff changeset
   545
                          Threads::number_of_non_daemon_threads(),
38216
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   546
                          created_workers(),
35061
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33126
diff changeset
   547
                          active_workers(),
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33126
diff changeset
   548
                          idle_workers(),
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33126
diff changeset
   549
                          more_inactive_workers);
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   550
    }
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   551
    GCTaskQueue* q = GCTaskQueue::create();
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   552
    for(uint i = 0; i < (uint) more_inactive_workers; i++) {
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   553
      q->enqueue(IdleGCTask::create_on_c_heap());
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   554
      increment_idle_workers();
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   555
    }
38216
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   556
    assert(created_workers() == active_workers() + idle_workers(),
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   557
      "total workers should equal active + inactive");
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   558
    add_list(q);
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   559
    // GCTaskQueue* q was created in a ResourceArea so a
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   560
    // destroy() call is not needed.
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   561
  }
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   562
}
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   563
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   564
void  GCTaskManager::release_idle_workers() {
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   565
  {
54623
1126f0607c70 8222811: Consolidate MutexLockerEx and MutexLocker
coleenp
parents: 52904
diff changeset
   566
    MutexLocker ml(monitor(),
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   567
      Mutex::_no_safepoint_check_flag);
33125
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   568
    _wait_helper.set_should_wait(false);
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   569
    monitor()->notify_all();
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   570
  // Release monitor
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   571
  }
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   572
}
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   573
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
void GCTaskManager::print_task_time_stamps() {
35061
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33126
diff changeset
   575
  if (!log_is_enabled(Debug, gc, task, time)) {
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33126
diff changeset
   576
    return;
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33126
diff changeset
   577
  }
38216
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   578
  uint num_thr = created_workers();
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   579
  for(uint i=0; i < num_thr; i++) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
    GCTaskThread* t = thread(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
    t->print_task_time_stamps();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
void GCTaskManager::print_threads_on(outputStream* st) {
38216
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   586
  uint num_thr = created_workers();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
  for (uint i = 0; i < num_thr; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
    thread(i)->print_on(st);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
    st->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
void GCTaskManager::threads_do(ThreadClosure* tc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
  assert(tc != NULL, "Null ThreadClosure");
38216
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   595
  uint num_thr = created_workers();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
  for (uint i = 0; i < num_thr; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
    tc->do_thread(thread(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
GCTaskThread* GCTaskManager::thread(uint which) {
38216
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   602
  assert(which < created_workers(), "index out of bounds");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
  assert(_thread[which] != NULL, "shouldn't have null thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
  return _thread[which];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
void GCTaskManager::set_thread(uint which, GCTaskThread* value) {
38216
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   608
  // "_created_workers" may not have been updated yet so use workers()
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
  assert(which < workers(), "index out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
  assert(value != NULL, "shouldn't have null thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
  _thread[which] = value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
void GCTaskManager::add_task(GCTask* task) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
  assert(task != NULL, "shouldn't have null task");
54623
1126f0607c70 8222811: Consolidate MutexLockerEx and MutexLocker
coleenp
parents: 52904
diff changeset
   616
  MutexLocker ml(monitor(), Mutex::_no_safepoint_check_flag);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
  if (TraceGCTaskManager) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
    tty->print_cr("GCTaskManager::add_task(" INTPTR_FORMAT " [%s])",
29798
451c73fdf690 8076071: parallelScavenge: PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC needs to be removed from source files
david
parents: 28163
diff changeset
   619
                  p2i(task), GCTask::Kind::to_string(task->kind()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
  queue()->enqueue(task);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
  // Notify with the lock held to avoid missed notifies.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
  if (TraceGCTaskManager) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
    tty->print_cr("    GCTaskManager::add_task (%s)->notify_all",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
                  monitor()->name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
  (void) monitor()->notify_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
  // Release monitor().
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
void GCTaskManager::add_list(GCTaskQueue* list) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
  assert(list != NULL, "shouldn't have null task");
54623
1126f0607c70 8222811: Consolidate MutexLockerEx and MutexLocker
coleenp
parents: 52904
diff changeset
   633
  MutexLocker ml(monitor(), Mutex::_no_safepoint_check_flag);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
  if (TraceGCTaskManager) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
    tty->print_cr("GCTaskManager::add_list(%u)", list->length());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
  queue()->enqueue(list);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
  // Notify with the lock held to avoid missed notifies.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
  if (TraceGCTaskManager) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
    tty->print_cr("    GCTaskManager::add_list (%s)->notify_all",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
                  monitor()->name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
  (void) monitor()->notify_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
  // Release monitor().
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   647
// GC workers wait in get_task() for new work to be added
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   648
// to the GCTaskManager's queue.  When new work is added,
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   649
// a notify is sent to the waiting GC workers which then
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   650
// compete to get tasks.  If a GC worker wakes up and there
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   651
// is no work on the queue, it is given a noop_task to execute
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   652
// and then loops to find more work.
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   653
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
GCTask* GCTaskManager::get_task(uint which) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
  GCTask* result = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
  // Grab the queue lock.
54645
05aaccf7d558 8222988: Use MonitorLocker rather than MutexLocker when wait/notify used
coleenp
parents: 54623
diff changeset
   657
  MonitorLocker ml(monitor(), Mutex::_no_safepoint_check_flag);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
  // Wait while the queue is block or
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
  // there is nothing to do, except maybe release resources.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
  while (is_blocked() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
         (queue()->is_empty() && !should_release_resources(which))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
    if (TraceGCTaskManager) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
      tty->print_cr("GCTaskManager::get_task(%u)"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
                    "  blocked: %s"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
                    "  empty: %s"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
                    "  release: %s",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
                    which,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
                    is_blocked() ? "true" : "false",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
                    queue()->is_empty() ? "true" : "false",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
                    should_release_resources(which) ? "true" : "false");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
      tty->print_cr("    => (%s)->wait()",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
                    monitor()->name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
    }
54645
05aaccf7d558 8222988: Use MonitorLocker rather than MutexLocker when wait/notify used
coleenp
parents: 54623
diff changeset
   674
    ml.wait(0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
  // We've reacquired the queue lock here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
  // Figure out which condition caused us to exit the loop above.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
  if (!queue()->is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
    if (UseGCTaskAffinity) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
      result = queue()->dequeue(which);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
      result = queue()->dequeue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
    if (result->is_barrier_task()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
      assert(which != sentinel_worker(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
             "blocker shouldn't be bogus");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
      set_blocking_worker(which);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
    // The queue is empty, but we were woken up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
    // Just hand back a Noop task,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
    // in case someone wanted us to release resources, or whatever.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
    result = noop_task();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
  assert(result != NULL, "shouldn't have null task");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
  if (TraceGCTaskManager) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
    tty->print_cr("GCTaskManager::get_task(%u) => " INTPTR_FORMAT " [%s]",
29798
451c73fdf690 8076071: parallelScavenge: PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC needs to be removed from source files
david
parents: 28163
diff changeset
   698
                  which, p2i(result), GCTask::Kind::to_string(result->kind()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
    tty->print_cr("     %s", result->name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
  }
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   701
  if (!result->is_idle_task()) {
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   702
    increment_busy_workers();
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   703
    increment_delivered_tasks();
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   704
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
  // Release monitor().
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
void GCTaskManager::note_completion(uint which) {
54623
1126f0607c70 8222811: Consolidate MutexLockerEx and MutexLocker
coleenp
parents: 52904
diff changeset
   710
  MutexLocker ml(monitor(), Mutex::_no_safepoint_check_flag);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
  if (TraceGCTaskManager) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
    tty->print_cr("GCTaskManager::note_completion(%u)", which);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
  // If we are blocked, check if the completing thread is the blocker.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
  if (blocking_worker() == which) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
    assert(blocking_worker() != sentinel_worker(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
           "blocker shouldn't be bogus");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
    increment_barriers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
    set_unblocked();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
  increment_completed_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
  uint active = decrement_busy_workers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
  if ((active == 0) && (queue()->is_empty())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
    increment_emptied_queue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
    if (TraceGCTaskManager) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
      tty->print_cr("    GCTaskManager::note_completion(%u) done", which);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
  if (TraceGCTaskManager) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
    tty->print_cr("    GCTaskManager::note_completion(%u) (%s)->notify_all",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
                  which, monitor()->name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
    tty->print_cr("  "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
                  "  blocked: %s"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
                  "  empty: %s"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
                  "  release: %s",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
                  is_blocked() ? "true" : "false",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
                  queue()->is_empty() ? "true" : "false",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
                  should_release_resources(which) ? "true" : "false");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
    tty->print_cr("  "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
                  "  delivered: %u"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
                  "  completed: %u"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
                  "  barriers: %u"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
                  "  emptied: %u",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
                  delivered_tasks(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
                  completed_tasks(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
                  barriers(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
                  emptied_queue());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
  // Tell everyone that a task has completed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
  (void) monitor()->notify_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
  // Release monitor().
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
uint GCTaskManager::increment_busy_workers() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
  assert(queue()->own_lock(), "don't own the lock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
  _busy_workers += 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
  return _busy_workers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
uint GCTaskManager::decrement_busy_workers() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
  assert(queue()->own_lock(), "don't own the lock");
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   762
  assert(_busy_workers > 0, "About to make a mistake");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
  _busy_workers -= 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
  return _busy_workers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   766
489c9b5090e2 Initial load
duke
parents:
diff changeset
   767
void GCTaskManager::release_all_resources() {
33124
e256f7a94c38 8138862: Remove some unused code and subclasses in gcTaskManager.hpp/cpp
brutisso
parents: 33105
diff changeset
   768
  // If you want this to be done atomically, do it in a WaitForBarrierGCTask.
38216
250794c6f95f 6858051: Create GC worker threads dynamically
jmasa
parents: 37242
diff changeset
   769
  for (uint i = 0; i < created_workers(); i += 1) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   770
    set_resource_flag(i, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   771
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
bool GCTaskManager::should_release_resources(uint which) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
  // This can be done without a lock because each thread reads one element.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
  return resource_flag(which);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
void GCTaskManager::note_release(uint which) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
  // This can be done without a lock because each thread writes one element.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
  set_resource_flag(which, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   784
// "list" contains tasks that are ready to execute.  Those
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   785
// tasks are added to the GCTaskManager's queue of tasks and
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   786
// then the GC workers are notified that there is new work to
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   787
// do.
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   788
//
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   789
// Typically different types of tasks can be added to the "list".
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   790
// For example in PSScavenge OldToYoungRootsTask, SerialOldToYoungRootsTask,
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   791
// ScavengeRootsTask, and StealTask tasks are all added to the list
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   792
// and then the GC workers are notified of new work.  The tasks are
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   793
// handed out in the order in which they are added to the list
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   794
// (although execution is not necessarily in that order).  As long
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   795
// as any tasks are running the GCTaskManager will wait for execution
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   796
// to complete.  GC workers that execute a stealing task remain in
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   797
// the stealing task until all stealing tasks have completed.  The load
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   798
// balancing afforded by the stealing tasks work best if the stealing
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   799
// tasks are added last to the list.
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   800
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   801
void GCTaskManager::execute_and_wait(GCTaskQueue* list) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
  WaitForBarrierGCTask* fin = WaitForBarrierGCTask::create();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   803
  list->enqueue(fin);
11208
101816314520 7119584: UseParallelGC barrier task can be overwritten.
jmasa
parents: 11174
diff changeset
   804
  // The barrier task will be read by one of the GC
101816314520 7119584: UseParallelGC barrier task can be overwritten.
jmasa
parents: 11174
diff changeset
   805
  // workers once it is added to the list of tasks.
101816314520 7119584: UseParallelGC barrier task can be overwritten.
jmasa
parents: 11174
diff changeset
   806
  // Be sure that is globally visible before the
101816314520 7119584: UseParallelGC barrier task can be overwritten.
jmasa
parents: 11174
diff changeset
   807
  // GC worker reads it (which is after the task is added
101816314520 7119584: UseParallelGC barrier task can be overwritten.
jmasa
parents: 11174
diff changeset
   808
  // to the list of tasks below).
101816314520 7119584: UseParallelGC barrier task can be overwritten.
jmasa
parents: 11174
diff changeset
   809
  OrderAccess::storestore();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   810
  add_list(list);
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   811
  fin->wait_for(true /* reset */);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   812
  // We have to release the barrier tasks!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   813
  WaitForBarrierGCTask::destroy(fin);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   814
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   815
489c9b5090e2 Initial load
duke
parents:
diff changeset
   816
bool GCTaskManager::resource_flag(uint which) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   817
  assert(which < workers(), "index out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   818
  return _resource_flag[which];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   819
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   820
489c9b5090e2 Initial load
duke
parents:
diff changeset
   821
void GCTaskManager::set_resource_flag(uint which, bool value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   822
  assert(which < workers(), "index out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   823
  _resource_flag[which] = value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   824
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   825
489c9b5090e2 Initial load
duke
parents:
diff changeset
   826
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   827
// NoopGCTask
489c9b5090e2 Initial load
duke
parents:
diff changeset
   828
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   829
489c9b5090e2 Initial load
duke
parents:
diff changeset
   830
NoopGCTask* NoopGCTask::create_on_c_heap() {
33124
e256f7a94c38 8138862: Remove some unused code and subclasses in gcTaskManager.hpp/cpp
brutisso
parents: 33105
diff changeset
   831
  NoopGCTask* result = new(ResourceObj::C_HEAP, mtGC) NoopGCTask();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   832
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   833
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   834
489c9b5090e2 Initial load
duke
parents:
diff changeset
   835
void NoopGCTask::destroy(NoopGCTask* that) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   836
  if (that != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
    that->destruct();
33124
e256f7a94c38 8138862: Remove some unused code and subclasses in gcTaskManager.hpp/cpp
brutisso
parents: 33105
diff changeset
   838
    FreeHeap(that);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   839
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   840
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   841
33126
260ff671354b 8138707: TestPromotionEventWithParallelScavenge.java crashes using undefined GC id.
brutisso
parents: 33125
diff changeset
   842
// This task should never be performing GC work that require
260ff671354b 8138707: TestPromotionEventWithParallelScavenge.java crashes using undefined GC id.
brutisso
parents: 33125
diff changeset
   843
// a valid GC id.
260ff671354b 8138707: TestPromotionEventWithParallelScavenge.java crashes using undefined GC id.
brutisso
parents: 33125
diff changeset
   844
NoopGCTask::NoopGCTask() : GCTask(GCTask::Kind::noop_task, GCId::undefined()) { }
260ff671354b 8138707: TestPromotionEventWithParallelScavenge.java crashes using undefined GC id.
brutisso
parents: 33125
diff changeset
   845
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   846
void NoopGCTask::destruct() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   847
  // This has to know it's superclass structure, just like the constructor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   848
  this->GCTask::destruct();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
  // Nothing else to do.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   850
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
//
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   853
// IdleGCTask
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   854
//
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   855
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   856
IdleGCTask* IdleGCTask::create() {
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   857
  IdleGCTask* result = new IdleGCTask(false);
11208
101816314520 7119584: UseParallelGC barrier task can be overwritten.
jmasa
parents: 11174
diff changeset
   858
  assert(UseDynamicNumberOfGCThreads,
101816314520 7119584: UseParallelGC barrier task can be overwritten.
jmasa
parents: 11174
diff changeset
   859
    "Should only be used with dynamic GC thread");
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   860
  return result;
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   861
}
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   862
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   863
IdleGCTask* IdleGCTask::create_on_c_heap() {
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 11208
diff changeset
   864
  IdleGCTask* result = new(ResourceObj::C_HEAP, mtGC) IdleGCTask(true);
11208
101816314520 7119584: UseParallelGC barrier task can be overwritten.
jmasa
parents: 11174
diff changeset
   865
  assert(UseDynamicNumberOfGCThreads,
101816314520 7119584: UseParallelGC barrier task can be overwritten.
jmasa
parents: 11174
diff changeset
   866
    "Should only be used with dynamic GC thread");
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   867
  return result;
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   868
}
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   869
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   870
void IdleGCTask::do_it(GCTaskManager* manager, uint which) {
33125
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   871
  WaitHelper* wait_helper = manager->wait_helper();
35061
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33126
diff changeset
   872
  log_trace(gc, task)("[" INTPTR_FORMAT "] IdleGCTask:::do_it() should_wait: %s",
33125
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   873
      p2i(this), wait_helper->should_wait() ? "true" : "false");
35061
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33126
diff changeset
   874
54645
05aaccf7d558 8222988: Use MonitorLocker rather than MutexLocker when wait/notify used
coleenp
parents: 54623
diff changeset
   875
  MonitorLocker ml(manager->monitor(), Mutex::_no_safepoint_check_flag);
35061
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33126
diff changeset
   876
  log_trace(gc, task)("--- idle %d", which);
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   877
  // Increment has to be done when the idle tasks are created.
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   878
  // manager->increment_idle_workers();
54645
05aaccf7d558 8222988: Use MonitorLocker rather than MutexLocker when wait/notify used
coleenp
parents: 54623
diff changeset
   879
  ml.notify_all();
33125
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   880
  while (wait_helper->should_wait()) {
35061
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33126
diff changeset
   881
    log_trace(gc, task)("[" INTPTR_FORMAT "] IdleGCTask::do_it()  [" INTPTR_FORMAT "] (%s)->wait()",
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33126
diff changeset
   882
      p2i(this), p2i(manager->monitor()), manager->monitor()->name());
54645
05aaccf7d558 8222988: Use MonitorLocker rather than MutexLocker when wait/notify used
coleenp
parents: 54623
diff changeset
   883
    ml.wait(0);
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   884
  }
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   885
  manager->decrement_idle_workers();
35061
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33126
diff changeset
   886
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33126
diff changeset
   887
  log_trace(gc, task)("--- release %d", which);
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33126
diff changeset
   888
  log_trace(gc, task)("[" INTPTR_FORMAT "] IdleGCTask::do_it() returns should_wait: %s",
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33126
diff changeset
   889
    p2i(this), wait_helper->should_wait() ? "true" : "false");
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   890
  // Release monitor().
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   891
}
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   892
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   893
void IdleGCTask::destroy(IdleGCTask* that) {
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   894
  if (that != NULL) {
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   895
    that->destruct();
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   896
    if (that->is_c_heap_obj()) {
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   897
      FreeHeap(that);
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   898
    }
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   899
  }
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   900
}
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   901
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   902
void IdleGCTask::destruct() {
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   903
  // This has to know it's superclass structure, just like the constructor.
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   904
  this->GCTask::destruct();
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   905
  // Nothing else to do.
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   906
}
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   907
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   908
//
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
// WaitForBarrierGCTask
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   911
WaitForBarrierGCTask* WaitForBarrierGCTask::create() {
33125
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   912
  WaitForBarrierGCTask* result = new WaitForBarrierGCTask();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   913
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   914
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   915
33125
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   916
WaitForBarrierGCTask::WaitForBarrierGCTask() : GCTask(GCTask::Kind::wait_for_barrier_task) { }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   917
489c9b5090e2 Initial load
duke
parents:
diff changeset
   918
void WaitForBarrierGCTask::destroy(WaitForBarrierGCTask* that) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   919
  if (that != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   920
    if (TraceGCTaskManager) {
33125
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   921
      tty->print_cr("[" INTPTR_FORMAT "] WaitForBarrierGCTask::destroy()", p2i(that));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   922
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   923
    that->destruct();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   924
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   925
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   926
489c9b5090e2 Initial load
duke
parents:
diff changeset
   927
void WaitForBarrierGCTask::destruct() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   928
  if (TraceGCTaskManager) {
33125
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   929
    tty->print_cr("[" INTPTR_FORMAT "] WaitForBarrierGCTask::destruct()", p2i(this));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   930
  }
33124
e256f7a94c38 8138862: Remove some unused code and subclasses in gcTaskManager.hpp/cpp
brutisso
parents: 33105
diff changeset
   931
  this->GCTask::destruct();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   932
  // Clean up that should be in the destructor,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
  // except that ResourceMarks don't call destructors.
33125
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   934
  _wait_helper.release_monitor();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   935
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
33124
e256f7a94c38 8138862: Remove some unused code and subclasses in gcTaskManager.hpp/cpp
brutisso
parents: 33105
diff changeset
   937
void WaitForBarrierGCTask::do_it_internal(GCTaskManager* manager, uint which) {
e256f7a94c38 8138862: Remove some unused code and subclasses in gcTaskManager.hpp/cpp
brutisso
parents: 33105
diff changeset
   938
  // Wait for this to be the only busy worker.
e256f7a94c38 8138862: Remove some unused code and subclasses in gcTaskManager.hpp/cpp
brutisso
parents: 33105
diff changeset
   939
  assert(manager->monitor()->owned_by_self(), "don't own the lock");
e256f7a94c38 8138862: Remove some unused code and subclasses in gcTaskManager.hpp/cpp
brutisso
parents: 33105
diff changeset
   940
  assert(manager->is_blocked(), "manager isn't blocked");
e256f7a94c38 8138862: Remove some unused code and subclasses in gcTaskManager.hpp/cpp
brutisso
parents: 33105
diff changeset
   941
  while (manager->busy_workers() > 1) {
e256f7a94c38 8138862: Remove some unused code and subclasses in gcTaskManager.hpp/cpp
brutisso
parents: 33105
diff changeset
   942
    if (TraceGCTaskManager) {
e256f7a94c38 8138862: Remove some unused code and subclasses in gcTaskManager.hpp/cpp
brutisso
parents: 33105
diff changeset
   943
      tty->print_cr("WaitForBarrierGCTask::do_it(%u) waiting on %u workers",
e256f7a94c38 8138862: Remove some unused code and subclasses in gcTaskManager.hpp/cpp
brutisso
parents: 33105
diff changeset
   944
                    which, manager->busy_workers());
e256f7a94c38 8138862: Remove some unused code and subclasses in gcTaskManager.hpp/cpp
brutisso
parents: 33105
diff changeset
   945
    }
54623
1126f0607c70 8222811: Consolidate MutexLockerEx and MutexLocker
coleenp
parents: 52904
diff changeset
   946
    manager->monitor()->wait_without_safepoint_check(0);
33124
e256f7a94c38 8138862: Remove some unused code and subclasses in gcTaskManager.hpp/cpp
brutisso
parents: 33105
diff changeset
   947
  }
e256f7a94c38 8138862: Remove some unused code and subclasses in gcTaskManager.hpp/cpp
brutisso
parents: 33105
diff changeset
   948
}
e256f7a94c38 8138862: Remove some unused code and subclasses in gcTaskManager.hpp/cpp
brutisso
parents: 33105
diff changeset
   949
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   950
void WaitForBarrierGCTask::do_it(GCTaskManager* manager, uint which) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   951
  if (TraceGCTaskManager) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
    tty->print_cr("[" INTPTR_FORMAT "]"
33125
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   953
                  " WaitForBarrierGCTask::do_it() waiting for idle",
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   954
                  p2i(this));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   955
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   956
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
    // First, wait for the barrier to arrive.
54623
1126f0607c70 8222811: Consolidate MutexLockerEx and MutexLocker
coleenp
parents: 52904
diff changeset
   958
    MutexLocker ml(manager->lock(), Mutex::_no_safepoint_check_flag);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   959
    do_it_internal(manager, which);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   960
    // Release manager->lock().
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
  }
33125
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   962
  // Then notify the waiter.
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   963
  _wait_helper.notify();
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   964
}
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   965
51332
c25572739e7c 8208669: GC changes to allow enabling -Wreorder
tschatzl
parents: 50429
diff changeset
   966
WaitHelper::WaitHelper() : _monitor(MonitorSupply::reserve()), _should_wait(true) {
33125
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   967
  if (TraceGCTaskManager) {
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   968
    tty->print_cr("[" INTPTR_FORMAT "]"
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   969
                  " WaitHelper::WaitHelper()"
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   970
                  "  monitor: " INTPTR_FORMAT,
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   971
                  p2i(this), p2i(monitor()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   972
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   973
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   974
33125
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   975
void WaitHelper::release_monitor() {
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   976
  assert(_monitor != NULL, "");
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   977
  MonitorSupply::release(_monitor);
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   978
  _monitor = NULL;
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   979
}
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   980
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   981
WaitHelper::~WaitHelper() {
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   982
  release_monitor();
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   983
}
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   984
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
   985
void WaitHelper::wait_for(bool reset) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   986
  if (TraceGCTaskManager) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   987
    tty->print_cr("[" INTPTR_FORMAT "]"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   988
                  " WaitForBarrierGCTask::wait_for()"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   989
      "  should_wait: %s",
29798
451c73fdf690 8076071: parallelScavenge: PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC needs to be removed from source files
david
parents: 28163
diff changeset
   990
      p2i(this), should_wait() ? "true" : "false");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   991
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   992
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   993
    // Grab the lock and check again.
54645
05aaccf7d558 8222988: Use MonitorLocker rather than MutexLocker when wait/notify used
coleenp
parents: 54623
diff changeset
   994
    MonitorLocker ml(monitor(), Mutex::_no_safepoint_check_flag);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   995
    while (should_wait()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   996
      if (TraceGCTaskManager) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   997
        tty->print_cr("[" INTPTR_FORMAT "]"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   998
                      " WaitForBarrierGCTask::wait_for()"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   999
          "  [" INTPTR_FORMAT "] (%s)->wait()",
29798
451c73fdf690 8076071: parallelScavenge: PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC needs to be removed from source files
david
parents: 28163
diff changeset
  1000
          p2i(this), p2i(monitor()), monitor()->name());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1001
      }
54645
05aaccf7d558 8222988: Use MonitorLocker rather than MutexLocker when wait/notify used
coleenp
parents: 54623
diff changeset
  1002
      ml.wait(0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1003
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1004
    // Reset the flag in case someone reuses this task.
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
  1005
    if (reset) {
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
  1006
      set_should_wait(true);
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
  1007
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1008
    if (TraceGCTaskManager) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1009
      tty->print_cr("[" INTPTR_FORMAT "]"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1010
                    " WaitForBarrierGCTask::wait_for() returns"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1011
        "  should_wait: %s",
29798
451c73fdf690 8076071: parallelScavenge: PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC needs to be removed from source files
david
parents: 28163
diff changeset
  1012
        p2i(this), should_wait() ? "true" : "false");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1013
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1014
    // Release monitor().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1015
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1016
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1017
33125
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
  1018
void WaitHelper::notify() {
54623
1126f0607c70 8222811: Consolidate MutexLockerEx and MutexLocker
coleenp
parents: 52904
diff changeset
  1019
  MutexLocker ml(monitor(), Mutex::_no_safepoint_check_flag);
33125
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
  1020
  set_should_wait(false);
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
  1021
  // Waiter doesn't miss the notify in the wait_for method
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
  1022
  // since it checks the flag after grabbing the monitor.
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
  1023
  if (TraceGCTaskManager) {
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
  1024
    tty->print_cr("[" INTPTR_FORMAT "]"
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
  1025
                  " WaitForBarrierGCTask::do_it()"
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
  1026
                  "  [" INTPTR_FORMAT "] (%s)->notify_all()",
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
  1027
                  p2i(this), p2i(monitor()), monitor()->name());
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
  1028
  }
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
  1029
  monitor()->notify_all();
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
  1030
}
bc61fce9bac3 8138863: Refactor WaitForBarrierGCTask
brutisso
parents: 33124
diff changeset
  1031
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1032
Mutex*                   MonitorSupply::_lock     = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1033
GrowableArray<Monitor*>* MonitorSupply::_freelist = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1034
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1035
Monitor* MonitorSupply::reserve() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1036
  Monitor* result = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1037
  // Lazy initialization: possible race.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1038
  if (lock() == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1039
    _lock = new Mutex(Mutex::barrier,                  // rank
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1040
                      "MonitorSupply mutex",           // name
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1041
                      Mutex::_allow_vm_block_flag);    // allow_vm_block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1042
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1043
  {
54623
1126f0607c70 8222811: Consolidate MutexLockerEx and MutexLocker
coleenp
parents: 52904
diff changeset
  1044
    MutexLocker ml(lock());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1045
    // Lazy initialization.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1046
    if (freelist() == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1047
      _freelist =
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 11208
diff changeset
  1048
        new(ResourceObj::C_HEAP, mtGC) GrowableArray<Monitor*>(ParallelGCThreads,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1049
                                                         true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1050
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1051
    if (! freelist()->is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1052
      result = freelist()->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1053
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1054
      result = new Monitor(Mutex::barrier,                  // rank
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1055
                           "MonitorSupply monitor",         // name
28163
322d55d167be 8047290: Make Mutex::_no_safepoint_check_flag locks verify that this lock never checks for safepoint
coleenp
parents: 27880
diff changeset
  1056
                           Mutex::_allow_vm_block_flag,     // allow_vm_block
322d55d167be 8047290: Make Mutex::_no_safepoint_check_flag locks verify that this lock never checks for safepoint
coleenp
parents: 27880
diff changeset
  1057
                           Monitor::_safepoint_check_never);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1058
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1059
    guarantee(result != NULL, "shouldn't return NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1060
    assert(!result->is_locked(), "shouldn't be locked");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1061
    // release lock().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1062
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1063
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1064
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1065
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1066
void MonitorSupply::release(Monitor* instance) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1067
  assert(instance != NULL, "shouldn't release NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1068
  assert(!instance->is_locked(), "shouldn't be locked");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1069
  {
54623
1126f0607c70 8222811: Consolidate MutexLockerEx and MutexLocker
coleenp
parents: 52904
diff changeset
  1070
    MutexLocker ml(lock());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1071
    freelist()->push(instance);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1072
    // release lock().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1073
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1074
}