summaryrefslogtreecommitdiff
path: root/sources/core/VSAbstractProcess.java
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2008-08-04 20:44:54 +0000
committerPaul Buetow <paul@buetow.org>2008-08-04 20:44:54 +0000
commit8ae434c63e6382a8cb850551d947285f5fcb3c25 (patch)
tree751b0b24cd86768d57e9338cf0718485f68a095e /sources/core/VSAbstractProcess.java
parentbb4eb6634485d05e9e8cff6497c60ef696a28eeb (diff)
restructured stuff
Diffstat (limited to 'sources/core/VSAbstractProcess.java')
-rw-r--r--sources/core/VSAbstractProcess.java739
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);
+}