hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.hpp
author stefank
Thu, 01 Sep 2011 16:18:17 +0200
changeset 10524 6594ca81279a
parent 7397 5b173b4ca846
child 11174 fccee5238e70
permissions -rw-r--r--
7085906: Replace the permgen allocated sentinelRef with a self-looped end Summary: Remove the sentinelRef and let the last Reference in a discovered chain point back to itself. Reviewed-by: ysr, jmasa
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
     2
 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    25
#ifndef SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_GCTASKMANAGER_HPP
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    26
#define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_GCTASKMANAGER_HPP
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    27
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    28
#include "runtime/mutex.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    29
#include "utilities/growableArray.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    30
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
// The GCTaskManager is a queue of GCTasks, and accessors
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
// to allow the queue to be accessed from many threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
// Forward declarations of types defined in this file.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
class GCTask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
class GCTaskQueue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
class SynchronizedGCTaskQueue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
class GCTaskManager;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
class NotifyDoneClosure;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
// Some useful subclasses of GCTask.  You can also make up your own.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
class NoopGCTask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
class BarrierGCTask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
class ReleasingBarrierGCTask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
class NotifyingBarrierGCTask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
class WaitForBarrierGCTask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
// A free list of Monitor*'s.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
class MonitorSupply;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
// Forward declarations of classes referenced in this file via pointer.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
class GCTaskThread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
class Mutex;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
class Monitor;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
class ThreadClosure;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
// The abstract base GCTask.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
class GCTask : public ResourceObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
  // Known kinds of GCTasks, for predicates.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
  class Kind : AllStatic {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
  public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
    enum kind {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
      unknown_task,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
      ordinary_task,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
      barrier_task,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
      noop_task
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
    };
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
    static const char* to_string(kind value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
  // Instance state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
  const Kind::kind _kind;               // For runtime type checking.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
  const uint       _affinity;           // Which worker should run task.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
  GCTask*          _newer;              // Tasks are on doubly-linked ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
  GCTask*          _older;              // ... lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
  virtual char* name() { return (char *)"task"; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
  // Abstract do_it method
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  virtual void do_it(GCTaskManager* manager, uint which) = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
  // Accessors
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
  Kind::kind kind() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
    return _kind;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
  uint affinity() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
    return _affinity;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  GCTask* newer() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
    return _newer;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
  void set_newer(GCTask* n) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
    _newer = n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
  GCTask* older() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
    return _older;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
  void set_older(GCTask* p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
    _older = p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
  // Predicates.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
  bool is_ordinary_task() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
    return kind()==Kind::ordinary_task;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
  bool is_barrier_task() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
    return kind()==Kind::barrier_task;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
  bool is_noop_task() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
    return kind()==Kind::noop_task;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
  void print(const char* message) const PRODUCT_RETURN;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
  // Constructors: Only create subclasses.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
  //     An ordinary GCTask.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
  GCTask();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
  //     A GCTask of a particular kind, usually barrier or noop.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
  GCTask(Kind::kind kind);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
  //     An ordinary GCTask with an affinity.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
  GCTask(uint affinity);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
  //     A GCTask of a particular kind, with and affinity.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
  GCTask(Kind::kind kind, uint affinity);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
  // We want a virtual destructor because virtual methods,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  // but since ResourceObj's don't have their destructors
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
  // called, we don't have one at all.  Instead we have
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
  // this method, which gets called by subclasses to clean up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
  virtual void destruct();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  // Methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
  void initialize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
// A doubly-linked list of GCTasks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
// The list is not synchronized, because sometimes we want to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
// build up a list and then make it available to other threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
// See also: SynchronizedGCTaskQueue.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
class GCTaskQueue : public ResourceObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
  // Instance state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
  GCTask*    _insert_end;               // Tasks are enqueued at this end.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
  GCTask*    _remove_end;               // Tasks are dequeued from this end.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
  uint       _length;                   // The current length of the queue.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
  const bool _is_c_heap_obj;            // Is this a CHeapObj?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
  // Factory create and destroy methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
  //     Create as ResourceObj.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
  static GCTaskQueue* create();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  //     Create as CHeapObj.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
  static GCTaskQueue* create_on_c_heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
  //     Destroyer.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  static void destroy(GCTaskQueue* that);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
  // Accessors.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
  //     These just examine the state of the queue.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
  bool is_empty() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
    assert(((insert_end() == NULL && remove_end() == NULL) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
            (insert_end() != NULL && remove_end() != NULL)),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
           "insert_end and remove_end don't match");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
    return insert_end() == NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
  uint length() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
    return _length;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
  // Methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
  //     Enqueue one task.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
  void enqueue(GCTask* task);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
  //     Enqueue a list of tasks.  Empties the argument list.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
  void enqueue(GCTaskQueue* list);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
  //     Dequeue one task.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
  GCTask* dequeue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
  //     Dequeue one task, preferring one with affinity.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
  GCTask* dequeue(uint affinity);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
  // Constructor. Clients use factory, but there might be subclasses.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
  GCTaskQueue(bool on_c_heap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
  // Destructor-like method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
  // Because ResourceMark doesn't call destructors.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
  // This method cleans up like one.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
  virtual void destruct();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
  // Accessors.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
  GCTask* insert_end() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
    return _insert_end;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
  void set_insert_end(GCTask* value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
    _insert_end = value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
  GCTask* remove_end() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
    return _remove_end;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
  void set_remove_end(GCTask* value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
    _remove_end = value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
  void increment_length() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
    _length += 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
  void decrement_length() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
    _length -= 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
  void set_length(uint value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
    _length = value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
  bool is_c_heap_obj() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
    return _is_c_heap_obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
  // Methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
  void initialize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
  GCTask* remove();                     // Remove from remove end.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
  GCTask* remove(GCTask* task);         // Remove from the middle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
  void print(const char* message) const PRODUCT_RETURN;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
// A GCTaskQueue that can be synchronized.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
// This "has-a" GCTaskQueue and a mutex to do the exclusion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
class SynchronizedGCTaskQueue : public CHeapObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
  // Instance state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
  GCTaskQueue* _unsynchronized_queue;   // Has-a unsynchronized queue.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
  Monitor *    _lock;                   // Lock to control access.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
  // Factory create and destroy methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
  static SynchronizedGCTaskQueue* create(GCTaskQueue* queue, Monitor * lock) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
    return new SynchronizedGCTaskQueue(queue, lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
  static void destroy(SynchronizedGCTaskQueue* that) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
    if (that != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
      delete that;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
  // Accessors
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
  GCTaskQueue* unsynchronized_queue() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
    return _unsynchronized_queue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
  Monitor * lock() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
    return _lock;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
  // GCTaskQueue wrapper methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
  // These check that you hold the lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
  // and then call the method on the queue.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
  bool is_empty() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
    guarantee(own_lock(), "don't own the lock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
    return unsynchronized_queue()->is_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
  void enqueue(GCTask* task) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
    guarantee(own_lock(), "don't own the lock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
    unsynchronized_queue()->enqueue(task);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
  void enqueue(GCTaskQueue* list) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
    guarantee(own_lock(), "don't own the lock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
    unsynchronized_queue()->enqueue(list);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
  GCTask* dequeue() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
    guarantee(own_lock(), "don't own the lock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
    return unsynchronized_queue()->dequeue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
  GCTask* dequeue(uint affinity) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
    guarantee(own_lock(), "don't own the lock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
    return unsynchronized_queue()->dequeue(affinity);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
  uint length() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
    guarantee(own_lock(), "don't own the lock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
    return unsynchronized_queue()->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
  // For guarantees.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
  bool own_lock() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
    return lock()->owned_by_self();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
  // Constructor.  Clients use factory, but there might be subclasses.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
  SynchronizedGCTaskQueue(GCTaskQueue* queue, Monitor * lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
  // Destructor.  Not virtual because no virtuals.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
  ~SynchronizedGCTaskQueue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
// This is an abstract base class for getting notifications
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
// when a GCTaskManager is done.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
class NotifyDoneClosure : public CHeapObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
  // The notification callback method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
  virtual void notify(GCTaskManager* manager) = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
  // Constructor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
  NotifyDoneClosure() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
    // Nothing to do.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
  // Virtual destructor because virtual methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
  virtual ~NotifyDoneClosure() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
    // Nothing to do.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
class GCTaskManager : public CHeapObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
 friend class ParCompactionManager;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
 friend class PSParallelCompact;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
 friend class PSScavenge;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
 friend class PSRefProcTaskExecutor;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
 friend class RefProcTaskExecutor;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
  // Instance state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
  NotifyDoneClosure*        _ndc;               // Notify on completion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
  const uint                _workers;           // Number of workers.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
  Monitor*                  _monitor;           // Notification of changes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
  SynchronizedGCTaskQueue*  _queue;             // Queue of tasks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
  GCTaskThread**            _thread;            // Array of worker threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
  uint                      _busy_workers;      // Number of busy workers.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
  uint                      _blocking_worker;   // The worker that's blocking.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
  bool*                     _resource_flag;     // Array of flag per threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
  uint                      _delivered_tasks;   // Count of delivered tasks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
  uint                      _completed_tasks;   // Count of completed tasks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
  uint                      _barriers;          // Count of barrier tasks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
  uint                      _emptied_queue;     // Times we emptied the queue.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
  NoopGCTask*               _noop_task;         // The NoopGCTask instance.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
  uint                      _noop_tasks;        // Count of noop tasks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
  // Factory create and destroy methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
  static GCTaskManager* create(uint workers) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
    return new GCTaskManager(workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
  static GCTaskManager* create(uint workers, NotifyDoneClosure* ndc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
    return new GCTaskManager(workers, ndc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
  static void destroy(GCTaskManager* that) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
    if (that != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
      delete that;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
  // Accessors.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
  uint busy_workers() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
    return _busy_workers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
  //     Pun between Monitor* and Mutex*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
  Monitor* monitor() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
    return _monitor;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
  Monitor * lock() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
    return _monitor;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
  // Methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
  //     Add the argument task to be run.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
  void add_task(GCTask* task);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
  //     Add a list of tasks.  Removes task from the argument list.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
  void add_list(GCTaskQueue* list);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
  //     Claim a task for argument worker.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
  GCTask* get_task(uint which);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
  //     Note the completion of a task by the argument worker.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
  void note_completion(uint which);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
  //     Is the queue blocked from handing out new tasks?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
  bool is_blocked() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
    return (blocking_worker() != sentinel_worker());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
  //     Request that all workers release their resources.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
  void release_all_resources();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
  //     Ask if a particular worker should release its resources.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
  bool should_release_resources(uint which); // Predicate.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
  //     Note the release of resources by the argument worker.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
  void note_release(uint which);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
  // Constants.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
  //     A sentinel worker identifier.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
  static uint sentinel_worker() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
    return (uint) -1;                   // Why isn't there a max_uint?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
  //     Execute the task queue and wait for the completion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
  void execute_and_wait(GCTaskQueue* list);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
  void print_task_time_stamps();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
  void print_threads_on(outputStream* st);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
  void threads_do(ThreadClosure* tc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
  // Constructors.  Clients use factory, but there might be subclasses.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
  //     Create a GCTaskManager with the appropriate number of workers.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
  GCTaskManager(uint workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
  //     Create a GCTaskManager that calls back when there's no more work.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
  GCTaskManager(uint workers, NotifyDoneClosure* ndc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
  //     Make virtual if necessary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
  ~GCTaskManager();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
  // Accessors.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
  uint workers() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
    return _workers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
  NotifyDoneClosure* notify_done_closure() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
    return _ndc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
  SynchronizedGCTaskQueue* queue() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
    return _queue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
  NoopGCTask* noop_task() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
    return _noop_task;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
  //     Bounds-checking per-thread data accessors.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
  GCTaskThread* thread(uint which);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
  void set_thread(uint which, GCTaskThread* value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
  bool resource_flag(uint which);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
  void set_resource_flag(uint which, bool value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
  // Modifier methods with some semantics.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
  //     Is any worker blocking handing out new tasks?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
  uint blocking_worker() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
    return _blocking_worker;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
  void set_blocking_worker(uint value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
    _blocking_worker = value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
  void set_unblocked() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
    set_blocking_worker(sentinel_worker());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
  //     Count of busy workers.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
  void reset_busy_workers() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
    _busy_workers = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
  uint increment_busy_workers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
  uint decrement_busy_workers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
  //     Count of tasks delivered to workers.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
  uint delivered_tasks() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
    return _delivered_tasks;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
  void increment_delivered_tasks() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
    _delivered_tasks += 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
  void reset_delivered_tasks() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
    _delivered_tasks = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
  //     Count of tasks completed by workers.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
  uint completed_tasks() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
    return _completed_tasks;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
  void increment_completed_tasks() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
    _completed_tasks += 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
  void reset_completed_tasks() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
    _completed_tasks = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
  //     Count of barrier tasks completed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
  uint barriers() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
    return _barriers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
  void increment_barriers() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
    _barriers += 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
  void reset_barriers() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
    _barriers = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
  //     Count of how many times the queue has emptied.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
  uint emptied_queue() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
    return _emptied_queue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
  void increment_emptied_queue() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
    _emptied_queue += 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
  void reset_emptied_queue() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
    _emptied_queue = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
  //     Count of the number of noop tasks we've handed out,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
  //     e.g., to handle resource release requests.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
  uint noop_tasks() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
    return _noop_tasks;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
  void increment_noop_tasks() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
    _noop_tasks += 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
  void reset_noop_tasks() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
    _noop_tasks = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
  // Other methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
  void initialize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
// Some exemplary GCTasks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
// A noop task that does nothing,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
// except take us around the GCTaskThread loop.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
class NoopGCTask : public GCTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
  const bool _is_c_heap_obj;            // Is this a CHeapObj?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
  // Factory create and destroy methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
  static NoopGCTask* create();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
  static NoopGCTask* create_on_c_heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
  static void destroy(NoopGCTask* that);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
  // Methods from GCTask.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
  void do_it(GCTaskManager* manager, uint which) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
    // Nothing to do.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
  // Constructor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
  NoopGCTask(bool on_c_heap) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
    GCTask(GCTask::Kind::noop_task),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
    _is_c_heap_obj(on_c_heap) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
    // Nothing to do.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
  // Destructor-like method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
  void destruct();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
  // Accessors.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
  bool is_c_heap_obj() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
    return _is_c_heap_obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
// A BarrierGCTask blocks other tasks from starting,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
// and waits until it is the only task running.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
class BarrierGCTask : public GCTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
  // Factory create and destroy methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
  static BarrierGCTask* create() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
    return new BarrierGCTask();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
  static void destroy(BarrierGCTask* that) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
    if (that != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
      that->destruct();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
      delete that;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
  // Methods from GCTask.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
  void do_it(GCTaskManager* manager, uint which);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
  // Constructor.  Clients use factory, but there might be subclasses.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
  BarrierGCTask() :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
    GCTask(GCTask::Kind::barrier_task) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
    // Nothing to do.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
  // Destructor-like method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
  void destruct();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
  // Methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
  //     Wait for this to be the only task running.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
  void do_it_internal(GCTaskManager* manager, uint which);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
// A ReleasingBarrierGCTask is a BarrierGCTask
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
// that tells all the tasks to release their resource areas.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
class ReleasingBarrierGCTask : public BarrierGCTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
  // Factory create and destroy methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
  static ReleasingBarrierGCTask* create() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
    return new ReleasingBarrierGCTask();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
  static void destroy(ReleasingBarrierGCTask* that) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
    if (that != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
      that->destruct();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
      delete that;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
  // Methods from GCTask.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
  void do_it(GCTaskManager* manager, uint which);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
  // Constructor.  Clients use factory, but there might be subclasses.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
  ReleasingBarrierGCTask() :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
    BarrierGCTask() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
    // Nothing to do.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
  // Destructor-like method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
  void destruct();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
// A NotifyingBarrierGCTask is a BarrierGCTask
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
// that calls a notification method when it is the only task running.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
class NotifyingBarrierGCTask : public BarrierGCTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
  // Instance state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
  NotifyDoneClosure* _ndc;              // The callback object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
  // Factory create and destroy methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
  static NotifyingBarrierGCTask* create(NotifyDoneClosure* ndc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
    return new NotifyingBarrierGCTask(ndc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
  static void destroy(NotifyingBarrierGCTask* that) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
    if (that != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
      that->destruct();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
      delete that;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
  // Methods from GCTask.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
  void do_it(GCTaskManager* manager, uint which);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
  // Constructor.  Clients use factory, but there might be subclasses.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
  NotifyingBarrierGCTask(NotifyDoneClosure* ndc) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
    BarrierGCTask(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
    _ndc(ndc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
    assert(notify_done_closure() != NULL, "can't notify on NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
  // Destructor-like method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
  void destruct();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
  // Accessor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
  NotifyDoneClosure* notify_done_closure() const { return _ndc; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
// A WaitForBarrierGCTask is a BarrierGCTask
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
// with a method you can call to wait until
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
// the BarrierGCTask is done.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
// This may cover many of the uses of NotifyingBarrierGCTasks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
class WaitForBarrierGCTask : public BarrierGCTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
  // Instance state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
  Monitor*   _monitor;                  // Guard and notify changes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
  bool       _should_wait;              // true=>wait, false=>proceed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
  const bool _is_c_heap_obj;            // Was allocated on the heap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
  virtual char* name() { return (char *) "waitfor-barrier-task"; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
  // Factory create and destroy methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
  static WaitForBarrierGCTask* create();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
  static WaitForBarrierGCTask* create_on_c_heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
  static void destroy(WaitForBarrierGCTask* that);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
  // Methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
  void     do_it(GCTaskManager* manager, uint which);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
  void     wait_for();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
  // Constructor.  Clients use factory, but there might be subclasses.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
  WaitForBarrierGCTask(bool on_c_heap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
  // Destructor-like method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
  void destruct();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
  // Accessors.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
  Monitor* monitor() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
    return _monitor;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
  bool should_wait() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
    return _should_wait;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
  void set_should_wait(bool value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
    _should_wait = value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
  bool is_c_heap_obj() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
    return _is_c_heap_obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
class MonitorSupply : public AllStatic {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
  // State.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
  //     Control multi-threaded access.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
  static Mutex*                   _lock;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
  //     The list of available Monitor*'s.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
  static GrowableArray<Monitor*>* _freelist;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
  // Reserve a Monitor*.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
  static Monitor* reserve();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
  // Release a Monitor*.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
  static void release(Monitor* instance);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
  // Accessors.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
  static Mutex* lock() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
    return _lock;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
  static GrowableArray<Monitor*>* freelist() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
    return _freelist;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
};
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
   645
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
   646
#endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_GCTASKMANAGER_HPP