< prev index next >

src/share/vm/utilities/taskqueue.hpp

Print this page
rev 8151 : 6407976: GC worker number should be unsigned
Reviewed-by: jwilhelm
   1 /*
   2  * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 581   for (uint j = 0; j < _n; j++) {
 582     if (_queues[j]->peek())
 583       return true;
 584   }
 585   return false;
 586 }
 587 
 588 // When to terminate from the termination protocol.
 589 class TerminatorTerminator: public CHeapObj<mtInternal> {
 590 public:
 591   virtual bool should_exit_termination() = 0;
 592 };
 593 
 594 // A class to aid in the termination of a set of parallel tasks using
 595 // TaskQueueSet's for work stealing.
 596 
 597 #undef TRACESPINNING
 598 
 599 class ParallelTaskTerminator: public StackObj {
 600 private:
 601   int _n_threads;
 602   TaskQueueSetSuper* _queue_set;
 603   int _offered_termination;
 604 
 605 #ifdef TRACESPINNING
 606   static uint _total_yields;
 607   static uint _total_spins;
 608   static uint _total_peeks;
 609 #endif
 610 
 611   bool peek_in_queue_set();
 612 protected:
 613   virtual void yield();
 614   void sleep(uint millis);
 615 
 616 public:
 617 
 618   // "n_threads" is the number of threads to be terminated.  "queue_set" is a
 619   // queue sets of work queues of other threads.
 620   ParallelTaskTerminator(int n_threads, TaskQueueSetSuper* queue_set);
 621 
 622   // The current thread has no work, and is ready to terminate if everyone
 623   // else is.  If returns "true", all threads are terminated.  If returns
 624   // "false", available work has been observed in one of the task queues,
 625   // so the global task is not complete.
 626   bool offer_termination() {
 627     return offer_termination(NULL);
 628   }
 629 
 630   // As above, but it also terminates if the should_exit_termination()
 631   // method of the terminator parameter returns true. If terminator is
 632   // NULL, then it is ignored.
 633   bool offer_termination(TerminatorTerminator* terminator);
 634 
 635   // Reset the terminator, so that it may be reused again.
 636   // The caller is responsible for ensuring that this is done
 637   // in an MT-safe manner, once the previous round of use of
 638   // the terminator is finished.
 639   void reset_for_reuse();
 640   // Same as above but the number of parallel threads is set to the
 641   // given number.
 642   void reset_for_reuse(int n_threads);
 643 
 644 #ifdef TRACESPINNING
 645   static uint total_yields() { return _total_yields; }
 646   static uint total_spins() { return _total_spins; }
 647   static uint total_peeks() { return _total_peeks; }
 648   static void print_termination_counts();
 649 #endif
 650 };
 651 
 652 template<class E, MEMFLAGS F, unsigned int N> inline bool
 653 GenericTaskQueue<E, F, N>::push(E t) {
 654   uint localBot = _bottom;
 655   assert(localBot < N, "_bottom out of range.");
 656   idx_t top = _age.top();
 657   uint dirty_n_elems = dirty_size(localBot, top);
 658   assert(dirty_n_elems < N, "n_elems out of range.");
 659   if (dirty_n_elems < max_elems()) {
 660     // g++ complains if the volatile result of the assignment is
 661     // unused, so we cast the volatile away.  We cannot cast directly
 662     // to void, because gcc treats that as not using the result of the


   1 /*
   2  * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 581   for (uint j = 0; j < _n; j++) {
 582     if (_queues[j]->peek())
 583       return true;
 584   }
 585   return false;
 586 }
 587 
 588 // When to terminate from the termination protocol.
 589 class TerminatorTerminator: public CHeapObj<mtInternal> {
 590 public:
 591   virtual bool should_exit_termination() = 0;
 592 };
 593 
 594 // A class to aid in the termination of a set of parallel tasks using
 595 // TaskQueueSet's for work stealing.
 596 
 597 #undef TRACESPINNING
 598 
 599 class ParallelTaskTerminator: public StackObj {
 600 private:
 601   uint _n_threads;
 602   TaskQueueSetSuper* _queue_set;
 603   uint _offered_termination;
 604 
 605 #ifdef TRACESPINNING
 606   static uint _total_yields;
 607   static uint _total_spins;
 608   static uint _total_peeks;
 609 #endif
 610 
 611   bool peek_in_queue_set();
 612 protected:
 613   virtual void yield();
 614   void sleep(uint millis);
 615 
 616 public:
 617 
 618   // "n_threads" is the number of threads to be terminated.  "queue_set" is a
 619   // queue sets of work queues of other threads.
 620   ParallelTaskTerminator(uint n_threads, TaskQueueSetSuper* queue_set);
 621 
 622   // The current thread has no work, and is ready to terminate if everyone
 623   // else is.  If returns "true", all threads are terminated.  If returns
 624   // "false", available work has been observed in one of the task queues,
 625   // so the global task is not complete.
 626   bool offer_termination() {
 627     return offer_termination(NULL);
 628   }
 629 
 630   // As above, but it also terminates if the should_exit_termination()
 631   // method of the terminator parameter returns true. If terminator is
 632   // NULL, then it is ignored.
 633   bool offer_termination(TerminatorTerminator* terminator);
 634 
 635   // Reset the terminator, so that it may be reused again.
 636   // The caller is responsible for ensuring that this is done
 637   // in an MT-safe manner, once the previous round of use of
 638   // the terminator is finished.
 639   void reset_for_reuse();
 640   // Same as above but the number of parallel threads is set to the
 641   // given number.
 642   void reset_for_reuse(uint n_threads);
 643 
 644 #ifdef TRACESPINNING
 645   static uint total_yields() { return _total_yields; }
 646   static uint total_spins() { return _total_spins; }
 647   static uint total_peeks() { return _total_peeks; }
 648   static void print_termination_counts();
 649 #endif
 650 };
 651 
 652 template<class E, MEMFLAGS F, unsigned int N> inline bool
 653 GenericTaskQueue<E, F, N>::push(E t) {
 654   uint localBot = _bottom;
 655   assert(localBot < N, "_bottom out of range.");
 656   idx_t top = _age.top();
 657   uint dirty_n_elems = dirty_size(localBot, top);
 658   assert(dirty_n_elems < N, "n_elems out of range.");
 659   if (dirty_n_elems < max_elems()) {
 660     // g++ complains if the volatile result of the assignment is
 661     // unused, so we cast the volatile away.  We cannot cast directly
 662     // to void, because gcc treats that as not using the result of the


< prev index next >