src/hotspot/share/gc/shared/taskqueue.cpp
author tschatzl
Fri, 22 Nov 2019 10:03:38 +0100
changeset 59221 cc3a82fc7bcb
parent 58041 d8902e9c307c
child 59252 623722a6aeb9
permissions -rw-r--r--
8233702: Introduce helper function to clamp value to range Reviewed-by: sjohanss, kbarrett
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
53545
2c38991dd9b0 8215047: Task terminators do not complete termination in consistent state
zgu
parents: 52905
diff changeset
     2
 * Copyright (c) 2001, 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: 5076
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5076
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: 5076
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6759
diff changeset
    25
#include "precompiled.hpp"
30764
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 30585
diff changeset
    26
#include "gc/shared/taskqueue.hpp"
52905
bec57b4a6d69 8204947: Port ShenandoahTaskTerminator to mainline and make it default
zgu
parents: 51292
diff changeset
    27
#include "gc/shared/owstTaskTerminator.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6759
diff changeset
    28
#include "oops/oop.inline.hpp"
35061
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33105
diff changeset
    29
#include "logging/log.hpp"
40655
9f644073d3a0 8157907: Incorrect inclusion of atomic.hpp instead of atomic.inline.hpp
dholmes
parents: 35061
diff changeset
    30
#include "runtime/atomic.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6759
diff changeset
    31
#include "runtime/os.hpp"
14583
d70ee55535f4 8003935: Simplify the needed includes for using Thread::current()
stefank
parents: 10565
diff changeset
    32
#include "runtime/thread.inline.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6759
diff changeset
    33
#include "utilities/debug.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6759
diff changeset
    34
#include "utilities/stack.inline.hpp"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
2010
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
    36
#ifdef TRACESPINNING
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
    37
uint ParallelTaskTerminator::_total_yields = 0;
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
    38
uint ParallelTaskTerminator::_total_spins = 0;
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
    39
uint ParallelTaskTerminator::_total_peeks = 0;
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
    40
#endif
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
    41
6067
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    42
#if TASKQUEUE_STATS
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    43
const char * const TaskQueueStats::_names[last_stat_id] = {
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    44
  "qpush", "qpop", "qpop-s", "qattempt", "qsteal", "opush", "omax"
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    45
};
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    46
6251
90e562b9f1cc 6966222: G1: simplify TaskQueue overflow handling
jcoomes
parents: 6067
diff changeset
    47
TaskQueueStats & TaskQueueStats::operator +=(const TaskQueueStats & addend)
90e562b9f1cc 6966222: G1: simplify TaskQueue overflow handling
jcoomes
parents: 6067
diff changeset
    48
{
90e562b9f1cc 6966222: G1: simplify TaskQueue overflow handling
jcoomes
parents: 6067
diff changeset
    49
  for (unsigned int i = 0; i < last_stat_id; ++i) {
90e562b9f1cc 6966222: G1: simplify TaskQueue overflow handling
jcoomes
parents: 6067
diff changeset
    50
    _stats[i] += addend._stats[i];
90e562b9f1cc 6966222: G1: simplify TaskQueue overflow handling
jcoomes
parents: 6067
diff changeset
    51
  }
90e562b9f1cc 6966222: G1: simplify TaskQueue overflow handling
jcoomes
parents: 6067
diff changeset
    52
  return *this;
90e562b9f1cc 6966222: G1: simplify TaskQueue overflow handling
jcoomes
parents: 6067
diff changeset
    53
}
90e562b9f1cc 6966222: G1: simplify TaskQueue overflow handling
jcoomes
parents: 6067
diff changeset
    54
