src/hotspot/share/gc/shared/taskqueue.inline.hpp
author stefank
Mon, 25 Nov 2019 12:22:13 +0100
changeset 59247 56bf71d64d51
parent 57978 be5865bda5b9
child 59252 623722a6aeb9
permissions -rw-r--r--
8234562: Move OrderAccess::release_store*/load_acquire to Atomic Reviewed-by: rehn, dholmes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
     1
/*
53244
9807daeb47c4 8216167: Update include guards to reflect correct directories
coleenp
parents: 51292
diff changeset
     2
 * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
     4
 *
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
     7
 * published by the Free Software Foundation.
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
     8
 *
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    13
 * accompanied this code).
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    14
 *
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    18
 *
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    21
 * questions.
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    22
 *
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    23
 */
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    24
53244
9807daeb47c4 8216167: Update include guards to reflect correct directories
coleenp
parents: 51292
diff changeset
    25
#ifndef SHARE_GC_SHARED_TASKQUEUE_INLINE_HPP
9807daeb47c4 8216167: Update include guards to reflect correct directories
coleenp
parents: 51292
diff changeset
    26
#define SHARE_GC_SHARED_TASKQUEUE_INLINE_HPP
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    27
30764
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 30566
diff changeset
    28
#include "gc/shared/taskqueue.hpp"
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    29
#include "memory/allocation.inline.hpp"
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    30
#include "oops/oop.inline.hpp"
40655
9f644073d3a0 8157907: Incorrect inclusion of atomic.hpp instead of atomic.inline.hpp
dholmes
parents: 39407
diff changeset
    31
#include "runtime/atomic.hpp"
50429
83aec1d357d4 8204301: Make OrderAccess functions available to hpp rather than inline.hpp files
coleenp
parents: 49911
diff changeset
    32
#include "runtime/orderAccess.hpp"
30764
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 30566
diff changeset
    33
#include "utilities/debug.hpp"
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 30566
diff changeset
    34
#include "utilities/stack.inline.hpp"
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    35
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    36
template <class T, MEMFLAGS F>
51292
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
    37
inline GenericTaskQueueSet<T, F>::GenericTaskQueueSet(uint n) : _n(n) {
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    38
  typedef T* GenericTaskQueuePtr;
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    39
  _queues = NEW_C_HEAP_ARRAY(GenericTaskQueuePtr, n, F);
51292
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
    40
  for (uint i = 0; i < n; i++) {
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    41
    _queues[i] = NULL;
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    42
  }
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    43
}
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    44
47885
5caa1d5f74c1 8186571: Implementation: JEP 307: Parallel Full GC for G1
sjohanss
parents: 47634
diff changeset
    45
template <class T, MEMFLAGS F>
5caa1d5f74c1 8186571: Implementation: JEP 307: Parallel Full GC for G1
sjohanss
parents: 47634
diff changeset
    46
