123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432 |
-
- package coordination;
-
- import java.util.*; //!!!
-
- /**
- * The Coordinator class provides the basic functionality for synchronizing
- * and coordinating different threads upon entering and exiting methods.
- * It can be used in two different ways:
- * 1) by instantiating regular coordinator objects that are used by aspects; or
- * 2) by extending it (sub-classing) with coordinator aspects.
- * <P>
- * Method invocations are the smallest units for defining critical sections
- * and pre-conditions. The use of coordinators, either regular objects or aspect
- * instances, should always end up by invoking guardedEntry(...) in a
- * before weave and guardedExit(...) in an after weave for all methods that
- * need coordination. guardedEntry and guardedExit are the methods that
- * actually manage the synchronization and coordination constraints given
- * by their parameters and by pre-existent exclusion markers.
- * <P>
- * The synchronization of threads for the execution of critical section
- * methods in an object is done by marking those methods as self- and/or
- * mutually-exclusive (addSelfex, addMutex).
- * Just by itself, addSelfex("M") does not enforce the self-exclusion
- * of method M - enforcement is done by invoking guardedEntry before
- * M is executed. Similarly, addMutex(new String[] {"M1", "M2"}) does
- * not enforce the mutual exclusion between methods M1 and M2.
- * <P>
- * A guardedEntry on a method that has been marked as self-exclusive
- * ensures that the method is executed in the invoked object by only one thread
- * at a time. A guardedEntry on a method that has been marked has mutually-
- * exclusive with other methods ensures that the execution of that method
- * by a thread in the invoked object temporarily blocks the execution by
- * other threads of the methods that are in the same mutex set.
- * <P>
- * The coordination of threads, i.e. their explicit suspension and
- * resumption, is done through the use of pre-conditions and coordination
- * actions that are passed as parameters to guardedEntry and guardedExit
- * with the form of anonymous classes.
- */
- public abstract aspect Coordinator {
- private Hashtable methods = null;
- private Vector exclusions = null;
-
- abstract protected pointcut synchronizationPoint();
-
- public Coordinator() {
- methods = new Hashtable();
- exclusions = new Vector(5);
- }
-
- before (): synchronizationPoint() {
- this.guardedEntry(thisJoinPointStaticPart.getSignature().getName());
- }
-
- after (): synchronizationPoint() {
- this.guardedExit(thisJoinPointStaticPart.getSignature().getName());
- }
-
- /**
- * Takes a multi-part method name (eg "BoundedBuffer.put")
- * and marks that method as self-exclusive.
- * No checks are made with respect to the existence of the method
- * whose name is given.
- */
- public synchronized void addSelfex(String methName) {
- Selfex sex = new Selfex (methName);
-
- // update db of all exclusions in this coordinator
- exclusions.addElement(sex);
-
- // update local info in method
- Method aMeth = getOrSetMethod(methName);
- aMeth.addExclusion(sex);
- }
-
- /**
- * Takes a multi-part method name (e.g. "BoundedBuffer.put")
- * and removes that method from the list of self-exclusive methods.
- */
- public synchronized void removeSelfex(String methName) {
- for (int i = 0; i < exclusions.size(); i++) {
- Exclusion sex = (Exclusion)exclusions.elementAt(i);
- if ((sex instanceof Selfex) &&
- (((Selfex)sex).methodName.equals(methName))) {
-
- // update db of all exclusions in this coordinator
- exclusions.removeElementAt(i);
-
- // update local info in method
- Method aMeth = getOrSetMethod(methName);
- aMeth.removeExclusion(sex);
- }
- }
- }
-
- /**
- * Takes an array of multi-part method names and marks those
- * methods as mutually exclusive.
- * No checks are made with respect to the existence of the methods
- * whose names are given.
- */
- public synchronized void addMutex(String[] methNames) {
- Mutex mux = new Mutex(methNames);
-
- // update db of all exclusions in this coordinator
- exclusions.addElement(mux);
-
- // update local info in each method
- for (int i = 0; i < methNames.length; i++) {
- Method aMeth = getOrSetMethod(methNames[i]);
- aMeth.addExclusion(mux);
- }
- }
-
- /**
- * Takes an array of multi-part method names that correspond
- * to an existing mutex set and remove the mutual exclusion constraint.
- * If the given mutex set does not exist, removeMutex does nothing.
- */
- public synchronized void removeMutex(String[] methNames) {
- for (int i = 0; i < exclusions.size(); i++) {
- Exclusion mux = (Exclusion)exclusions.elementAt(i);
- if (mux instanceof Mutex) {
- boolean same = true;
- for (int j = 0; j < methNames.length; j++)
- if (!methNames[j].equals(((Mutex)mux).methodNames[j]))
- same = false;
- if (same) {
- // update db of all exclusions in this coordinator
- exclusions.removeElementAt(i);
-
- // update local info in each method involved
- for (int j = 0; j < methNames.length; j++) {
- Method aMeth = getOrSetMethod(methNames[j]);
- aMeth.removeExclusion(mux);
- }
- }
- }
- }
- }
-
- /**
- * This method is the guard for enforcing all synchronization and
- * coordination constraints of a given method, and it should be called
- * just before the method is executed.
- * In this form, only the method name is given. The only constraints
- * checked are the exclusion constraints.
- * If the method was previousely marked as selfex (through addSelfex),
- * guardedEntry ensures that the method is executed only when no other
- * thread is executing it.
- * If the method was previousely marked as being in one or more mutex
- * sets, guardedEntry ensures that the method is executed only when no other
- * thread is executing any of the methods with which the give method is
- * mutexed.
- */
- public synchronized void guardedEntry(String methName) {
- guardedEntry(methName, new Condition() {
- public boolean checkit() {
- return true;
- }
- }, null);
- }
-
- /**
- * Just like guardedEntry(String methName), but the given method is executed
- * only when the given condition is true.
- * guardedEntry is the guard for enforcing all synchronization and
- * coordination constraints of a given method, and it should be called
- * just before the method is executed.
- * In this form, the method name is given along with a condition.
- * The constraints checked are the exclusion constraints and whether
- * the given condition is true.
- * If the method was previousely marked as selfex (through addSelfex),
- * guardedEntry ensures that the method is executed only when no other
- * thread is executing it.
- * If the method was previousely marked as being in one or more mutex
- * sets, guardedEntry ensures that the method is executed only when no other
- * thread is executing any of the methods with which the give method is
- * mutexed.
- * If the condition is false, guardedEntry suspends the current thread.
- * That thread remains suspended until the condition becomes true, in
- * which case all constraints are rechecked before the method is executed.
- * When all exclusion constraints are checked and the given condition is
- * true, the given method is executed.
- */
- public synchronized void guardedEntry(String methName, Condition condition) {
- guardedEntry(methName, condition, null);
- }
-
- /**
- * Just like guardedEntry(String methName), but with an additional
- * coordination action that is executed before the given method is
- * executed.
- * guardedEntry is the guard for enforcing all synchronization and
- * coordination constraints of a given method, and it should be called
- * just before the method is executed.
- * In this form, the method name is given along with a coordination action.
- * The only constraints checked are the exclusion constraints.
- * If the method was previousely marked as selfex (through addSelfex),
- * guardedEntry ensures that the method is executed only when no other
- * thread is executing it.
- * If the method was previousely marked as being in one or more mutex
- * sets, guardedEntry ensures that the method is executed only when no other
- * thread is executing any of the methods with which the give method is
- * mutexed.
- * The given coordination action is executed just before the given method
- * is executed.
- */
- public synchronized void guardedEntry(String methName,
- CoordinationAction action) {
- guardedEntry(methName, new Condition() {
- public boolean checkit() {
- return true;
- }
- },
- action);
- }
-
- /**
- * Just like guardedEntry(String methName), but the given method is executed
- * only when the given condition is true; the additional
- * coordination action that is executed before the given method is
- * executed.
- * guardedEntry is the guard for enforcing all synchronization and
- * coordination constraints of a given method, and it should be called
- * just before the method is executed.
- * In this form, the method name is given along with a condition and
- * a coordination action.
- * The constraints checked are the exclusion constraints and whether the
- * given condition is true.
- * If the method was previousely marked as selfex (through addSelfex),
- * guardedEntry ensures that the method is executed only when no other
- * thread is executing it.
- * If the method was previousely marked as being in one or more mutex
- * sets, guardedEntry ensures that the method is executed only when no other
- * thread is executing any of the methods with which the give method is
- * mutexed.
- * If the condition is false, guardedEntry suspends the current thread.
- * That thread remains suspended until the condition becomes true, in
- * which case all constraints are rechecked before the method is executed.
- * When all exclusion constraints are checked and the given condition is
- * true, the given method is executed.
- * The given coordination action is executed just before the given method
- * is executed.
- */
- public synchronized void guardedEntry(String methName,
- Condition condition,
- CoordinationAction action) {
- Method aMeth = getOrSetMethod(methName);
- boolean canGo = false;
-
- // test pre-conditions for entering the method
- while (!canGo) {
- canGo = true;
- for (int i = 0; i < aMeth.exes.size() && canGo; i++)
- if (!((Exclusion)aMeth.exes.elementAt(i)).testExclusion(aMeth.name)) {
- canGo = false;
- }
- if (canGo && !condition.checkit()) {
- canGo = false;
- }
- if (!canGo)
- try {
- wait();
- } catch (InterruptedException e) { }
- }
-
- // OK.
- enterMethod(aMeth, action);
- }
-
- /**
- * This method is similar to guardedEntry, but it takes
- * an additional parameter - the milliseconds after which any suspension
- * will abort with a timeout.
- */
- public synchronized void guardedEntryWithTimeout(String methName,
- long millis)
- throws TimeoutException {
- guardedEntryWithTimeout(methName, new Condition() {
- public boolean checkit() {
- return true;
- }
- }, null, millis);
- }
-
- /**
- * This method is similar to guardedEntry, but it takes
- * an additional parameter - the milliseconds after which any suspension
- * will abort with a timeout.
- */
- public synchronized void guardedEntryWithTimeout(String methName,
- Condition condition,
- long millis)
- throws TimeoutException {
- guardedEntryWithTimeout(methName, condition, null, millis);
- }
-
- /**
- * This method is similar to guardedEntry, but it takes
- * an additional parameter - the milliseconds after which any suspension
- * will abort with a timeout.
- */
- public synchronized void guardedEntryWithTimeout(String methName,
- CoordinationAction action,
- long millis)
- throws TimeoutException {
- guardedEntryWithTimeout(methName, new Condition() {
- public boolean checkit() {
- return true;
- }
- }, action, millis);
- }
-
- /**
- * This method is similar to guardedEntry, but it takes
- * an additional parameter - the milliseconds after which any suspension
- * will abort with a timeout.
- */
- public synchronized void guardedEntryWithTimeout(String methName,
- Condition condition,
- CoordinationAction action,
- long millis)
- throws TimeoutException {
-
- Method aMeth = getOrSetMethod(methName);
- boolean canGo = false;
- long waitTime = millis;
- long startTime = System.currentTimeMillis();
-
- // test pre-conditions for entering the method
- while (!canGo) {
- canGo = true;
- for (int i = 0; i < aMeth.exes.size() && canGo; i++)
- if ((!((Exclusion)aMeth.exes.elementAt(i)).testExclusion(aMeth.name)) ||
- (!condition.checkit())) {
- canGo = false;
- }
- if (!canGo) {
- try {
- wait(waitTime);
- } catch (InterruptedException e) {}
-
- long now = System.currentTimeMillis();
- long timeSoFar = now - startTime;
- if (timeSoFar >= millis) // timeout!
- throw new TimeoutException(timeSoFar);
- else // adjust time
- waitTime = millis - timeSoFar;
- }
- }
-
- // OK.
- enterMethod(aMeth, action);
- }
-
- /**
- * This method provides the means for updating all synchronization and
- * coordination state after the execution of a given method, and it should be
- * called after the method is executed.
- * In this form, only the method name is given.
- * The synchronization state for self- and mutual-exclusion is
- * automatically upadted.
- */
- public synchronized void guardedExit(String methName) {
- guardedExit(methName, null);
- }
-
- /**
- * Just like guardedExit(String methName) but with an additional
- * coordination action that is executed.
- * guardedExit provides the means for updating all synchronization and
- * coordination state after the execution of a given method, and it should be
- * called after the method is executed.
- * In this form, the method name is given along with a coordination action.
- * The synchronization state for self- and mutual-exclusion is
- * automatically upadted.
- * The given coordination action is executed.
- */
- public synchronized void guardedExit(String methName,
- CoordinationAction action) {
- Method aMeth = getOrSetMethod(methName);
-
- for (int i = 0; i < aMeth.exes.size(); i++)
- ((Exclusion)aMeth.exes.elementAt(i)).exitExclusion(methName);
- if (action != null) action.doit();
- notifyAll();
- }
-
- private Method getOrSetMethod(String methName) {
- Method aMeth = null;
- if (!methods.containsKey(methName)) {
- methods.put(methName, (aMeth = new Method(methName)));
- }
- else {
- aMeth = (Method) methods.get(methName);
- }
- return aMeth;
- }
-
- private void enterMethod(Method aMeth, CoordinationAction action) {
- for (int i = 0; i < aMeth.exes.size(); i++)
- ((Exclusion)aMeth.exes.elementAt(i)).enterExclusion(aMeth.name);
-
- if (action != null) action.doit();
- }
-
-
-
- }
-
- class Method {
- String name;
- Vector exes = new Vector(3);
-
- Method(String n) {
- name = n;
- }
-
- void addExclusion(Exclusion ex) {
- exes.addElement(ex);
- }
-
- void removeExclusion(Exclusion ex) {
- for (int i = 0; i < exes.size(); i++) {
- if (exes.elementAt(i) == ex)
- exes.removeElementAt(i);
- }
- }
- }
|