6067
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    55
void TaskQueueStats::print_header(unsigned int line, outputStream* const stream,
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    56
                                  unsigned int width)
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    57
{
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    58
  // Use a width w: 1 <= w <= max_width
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    59
  const unsigned int max_width = 40;
59221
cc3a82fc7bcb 8233702: Introduce helper function to clamp value to range
tschatzl
parents: 58041
diff changeset
    60
  const unsigned int w = clamp(width, 1u, max_width);
6067
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    61
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    62
  if (line == 0) { // spaces equal in width to the header
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    63
    const unsigned int hdr_width = w * last_stat_id + last_stat_id - 1;
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    64
    stream->print("%*s", hdr_width, " ");
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    65
  } else if (line == 1) { // labels
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    66
    stream->print("%*s", w, _names[0]);
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    67
    for (unsigned int i = 1; i < last_stat_id; ++i) {
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    68
      stream->print(" %*s", w, _names[i]);
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    69
    }
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    70
  } else if (line == 2) { // dashed lines
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    71
    char dashes[max_width + 1];
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    72
    memset(dashes, '-', w);
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    73
    dashes[w] = '\0';
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    74
    stream->print("%s", dashes);
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    75
    for (unsigned int i = 1; i < last_stat_id; ++i) {
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    76
      stream->print(" %s", dashes);
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    77
    }
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    78
  }
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    79
}
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    80
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    81
void TaskQueueStats::print(outputStream* stream, unsigned int width) const
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    82
{
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    83
  #define FMT SIZE_FORMAT_W(*)
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    84
  stream->print(FMT, width, _stats[0]);
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    85
  for (unsigned int i = 1; i < last_stat_id; ++i) {
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    86
    stream->print(" " FMT, width, _stats[i]);
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    87
  }
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    88
  #undef FMT
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
    89
}
6251
90e562b9f1cc 6966222: G1: simplify TaskQueue overflow handling
jcoomes
parents: 6067
diff changeset
    90
90e562b9f1cc 6966222: G1: simplify TaskQueue overflow handling
jcoomes
parents: 6067
diff changeset
    91
#ifdef ASSERT
90e562b9f1cc 6966222: G1: simplify TaskQueue overflow handling
jcoomes
parents: 6067
diff changeset
    92
// Invariants which should hold after a TaskQueue has been emptied and is
90e562b9f1cc 6966222: G1: simplify TaskQueue overflow handling
jcoomes
parents: 6067
diff changeset
    93
// quiescent; they do not hold at arbitrary times.
90e562b9f1cc 6966222: G1: simplify TaskQueue overflow handling
jcoomes
parents: 6067
diff changeset
    94
