1 /* |
1 /* |
2 * Copyright (c) 2001, 2007, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
51 |
51 |
52 WorkGang::WorkGang(const char* name, |
52 WorkGang::WorkGang(const char* name, |
53 int workers, |
53 int workers, |
54 bool are_GC_task_threads, |
54 bool are_GC_task_threads, |
55 bool are_ConcurrentGC_threads) : |
55 bool are_ConcurrentGC_threads) : |
56 AbstractWorkGang(name, are_GC_task_threads, are_ConcurrentGC_threads) |
56 AbstractWorkGang(name, are_GC_task_threads, are_ConcurrentGC_threads) { |
57 { |
|
58 // Save arguments. |
57 // Save arguments. |
59 _total_workers = workers; |
58 _total_workers = workers; |
|
59 } |
|
60 |
|
61 GangWorker* WorkGang::allocate_worker(int which) { |
|
62 GangWorker* new_worker = new GangWorker(this, which); |
|
63 return new_worker; |
|
64 } |
|
65 |
|
66 // The current implementation will exit if the allocation |
|
67 // of any worker fails. Still, return a boolean so that |
|
68 // a future implementation can possibly do a partial |
|
69 // initialization of the workers and report such to the |
|
70 // caller. |
|
71 bool WorkGang::initialize_workers() { |
60 |
72 |
61 if (TraceWorkGang) { |
73 if (TraceWorkGang) { |
62 tty->print_cr("Constructing work gang %s with %d threads", name, workers); |
74 tty->print_cr("Constructing work gang %s with %d threads", |
63 } |
75 name(), |
64 _gang_workers = NEW_C_HEAP_ARRAY(GangWorker*, workers); |
76 total_workers()); |
|
77 } |
|
78 _gang_workers = NEW_C_HEAP_ARRAY(GangWorker*, total_workers()); |
65 if (gang_workers() == NULL) { |
79 if (gang_workers() == NULL) { |
66 vm_exit_out_of_memory(0, "Cannot create GangWorker array."); |
80 vm_exit_out_of_memory(0, "Cannot create GangWorker array."); |
|
81 return false; |
|
82 } |
|
83 os::ThreadType worker_type; |
|
84 if (are_ConcurrentGC_threads()) { |
|
85 worker_type = os::cgc_thread; |
|
86 } else { |
|
87 worker_type = os::pgc_thread; |
67 } |
88 } |
68 for (int worker = 0; worker < total_workers(); worker += 1) { |
89 for (int worker = 0; worker < total_workers(); worker += 1) { |
69 GangWorker* new_worker = new GangWorker(this, worker); |
90 GangWorker* new_worker = allocate_worker(worker); |
70 assert(new_worker != NULL, "Failed to allocate GangWorker"); |
91 assert(new_worker != NULL, "Failed to allocate GangWorker"); |
71 _gang_workers[worker] = new_worker; |
92 _gang_workers[worker] = new_worker; |
72 if (new_worker == NULL || !os::create_thread(new_worker, os::pgc_thread)) |
93 if (new_worker == NULL || !os::create_thread(new_worker, worker_type)) { |
73 vm_exit_out_of_memory(0, "Cannot create worker GC thread. Out of system resources."); |
94 vm_exit_out_of_memory(0, "Cannot create worker GC thread. Out of system resources."); |
|
95 return false; |
|
96 } |
74 if (!DisableStartThread) { |
97 if (!DisableStartThread) { |
75 os::start_thread(new_worker); |
98 os::start_thread(new_worker); |
76 } |
99 } |
77 } |
100 } |
|
101 return true; |
78 } |
102 } |
79 |
103 |
80 AbstractWorkGang::~AbstractWorkGang() { |
104 AbstractWorkGang::~AbstractWorkGang() { |
81 if (TraceWorkGang) { |
105 if (TraceWorkGang) { |
82 tty->print_cr("Destructing work gang %s", name()); |
106 tty->print_cr("Destructing work gang %s", name()); |
381 |
405 |
382 bool SubTasksDone::valid() { |
406 bool SubTasksDone::valid() { |
383 return _tasks != NULL; |
407 return _tasks != NULL; |
384 } |
408 } |
385 |
409 |
386 void SubTasksDone::set_par_threads(int t) { |
410 void SubTasksDone::set_n_threads(int t) { |
387 #ifdef ASSERT |
411 #ifdef ASSERT |
388 assert(_claimed == 0 || _threads_completed == _n_threads, |
412 assert(_claimed == 0 || _threads_completed == _n_threads, |
389 "should not be called while tasks are being processed!"); |
413 "should not be called while tasks are being processed!"); |
390 #endif |
414 #endif |
391 _n_threads = (t == 0 ? 1 : t); |
415 _n_threads = (t == 0 ? 1 : t); |