/* This file is part of JOP, the Java Optimized Processor see <http://www.jopdesign.com/> Copyright (C) 2001-2008, Martin Schoeberl (martin@jopdesign.com) 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/>. */ /* * Created on 13.12.2005 * */ package gctest; import util.Timer; import joprt.RtThread; import com.jopdesign.sys.Const; import com.jopdesign.sys.GC; import com.jopdesign.sys.Native; public class PaperEx2 { static Object mutex; // We have to use static data for our experiments because // the current GC prototype does not get the roots from the // other threads stack frames. static class Data { int[] n; // the data Data next; // a simple list for the producer/consumer } // used by the worker static Data da[]; // references used by producer and consumer static Data prod, cons; static class Worker extends RtThread { int cnt; int wcet; int nr; char ch; public Worker(int nr, int prio, int period, int wcet, int cnt) { super(prio, period); this.wcet = wcet; this.cnt = cnt; this.nr = nr; ch = (char) ('0'+nr); } public void run() { for (;;) { System.out.print(ch); da[nr].n = new int[cnt]; busyWait(wcet); da[nr].n = null; if (!waitForNextPeriod()) { System.out.println("Worker missed deadline!"); } } } } static class Producer extends Worker { public Producer(int nr, int prio, int period, int wcet, int cnt) { super(nr, prio, period, wcet, cnt); } public void run() { for (;;) { System.out.print(ch); da[nr].n = new int[cnt]; busyWait(wcet); // synchronize list access between producer // and consumer synchronized (mutex) { // we also avoid with this int. disabeling // that the GC ignores the local reference d. // However, as the GC runs at a lower // priority there is no real problem. Data d = new Data(); d.n = da[nr].n; d.next = prod; prod = d; } da[nr].n = null; if (!waitForNextPeriod()) { System.out.println("Producer missed deadline!"); } } } } static class Consumer extends Worker { public Consumer(int nr, int prio, int period, int wcet, int cnt) { super(nr, prio, period, wcet, cnt); } public void run() { for (;;) { System.out.print(ch); synchronized (mutex) { cons = prod; // take the current data prod = null; // from the producer list } busyWait(wcet); // set the list free cons = null; if (!waitForNextPeriod()) { System.out.println("Consumer missed deadline!"); } } } } /** * @param args */ public static void main(String[] args) { int i; new RtThread(1, 63*1000) { public void run() { GC.setConcurrent(); for (int i=0; i<30; ++i) { System.out.print("G"); // int ts; // synchronized (mutex) { // ts = Timer.us(); GC.gc(); // ts = Timer.us()-ts; // } // System.out.print("GC took "); // System.out.print(ts); // System.out.println(" us"); // System.out.print("g"); if (!waitForNextPeriod()) { System.out.println("GC missed deadline!"); } } synchronized (mutex) { // dump the results // GC.dump(); System.exit(0); } } }; // initialize static data mutex = new Object(); da = new Data[3]; prod = null; cons = null; for (i=0; i<da.length; ++i) { da[i] = new Data(); } // about memory consumption: // allocates an integer array of n*256-1 elements // plus the size field results in exact n*1024 // bytes. // Producer allocates two more words => -3 new Producer(0, 4, 5*1000, 500, 1*1024/4-3); new Worker(1, 3, 10*1000, 3*1000, 3*1024/4-1); new Consumer(2, 2, 30*1000, 2*1000, 0); System.out.println("GC Example 2 (producer/consumer + worker thread)"); RtThread.startMission(); // sleep for (i=0;i<3*2;++i) { System.out.print("M"); Timer.wd(); RtThread.sleepMs(500); } System.exit(0); } }