Laborator 13
In pseudocodul de mai jos este descrisa o bariera cu detectie a terminarii, mecanism de sincronizare a fazei de executie a lucrului pentru mai multe threaduri, urmata de un exemplu simplificat a pseudocodului pentru thread-uri ce urmeaza un pattern de work stealing care isi vor inceta executia la detectia terminarii cantitatii de work (nu mai exista taskuri de "furat").
// bariera
public class TDBarrier {
AtomicInteger count;
public TDBarrier(int n){
this.count = new AtomicInteger(n);
}
public void setActive(boolean active) {
if (active) {
count.getAndIncrement();
} else {
count.getAndDecrement();
}
}
public boolean isTerminated() {
return count.get() == 0;
}
}
// initializare context work stealing
DEQueue[] queue = new DEQueue[n]; // faza curenta de lucru va implica
TDBarrier tdBarrier = new TDBarrier(n); // un numar de taskuri distribuite
for (int i = 0; i < n; i++) { // initial la n threads
queue[i] = new DEQueue();
}
// codul fiecarui thread
public void run() {
int me = ThreadID.get();
tdBarrier.setActive(true);
Runnable task = queue[me].popBottom(); // extrage primul task
while (true) {
while (task != null) { // daca exista un task de lucru
task.compute(); // se executa
task = queue[me].popBottom(); // dupa care se preia urmatorul task
}
tdBarrier.setActive(false); // taskurile s-au terminat
// threadul devine inactiv
while (task == null) { // se incearca "furtul" unui task
int victim = random.nextInt(queue.length); // de la un alt thread
if (!queue[victim].isEmpty()) {
tdBarrier.setActive(true); // threadul se re-activeaza daca
task = queue[victim].popTop(); // un task nou este gasit
if (task == null) { // si se dezactiveaza
tdBarrier.setActive(false); // in caz contrar
}
}
if (tdBarrier.isTerminated()) { // dupa ce s-a terminat de executat
return; // taskul "furat" sau daca nu s-a gasit
} // se verifica daca mai exista lucru
} // adica threaduri active pentru faza curenta
} // prin intermediul barierei
}