Revision: 14792
http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=14792&view=revAuthor: pizlo
Date: 2008-07-24 23:13:36 +0000 (Thu, 24 Jul 2008)
Log Message:
-----------
fix GC trigger
Modified Paths:
--------------
rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/VM.java
rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/memorymanagers/mminterface/Barrier.java
rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/memorymanagers/mminterface/CollectorThread.java
rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/memorymanagers/mminterface/Handshake.java
rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/memorymanagers/mminterface/SynchronizationBarrier.java
rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/RVMThread.java
Modified: rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/VM.java
===================================================================
--- rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/VM.java 2008-07-24 20:24:53 UTC (rev 14791)
+++ rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/VM.java 2008-07-24 23:13:36 UTC (rev 14792)
@@ -1724,6 +1724,18 @@
}
@NoInline
+ public static void sysWriteln(String s1, int i, String s2, Word w, String s3) {
+ swLock();
+ write(s1);
+ write(i);
+ write(s2);
+ write(w);
+ write(s3);
+ writeln();
+ swUnlock();
+ }
+
+ @NoInline
public static void sysWriteln(String s1, int i1, String s2, int i2, String s3) {
swLock();
write(s1);
Modified: rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/memorymanagers/mminterface/Barrier.java
===================================================================
--- rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/memorymanagers/mminterface/Barrier.java 2008-07-24 20:24:53 UTC (rev 14791)
+++ rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/memorymanagers/mminterface/Barrier.java 2008-07-24 23:13:36 UTC (rev 14792)
@@ -13,9 +13,7 @@
package org.jikesrvm.memorymanagers.mminterface;
import org.jikesrvm.VM;
-import org.jikesrvm.mm.mmtk.SynchronizedCounter;
-import org.jikesrvm.runtime.Magic;
-import org.jikesrvm.runtime.Time;
+import org.jikesrvm.scheduler.HeavyCondLock;
import org.vmmagic.pragma.Uninterruptible;
/**
@@ -28,107 +26,38 @@
final class Barrier {
public static final int VERBOSE = 0;
-
- // The value of target is one more than the number of threads we expect to arrive.
- // It is one greater to allow safely updating the currentCounter value.
- // If target is -1, no thread can proceed past the barrier.
- // 3 counters are needed to support proper resetting without race conditions.
- //
- private volatile int target = -1;
- private static final int NUM_COUNTERS = 3;
- final SynchronizedCounter[] counters;
- SynchronizedCounter currentCounter;
-
- // Debugging constants
- private static final long WARN_PERIOD = Time.secsToNanos(20); // Print msg every WARN_PERIOD seconds
- private static final long TIME_OUT = 3 * WARN_PERIOD; // Die after TIME_OUT seconds;
-
- public Barrier() {
- counters = new SynchronizedCounter[NUM_COUNTERS];
- for (int i = 0; i < NUM_COUNTERS; i++) {
- counters[i] = new SynchronizedCounter();
- }
- currentCounter = new SynchronizedCounter();
+
+ private HeavyCondLock lock;
+ private int target;
+ private int[] counters=new int[2]; // are two counters enough?
+ private int countIdx;
+
+ public Barrier() {}
+
+ public void boot(int target) {
+ lock=new HeavyCondLock();
+ this.target=target;
+ countIdx=0;
}
-
- // Set target to appropriate value
- //
- public void setTarget(int t) {
- Magic.isync();
- if (VM.VerifyAssertions) VM._assert(t >= 0);
- target = t + 1;
- Magic.sync();
- }
-
- public void clearTarget() {
- Magic.isync();
- target = -1;
- Magic.sync();
- }
-
- // Returns whether caller was first to arrive.
- // The coding to ensure resetting is delicate.
- //
- public int arrive(int where) {
- Magic.isync();
- int cur = currentCounter.peek();
- SynchronizedCounter c = counters[cur];
- int myValue = c.increment();
- // Do NOT use the currentCounter variables unless designated thread
- if (VERBOSE >= 1) {
- VM.sysWriteln(where,": myValue = ",myValue);
- }
- if (VM.VerifyAssertions) VM._assert(myValue >= 0 && (target == -1 || myValue <= target));
- if (myValue + 2 == target) {
- // last one to show up
- int next = (cur + 1) % NUM_COUNTERS;
- int prev = (cur - 1 + NUM_COUNTERS) % NUM_COUNTERS;
- counters[prev].reset(); // everyone has seen the value so safe to reset now
- if (next == 0) {
- currentCounter.reset(); // everyone has arrived but still waiting
- } else {
- currentCounter.increment();
- }
- c.increment(); // now safe to let others past barrier
- Magic.sync();
- return myValue;
+
+ public void arrive() {
+ lock.lock();
+ int myCountIdx=countIdx;
+ counters[myCountIdx]++;
+ if (counters[myCountIdx]==target) {
+ counters[myCountIdx]=0;
+ countIdx^=1;
+ lock.broadcast();
} else {
- // everyone else
- long startNano = 0;
- long lastElapsedNano = 0;
- while (true) {
- long startCycles = Time.cycles();
- long endCycles = startCycles + ((long) 1e9); // a few hundred milliseconds more or less.
- long nowCycles;
- do {
- if (target != -1 && c.peek() == target) {
- Magic.sync();
- return myValue;
- }
- nowCycles = Time.cycles();
- } while (startCycles < nowCycles && nowCycles < endCycles); /* check against both ends to guard against CPU migration */
-
- /*
- * According to the cycle counter, we've been spinning for a while.
- * Time to check nanoTime and see if we should print a warning and/or sysFail.
- */
- if (startNano == 0) {
- startNano = Time.nanoTime();
- } else {
- long nowNano = Time.nanoTime();
- long elapsedNano = nowNano - startNano;
- if (elapsedNano - lastElapsedNano > WARN_PERIOD) {
- VM.sysWrite("GC Warning: Barrier wait has reached ",Time.nanosToSecs(elapsedNano),
- " seconds. Called from ");
- VM.sysWrite(where,". myOrder = ",myValue," count is ");
- VM.sysWriteln(c.peek()," waiting for ",target - 1);
- lastElapsedNano = elapsedNano;
- }
- if (elapsedNano > TIME_OUT) {
- VM.sysFail("GC Error: Barrier Timeout");
- }
- }
+ while (counters[myCountIdx]!=0) {
+ lock.await();
}
}
+ lock.unlock();
}
}
+/*
+Local Variables:
+ c-basic-offset: 2
+End:
+*/
Modified: rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/memorymanagers/mminterface/CollectorThread.java
===================================================================
--- rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/memorymanagers/mminterface/CollectorThread.java 2008-07-24 20:24:53 UTC (rev 14791)
+++ rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/memorymanagers/mminterface/CollectorThread.java 2008-07-24 23:13:36 UTC (rev 14792)
@@ -215,6 +215,7 @@
public static void boot() {
handshake.boot();
+ gcBarrier.boot();
}
/**
@@ -344,7 +345,8 @@
Plan.setCollectionTrigger(handshake.gcTrigger);
}
- /* block all threads. */
+ /* block all threads. note that some threads will have already blocked
+ themselves (if they had made their own GC requests). */
if (gcOrdinal == GC_ORDINAL_BASE) {
VM.sysWriteln("Thread #",getThreadSlot()," is about to block a bunch of threads.");
RVMThread.handshakeLock.lock();
@@ -471,10 +473,18 @@
* is enabled, so no mutators can possibly arrive at old
* handshake object: it's safe to replace it with a new one. */
if (gcOrdinal == GC_ORDINAL_BASE) {
+
+ // reset the handshake. this ensures that once threads are awakened,
+ // any new GC requests that they make actually result in GC activity.
+ handshake.reset();
+ VM.sysWriteln("Thread #",getThreadSlot()," just reset the handshake.");
+
+ Plan.collectionComplete();
+
+ VM.sysWriteln("Marked the collection as complete.");
+
collectionAttemptBase = 0;
- /* notify mutators waiting on previous handshake object -
- * actually we don't notify anymore, mutators are simply in
- * processor ready queues waiting to be dispatched. */
+
VM.sysWriteln("Thread #",getThreadSlot()," is unblocking a bunch of threads.");
// and now unblock all threads
RVMThread.handshakeLock.lock();
@@ -509,16 +519,6 @@
if (gcOrdinal == GC_ORDINAL_BASE) {
/* clear the GC flags */
- Plan.collectionComplete();
-
- VM.sysWriteln("Marked the collection as complete.");
-
- handshake.notifyCompletion();
-
- VM.sysWriteln("Notified collection completion.");
-
- handshake.reset();
-
gcThreadRunning = false;
} // if designated thread
rendezvous(9999);
Modified: rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/memorymanagers/mminterface/Handshake.java
===================================================================
--- rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/memorymanagers/mminterface/Handshake.java 2008-07-24 20:24:53 UTC (rev 14791)
+++ rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/memorymanagers/mminterface/Handshake.java 2008-07-24 23:13:36 UTC (rev 14792)
@@ -48,7 +48,6 @@
*/
private HeavyCondLock lock;
protected boolean requestFlag;
- protected boolean completionFlag;
public int gcTrigger; // reason for this GC
private int collectorThreadsParked;
@@ -65,11 +64,7 @@
if (verbose >= 1) VM.sysWriteln("GC Message: Handshake.requestAndAwaitCompletion - yielding");
/* allow a gc thread to run */
VM.sysWriteln("Thread #",RVMThread.getCurrentThreadSlot()," is waiting for the GC to finish.");
- lock.lock();
- while (!completionFlag) {
- lock.waitNicely();
- }
- lock.unlock();
+ RVMThread.getCurrentThread().block(RVMThread.gcBlockAdapter);
VM.sysWriteln("Thread #",RVMThread.getCurrentThreadSlot()," is done waiting for the GC.");
if (verbose >= 1) VM.sysWriteln("GC Message: Handshake.requestAndAwaitCompletion - mutator running");
}
@@ -85,9 +80,8 @@
@LogicallyUninterruptible
@Uninterruptible
public void requestAndAwaitCompletion(int why) {
- if (request(why)) {
- waitForGCToFinish();
- }
+ request(why);
+ waitForGCToFinish();
}
/**
@@ -128,34 +122,7 @@
}
/**
- * Wait for all GC threads to complete previous collection cycle.
- */
- @Uninterruptible
- private void waitForPrecedingGC() {
- VM.sysWriteln("Thread #",RVMThread.getCurrentThreadSlot()," is waiting for the preceding GC to finish");
-
- int maxCollectorThreads = RVMThread.numProcessors;
-
- /* Wait for all gc threads to finish preceeding collection cycle */
- if (verbose >= 1) {
- VM.sysWrite("GC Message: Handshake.initiateCollection ");
- VM.sysWriteln("checking if previous collection is finished");
- }
-
- lock.lock();
- while (collectorThreadsParked < maxCollectorThreads) {
- lock.await();
- }
- lock.unlock();
-
- VM.sysWriteln("Thread #",RVMThread.getCurrentThreadSlot()," is done waiting for the preceding GC to finish");
- }
-
- /**
- * Called by mutators to request a garbage collection. If the
- * completionFlag is already set, return false. Else, if the
- * requestFlag is not yet set (ie this is the first mutator to
- * request this collection) then initiate the collection sequence
+ * Called by mutators to request a garbage collection.
*
* @return true if the completion flag is not already set.
*/
@@ -181,9 +148,7 @@
VM.shutdown(VM.EXIT_STATUS_MISC_TROUBLE);
}
- waitForPrecedingGC();
requestFlag = true;
- completionFlag = false;
Plan.setCollectionTriggered();
@@ -192,26 +157,6 @@
lock.unlock();
return true;
}
-
- /**
- * Set the completion flag that indicates the collection has
- * completed. Called by a collector thread after the collection has
- * completed.
- *
- * @see CollectorThread
- */
- @Uninterruptible
- void notifyCompletion() {
- VM.sysWriteln("Thread #",RVMThread.getCurrentThreadSlot()," is notifying the world that GC is done.");
- lock.lock();
- if (verbose >= 1) {
- VM.sysWriteln("GC Message: Handshake.notifyCompletion");
- }
- completionFlag = true;
- lock.broadcast();
- lock.unlock();
- VM.sysWriteln("Thread #",RVMThread.getCurrentThreadSlot()," is done notifying the world that GC is done.");
- }
}
/*
Modified: rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/memorymanagers/mminterface/SynchronizationBarrier.java
===================================================================
--- rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/memorymanagers/mminterface/SynchronizationBarrier.java 2008-07-24 20:24:53 UTC (rev 14791)
+++ rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/memorymanagers/mminterface/SynchronizationBarrier.java 2008-07-24 23:13:36 UTC (rev 14792)
@@ -32,17 +32,16 @@
private static final int verbose = 0;
- // number of physical processors on running computer
- private int numRealProcessors;
-
final Barrier barrier = new Barrier();
/**
* Constructor
*/
public SynchronizationBarrier() {
- // initialize numRealProcessors to 1. Will be set to actual value later.
- numRealProcessors = 1;
}
+
+ public void boot() {
+ barrier.boot(RVMThread.numProcessors);
+ }
/**
* Wait for all other collectorThreads/processors to arrive at this barrier.
@@ -50,7 +49,7 @@
@Uninterruptible
public int rendezvous(int where) {
- barrier.arrive(where);
+ barrier.arrive();
Magic.isync(); // so subsequent instructions won't see stale values
@@ -67,7 +66,7 @@
@Uninterruptible
public void startupRendezvous() {
- // PNT: FIXME: should not spin GC threads while there are mutator threads that need to do work to stop for GC.
+ // PNT: FIXME: this is more complicated than it needs to be.
CollectorThread th = Magic.threadAsCollectorThread(RVMThread.getCurrentThread());
int myNumber = th.getGCOrdinal();
@@ -80,7 +79,7 @@
}
if (myNumber > 1) {
- barrier.arrive(8888); // wait for designated guy to do his job
+ barrier.arrive(); // wait for designated guy to do his job
Magic.isync(); // so subsequent instructions won't see stale values
if (verbose > 0) VM.sysWriteln("GC Message: startupRendezvous leaving as ", myNumber);
return; // leave barrier
@@ -91,8 +90,7 @@
if (verbose > 0) {
VM.sysWriteln("GC Message: startupRendezvous numParticipating = ", numParticipating);
}
- barrier.setTarget(numParticipating); // retarded
- barrier.arrive(8888); // all setup now complete and we can proceed
+ barrier.arrive(); // all setup now complete and we can proceed
Magic.sync(); // update main memory so other processors will see it in "while" loop
Magic.isync(); // so subsequent instructions won't see stale values
if (verbose > 0) {
@@ -100,3 +98,8 @@
}
} // startupRendezvous
}
+/*
+Local Variables:
+ c-basic-offset: 2
+End:
+*/
Modified: rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/RVMThread.java
===================================================================
--- rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/RVMThread.java 2008-07-24 20:24:53 UTC (rev 14791)
+++ rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/RVMThread.java 2008-07-24 23:13:36 UTC (rev 14792)
@@ -89,7 +89,7 @@
/** Trace when a thread is really blocked */
protected static final boolean traceReallyBlock = true || traceBlock;
/** Trace thread start/stop */
- protected static final boolean traceAcct = false;
+ protected static final boolean traceAcct = true;
/** Trace execution */
protected static final boolean trace = false;
/** Trace thread termination */
@@ -299,7 +299,7 @@
public long totalObjectsAllocated;
/** used for instrumentation in allocators */
public long synchronizedObjectsAllocated;
-
+
/**
* Is the next taken yieldpoint in response to a request to perform OSR?
*/
@@ -1331,7 +1331,7 @@
}
final void enterNativeBlocked(boolean jni) {
- if (traceBlock) VM.sysWriteln("Thread #",threadSlot," entering native blocked.");
+ if (traceReallyBlock) VM.sysWriteln("Thread #",threadSlot," entering native blocked.");
// NB: anything this method calls CANNOT change the contextRegisters
// or the JNI env. as well, this code will be running concurrently
// with stop-the-world GC!
@@ -1419,7 +1419,7 @@
// do a timed wait, and assert that the thread did not disappear
// into native in the meantime
monitor().timedWaitRelative(1000L*1000L*1000L); // 1 sec
- if (traceBlock) {
+ if (traceReallyBlock) {
VM.sysWriteln("Thread #",threadSlot,"'s status is ",execStatus);
}
VM._assert(execStatus!=IN_NATIVE);
@@ -1675,7 +1675,10 @@
sysCall.sysStashVmThreadInPthread(currentThread);
- if (traceAcct) VM.sysWriteln("Thread #",currentThread.threadSlot," running!");
+ if (traceAcct) {
+ VM.sysWriteln("Thread #",currentThread.threadSlot," with pthread id ",
+ currentThread.pthread_id," running!");
+ }
if (trace) {
VM.sysWriteln("Thread.startoff(): about to call ", currentThread.toString(), ".run()");
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/_______________________________________________
Jikesrvm-commits mailing list
Jikesrvm-commits@...
https://lists.sourceforge.net/lists/listinfo/jikesrvm-commits