/* This file is part of JOP, the Java Optimized Processor see <http://www.jopdesign.com/> Copyright (C) 2006, Rasmus Ulslev Pedersen This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package gctest; import joprt.RtThread; import com.jopdesign.sys.GC; // GcTest2 // The test is supposed to test if GC takes place after several // threads has passes ONE reference down the line. The last thread // nulls the reference and we check that GC detects it. // Parameters: This test can be changed using the NUMTHREADS constant public class GCTest2 { static int NUMTHREADS; static GarbageThread[] garbageThreads; public static void main(String s[]) { NUMTHREADS = 500; //Takes about 2 min to run. System.out.print("NUMTHREADS "); System.out.println(NUMTHREADS); garbageThreads = new GarbageThread[NUMTHREADS]; System.out.println("gabagethreads length " + garbageThreads.length); for (int i = 0; i < NUMTHREADS; i++) { GarbageThread gt = new GarbageThread(i + 10, (i + 1) * 100000, i, NUMTHREADS, garbageThreads); garbageThreads[i] = gt; } System.out.println("Threads created"); int gcBefore = GC.freeMemory(); Garbage2 garbage = new Garbage2(); garbage.size = gcBefore - GC.freeMemory(); System.out.println("here2"); // Give the garbage object to the first thread garbageThreads[0].garbage = garbage; System.out.println("here3"); garbage = null; System.out.println("here2"); RtThread.startMission(); System.out.println("startMission called"); for (;;) { System.out.println("Sleeping for 1000 ms"); RtThread.sleepMs(1000); } } } class GarbageThread extends RtThread { int id; public Garbage2 garbage; public GarbageThread[] garbageThreads; public int NUMTHREADS; public GarbageThread(int prio, int us, int id, int NUMTHREADS, GarbageThread[] garbageThreads) { super(prio, us); this.id = id; this.NUMTHREADS = NUMTHREADS; this.garbageThreads = garbageThreads; } public void run() { for (;;) { // The threads just pass on the reference System.out.print("Garbage therad "); System.out.println(id); if (id < NUMTHREADS - 1) { if (garbage != null) { // Pass on the garbage reference if I // have it garbageThreads[id + 1].garbage = garbage; garbage = null; System.out.println("garbage passed on"); } } // The last thread releases the reference and checks GC if (id == NUMTHREADS - 1 && garbage != null) { System.out.println("Final stuff"); int size = garbage.size; System.out.print("Size of gabage object:"); System.out.println(size); GC.gc(); // Remove other garbage first to calibrate int gcBefore = GC.freeMemory(); garbage = null; // So much work for so little, but here it is GC.gc(); int gcAfter = GC.freeMemory(); if ((gcAfter-gcBefore) != size) { System.out.println("GC did not collect the floating reference"); System.out.println("gcBefore " + gcBefore); System.out.println("gcAfter " + gcAfter); System.exit(-1); } else { System.out.println("Test completed OK"); System.exit(0); } } waitForNextPeriod(); } } } class Garbage2 { public int size = -1; public Garbage2() { System.out.println("The only Garbage object created."); } }