diff --git a/linda/shm/CentralizedLinda.java b/linda/shm/CentralizedLinda.java index 78039a7..5f5623b 100644 --- a/linda/shm/CentralizedLinda.java +++ b/linda/shm/CentralizedLinda.java @@ -6,113 +6,81 @@ import linda.Tuple; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; +class Reveil implements Callback { + + static Lock lock = new ReentrantLock(); + + Tuple template; + Condition condition; + + Reveil(Tuple template) { + this.template = template; + this.condition = lock.newCondition(); + } + + public void call(Tuple t) { + return; + } + + void sleep() { + try { + condition.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + void reveil(Tuple t) { + if (t.matches(this.template)) { + condition.signal(); + } + } +} + /** Shared memory implementation of Linda. */ public class CentralizedLinda implements Linda { List tuples; - - Lock moniteur; - Condition accessDemand; - Condition SAS; - - int nbReaders; - int nbWaiting; - boolean writing; - boolean SASused; + List reveils; public CentralizedLinda() { - nbReaders = 0; - nbWaiting = 0; - writing = false; - SASused = false; - moniteur = new ReentrantLock(); - accessDemand = moniteur.newCondition(); - SAS = moniteur.newCondition(); - tuples = new ArrayList(); + this.tuples = Collections.synchronizedList(new ArrayList()); + this.reveils = Collections.synchronizedList(new ArrayList()); } public void write(Tuple t) { - try { - // Wait for writing access - requestWriting(); - - // Add the new tuple - tuples.add(t); - - // End writing - endWriting(); - } catch (InterruptedException e) { - e.printStackTrace(); - } + tuples.add(t); + reveils.forEach(r -> r.reveil(t)); } public Tuple take(Tuple template) { Tuple result = null; - boolean found = false; - int index; + Reveil reveil = new Reveil(template); - try { - - while (!found) { - // Wait for writing access - requestWriting(); - - // Find the tuple in the tuple list - for (index = 0; index < tuples.size(); index++) { - if (tuples.get(index).matches(template)) { - found = true; - break; - } - } - - if (found) { - // Result found, remove it from the tuple list - result = tuples.remove(index); - } - - // End writing - endWriting(); - } - } catch (InterruptedException e) { - e.printStackTrace(); + result = tryTake(template); + while (result == null) { + reveil.sleep(); + result = tryTake(template); } + return result; } public Tuple read(Tuple template) { Tuple result = null; - boolean found = false; - int index; + Reveil reveil = new Reveil(template); - try { - while (!found) { - // Waiting for reading access - requestReading(); - - // Find the tuple in the tuple list - for (index = 0; index < tuples.size(); index++) { - if (tuples.get(index).matches(template)) { - found = true; - break; - } - } - - if (found) { - // Result found, get it from the tuple list - result = tuples.get(index); - } - - // End reading - endReading(); - } - } catch (InterruptedException e) { - e.printStackTrace(); + result = tryRead(template); + while (result == null) { + reveil.sleep(); + result = tryRead(template); } return result; @@ -120,98 +88,57 @@ public class CentralizedLinda implements Linda { public Tuple tryTake(Tuple template) { Tuple result = null; - int index; - try { - // Wait for writing access - requestWriting(); - - // Extract the tuple in the tuple list - for (index = 0; index < tuples.size(); index++) { - if (tuples.get(index).matches(template)) { - result = tuples.remove(index); - break; - } + // Extract the tuple from the tuple list + // TODO: faire avec iterator, hasNext, pour être thread safe :) + for (int i = 0; i < tuples.size(); i++) { + if (tuples.get(i).matches(template)) { + result = tuples.remove(i); + break; } - - // End writing - endWriting(); - } catch (InterruptedException e) { - e.printStackTrace(); } return result; } public Tuple tryRead(Tuple template) { Tuple result = null; - int index; - try { - // Waiting for reading access - requestReading(); - - // Find the tuple in the tuple list - for (index = 0; index < tuples.size(); index++) { - if (tuples.get(index).matches(template)) { - result = tuples.get(index); - break; - } + // Get the tuple from the tuple list + // TODO: faire avec iterator, hasNext, pour être thread safe :) + for (int i = 0; i < tuples.size(); i++) { + result = tuples.get(i); + if (result.matches(template)) { + break; } - - // End reading - endReading(); - } catch (InterruptedException e) { - e.printStackTrace(); } - return result; } public Collection takeAll(Tuple template) { List results = new ArrayList(); - int index; + Tuple result = new Tuple(); - try { - // Wait for writing access - requestWriting(); - - // Extract the tuples in the tuple list - for (index = 0; index < tuples.size(); index++) { - if (tuples.get(index).matches(template)) { - results.add(tuples.remove(index)); - } + // Extract the tuples in the tuple list + while (result != null) { + result = tryTake(template); + if (result != null) { + results.add(result); } - - // End writing - endWriting(); - } catch (InterruptedException e) { - e.printStackTrace(); } - return results; } public Collection readAll(Tuple template) { List results = new ArrayList(); - int index; + Tuple result; - try { - // Waiting for reading access - requestReading(); - - // Find the tuples in the tuple list - for (index = 0; index < tuples.size(); index++) { - if (tuples.get(index).matches(template)) { - results.add(tuples.get(index)); - } - } - - // End reading - endReading(); - } catch (InterruptedException e) { - e.printStackTrace(); + // Extract the tuples in the tuple list + // TODO: faire avec iterator, hasNext, pour être thread safe :) + for (int i = 0; i < tuples.size(); i++) { + result = tuples.get(i); + if (result.matches(template)) + results.add(result); } - return results; } @@ -310,60 +237,4 @@ public class CentralizedLinda implements Linda { } } - private void requestReading() throws InterruptedException { - moniteur.lock(); - - if (!(!writing && nbWaiting == 0)) { - nbWaiting++; - accessDemand.await(); - nbWaiting--; - } - nbReaders++; - accessDemand.signal(); - - moniteur.unlock(); - } - - private void endReading() throws InterruptedException { - moniteur.lock(); - - nbReaders--; - if (nbReaders == 0) { - if (SASused) { - SAS.signal(); - } else { - accessDemand.signal(); - } - } - - moniteur.unlock(); - } - - private void requestWriting() throws InterruptedException { - moniteur.lock(); - - if (!(!writing && nbReaders == 0 && !SASused && nbWaiting == 0)) { - nbWaiting++; - accessDemand.await(); - nbWaiting--; - } - if (nbReaders > 0) { - SASused = true; - SAS.await(); - SASused = false; - } - writing = true; - - moniteur.unlock(); - } - - private void endWriting() throws InterruptedException { - moniteur.lock(); - - writing = false; - accessDemand.signal(); - - moniteur.unlock(); - } - }