001: /*
002: * Profiler.java
003: *
004: * Copyright (C) 2003-2004 Peter Graves
005: * $Id: Profiler.java,v 1.6 2004/08/09 18:45:35 piso Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.lisp;
023:
024: public class Profiler extends Lisp {
025: private static int sleep = 1;
026:
027: public static final void sample(LispThread thread)
028: throws ConditionThrowable {
029: sampleNow = false;
030: thread.incrementCallCounts();
031: }
032:
033: private static final Runnable profilerRunnable = new Runnable() {
034: public void run() {
035: while (profiling) {
036: sampleNow = true;
037: try {
038: Thread.sleep(sleep);
039: } catch (InterruptedException e) {
040: Debug.trace(e);
041: }
042: }
043: }
044: };
045:
046: // ### %start-profiler
047: // %start-profiler type granularity
048: public static final Primitive2 _START_PROFILER = new Primitive2(
049: "%start-profiler", PACKAGE_PROF, false) {
050: public LispObject execute(LispObject first, LispObject second)
051: throws ConditionThrowable {
052: final LispThread thread = LispThread.currentThread();
053: Stream out = getStandardOutput();
054: out.freshLine();
055: if (profiling) {
056: out._writeLine("; Profiler already started.");
057: } else {
058: if (first == Keyword.TIME)
059: sampling = true;
060: else if (first == Keyword.COUNT_ONLY)
061: sampling = false;
062: else
063: return signal(new LispError(
064: "%START-PROFILER: argument must be either :TIME or :COUNT-ONLY"));
065: Package[] packages = Packages.getAllPackages();
066: for (int i = 0; i < packages.length; i++) {
067: Package pkg = packages[i];
068: Symbol[] symbols = pkg.symbols();
069: for (int j = 0; j < symbols.length; j++) {
070: Symbol symbol = symbols[j];
071: LispObject f = symbol.getSymbolFunction();
072: if (f != null)
073: f.setCallCount(0);
074: }
075: }
076: if (sampling) {
077: sleep = Fixnum.getValue(second);
078: thread.resetStack();
079: Thread t = new Thread(profilerRunnable);
080: int priority = Math.min(Thread.currentThread()
081: .getPriority() + 1, Thread.MAX_PRIORITY);
082: t.setPriority(priority);
083: new Thread(profilerRunnable).start();
084: }
085: out._writeLine("; Profiler started.");
086: profiling = true;
087: }
088: return thread.nothing();
089: }
090: };
091:
092: // ### stop-profiler
093: public static final Primitive0 STOP_PROFILER = new Primitive0(
094: "stop-profiler", PACKAGE_PROF, true) {
095: public LispObject execute() throws ConditionThrowable {
096: Stream out = getStandardOutput();
097: out.freshLine();
098: if (profiling) {
099: profiling = false;
100: out._writeLine("; Profiler stopped.");
101: } else
102: out._writeLine("; Profiler was not started.");
103: out._finishOutput();
104: return LispThread.currentThread().nothing();
105: }
106: };
107: }
|