/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Common Public License (CPL); * You may not use this file except in compliance with the License. You * may obtain a copy of the License at * * http://www.opensource.org/licenses/cpl1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.jikesrvm.memorymanagers.mminterface; import org.jikesrvm.ArchitectureSpecific; import org.jikesrvm.VM; import org.jikesrvm.scheduler.VM_Scheduler; import org.jikesrvm.scheduler.greenthreads.VM_GreenProcessor; import org.jikesrvm.scheduler.greenthreads.VM_GreenScheduler; import org.jikesrvm.scheduler.greenthreads.VM_GreenThread; import org.vmmagic.pragma.Interruptible; import org.vmmagic.pragma.LogicallyUninterruptible; import org.vmmagic.pragma.Uninterruptible; /** * Threads that perform collector work while mutators are active. these * threads wait for the collector to activate them. */ public final class VM_ConcurrentCollectorThread extends VM_GreenThread { /*********************************************************************** * * Class variables */ private static final int verbose = 0; /** Name used by toString() and when we create the associated * java.lang.Thread. */ private static final String myName = "VM_ConcurrentCollectorThread"; /** maps processor id to associated collector thread */ public static VM_ConcurrentCollectorThread[] concurrentCollectorThreads; /*********************************************************************** * * Instance variables */ /*********************************************************************** * * Initialization */ /** * Constructor * * @param stack The stack this thread will run on * @param isActive Whether or not this thread will participate in GC * @param processorAffinity The processor with which this thread is * associated. */ VM_ConcurrentCollectorThread(byte[] stack, VM_GreenProcessor processorAffinity) { super(stack, myName); makeDaemon(true); // this is redundant, but harmless this.processorAffinity = processorAffinity; /* associate this collector thread with its affinity processor */ concurrentCollectorThreads[processorAffinity.id] = this; } /** * Initialize for boot image. */ @Interruptible public static void init() { concurrentCollectorThreads = new VM_ConcurrentCollectorThread[1 + VM_GreenScheduler.MAX_PROCESSORS]; } /** * Make a concurrent collector thread.<p> * * Note: the new thread's stack must be in pinned memory: currently * done by allocating it in immortal memory. * * @param processorAffinity processor to run on * @return a new collector thread */ @Interruptible public static VM_ConcurrentCollectorThread createConcurrentCollectorThread(VM_GreenProcessor processorAffinity) { byte[] stack = MM_Interface.newStack(ArchitectureSpecific.VM_StackframeLayoutConstants.STACK_SIZE_COLLECTOR, true); return new VM_ConcurrentCollectorThread(stack, processorAffinity); } /** * Override VM_Thread.toString * * @return A string describing this thread. */ @Uninterruptible public String toString() { return myName; } /** * Run method for concurrent collector thread. */ @LogicallyUninterruptible @Uninterruptible public void run() { if (verbose >= 1) VM.sysWriteln("GC Message: Concurrent collector thread entered run..."); while (true) { /* suspend this thread: it will resume when the garbage collector * notifies it there is work to do. */ VM_Scheduler.suspendConcurrentCollectorThread(); if (verbose >= 1) VM.sysWriteln("GC Message: Concurrent collector awake"); Selected.Collector.get().concurrentCollect(); if (verbose >= 1) VM.sysWriteln("GC Message: Concurrent collector finished"); } } }