23 */
24
25 #include "precompiled.hpp"
26 #include "gc/shared/gcId.hpp"
27 #include "gc/shared/workgroup.hpp"
28 #include "gc/shared/workerManager.hpp"
29 #include "memory/allocation.hpp"
30 #include "memory/allocation.inline.hpp"
31 #include "runtime/atomic.hpp"
32 #include "runtime/os.hpp"
33 #include "runtime/semaphore.hpp"
34 #include "runtime/thread.inline.hpp"
35
36 // Definitions of WorkGang methods.
37
38 // The current implementation will exit if the allocation
39 // of any worker fails.
40 void AbstractWorkGang::initialize_workers() {
41 log_develop_trace(gc, workgang)("Constructing work gang %s with %u threads", name(), total_workers());
42 _workers = NEW_C_HEAP_ARRAY(AbstractGangWorker*, total_workers(), mtInternal);
43 if (_workers == NULL) {
44 vm_exit_out_of_memory(0, OOM_MALLOC_ERROR, "Cannot create GangWorker array.");
45 }
46
47 add_workers(true);
48 }
49
50
51 AbstractGangWorker* AbstractWorkGang::install_worker(uint worker_id) {
52 AbstractGangWorker* new_worker = allocate_worker(worker_id);
53 set_thread(worker_id, new_worker);
54 return new_worker;
55 }
56
57 void AbstractWorkGang::add_workers(bool initializing) {
58 add_workers(_active_workers, initializing);
59 }
60
61 void AbstractWorkGang::add_workers(uint active_workers, bool initializing) {
62
63 os::ThreadType worker_type;
64 if (are_ConcurrentGC_threads()) {
65 worker_type = os::cgc_thread;
66 } else {
392 ml.notify_all();
393 } else {
394 while (n_completed() != n_workers() && !aborted()) {
395 ml.wait();
396 }
397 }
398 return !aborted();
399 }
400
401 void WorkGangBarrierSync::abort() {
402 MutexLocker x(monitor(), Mutex::_no_safepoint_check_flag);
403 set_aborted();
404 monitor()->notify_all();
405 }
406
407 // SubTasksDone functions.
408
409 SubTasksDone::SubTasksDone(uint n) :
410 _tasks(NULL), _n_tasks(n), _threads_completed(0) {
411 _tasks = NEW_C_HEAP_ARRAY(uint, n, mtInternal);
412 guarantee(_tasks != NULL, "alloc failure");
413 clear();
414 }
415
416 bool SubTasksDone::valid() {
417 return _tasks != NULL;
418 }
419
420 void SubTasksDone::clear() {
421 for (uint i = 0; i < _n_tasks; i++) {
422 _tasks[i] = 0;
423 }
424 _threads_completed = 0;
425 #ifdef ASSERT
426 _claimed = 0;
427 #endif
428 }
429
430 bool SubTasksDone::try_claim_task(uint t) {
431 assert(t < _n_tasks, "bad task id.");
432 uint old = _tasks[t];
|
23 */
24
25 #include "precompiled.hpp"
26 #include "gc/shared/gcId.hpp"
27 #include "gc/shared/workgroup.hpp"
28 #include "gc/shared/workerManager.hpp"
29 #include "memory/allocation.hpp"
30 #include "memory/allocation.inline.hpp"
31 #include "runtime/atomic.hpp"
32 #include "runtime/os.hpp"
33 #include "runtime/semaphore.hpp"
34 #include "runtime/thread.inline.hpp"
35
36 // Definitions of WorkGang methods.
37
38 // The current implementation will exit if the allocation
39 // of any worker fails.
40 void AbstractWorkGang::initialize_workers() {
41 log_develop_trace(gc, workgang)("Constructing work gang %s with %u threads", name(), total_workers());
42 _workers = NEW_C_HEAP_ARRAY(AbstractGangWorker*, total_workers(), mtInternal);
43 add_workers(true);
44 }
45
46
47 AbstractGangWorker* AbstractWorkGang::install_worker(uint worker_id) {
48 AbstractGangWorker* new_worker = allocate_worker(worker_id);
49 set_thread(worker_id, new_worker);
50 return new_worker;
51 }
52
53 void AbstractWorkGang::add_workers(bool initializing) {
54 add_workers(_active_workers, initializing);
55 }
56
57 void AbstractWorkGang::add_workers(uint active_workers, bool initializing) {
58
59 os::ThreadType worker_type;
60 if (are_ConcurrentGC_threads()) {
61 worker_type = os::cgc_thread;
62 } else {
388 ml.notify_all();
389 } else {
390 while (n_completed() != n_workers() && !aborted()) {
391 ml.wait();
392 }
393 }
394 return !aborted();
395 }
396
397 void WorkGangBarrierSync::abort() {
398 MutexLocker x(monitor(), Mutex::_no_safepoint_check_flag);
399 set_aborted();
400 monitor()->notify_all();
401 }
402
403 // SubTasksDone functions.
404
405 SubTasksDone::SubTasksDone(uint n) :
406 _tasks(NULL), _n_tasks(n), _threads_completed(0) {
407 _tasks = NEW_C_HEAP_ARRAY(uint, n, mtInternal);
408 clear();
409 }
410
411 bool SubTasksDone::valid() {
412 return _tasks != NULL;
413 }
414
415 void SubTasksDone::clear() {
416 for (uint i = 0; i < _n_tasks; i++) {
417 _tasks[i] = 0;
418 }
419 _threads_completed = 0;
420 #ifdef ASSERT
421 _claimed = 0;
422 #endif
423 }
424
425 bool SubTasksDone::try_claim_task(uint t) {
426 assert(t < _n_tasks, "bad task id.");
427 uint old = _tasks[t];
|