inline GenericTaskQueueSet<T, F>::~GenericTaskQueueSet() {
5caa1d5f74c1 8186571: Implementation: JEP 307: Parallel Full GC for G1
sjohanss
parents: 47634
diff changeset
    47
  FREE_C_HEAP_ARRAY(T*, _queues);
5caa1d5f74c1 8186571: Implementation: JEP 307: Parallel Full GC for G1
sjohanss
parents: 47634
diff changeset
    48
}
5caa1d5f74c1 8186571: Implementation: JEP 307: Parallel Full GC for G1
sjohanss
parents: 47634
diff changeset
    49
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    50
template<class E, MEMFLAGS F, unsigned int N>
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    51
inline void GenericTaskQueue<E, F, N>::initialize() {
46704
211b3f6b75ef 8182169: ArrayAllocator should take MEMFLAGS as regular parameter
kbarrett
parents: 40655
diff changeset
    52
  _elems = ArrayAllocator<E>::allocate(N, F);
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    53
}
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    54
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    55
template<class E, MEMFLAGS F, unsigned int N>
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    56
inline GenericTaskQueue<E, F, N>::~GenericTaskQueue() {
46704
211b3f6b75ef 8182169: ArrayAllocator should take MEMFLAGS as regular parameter
kbarrett
parents: 40655
diff changeset
    57
  ArrayAllocator<E>::free(const_cast<E*>(_elems), N);
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    58
}
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    59
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    60
template<class E, MEMFLAGS F, unsigned int N>
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    61
bool GenericTaskQueue<E, F, N>::push_slow(E t, uint dirty_n_elems) {
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    62
  if (dirty_n_elems == N - 1) {
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    63
    // Actually means 0, so do the push.
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    64
    uint localBot = _bottom;
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    65
    // g++ complains if the volatile result of the assignment is
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    66
    // unused, so we cast the volatile away.  We cannot cast directly
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    67
    // to void, because gcc treats that as not using the result of the
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    68
    // assignment.  However, casting to E& means that we trigger an
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    69
    // unused-value warning.  So, we cast the E& to void.
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    70
    (void)const_cast<E&>(_elems[localBot] = t);
59247
56bf71d64d51 8234562: Move OrderAccess::release_store*/load_acquire to Atomic
stefank
parents: 57978
diff changeset
    71
    Atomic::release_store(&_bottom, increment_index(localBot));
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    72
    TASKQUEUE_STATS_ONLY(stats.record_push());
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    73
    return true;
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    74
  }
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    75
  return false;
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    76
}
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    77
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    78
template<class E, MEMFLAGS F, unsigned int N> inline bool
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    79
GenericTaskQueue<E, F, N>::push(E t) {
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    80
  uint localBot = _bottom;
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    81
  assert(localBot < N, "_bottom out of range.");
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    82
  idx_t top = _age.top();
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    83
  uint dirty_n_elems = dirty_size(localBot, top);
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    84
  assert(dirty_n_elems < N, "n_elems out of range.");
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    85
  if (dirty_n_elems < max_elems()) {
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    86
    // g++ complains if the volatile result of the assignment is
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    87
    // unused, so we cast the volatile away.  We cannot cast directly
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    88
    // to void, because gcc treats that as not using the result of the
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    89
    // assignment.  However, casting to E& means that we trigger an
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    90
    // unused-value warning.  So, we cast the E& to void.
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    91
    (void) const_cast<E&>(_elems[localBot] = t);
59247
56bf71d64d51 8234562: Move OrderAccess::release_store*/load_acquire to Atomic
stefank
parents: 57978
diff changeset
    92
    Atomic::release_store(&_bottom, increment_index(localBot));
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    93
    TASKQUEUE_STATS_ONLY(stats.record_push());
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    94
    return true;
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    95
  } else {
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    96
    return push_slow(t, dirty_n_elems);
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    97
  }
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    98
}
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
    99
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   100
template <class E, MEMFLAGS F, unsigned int N>
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   101
inline bool OverflowTaskQueue<E, F, N>::push(E t)
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   102
{
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   103
  if (!taskqueue_t::push(t)) {
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   104
    overflow_stack()->push(t);
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   105
    TASKQUEUE_STATS_ONLY(stats.record_overflow(overflow_stack()->size()));
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   106
  }
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   107
  return true;
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   108
}
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   109
39407
2e75eb109278 8152438: Threads may do significant work out of the non-shared overflow buffer
tschatzl
parents: 37057
diff changeset
   110
template <class E, MEMFLAGS F, unsigned int N>
2e75eb109278 8152438: Threads may do significant work out of the non-shared overflow buffer
tschatzl
parents: 37057
diff changeset
   111
