diff -r 97fbf5beff7b -r 8b10f48633dc src/share/vm/utilities/workgroup.hpp --- a/src/share/vm/utilities/workgroup.hpp Thu Sep 16 13:45:55 2010 -0700 +++ b/src/share/vm/utilities/workgroup.hpp Mon Sep 20 14:38:38 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ class YieldingFlexibleGangWorker; class YieldingFlexibleGangTask; class WorkData; +class AbstractWorkGang; // An abstract task to be worked on by a gang. // You subclass this to supply your own work() method @@ -38,6 +39,13 @@ // The argument tells you which member of the gang you are. virtual void work(int i) = 0; + // This method configures the task for proper termination. + // Some tasks do not have any requirements on termination + // and may inherit this method that does nothing. Some + // tasks do some coordination on termination and override + // this method to implement that coordination. + virtual void set_for_termination(int active_workers) {}; + // Debugging accessor for the name. const char* name() const PRODUCT_RETURN_(return NULL;); int counter() { return _counter; } @@ -64,6 +72,18 @@ virtual ~AbstractGangTask() { } }; +class AbstractGangTaskWOopQueues : public AbstractGangTask { + OopTaskQueueSet* _queues; + ParallelTaskTerminator _terminator; + public: + AbstractGangTaskWOopQueues(const char* name, OopTaskQueueSet* queues) : + AbstractGangTask(name), _queues(queues), _terminator(0, _queues) {} + ParallelTaskTerminator* terminator() { return &_terminator; } + virtual void set_for_termination(int active_workers) { + terminator()->reset_for_reuse(active_workers); + } + OopTaskQueueSet* queues() { return _queues; } +}; // Class AbstractWorkGang: // An abstract class representing a gang of workers. @@ -114,6 +134,9 @@ int total_workers() const { return _total_workers; } + virtual int active_workers() const { + return _total_workers; + } bool terminate() const { return _terminate; } @@ -199,6 +222,13 @@ bool are_GC_task_threads, bool are_ConcurrentGC_threads); // Run a task, returns when the task is done (or terminated). virtual void run_task(AbstractGangTask* task); + void run_task(AbstractGangTask* task, uint no_of_parallel_workers); + // Allocate a worker and return a pointer to it. + virtual GangWorker* allocate_worker(int which); + // Initialize workers in the gang. Return true if initialization + // succeeded. The type of the worker can be overridden in a derived + // class with the appropriate implementation of allocate_worker(). + bool initialize_workers(); }; // Class GangWorker: @@ -226,6 +256,34 @@ AbstractWorkGang* gang() const { return _gang; } }; +class FlexibleWorkGang: public WorkGang { + protected: + int _active_workers; + public: + // Constructor and destructor. + FlexibleWorkGang(const char* name, int workers, + bool are_GC_task_threads, + bool are_ConcurrentGC_threads) : + WorkGang(name, workers, are_GC_task_threads, are_ConcurrentGC_threads) { + _active_workers = ParallelGCThreads; + }; + // Accessors for fields + virtual int active_workers() const { return _active_workers; } + void set_active_workers(int v) { _active_workers = v; } +}; + +// Work gangs in garbage collectors: 2009-06-10 +// +// SharedHeap - work gang for stop-the-world parallel collection. +// Used by +// ParNewGeneration +// CMSParRemarkTask +// CMSRefProcTaskExecutor +// G1CollectedHeap +// G1ParFinalCountTask +// ConcurrentMark +// CMSCollector + // A class that acts as a synchronisation barrier. Workers enter // the barrier and must wait until all other workers have entered // before any of them may leave. @@ -271,7 +329,7 @@ int _n_threads; jint _threads_completed; #ifdef ASSERT - jint _claimed; + volatile jint _claimed; #endif // Set all tasks to unclaimed. @@ -286,9 +344,10 @@ // True iff the object is in a valid state. bool valid(); - // Set the number of parallel threads doing the tasks to "t". Can only + // Get/set the number of parallel threads doing the tasks to "t". Can only // be called before tasks start or after they are complete. - void set_par_threads(int t); + int n_threads() { return _n_threads; } + void set_n_threads(int t); // Returns "false" if the task "t" is unclaimed, and ensures that task is // claimed. The task "t" is required to be within the range of "this". @@ -315,13 +374,17 @@ protected: jint _n_tasks; // Total number of tasks available. jint _n_claimed; // Number of tasks claimed. + // _n_threads is used to determine when a sub task is done. + // See comments on SubTasksDone::_n_threads jint _n_threads; // Total number of parallel threads. jint _n_completed; // Number of completed threads. void clear(); public: - SequentialSubTasksDone() { clear(); } + SequentialSubTasksDone() { + clear(); + } ~SequentialSubTasksDone() {} // True iff the object is in a valid state. @@ -330,11 +393,12 @@ // number of tasks jint n_tasks() const { return _n_tasks; } - // Set the number of parallel threads doing the tasks to t. + // Get/set the number of parallel threads doing the tasks to t. // Should be called before the task starts but it is safe // to call this once a task is running provided that all // threads agree on the number of threads. - void set_par_threads(int t) { _n_threads = t; } + int n_threads() { return _n_threads; } + void set_n_threads(int t) { _n_threads = t; } // Set the number of tasks to be claimed to t. As above, // should be called before the tasks start but it is safe