20 * or visit www.oracle.com if you need additional information or have any |
20 * or visit www.oracle.com if you need additional information or have any |
21 * questions. |
21 * questions. |
22 * |
22 * |
23 */ |
23 */ |
24 |
24 |
25 /* |
|
26 * This file has been modified by Loongson Technology in 2015. These |
|
27 * modifications are Copyright (c) 2015 Loongson Technology, and are made |
|
28 * available on the same license terms set forth above. |
|
29 */ |
|
30 |
|
31 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
32 #include "gc_implementation/parallelScavenge/gcTaskManager.hpp" |
26 #include "gc_implementation/parallelScavenge/gcTaskManager.hpp" |
33 #include "gc_implementation/parallelScavenge/gcTaskThread.hpp" |
27 #include "gc_implementation/parallelScavenge/gcTaskThread.hpp" |
34 #include "gc_implementation/shared/adaptiveSizePolicy.hpp" |
28 #include "gc_implementation/shared/adaptiveSizePolicy.hpp" |
35 #include "memory/allocation.hpp" |
29 #include "memory/allocation.hpp" |
284 print("after:"); |
278 print("after:"); |
285 } |
279 } |
286 return result; |
280 return result; |
287 } |
281 } |
288 |
282 |
289 // Dequeue one task, preferring one with numa_aware. |
|
290 GCTask* GCTaskQueue::numa_dequeue(int numa_id) { |
|
291 if (TraceGCTaskQueue) { |
|
292 tty->print_cr("[" INTPTR_FORMAT "]" |
|
293 " GCTaskQueue::dequeue(%u)", this, numa_id); |
|
294 print("before:"); |
|
295 } |
|
296 assert(!is_empty(), "shouldn't dequeue from empty list"); |
|
297 // Look down to the next barrier for a task with this affinity. |
|
298 GCTask* result = NULL; |
|
299 for (GCTask* element = remove_end(); |
|
300 element != NULL; |
|
301 element = element->newer()) { |
|
302 if (element->is_barrier_task()) { |
|
303 // Don't consider barrier tasks, nor past them. |
|
304 result = NULL; |
|
305 break; |
|
306 } |
|
307 if (element->task_numa_id() == numa_id) { |
|
308 result = remove(element); |
|
309 break; |
|
310 } |
|
311 } |
|
312 // If we didn't find anything with affinity, just take the next task. |
|
313 if (result == NULL) { |
|
314 result = remove(); |
|
315 } |
|
316 |
|
317 if (TraceGCTaskQueue) { |
|
318 tty->print_cr(" return: " INTPTR_FORMAT, result); |
|
319 print("after:"); |
|
320 } |
|
321 return result; |
|
322 } |
|
323 |
|
324 GCTask* GCTaskQueue::remove() { |
283 GCTask* GCTaskQueue::remove() { |
325 // Dequeue from remove end. |
284 // Dequeue from remove end. |
326 GCTask* result = remove_end(); |
285 GCTask* result = remove_end(); |
327 assert(result != NULL, "shouldn't have null task"); |
286 assert(result != NULL, "shouldn't have null task"); |
328 assert(result->older() == NULL, "not the remove_end"); |
287 assert(result->older() == NULL, "not the remove_end"); |
450 { |
409 { |
451 // Set up worker threads. |
410 // Set up worker threads. |
452 // Distribute the workers among the available processors, |
411 // Distribute the workers among the available processors, |
453 // unless we were told not to, or if the os doesn't want to. |
412 // unless we were told not to, or if the os doesn't want to. |
454 uint* processor_assignment = NEW_C_HEAP_ARRAY(uint, workers(), mtGC); |
413 uint* processor_assignment = NEW_C_HEAP_ARRAY(uint, workers(), mtGC); |
455 if (BindGCTaskThreadsToCPUs || |
414 if (!BindGCTaskThreadsToCPUs || |
456 !os::distribute_processes(workers(), processor_assignment)) { |
415 !os::distribute_processes(workers(), processor_assignment)) { |
457 for (uint a = 0; a < workers(); a += 1) { |
416 for (uint a = 0; a < workers(); a += 1) { |
458 /*2014/7/7 Liao: Bind GCThread [a] to processor [a] */ |
417 processor_assignment[a] = sentinel_worker(); |
459 processor_assignment[a] = a; |
|
460 } |
418 } |
461 } |
419 } |
462 _thread = NEW_C_HEAP_ARRAY(GCTaskThread*, workers(), mtGC); |
420 _thread = NEW_C_HEAP_ARRAY(GCTaskThread*, workers(), mtGC); |
463 for (uint t = 0; t < workers(); t += 1) { |
421 for (uint t = 0; t < workers(); t += 1) { |
464 set_thread(t, GCTaskThread::create(this, t, processor_assignment[t])); |
422 set_thread(t, GCTaskThread::create(this, t, processor_assignment[t])); |
699 // Figure out which condition caused us to exit the loop above. |
657 // Figure out which condition caused us to exit the loop above. |
700 if (!queue()->is_empty()) { |
658 if (!queue()->is_empty()) { |
701 if (UseGCTaskAffinity) { |
659 if (UseGCTaskAffinity) { |
702 result = queue()->dequeue(which); |
660 result = queue()->dequeue(which); |
703 } else { |
661 } else { |
704 /* 2014/7/7 Liao: GCThread get task on numa machines with numa_aware. */ |
662 result = queue()->dequeue(); |
705 if(UseNUMAThreadRoots) { |
|
706 result = queue()->numa_dequeue(os::numa_get_group_id()); |
|
707 } |
|
708 else { |
|
709 result = queue()->dequeue(); |
|
710 } |
|
711 } |
663 } |
712 if (result->is_barrier_task()) { |
664 if (result->is_barrier_task()) { |
713 assert(which != sentinel_worker(), |
665 assert(which != sentinel_worker(), |
714 "blocker shouldn't be bogus"); |
666 "blocker shouldn't be bogus"); |
715 set_blocking_worker(which); |
667 set_blocking_worker(which); |