void TaskQueueStats::verify() const
90e562b9f1cc 6966222: G1: simplify TaskQueue overflow handling
jcoomes
parents: 6067
diff changeset
    95
{
90e562b9f1cc 6966222: G1: simplify TaskQueue overflow handling
jcoomes
parents: 6067
diff changeset
    96
  assert(get(push) == get(pop) + get(steal),
33105
294e48b4f704 8080775: Better argument formatting for assert() and friends
david
parents: 32606
diff changeset
    97
         "push=" SIZE_FORMAT " pop=" SIZE_FORMAT " steal=" SIZE_FORMAT,
294e48b4f704 8080775: Better argument formatting for assert() and friends
david
parents: 32606
diff changeset
    98
         get(push), get(pop), get(steal));
6251
90e562b9f1cc 6966222: G1: simplify TaskQueue overflow handling
jcoomes
parents: 6067
diff changeset
    99
  assert(get(pop_slow) <= get(pop),
33105
294e48b4f704 8080775: Better argument formatting for assert() and friends
david
parents: 32606
diff changeset
   100
         "pop_slow=" SIZE_FORMAT " pop=" SIZE_FORMAT,
294e48b4f704 8080775: Better argument formatting for assert() and friends
david
parents: 32606
diff changeset
   101
         get(pop_slow), get(pop));
6251
90e562b9f1cc 6966222: G1: simplify TaskQueue overflow handling
jcoomes
parents: 6067
diff changeset
   102
  assert(get(steal) <= get(steal_attempt),
33105
294e48b4f704 8080775: Better argument formatting for assert() and friends
david
parents: 32606
diff changeset
   103
         "steal=" SIZE_FORMAT " steal_attempt=" SIZE_FORMAT,
294e48b4f704 8080775: Better argument formatting for assert() and friends
david
parents: 32606
diff changeset
   104
         get(steal), get(steal_attempt));
6251
90e562b9f1cc 6966222: G1: simplify TaskQueue overflow handling
jcoomes
parents: 6067
diff changeset
   105
  assert(get(overflow) == 0 || get(push) != 0,
33105
294e48b4f704 8080775: Better argument formatting for assert() and friends
david
parents: 32606
diff changeset
   106
         "overflow=" SIZE_FORMAT " push=" SIZE_FORMAT,
294e48b4f704 8080775: Better argument formatting for assert() and friends
david
parents: 32606
diff changeset
   107
         get(overflow), get(push));
6251
90e562b9f1cc 6966222: G1: simplify TaskQueue overflow handling
jcoomes
parents: 6067
diff changeset
   108
  assert(get(overflow_max_len) == 0 || get(overflow) != 0,
33105
294e48b4f704 8080775: Better argument formatting for assert() and friends
david
parents: 32606
diff changeset
   109
         "overflow_max_len=" SIZE_FORMAT " overflow=" SIZE_FORMAT,
294e48b4f704 8080775: Better argument formatting for assert() and friends
david
parents: 32606
diff changeset
   110
         get(overflow_max_len), get(overflow));
6251
90e562b9f1cc 6966222: G1: simplify TaskQueue overflow handling
jcoomes
parents: 6067
diff changeset
   111
}
90e562b9f1cc 6966222: G1: simplify TaskQueue overflow handling
jcoomes
parents: 6067
diff changeset
   112
#endif // ASSERT
6067
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
   113
#endif // TASKQUEUE_STATS
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5918
diff changeset
   114
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
ParallelTaskTerminator::
30585
12f312d694cd 6407976: GC worker number should be unsigned
eistepan
parents: 30584
diff changeset
   116
