diff options
| author | Paul Buetow <paul@buetow.org> | 2008-08-04 20:44:54 +0000 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2008-08-04 20:44:54 +0000 |
| commit | 8ae434c63e6382a8cb850551d947285f5fcb3c25 (patch) | |
| tree | 751b0b24cd86768d57e9338cf0718485f68a095e /sources/core/VSAbstractProcess.java | |
| parent | bb4eb6634485d05e9e8cff6497c60ef696a28eeb (diff) | |
restructured stuff
Diffstat (limited to 'sources/core/VSAbstractProcess.java')
| -rw-r--r-- | sources/core/VSAbstractProcess.java | 739 |
1 files changed, 739 insertions, 0 deletions
diff --git a/sources/core/VSAbstractProcess.java b/sources/core/VSAbstractProcess.java new file mode 100644 index 0000000..c526f3f --- /dev/null +++ b/sources/core/VSAbstractProcess.java @@ -0,0 +1,739 @@ +/* + * Copyright (c) 2008 Paul C. Buetow, vs@dev.buetow.org + * + * 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 2 + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * All icons of the icons/ folder are under a Creative Commons + * Attribution-Noncommercial-Share Alike License a CC-by-nc-sa. + * + * The icon's homepage is http://code.google.com/p/ultimate-gnome/ + */ + +package core; + +import java.awt.*; +import java.io.*; +import java.util.*; + +import core.time.*; +import events.*; +import events.implementations.*; +import prefs.*; +import protocols.*; +import serialize.*; +import simulator.*; +import utils.*; + +/** + * The class VSAbstractProcess, an object of this class represents a process + * of a simulator. + * + * @author Paul C. Buetow + */ +public abstract class VSAbstractProcess extends VSPrefs + implements VSSerializable { + /** The data serialization id. */ + protected static final long serialVersionUID = 1L; + + /** The protocols to reset if the simulator is over or the reset + * button has been pressed. + */ + protected ArrayList<VSAbstractProtocol> protocolsToReset; + + /** The crash history. represents all crashes of the process using the + * global simulator time. + */ + protected ArrayList<Long> crashHistory; + + /** The lamport time history. */ + protected ArrayList<VSLamportTime> lamportTimeHistory; + + /** The vector time history. */ + protected ArrayList<VSVectorTime> vectorTimeHistory; + + /** The color used if the process has crashed. */ + protected Color crashedColor;; + + /** The process' current color. */ + protected Color currentColor; + + /** A temp. color. For internal usage. */ + protected Color tmpColor; + + /** The logging object. */ + protected VSLogging logging; + + /** The simulator's default prefs. */ + protected VSPrefs prefs; + + /** The random generator of the process. */ + protected VSRandom random; + + /** The simulator canvas. */ + protected VSSimulatorCanvas simulatorCanvas; + + /** The random crash task. May be null if there is no such random task. */ + protected VSTask randomCrashTask; + + /** The vector time. */ + protected VSVectorTime vectorTime; + + /** The tasks of the process. DO ONLY MANIPULATE THIS OBJECT WITHIN THE + * VSTaskManager CLASS! OTHERWISE THE SYNCHRONIZATION IS WRONG! Use the + * VSAbstractProcess.getTasks() method to get a reference to this object within the + * VSTaskManager! */ + protected VSPriorityQueue<VSTask> tasks; + + /** The process has crashed. But may be working again. */ + protected boolean hasCrashed; + + /** The process has started. But may be paused or crashed.. */ + protected boolean hasStarted; + + /** The process is crashed. */ + protected boolean isCrashed; + + /** The process is highlighted. */ + protected boolean isHighlighted; + + /** The process is paused. */ + protected boolean isPaused; + + /** The time has been modified in a task. Needed by the task manager to + * calculate correct offsets. + */ + protected boolean timeModified; + + /** The clock offset. Used by the task manager and also by the process' + * clock variance. + */ + protected double clockOffset; + + /** The clock variance. */ + protected float clockVariance; + + /** The process id. */ + protected int processID; + + /** The process num. It is different to the process id. It represents the + * array index of there the process is stored at. + */ + protected int processNum; + + /** The global time. */ + protected long globalTime; + + /** The lamport time. */ + protected long lamportTime; + + /** The local time. */ + protected long localTime; + + /** The Constant DEFAULT_INTEGER_VALUE_KEYS. + * This array contains all Integer prefs of the process which should show + * up in the prefs menu! All keys which dont start with "sim." only show + * up in the extended prefs menu! + */ + protected static final String DEFAULT_INTEGER_VALUE_KEYS[] = { + "process.prob.crash", + "message.prob.outage", + }; + + /** The Constant DEFAULT_LONG_VALUE_KEYS. + * This array contains all Long prefs of the process which should show + * up in the prefs menu! All keys which dont start with "sim." only show + * up in the extended prefs menu! + */ + protected static final String DEFAULT_LONG_VALUE_KEYS[] = { + "message.sendingtime.min", + "message.sendingtime.max", + }; + + /** The Constant DEFAULT_FLOAT_VALUE_KEYS. + * This array contains all Float prefs of the process which should show + * up in the prefs menu! All keys which dont start with "sim." only show + * up in the extended prefs menu! + */ + protected static final String DEFAULT_FLOAT_VALUE_KEYS[] = { + "process.clock.variance", + }; + + /** The Constant DEFAULT_COLOR_VALUE_KEYS. + * This array contains all Color prefs of the process which should show + * up in the prefs menu! All keys which dont start with "sim." only show + * up in the extended prefs menu! + */ + protected static final String DEFAULT_COLOR_VALUE_KEYS[] = { + "col.process.default", + "col.process.running", + "col.process.stopped", + "col.process.highlight", + "col.process.crashed", + }; + + /** The Constant DEFAULT_STRING_VALUE_KEYS. + * This array contains all String prefs of the process which should show + * up in the prefs menu! All keys which dont start with "sim." only show + * up in the extended prefs menu! + */ + protected static final String DEFAULT_STRING_VALUE_KEYS[] = { + }; + + /** + * Instantiates a new process. + * + * @param prefs the simulator's default prefs + * @param processNum the process num + * @param simulatorCanvas the simulator canvas + * @param logging the logging object + */ + public VSAbstractProcess(VSPrefs prefs, int processNum, + VSSimulatorCanvas simulatorCanvas, VSLogging logging) { + init(prefs, processNum, simulatorCanvas, logging); + } + + /** + * Inits a the process. + * + * @param prefs the simulator's default prefs + * @param processNum the process num + * @param simulatorCanvas the simulator canvas + * @param logging the logging object + */ + protected void init(VSPrefs prefs, int processNum, + VSSimulatorCanvas simulatorCanvas, VSLogging logging) { + /* May be not null if called from deserialization */ + if (this.protocolsToReset == null) + this.protocolsToReset = new ArrayList<VSAbstractProtocol>(); + + this.processNum = processNum; + this.prefs = prefs; + this.simulatorCanvas = simulatorCanvas; + this.logging = logging; + + processID = simulatorCanvas.processIDCount(); + random = new VSRandom(processID*processNum+processID+processNum); + tasks = new VSPriorityQueue<VSTask>(); + + initTimeFormats(); + + isPaused = true; + + /* Create the super.VSPrefs with it's default prefs */ + fillWithDefaults(); + + /* Make local copys in order to have more performance */ + clockVariance = getFloat("process.clock.variance"); + currentColor = getColor("col.process.default"); + crashedColor = getColor("col.process.crashed"); + + /* Make additional process settings editable through GUI */ + initLong("process.localtime", localTime, + prefs.getString("lang.process.time.local"), "ms"); + + createRandomCrashTask_(); + } + + /** + * Inits the time formats. E.g. lamport and vector time stamps. + */ + protected void initTimeFormats() { + lamportTime = 0; + lamportTimeHistory = new ArrayList<VSLamportTime>(); + + vectorTime = new VSVectorTime(0); + vectorTimeHistory = new ArrayList<VSVectorTime>(); + crashHistory = new ArrayList<Long>(); + + final int numProcesses = simulatorCanvas.getNumProcesses(); + for (int i = 0; i < numProcesses; ++i) + vectorTime.add(new Long(0)); + } + + /** + * Reset time formats. E.g. lamport and vector time stamps. + */ + protected void resetTimeFormats() { + lamportTime = 0; + lamportTimeHistory.clear(); + + vectorTime = new VSVectorTime(0); + vectorTimeHistory.clear(); + crashHistory.clear(); + + final int numProcesses = simulatorCanvas.getNumProcesses(); + for (int i = numProcesses; i > 0; --i) + vectorTime.add(new Long(0)); + } + + /** + * Creates a random percentage 0..100 using the process' own pseudo + * random number generator object of the VSRandom class. + * + * @return A random percentage 0..100. + */ + public synchronized int getRandomPercentage() { + return random.nextInt() % 101; + } + + /** + * Adds the clock offset. This method is used by the task manager. The + * clock offset identifies if the local time of the process has changed and + * how much.. + * + * @param add the clock offset to add. + */ + protected synchronized void addClockOffset(long add) { + this.clockOffset += add; + } + + /** + * Gets the process id. + * + * @return the process id + */ + public synchronized int getProcessID() { + return processID; + } + + /** + * Gets the process num. The num is different to the process id. It + * represents the array index of there the process is stored at. + * + * @return the process num + */ + public synchronized int getProcessNum() { + return processNum; + } + + /** + * Sets the process id. + * + * @param processID the new process id + */ + public synchronized void setProcessID(int processID) { + this.processID = processID; + } + + /** + * Gets the process' local time. + * + * @return the process' local time + */ + public synchronized long getTime() { + return localTime; + } + + /** + * Sets the process' local time. + * + * @param time the new local time of the process. + */ + public synchronized void setTime(final long time) { + if (time >= 0) + this.localTime = time; + else + this.localTime = 0; + + this.timeModified = true; + } + + /** + * Checks if the process is crashed. + * + * @return true, if is crashed + */ + public synchronized boolean isCrashed() { + return isCrashed; + } + + /** + * Sets if the process is crashed. + * + * @param isCrashed true if the process is crashed. + */ + public synchronized void isCrashed(boolean isCrashed) { + this.isCrashed = isCrashed; + crashHistory.add(new Long(globalTime)); + if (!hasCrashed) + hasCrashed = true; + } + + /** + * Checks if the process has crashed. The difference to isCrashed is, + * that the process may be fully functional again after crashing. This + * method is needed by the simulator canvas in order to see if it should + * paint 'crashed areas' using the crash history of this process. + * + * @return true, if yes + */ + public synchronized boolean hasCrashed() { + return hasCrashed; + } + + /** + * Gets the global time. + * + * @return the global time + */ + public synchronized long getGlobalTime() { + return globalTime; + } + + /** + * Gets the clock variance. + * + * @return the clock variance + */ + public synchronized float getClockVariance() { + return clockVariance; + } + + /** + * Sets the clock variance. + * + * @param clockVariance the new clock variance + */ + public synchronized void setClockVariance(float clockVariance) { + /* If negative, only allow < 1 prefs */ + if (clockVariance < 0) { + int part = (int) -clockVariance; + if (part > 0) { + this.clockVariance = 0; + return; + } + } + + this.clockVariance = clockVariance; + } + + /** + * Gets the a random crash time. + * + * @return the a random crash time. It will be -1 if the process will not + * crash at all randomly! + */ + protected long getARandomCrashTime() { + /* Check if the process will crash or not */ + if (getRandomPercentage() < getInteger("process.prob.crash")) { + /* Calculate the random crash time! */ + final long crashTime = random.nextLong( + simulatorCanvas.getUntilTime()+1) % + simulatorCanvas.getUntilTime(); + return crashTime; + } + + /* No crash */ + return -1; + } + + /** + * Increases the process' lamport time. + */ + public synchronized void increaseLamportTime() { + setLamportTime(getLamportTime()+1); + } + + /** + * Updates the process' lamport time. + * + * @param time the lamport time to use as its update reference. + */ + public synchronized void updateLamportTime(long time) { + final long lamportTime = getLamportTime() + 1; + + if (time > lamportTime) + setLamportTime(time); + else + setLamportTime(lamportTime); + } + + /** + * Gets the lamport time. + * + * @return the lamport time. + */ + public synchronized long getLamportTime() { + return lamportTime; + } + + /** + * Sets the lamport time. + * + * @param lamportTime the new lamport time + */ + public synchronized void setLamportTime(long lamportTime) { + this.lamportTime = lamportTime; + lamportTimeHistory.add(new VSLamportTime(globalTime, lamportTime)); + } + + /** + * Gets the lamport time history as an array. + * + * @return the lamport time history array + */ + public synchronized VSTime[] getLamportTimeArray() { + final int size = lamportTimeHistory.size(); + final VSTime[] arr = new VSLamportTime[size]; + + for (int i = 0; i < size; ++i) + arr[i] = (VSTime) lamportTimeHistory.get(i); + + return arr; + } + + /** + * Increases the vector and the lamport time by 1 each if + * sim.update.vectortime.all/sim.update.lamporttime.all are set + * to true. + */ + public void increaseVectorAndLamportTimeIfAll() { + if (prefs.getBoolean("sim.update.lamporttime.all")) + increaseLamportTime(); + + if (prefs.getBoolean("sim.update.vectortime.all")) + increaseVectorTime(); + } + + /** + * Increases the vector time by 1. + */ + public synchronized void increaseVectorTime() { + vectorTime.set(processNum, + new Long(vectorTime.get(processNum).longValue()+1)); + vectorTime.setGlobalTime(globalTime); + vectorTimeHistory.add(vectorTime.getCopy()); + } + + /** + * Updates the vector time. + * + * @param vectorTimeUpdate the vector time of the other process to use for + * the update + */ + public synchronized void updateVectorTime(VSVectorTime vectorTimeUpdate) { + final int size = vectorTime.size(); + + for (int i = 0; i < size; ++i) { + if (i == processNum) + vectorTime.set(i, new Long(vectorTime.get(i).longValue()+1)); + else if (vectorTimeUpdate.get(i) > vectorTime.get(i)) + vectorTime.set(i, vectorTimeUpdate.get(i)); + } + + vectorTime.setGlobalTime(globalTime); + vectorTimeHistory.add(vectorTime.getCopy()); + } + + /** + * Gets the vector time. + * + * @return the vector time + */ + public synchronized VSVectorTime getVectorTime() { + return vectorTime; + } + + /** + * Gets the vector time history as an array. + * + * @return the vector time history array + */ + public synchronized VSTime[] getVectorTimeArray() { + final int size = vectorTimeHistory.size(); + final VSTime[] arr = new VSTime[size]; + + for (int i = 0; i < size; ++i) + arr[i] = (VSTime) vectorTimeHistory.get(i); + + return arr; + } + + /** + * Gets the crash history array. + * + * @return the crash history array + */ + public synchronized Long[] getCrashHistoryArray() { + final int size = crashHistory.size(); + final Long[] arr = new Long[size]; + + for (int i = 0; i < size; ++i) + arr[i] = crashHistory.get(i); + + return arr; + } + + /** + * Logg a message to the logging area. + * + * @param message the message to logg + */ + public void logg(String message) { + logging.logg(toString() + "; " + message, globalTime); + } + + /* (non-Javadoc) + * @see prefs.VSPrefs#fillWithDefaults() + */ + public void fillWithDefaults() { + prefs.copyIntegers(this, DEFAULT_INTEGER_VALUE_KEYS); + prefs.copyLongs(this, DEFAULT_LONG_VALUE_KEYS); + prefs.copyFloats(this, DEFAULT_FLOAT_VALUE_KEYS); + prefs.copyColors(this, DEFAULT_COLOR_VALUE_KEYS); + prefs.copyStrings(this, DEFAULT_STRING_VALUE_KEYS); + } + + /* (non-Javadoc) + * @see prefs.VSPrefs#toString() + */ + public synchronized String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append(prefs.getString("lang.process.id")); + buffer.append(": "); + buffer.append(getProcessID()); + buffer.append("; "); + buffer.append(prefs.getString("lang.process.time.local")); + buffer.append(": "); + buffer.append(VSTools.getTimeString(getTime())); + buffer.append("; "); + buffer.append(prefs.getString("lang.time.lamport")); + buffer.append(": "); + buffer.append(lamportTime); + buffer.append("; "); + buffer.append(prefs.getString("lang.time.vector")); + buffer.append(": "); + buffer.append(vectorTime); + return buffer.toString(); + } + + /** + * The extended string representation of the process object. + * + * @return the extended string representation + */ + public synchronized String toStringFull() { + StringBuffer buffer = new StringBuffer(); + buffer.append(toString()); + buffer.append("; paused: "); + buffer.append(isPaused); + buffer.append("; crashed: "); + buffer.append(isCrashed); + buffer.append("; crashTask: "); + buffer.append(randomCrashTask); + return buffer.toString(); + } + + /** + * Equals. Checks, if both processes have the same process num. + * + * @param process the process to compare to + * + * @return true, if both processes are the same (same processNum). + */ + public boolean equals(VSAbstractProcess process) { + return process.getProcessNum() == processNum; + } + + /** + * Gets the simulator's default prefs. + * + * @return the default prefs + */ + public VSPrefs getPrefs() { + return prefs; + } + + /* (non-Javadoc) + * @see serialize.VSSerializable#serialize(serialize.VSSerialize, + * java.io.ObjectOutputStream) + */ + public synchronized void serialize(VSSerialize serialize, + ObjectOutputStream objectOutputStream) + throws IOException { + super.serialize(serialize, objectOutputStream); + + if (VSSerialize.DEBUG) + System.out.println("Serializing: VSAbstractProcess (num: " + processNum + + "; id: " + processID + ")"); + + /** For later backwards compatibility, to add more stuff */ + objectOutputStream.writeObject(new Boolean(false)); + + objectOutputStream.writeObject(new Integer(processID)); + objectOutputStream.writeObject(new Integer(protocolsToReset.size())); + for (VSAbstractProtocol protocol : protocolsToReset) { + objectOutputStream.writeObject(protocol.getClassname()); + protocol.serialize(serialize, objectOutputStream); + } + + /** For later backwards compatibility, to add more stuff */ + objectOutputStream.writeObject(new Boolean(false)); + } + + /* (non-Javadoc) + * @see serialize.VSSerializable#deserialize(serialize.VSSerialize, + * java.io.ObjectInputStream) + */ + @SuppressWarnings("unchecked") + public synchronized void deserialize(VSSerialize serialize, + ObjectInputStream objectInputStream) + throws IOException, ClassNotFoundException { + super.deserialize(serialize, objectInputStream); + updateFromPrefs_(); + + if (VSSerialize.DEBUG) + System.out.println("Deserializing: VSAbstractProcess"); + + /** For later backwards compatibility, to add more stuff */ + objectInputStream.readObject(); + + this.processID = ((Integer) + objectInputStream.readObject()).intValue(); + int numProtocols = ((Integer) + objectInputStream.readObject()).intValue(); + + for (int i = 0; i < numProtocols; ++i) { + String protocolClassname = (String) objectInputStream.readObject(); + VSAbstractProtocol protocol = getProtocolObject_(protocolClassname); + protocol.deserialize(serialize, objectInputStream); + } + + localTime = 0; + setLong("process.localTime", localTime); + + /** For later backwards compatibility, to add more stuff */ + objectInputStream.readObject(); + + serialize.setObject(processNum, "process", this); + } + + /** + * Sets the current color. + * + * @param newColor the new current color + */ + protected void setCurrentColor(Color newColor) { + if (isHighlighted) + tmpColor = newColor; + else + currentColor = newColor; + } + + protected abstract void updateFromPrefs_(); + protected abstract void createRandomCrashTask_(); + protected abstract VSAbstractProtocol getProtocolObject_( + String protocolClassname); +} |