inline bool OverflowTaskQueue<E, F, N>::try_push_to_taskqueue(E t) {
2e75eb109278 8152438: Threads may do significant work out of the non-shared overflow buffer
tschatzl
parents: 37057
diff changeset
   112
  return taskqueue_t::push(t);
2e75eb109278 8152438: Threads may do significant work out of the non-shared overflow buffer
tschatzl
parents: 37057
diff changeset
   113
}
2e75eb109278 8152438: Threads may do significant work out of the non-shared overflow buffer
tschatzl
parents: 37057
diff changeset
   114
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   115
// pop_local_slow() is done by the owning thread and is trying to
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   116
// get the last task in the queue.  It will compete with pop_global()
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   117
// that will be used by other threads.  The tag age is incremented
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   118
// whenever the queue goes empty which it will do here if this thread
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   119
// gets the last task or in pop_global() if the queue wraps (top == 0
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   120
// and pop_global() succeeds, see pop_global()).
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   121
template<class E, MEMFLAGS F, unsigned int N>
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   122
bool GenericTaskQueue<E, F, N>::pop_local_slow(uint localBot, Age oldAge) {
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   123
  // This queue was observed to contain exactly one element; either this
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   124
  // thread will claim it, or a competing "pop_global".  In either case,
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   125
  // the queue will be logically empty afterwards.  Create a new Age value
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   126
  // that represents the empty queue for the given value of "_bottom".  (We
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   127
  // must also increment "tag" because of the case where "bottom == 1",
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   128
  // "top == 0".  A pop_global could read the queue element in that case,
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   129
  // then have the owner thread do a pop followed by another push.  Without
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   130
  // the incrementing of "tag", the pop_global's CAS could succeed,
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   131
  // allowing it to believe it has claimed the stale element.)
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   132
  Age newAge((idx_t)localBot, oldAge.tag() + 1);
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   133
  // Perhaps a competing pop_global has already incremented "top", in which
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   134
  // case it wins the element.
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   135
  if (localBot == oldAge.top()) {
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   136
    // No competing pop_global has yet incremented "top"; we'll try to
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   137
    // install new_age, thus claiming the element.
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   138
    Age tempAge = _age.cmpxchg(newAge, oldAge);
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   139
    if (tempAge == oldAge) {
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   140
      // We win.
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   141
      assert(dirty_size(localBot, _age.top()) != N - 1, "sanity");
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   142
      TASKQUEUE_STATS_ONLY(stats.record_pop_slow());
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   143
      return true;
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   144
    }
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   145
  }
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   146
  // We lose; a completing pop_global gets the element.  But the queue is empty
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   147
  // and top is greater than bottom.  Fix this representation of the empty queue
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   148
  // to become the canonical one.
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   149
  _age.set(newAge);
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   150
  assert(dirty_size(localBot, _age.top()) != N - 1, "sanity");
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   151
  return false;
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   152
}
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   153
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   154
template<class E, MEMFLAGS F, unsigned int N> inline bool
49911
358be4680d12 6672778: G1 should trim task queues more aggressively during evacuation pauses
tschatzl
parents: 48955
diff changeset
   155