ParallelTaskTerminator(uint n_threads, TaskQueueSetSuper* queue_set) :
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
  _n_threads(n_threads),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
  _queue_set(queue_set),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
  _offered_termination(0) {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
53545
2c38991dd9b0 8215047: Task terminators do not complete termination in consistent state
zgu
parents: 52905
diff changeset
   121
ParallelTaskTerminator::~ParallelTaskTerminator() {
2c38991dd9b0 8215047: Task terminators do not complete termination in consistent state
zgu
parents: 52905
diff changeset
   122
  assert(_offered_termination == 0 || !peek_in_queue_set(), "Precondition");
2c38991dd9b0 8215047: Task terminators do not complete termination in consistent state
zgu
parents: 52905
diff changeset
   123
  assert(_offered_termination == 0 || _offered_termination == _n_threads, "Terminated or aborted" );
2c38991dd9b0 8215047: Task terminators do not complete termination in consistent state
zgu
parents: 52905
diff changeset
   124
}
2c38991dd9b0 8215047: Task terminators do not complete termination in consistent state
zgu
parents: 52905
diff changeset
   125
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
bool ParallelTaskTerminator::peek_in_queue_set() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  return _queue_set->peek();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
void ParallelTaskTerminator::yield() {
3262
30d1c247fc25 6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents: 2105
diff changeset
   131
  assert(_offered_termination <= _n_threads, "Invariant");
25477
7dad9f95fd31 8047714: Fix for JDK-6546236 made Solaris os::yield() a no-op
fparain
parents: 25351
diff changeset
   132
  os::naked_yield();
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
void ParallelTaskTerminator::sleep(uint millis) {
3262
30d1c247fc25 6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents: 2105
diff changeset
   136
  assert(_offered_termination <= _n_threads, "Invariant");
58041
d8902e9c307c 8230422: Convert uninterruptible os::sleep calls to os::naked_short_sleep
dholmes
parents: 53586
diff changeset
   137
  os::naked_sleep(millis);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   140
bool
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   141
ParallelTaskTerminator::offer_termination(TerminatorTerminator* terminator) {
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6251
diff changeset
   142
  assert(_n_threads > 0, "Initialization is incorrect");
3262
30d1c247fc25 6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents: 2105
diff changeset
   143
  assert(_offered_termination < _n_threads, "Invariant");
48955
e22914003cf0 8194691: Cleanup unnecessary casts in Atomic/OrderAccess uses
kbarrett
parents: 47216
diff changeset
   144
  Atomic::inc(&_offered_termination);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
2005
42075507972b 6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents: 1623
diff changeset
   146
  uint yield_count = 0;
2010
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   147
  // Number of hard spin loops done since last yield
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   148
  uint hard_spin_count = 0;
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   149
  // Number of iterations in the hard spin loop.
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   150
  uint hard_spin_limit = WorkStealingHardSpins;
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   151
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   152
  // If WorkStealingSpinToYieldRatio is 0, no hard spinning is done.
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   153
  // If it is greater than 0, then start with a small number
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   154
  // of spins and increase number with each turn at spinning until
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   155
  // the count of hard spins exceeds WorkStealingSpinToYieldRatio.
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   156
  // Then do a yield() call and start spinning afresh.
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   157
  if (WorkStealingSpinToYieldRatio > 0) {
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   158
    hard_spin_limit = WorkStealingHardSpins >> WorkStealingSpinToYieldRatio;
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   159
    hard_spin_limit = MAX2(hard_spin_limit, 1U);
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   160
  }
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   161
  // Remember the initial spin limit.
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   162
  uint hard_spin_start = hard_spin_limit;
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   163
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   164
  // Loop waiting for all threads to offer termination or
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   165
  // more work.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
  while (true) {
3262
30d1c247fc25 6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents: 2105
diff changeset
   167
    assert(_offered_termination <= _n_threads, "Invariant");
2010
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   168
    // Are all threads offering termination?
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
    if (_offered_termination == _n_threads) {
53545
2c38991dd9b0 8215047: Task terminators do not complete termination in consistent state
zgu
parents: 52905
diff changeset
   170
      assert(!peek_in_queue_set(), "Precondition");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
    } else {
2010
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   173
      // Look for more work.
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   174
      // Periodically sleep() instead of yield() to give threads
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   175
      // waiting on the cores the chance to grab this code
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
      if (yield_count <= WorkStealingYieldsBeforeSleep) {
2010
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   177
        // Do a yield or hardspin.  For purposes of deciding whether
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   178
        // to sleep, count this as a yield.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
        yield_count++;
2010
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   180
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   181
        // Periodically call yield() instead spinning
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   182
        // After WorkStealingSpinToYieldRatio spins, do a yield() call
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   183
        // and reset the counts and starting limit.
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   184
        if (hard_spin_count > WorkStealingSpinToYieldRatio) {
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   185
          yield();
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   186
          hard_spin_count = 0;
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   187
          hard_spin_limit = hard_spin_start;
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   188
#ifdef TRACESPINNING
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   189
          _total_yields++;
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   190
#endif
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   191
        } else {
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   192
          // Hard spin this time
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   193
          // Increase the hard spinning period but only up to a limit.
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   194
          hard_spin_limit = MIN2(2*hard_spin_limit,
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   195
                                 (uint) WorkStealingHardSpins);
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   196
          for (uint j = 0; j < hard_spin_limit; j++) {
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   197
            SpinPause();
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   198
          }
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   199
          hard_spin_count++;
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   200
#ifdef TRACESPINNING
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   201
          _total_spins++;
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   202
#endif
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   203
        }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
      } else {
35061
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33105
diff changeset
   205
        log_develop_trace(gc, task)("ParallelTaskTerminator::offer_termination() thread " PTR_FORMAT " sleeps after %u yields",
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33105
diff changeset
   206
                                    p2i(Thread::current()), yield_count);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
        yield_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
        // A sleep will cause this processor to seek work on another processor's
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
        // runqueue, if it has nothing else to run (as opposed to the yield
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
        // which may only move the thread to the end of the this processor's
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
        // runqueue).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
        sleep(WorkStealingSleepMillis);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
2010
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   215
#ifdef TRACESPINNING
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   216
      _total_peeks++;
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   217
#endif
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   218
      if (peek_in_queue_set() ||
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   219
          (terminator != NULL && terminator->should_exit_termination())) {
53545
2c38991dd9b0 8215047: Task terminators do not complete termination in consistent state
zgu
parents: 52905
diff changeset
   220
        return complete_or_exit_termination();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
2010
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   226
#ifdef TRACESPINNING
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   227
void ParallelTaskTerminator::print_termination_counts() {
35061
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33105
diff changeset
   228
  log_trace(gc, task)("ParallelTaskTerminator Total yields: %u"
23858
dae377f5a7c7 8039244: Don't use UINT32_FORMAT and INT32_FORMAT when printing uints and ints in the GC code
stefank
parents: 15228
diff changeset
   229
    " Total spins: %u Total peeks: %u",
2010
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   230
    total_yields(),
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   231
    total_spins(),
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   232
    total_peeks());
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   233
}
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   234
#endif
c13462bbad17 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 2005
diff changeset
   235
53545
2c38991dd9b0 8215047: Task terminators do not complete termination in consistent state
zgu
parents: 52905
diff changeset
   236
bool ParallelTaskTerminator::complete_or_exit_termination() {
2c38991dd9b0 8215047: Task terminators do not complete termination in consistent state
zgu
parents: 52905
diff changeset
   237
  // If termination is ever reached, terminator should stay in such state,
2c38991dd9b0 8215047: Task terminators do not complete termination in consistent state
zgu
parents: 52905
diff changeset
   238
  // so that all threads see the same state
2c38991dd9b0 8215047: Task terminators do not complete termination in consistent state
zgu
parents: 52905
diff changeset
   239
  uint current_offered = _offered_termination;
2c38991dd9b0 8215047: Task terminators do not complete termination in consistent state
zgu
parents: 52905
diff changeset
   240
  uint expected_value;
2c38991dd9b0 8215047: Task terminators do not complete termination in consistent state
zgu
parents: 52905
diff changeset
   241
  do {
2c38991dd9b0 8215047: Task terminators do not complete termination in consistent state
zgu
parents: 52905
diff changeset
   242
    if (current_offered == _n_threads) {
2c38991dd9b0 8215047: Task terminators do not complete termination in consistent state
zgu
parents: 52905
diff changeset
   243
      assert(!peek_in_queue_set(), "Precondition");
2c38991dd9b0 8215047: Task terminators do not complete termination in consistent state
zgu
parents: 52905
diff changeset
   244
      return true;
2c38991dd9b0 8215047: Task terminators do not complete termination in consistent state
zgu
parents: 52905
diff changeset
   245
    }
2c38991dd9b0 8215047: Task terminators do not complete termination in consistent state
zgu
parents: 52905
diff changeset
   246
    expected_value = current_offered;
2c38991dd9b0 8215047: Task terminators do not complete termination in consistent state
zgu
parents: 52905
diff changeset
   247
  } while ((current_offered = Atomic::cmpxchg(current_offered - 1, &_offered_termination, current_offered)) != expected_value);
2c38991dd9b0 8215047: Task terminators do not complete termination in consistent state
zgu
parents: 52905
diff changeset
   248
2c38991dd9b0 8215047: Task terminators do not complete termination in consistent state
zgu
parents: 52905
diff changeset
   249
  assert(_offered_termination < _n_threads, "Invariant");
2c38991dd9b0 8215047: Task terminators do not complete termination in consistent state
zgu
parents: 52905
diff changeset
   250
  return false;
2c38991dd9b0 8215047: Task terminators do not complete termination in consistent state
zgu
parents: 52905
diff changeset
   251
}
2c38991dd9b0 8215047: Task terminators do not complete termination in consistent state
zgu
parents: 52905
diff changeset
   252
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
void ParallelTaskTerminator::reset_for_reuse() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
  if (_offered_termination != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
    assert(_offered_termination == _n_threads,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
           "Terminator may still be in use");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
    _offered_termination = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
5076
8b74a4b60b31 4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents: 3262
diff changeset
   261
#ifdef ASSERT
8b74a4b60b31 4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents: 3262
diff changeset
   262
bool ObjArrayTask::is_valid() const {
32606
fdaa30d06ada 8129417: Oop iteration clean-up to remove oop_ms_follow_contents
sjohanss
parents: 30764
diff changeset
   263
  return _obj != NULL && _obj->is_objArray() && _index >= 0 &&
fdaa30d06ada 8129417: Oop iteration clean-up to remove oop_ms_follow_contents
sjohanss
parents: 30764
diff changeset
   264
      _index < objArrayOop(_obj)->length();
5076
8b74a4b60b31 4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents: 3262
diff changeset
   265
}
8b74a4b60b31 4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents: 3262
diff changeset
   266
#endif // ASSERT
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6251
diff changeset
   267
30585
12f312d694cd 6407976: GC worker number should be unsigned
eistepan
parents: 30584
diff changeset
   268
void ParallelTaskTerminator::reset_for_reuse(uint n_threads) {
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6251
diff changeset
   269
  reset_for_reuse();
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6251
diff changeset
   270
  _n_threads = n_threads;
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6251
diff changeset
   271
}
52905
bec57b4a6d69 8204947: Port ShenandoahTaskTerminator to mainline and make it default
zgu
parents: 51292
diff changeset
   272
bec57b4a6d69 8204947: Port ShenandoahTaskTerminator to mainline and make it default
zgu
parents: 51292
diff changeset
   273
TaskTerminator::TaskTerminator(uint n_threads, TaskQueueSetSuper* queue_set) :
bec57b4a6d69 8204947: Port ShenandoahTaskTerminator to mainline and make it default
zgu
parents: 51292
diff changeset
   274
  _terminator(UseOWSTTaskTerminator ? new OWSTTaskTerminator(n_threads, queue_set)
bec57b4a6d69 8204947: Port ShenandoahTaskTerminator to mainline and make it default
zgu
parents: 51292
diff changeset
   275
                                    : new ParallelTaskTerminator(n_threads, queue_set)) {
bec57b4a6d69 8204947: Port ShenandoahTaskTerminator to mainline and make it default
zgu
parents: 51292
diff changeset
   276
}
bec57b4a6d69 8204947: Port ShenandoahTaskTerminator to mainline and make it default
zgu
parents: 51292
diff changeset
   277
bec57b4a6d69 8204947: Port ShenandoahTaskTerminator to mainline and make it default
zgu
parents: 51292
diff changeset
   278
TaskTerminator::~TaskTerminator() {
bec57b4a6d69 8204947: Port ShenandoahTaskTerminator to mainline and make it default
zgu
parents: 51292
diff changeset
   279
  if (_terminator != NULL) {
bec57b4a6d69 8204947: Port ShenandoahTaskTerminator to mainline and make it default
zgu
parents: 51292
diff changeset
   280
    delete _terminator;
bec57b4a6d69 8204947: Port ShenandoahTaskTerminator to mainline and make it default
zgu
parents: 51292
diff changeset
   281
  }
bec57b4a6d69 8204947: Port ShenandoahTaskTerminator to mainline and make it default
zgu
parents: 51292
diff changeset
   282
}