353 // work because as noted a thread is not guaranteed to get a draining task.
354 //
355 // For PSScavenge and ParCompactionManager the GC threads are
356 // held in the GCTaskThread** _thread array in GCTaskManager.
357
358
359 class GCTaskManager : public CHeapObj<mtGC> {
360 friend class ParCompactionManager;
361 friend class PSParallelCompact;
362 friend class PSScavenge;
363 friend class PSRefProcTaskExecutor;
364 friend class RefProcTaskExecutor;
365 friend class GCTaskThread;
366 friend class IdleGCTask;
367 private:
368 // Instance state.
369 const uint _workers; // Number of workers.
370 Monitor* _monitor; // Notification of changes.
371 SynchronizedGCTaskQueue* _queue; // Queue of tasks.
372 GCTaskThread** _thread; // Array of worker threads.
373 uint _active_workers; // Number of active workers.
374 uint _busy_workers; // Number of busy workers.
375 uint _blocking_worker; // The worker that's blocking.
376 bool* _resource_flag; // Array of flag per threads.
377 uint _delivered_tasks; // Count of delivered tasks.
378 uint _completed_tasks; // Count of completed tasks.
379 uint _barriers; // Count of barrier tasks.
380 uint _emptied_queue; // Times we emptied the queue.
381 NoopGCTask* _noop_task; // The NoopGCTask instance.
382 WaitHelper _wait_helper; // Used by inactive worker
383 volatile uint _idle_workers; // Number of idled workers
384 public:
385 // Factory create and destroy methods.
386 static GCTaskManager* create(uint workers) {
387 return new GCTaskManager(workers);
388 }
389 static void destroy(GCTaskManager* that) {
390 if (that != NULL) {
391 delete that;
392 }
393 }
394 // Accessors.
395 uint busy_workers() const {
396 return _busy_workers;
397 }
398 volatile uint idle_workers() const {
399 return _idle_workers;
400 }
401 // Pun between Monitor* and Mutex*
402 Monitor* monitor() const {
403 return _monitor;
529 _emptied_queue += 1;
530 }
531 void reset_emptied_queue() {
532 _emptied_queue = 0;
533 }
534 void increment_idle_workers() {
535 _idle_workers++;
536 }
537 void decrement_idle_workers() {
538 _idle_workers--;
539 }
540 // Other methods.
541 void initialize();
542
543 public:
544 // Return true if all workers are currently active.
545 bool all_workers_active() { return workers() == active_workers(); }
546 uint active_workers() const {
547 return _active_workers;
548 }
549 };
550
551 //
552 // Some exemplary GCTasks.
553 //
554
555 // A noop task that does nothing,
556 // except take us around the GCTaskThread loop.
557 class NoopGCTask : public GCTask {
558 public:
559 // Factory create and destroy methods.
560 static NoopGCTask* create_on_c_heap();
561 static void destroy(NoopGCTask* that);
562
563 virtual char* name() { return (char *)"noop task"; }
564 // Methods from GCTask.
565 void do_it(GCTaskManager* manager, uint which) {
566 // Nothing to do.
567 }
568 protected:
|
353 // work because as noted a thread is not guaranteed to get a draining task.
354 //
355 // For PSScavenge and ParCompactionManager the GC threads are
356 // held in the GCTaskThread** _thread array in GCTaskManager.
357
358
359 class GCTaskManager : public CHeapObj<mtGC> {
360 friend class ParCompactionManager;
361 friend class PSParallelCompact;
362 friend class PSScavenge;
363 friend class PSRefProcTaskExecutor;
364 friend class RefProcTaskExecutor;
365 friend class GCTaskThread;
366 friend class IdleGCTask;
367 private:
368 // Instance state.
369 const uint _workers; // Number of workers.
370 Monitor* _monitor; // Notification of changes.
371 SynchronizedGCTaskQueue* _queue; // Queue of tasks.
372 GCTaskThread** _thread; // Array of worker threads.
373 uint _created_workers; // Number of workers created.
374 uint _active_workers; // Number of active workers.
375 uint _busy_workers; // Number of busy workers.
376 uint _blocking_worker; // The worker that's blocking.
377 bool* _resource_flag; // Array of flag per threads.
378 uint _delivered_tasks; // Count of delivered tasks.
379 uint _completed_tasks; // Count of completed tasks.
380 uint _barriers; // Count of barrier tasks.
381 uint _emptied_queue; // Times we emptied the queue.
382 NoopGCTask* _noop_task; // The NoopGCTask instance.
383 WaitHelper _wait_helper; // Used by inactive worker
384 volatile uint _idle_workers; // Number of idled workers
385 uint* _processor_assignment; // Worker to cpu mappings. May
386 // be used lazily
387 public:
388 // Factory create and destroy methods.
389 static GCTaskManager* create(uint workers) {
390 return new GCTaskManager(workers);
391 }
392 static void destroy(GCTaskManager* that) {
393 if (that != NULL) {
394 delete that;
395 }
396 }
397 // Accessors.
398 uint busy_workers() const {
399 return _busy_workers;
400 }
401 volatile uint idle_workers() const {
402 return _idle_workers;
403 }
404 // Pun between Monitor* and Mutex*
405 Monitor* monitor() const {
406 return _monitor;
532 _emptied_queue += 1;
533 }
534 void reset_emptied_queue() {
535 _emptied_queue = 0;
536 }
537 void increment_idle_workers() {
538 _idle_workers++;
539 }
540 void decrement_idle_workers() {
541 _idle_workers--;
542 }
543 // Other methods.
544 void initialize();
545
546 public:
547 // Return true if all workers are currently active.
548 bool all_workers_active() { return workers() == active_workers(); }
549 uint active_workers() const {
550 return _active_workers;
551 }
552 uint created_workers() const {
553 return _created_workers;
554 }
555 // Create a GC worker and install into GCTaskManager
556 GCTaskThread* install_worker(uint worker_id);
557 // Add GC workers as needed.
558 bool add_workers(bool initializing);
559 };
560
561 //
562 // Some exemplary GCTasks.
563 //
564
565 // A noop task that does nothing,
566 // except take us around the GCTaskThread loop.
567 class NoopGCTask : public GCTask {
568 public:
569 // Factory create and destroy methods.
570 static NoopGCTask* create_on_c_heap();
571 static void destroy(NoopGCTask* that);
572
573 virtual char* name() { return (char *)"noop task"; }
574 // Methods from GCTask.
575 void do_it(GCTaskManager* manager, uint which) {
576 // Nothing to do.
577 }
578 protected:
|