GenericTaskQueue<E, F, N>::pop_local(volatile E& t, uint threshold) {
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   156
  uint localBot = _bottom;
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   157
  // This value cannot be N-1.  That can only occur as a result of
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   158
  // the assignment to bottom in this method.  If it does, this method
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   159
  // resets the size to 0 before the next call (which is sequential,
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   160
  // since this is pop_local.)
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   161
  uint dirty_n_elems = dirty_size(localBot, _age.top());
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   162
  assert(dirty_n_elems != N - 1, "Shouldn't be possible...");
49911
358be4680d12 6672778: G1 should trim task queues more aggressively during evacuation pauses
tschatzl
parents: 48955
diff changeset
   163
  if (dirty_n_elems <= threshold) return false;
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   164
  localBot = decrement_index(localBot);
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   165
  _bottom = localBot;
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   166
  // This is necessary to prevent any read below from being reordered
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   167
  // before the store just above.
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   168
  OrderAccess::fence();
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   169
  // g++ complains if the volatile result of the assignment is
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   170
  // unused, so we cast the volatile away.  We cannot cast directly
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   171
  // to void, because gcc treats that as not using the result of the
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   172
  // assignment.  However, casting to E& means that we trigger an
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   173
  // unused-value warning.  So, we cast the E& to void.
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   174
  (void) const_cast<E&>(t = _elems[localBot]);
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   175
  // This is a second read of "age"; the "size()" above is the first.
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   176
  // If there's still at least one element in the queue, based on the
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   177
  // "_bottom" and "age" we've read, then there can be no interference with
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   178
  // a "pop_global" operation, and we're done.
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   179
  idx_t tp = _age.top();    // XXX
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   180
  if (size(localBot, tp) > 0) {
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   181
    assert(dirty_size(localBot, tp) != N - 1, "sanity");
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   182
    TASKQUEUE_STATS_ONLY(stats.record_pop());
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   183
    return true;
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   184
  } else {
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   185
    // Otherwise, the queue contained exactly one element; we take the slow
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   186
    // path.
57672
167cb7b4cd81 8229169: False failure of GenericTaskQueue::pop_local on architectures with weak memory model
jiefu
parents: 53244
diff changeset
   187
167cb7b4cd81 8229169: False failure of GenericTaskQueue::pop_local on architectures with weak memory model
jiefu
parents: 53244
diff changeset
   188
    // The barrier is required to prevent reordering the two reads of _age:
167cb7b4cd81 8229169: False failure of GenericTaskQueue::pop_local on architectures with weak memory model
jiefu
parents: 53244
diff changeset
   189
    // one is the _age.get() below, and the other is _age.top() above the if-stmt.
167cb7b4cd81 8229169: False failure of GenericTaskQueue::pop_local on architectures with weak memory model
jiefu
parents: 53244
diff changeset
   190
    // The algorithm may fail if _age.get() reads an older value than _age.top().
167cb7b4cd81 8229169: False failure of GenericTaskQueue::pop_local on architectures with weak memory model
jiefu
parents: 53244
diff changeset
   191
    OrderAccess::loadload();
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   192
    return pop_local_slow(localBot, _age.get());
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   193
  }
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   194
}
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   195
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   196
template <class E, MEMFLAGS F, unsigned int N>
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   197
bool OverflowTaskQueue<E, F, N>::pop_overflow(E& t)
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   198
{
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   199
  if (overflow_empty()) return false;
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   200
  t = overflow_stack()->pop();
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   201
  return true;
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   202
}
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   203
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   204
template<class E, MEMFLAGS F, unsigned int N>
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   205
bool GenericTaskQueue<E, F, N>::pop_global(volatile E& t) {
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   206
  Age oldAge = _age.get();
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   207
  // Architectures with weak memory model require a barrier here
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   208
  // to guarantee that bottom is not older than age,
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   209
  // which is crucial for the correctness of the algorithm.
57978
be5865bda5b9 8229422: Taskqueue: Outdated selection of weak memory model platforms
mdoerr
parents: 57672
diff changeset
   210
#ifndef CPU_MULTI_COPY_ATOMIC
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   211
  OrderAccess::fence();
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   212
#endif
59247
56bf71d64d51 8234562: Move OrderAccess::release_store*/load_acquire to Atomic
stefank
parents: 57978
diff changeset
   213
  uint localBot = Atomic::load_acquire(&_bottom);
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   214
  uint n_elems = size(localBot, oldAge.top());
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   215
  if (n_elems == 0) {
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   216
    return false;
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   217
  }
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   218
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   219
  // g++ complains if the volatile result of the assignment is
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   220
  // unused, so we cast the volatile away.  We cannot cast directly
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   221
  // to void, because gcc treats that as not using the result of the
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   222
  // assignment.  However, casting to E& means that we trigger an
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   223
  // unused-value warning.  So, we cast the E& to void.
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   224
  (void) const_cast<E&>(t = _elems[oldAge.top()]);
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   225
  Age newAge(oldAge);
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   226
  newAge.increment();
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   227
  Age resAge = _age.cmpxchg(newAge, oldAge);
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   228
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   229
  // Note that using "_bottom" here might fail, since a pop_local might
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   230
  // have decremented it.
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   231
  assert(dirty_size(localBot, newAge.top()) != N - 1, "sanity");
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   232
  return resAge == oldAge;
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   233
}
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   234
51292
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   235
inline int randomParkAndMiller(int *seed0) {
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   236
  const int a =      16807;
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   237
  const int m = 2147483647;
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   238
  const int q =     127773;  /* m div a */
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   239
  const int r =       2836;  /* m mod a */
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   240
  STATIC_ASSERT(sizeof(int) == 4);
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   241
  int seed = *seed0;
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   242
  int hi   = seed / q;
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   243
  int lo   = seed % q;
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   244
  int test = a * lo - r * hi;
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   245
  if (test > 0) {
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   246
    seed = test;
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   247
  } else {
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   248
    seed = test + m;
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   249
  }
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   250
  *seed0 = seed;
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   251
  return seed;
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   252
}
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   253
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   254
template<class E, MEMFLAGS F, unsigned int N>
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   255
int GenericTaskQueue<E, F, N>::next_random_queue_id() {
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   256
  return randomParkAndMiller(&_seed);
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   257
}
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   258
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   259
template<class T, MEMFLAGS F> bool
51292
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   260
GenericTaskQueueSet<T, F>::steal_best_of_2(uint queue_num, E& t) {
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   261
  if (_n > 2) {
51292
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   262
    T* const local_queue = _queues[queue_num];
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   263
    uint k1 = queue_num;
51292
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   264
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   265
    if (local_queue->is_last_stolen_queue_id_valid()) {
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   266
      k1 = local_queue->last_stolen_queue_id();
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   267
      assert(k1 != queue_num, "Should not be the same");
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   268
    } else {
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   269
      while (k1 == queue_num) {
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   270
        k1 = local_queue->next_random_queue_id() % _n;
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   271
      }
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   272
    }
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   273
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   274
    uint k2 = queue_num;
51292
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   275
    while (k2 == queue_num || k2 == k1) {
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   276
      k2 = local_queue->next_random_queue_id() % _n;
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   277
    }
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   278
    // Sample both and try the larger.
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   279
    uint sz1 = _queues[k1]->size();
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   280
    uint sz2 = _queues[k2]->size();
51292
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   281
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   282
    uint sel_k = 0;
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   283
    bool suc = false;
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   284
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   285
    if (sz2 > sz1) {
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   286
      sel_k = k2;
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   287
      suc = _queues[k2]->pop_global(t);
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   288
    } else if (sz1 > 0) {
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   289
      sel_k = k1;
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   290
      suc = _queues[k1]->pop_global(t);
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   291
    }
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   292
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   293
    if (suc) {
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   294
      local_queue->set_last_stolen_queue_id(sel_k);
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   295
    } else {
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   296
      local_queue->invalidate_last_stolen_queue_id();
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   297
    }
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   298
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   299
    return suc;
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   300
  } else if (_n == 2) {
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   301
    // Just try the other one.
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   302
    uint k = (queue_num + 1) % 2;
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   303
    return _queues[k]->pop_global(t);
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   304
  } else {
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   305
    assert(_n == 1, "can't be zero.");
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   306
    return false;
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   307
  }
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   308
}
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   309
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   310
template<class T, MEMFLAGS F> bool
51292
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   311
GenericTaskQueueSet<T, F>::steal(uint queue_num, E& t) {
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   312
  for (uint i = 0; i < 2 * _n; i++) {
50953
0fad17c646c9 8206453: Taskqueue stats should count real steal attempts, not calls to GenericTaskQueueSet::steal
tschatzl
parents: 50429
diff changeset
   313
    TASKQUEUE_STATS_ONLY(queue(queue_num)->stats.record_steal_attempt());
51292
0538a5cdb474 8205921: Optimizing best-of-2 work stealing queue selection
zgu
parents: 50953
diff changeset
   314
    if (steal_best_of_2(queue_num, t)) {
50953
0fad17c646c9 8206453: Taskqueue stats should count real steal attempts, not calls to GenericTaskQueueSet::steal
tschatzl
parents: 50429
diff changeset
   315
      TASKQUEUE_STATS_ONLY(queue(queue_num)->stats.record_steal());
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   316
      return true;
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   317
    }
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   318
  }
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   319
  return false;
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   320
}
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   321
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   322
template <unsigned int N, MEMFLAGS F>
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   323
inline typename TaskQueueSuper<N, F>::Age TaskQueueSuper<N, F>::Age::cmpxchg(const Age new_age, const Age old_age) volatile {
47634
6a0c42c40cd1 8188220: Remove Atomic::*_ptr() uses and overloads from hotspot
coleenp
parents: 47216
diff changeset
   324
  return Atomic::cmpxchg(new_age._data, &_data, old_age._data);
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   325
}
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   326
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   327
template<class E, MEMFLAGS F, unsigned int N>
31994
3721b7aa3a0d 8079082: VerifyNoCSetOopsClosure is derived twice from Closure
kbarrett
parents: 30764
diff changeset
   328
template<class Fn>
3721b7aa3a0d 8079082: VerifyNoCSetOopsClosure is derived twice from Closure
kbarrett
parents: 30764
diff changeset
   329
inline void GenericTaskQueue<E, F, N>::iterate(Fn fn) {
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   330
  uint iters = size();
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   331
  uint index = _bottom;
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   332
  for (uint i = 0; i < iters; ++i) {
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   333
    index = decrement_index(index);
31994
3721b7aa3a0d 8079082: VerifyNoCSetOopsClosure is derived twice from Closure
kbarrett
parents: 30764
diff changeset
   334
    fn(const_cast<E&>(_elems[index])); // cast away volatility
30566
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   335
  }
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   336
}
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   337
18eb9aa972d0 8076177: Remove usage of stack.inline.hpp functions from taskqueue.hpp
stefank
parents:
diff changeset
   338
53244
9807daeb47c4 8216167: Update include guards to reflect correct directories
coleenp
parents: 51292
diff changeset
   339
#endif // SHARE_GC_SHARED_TASKQUEUE_INLINE_HPP