1.1 --- a/src/share/vm/utilities/workgroup.hpp Thu Sep 16 13:45:55 2010 -0700 1.2 +++ b/src/share/vm/utilities/workgroup.hpp Mon Sep 20 14:38:38 2010 -0700 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -29,6 +29,7 @@ 1.11 class YieldingFlexibleGangWorker; 1.12 class YieldingFlexibleGangTask; 1.13 class WorkData; 1.14 +class AbstractWorkGang; 1.15 1.16 // An abstract task to be worked on by a gang. 1.17 // You subclass this to supply your own work() method 1.18 @@ -38,6 +39,13 @@ 1.19 // The argument tells you which member of the gang you are. 1.20 virtual void work(int i) = 0; 1.21 1.22 + // This method configures the task for proper termination. 1.23 + // Some tasks do not have any requirements on termination 1.24 + // and may inherit this method that does nothing. Some 1.25 + // tasks do some coordination on termination and override 1.26 + // this method to implement that coordination. 1.27 + virtual void set_for_termination(int active_workers) {}; 1.28 + 1.29 // Debugging accessor for the name. 1.30 const char* name() const PRODUCT_RETURN_(return NULL;); 1.31 int counter() { return _counter; } 1.32 @@ -64,6 +72,18 @@ 1.33 virtual ~AbstractGangTask() { } 1.34 }; 1.35 1.36 +class AbstractGangTaskWOopQueues : public AbstractGangTask { 1.37 + OopTaskQueueSet* _queues; 1.38 + ParallelTaskTerminator _terminator; 1.39 + public: 1.40 + AbstractGangTaskWOopQueues(const char* name, OopTaskQueueSet* queues) : 1.41 + AbstractGangTask(name), _queues(queues), _terminator(0, _queues) {} 1.42 + ParallelTaskTerminator* terminator() { return &_terminator; } 1.43 + virtual void set_for_termination(int active_workers) { 1.44 + terminator()->reset_for_reuse(active_workers); 1.45 + } 1.46 + OopTaskQueueSet* queues() { return _queues; } 1.47 +}; 1.48 1.49 // Class AbstractWorkGang: 1.50 // An abstract class representing a gang of workers. 1.51 @@ -114,6 +134,9 @@ 1.52 int total_workers() const { 1.53 return _total_workers; 1.54 } 1.55 + virtual int active_workers() const { 1.56 + return _total_workers; 1.57 + } 1.58 bool terminate() const { 1.59 return _terminate; 1.60 } 1.61 @@ -199,6 +222,13 @@ 1.62 bool are_GC_task_threads, bool are_ConcurrentGC_threads); 1.63 // Run a task, returns when the task is done (or terminated). 1.64 virtual void run_task(AbstractGangTask* task); 1.65 + void run_task(AbstractGangTask* task, uint no_of_parallel_workers); 1.66 + // Allocate a worker and return a pointer to it. 1.67 + virtual GangWorker* allocate_worker(int which); 1.68 + // Initialize workers in the gang. Return true if initialization 1.69 + // succeeded. The type of the worker can be overridden in a derived 1.70 + // class with the appropriate implementation of allocate_worker(). 1.71 + bool initialize_workers(); 1.72 }; 1.73 1.74 // Class GangWorker: 1.75 @@ -226,6 +256,34 @@ 1.76 AbstractWorkGang* gang() const { return _gang; } 1.77 }; 1.78 1.79 +class FlexibleWorkGang: public WorkGang { 1.80 + protected: 1.81 + int _active_workers; 1.82 + public: 1.83 + // Constructor and destructor. 1.84 + FlexibleWorkGang(const char* name, int workers, 1.85 + bool are_GC_task_threads, 1.86 + bool are_ConcurrentGC_threads) : 1.87 + WorkGang(name, workers, are_GC_task_threads, are_ConcurrentGC_threads) { 1.88 + _active_workers = ParallelGCThreads; 1.89 + }; 1.90 + // Accessors for fields 1.91 + virtual int active_workers() const { return _active_workers; } 1.92 + void set_active_workers(int v) { _active_workers = v; } 1.93 +}; 1.94 + 1.95 +// Work gangs in garbage collectors: 2009-06-10 1.96 +// 1.97 +// SharedHeap - work gang for stop-the-world parallel collection. 1.98 +// Used by 1.99 +// ParNewGeneration 1.100 +// CMSParRemarkTask 1.101 +// CMSRefProcTaskExecutor 1.102 +// G1CollectedHeap 1.103 +// G1ParFinalCountTask 1.104 +// ConcurrentMark 1.105 +// CMSCollector 1.106 + 1.107 // A class that acts as a synchronisation barrier. Workers enter 1.108 // the barrier and must wait until all other workers have entered 1.109 // before any of them may leave. 1.110 @@ -271,7 +329,7 @@ 1.111 int _n_threads; 1.112 jint _threads_completed; 1.113 #ifdef ASSERT 1.114 - jint _claimed; 1.115 + volatile jint _claimed; 1.116 #endif 1.117 1.118 // Set all tasks to unclaimed. 1.119 @@ -286,9 +344,10 @@ 1.120 // True iff the object is in a valid state. 1.121 bool valid(); 1.122 1.123 - // Set the number of parallel threads doing the tasks to "t". Can only 1.124 + // Get/set the number of parallel threads doing the tasks to "t". Can only 1.125 // be called before tasks start or after they are complete. 1.126 - void set_par_threads(int t); 1.127 + int n_threads() { return _n_threads; } 1.128 + void set_n_threads(int t); 1.129 1.130 // Returns "false" if the task "t" is unclaimed, and ensures that task is 1.131 // claimed. The task "t" is required to be within the range of "this". 1.132 @@ -315,13 +374,17 @@ 1.133 protected: 1.134 jint _n_tasks; // Total number of tasks available. 1.135 jint _n_claimed; // Number of tasks claimed. 1.136 + // _n_threads is used to determine when a sub task is done. 1.137 + // See comments on SubTasksDone::_n_threads 1.138 jint _n_threads; // Total number of parallel threads. 1.139 jint _n_completed; // Number of completed threads. 1.140 1.141 void clear(); 1.142 1.143 public: 1.144 - SequentialSubTasksDone() { clear(); } 1.145 + SequentialSubTasksDone() { 1.146 + clear(); 1.147 + } 1.148 ~SequentialSubTasksDone() {} 1.149 1.150 // True iff the object is in a valid state. 1.151 @@ -330,11 +393,12 @@ 1.152 // number of tasks 1.153 jint n_tasks() const { return _n_tasks; } 1.154 1.155 - // Set the number of parallel threads doing the tasks to t. 1.156 + // Get/set the number of parallel threads doing the tasks to t. 1.157 // Should be called before the task starts but it is safe 1.158 // to call this once a task is running provided that all 1.159 // threads agree on the number of threads. 1.160 - void set_par_threads(int t) { _n_threads = t; } 1.161 + int n_threads() { return _n_threads; } 1.162 + void set_n_threads(int t) { _n_threads = t; } 1.163 1.164 // Set the number of tasks to be claimed to t. As above, 1.165 // should be called before the tasks start but it is safe