уторак, 9. фебруар 2010.

OSP - Resources

#################################################################################
KLASA ResourceCB
#################################################################################

package osp.Resources;

import java.util.*;

import osp.IFLModules.*;
import osp.Tasks.*;
import osp.Threads.*;
import osp.Utilities.*;
import osp.Memory.*;

/**
* @author Mihajlo
*
*/

@SuppressWarnings("unused")
public class ResourceCB extends IflResourceCB
{
// Lista heš tabela, gde se u svakoj pojedinačnoj heš tabeli čuvaju informacije
// o zahtevima svih niti za nekim resursom.
private static List zahtevaniBlokovi;
private static Set Tredovi;
private static HashMap[] alokacionaLista;
private static HashMap[] Maximum;

public ResourceCB(int qty)
{
// Pozovite super(), a ostalo ako imate potrebu nešto da inicijalizujete u vašoj implementaciji
super(qty);
}

// metod za osvezavanje liste
private static void osvezavanjeListe(ThreadCB thread, int quantity, int resourceID) {

if (alokacionaLista[resourceID].containsKey(thread)) {
alokacionaLista[resourceID].put(thread, alokacionaLista[resourceID].get(thread) + quantity);
} else {
alokacionaLista[resourceID].put(thread, quantity);
}
}

@SuppressWarnings("unchecked")
public static void init()
{
// Kao i ranije, možete koristiti ovaj metod da inicijalizujete neke statičke promenljive
// koje bi vam možda zatrebale.
zahtevaniBlokovi = new ArrayList();
Tredovi = new HashSet();
Maximum = new HashMap[ResourceTable.getSize()];
alokacionaLista = new HashMap[ResourceTable.getSize()];

int size = ResourceTable.getSize();

for (int i=0; i < size; i++)
{
Maximum[i] = new HashMap();
alokacionaLista[i] = new HashMap();
}
}

public RRB do_acquire(int quantity)
{
// Da bi utvrdili koji proces je zahtevalo resurse, koristimo se PTBRom.
// Konkretnije koristimo metode getPTBR() i nad dobijenim objektom pozivamo metodu getTask().
ThreadCB tred = MMU.getPTBR().getTask().getCurrentThread();

// inicijalizacija
int deadlockMetod = getDeadlockMethod();
int slobodniResursi = getAvailable();
int ukupniResursi = getTotal();

// ako se zahtevani broj resursa ne može dodeliti ni pod kojim uslovom,
// npr ne postoji ih toliko u sistemu, zahtev se odbija, odnosno metoda vraća null
if ((quantity > ukupniResursi) || ((getAllocated(tred) + quantity) > ukupniResursi))
return null;

// dodajem tred
Tredovi.add(tred);

// menjam maximum mapu
Maximum[getID()].put(tred, getMaxClaim(tred));


// u suprotnom, možda u budućnosti će nit moći da bude opslužena, tako da se mora suspendovati.
if ((quantity > slobodniResursi) && (quantity < ukupniResursi))
{
// inicijalizacija novog resurs bloka
RRB noviResursBlok = new RRB(tred, this, quantity);
zahtevaniBlokovi.add(noviResursBlok);

// Zahtevu se status postavlja na Suspended metodom setStatus(),
// a nit se suspenduje metodom suspend()
// i prosleđuje se napravljeni RRB objekat
noviResursBlok.setStatus(Suspended);
tred.suspend(noviResursBlok);

return noviResursBlok;
}

// ispitujemo vrste deadlock metoda

// Kada god je moguće zahtevi za resursima se opslužuju bez dodatnog ispitivanja.
// Povremeno, OS izvršava metodu koja proverava da li postoji deadlock u sistemu.
// Ako postoji moguće je ubiti sve procese, ubijati procese koji učestvuju u deadlocku
// sve dok se deadlock ne otkloni, osloboditi resurse uključene u deadlock, itd.

if (deadlockMetod == Detection)
{
RRB noviResursBlok = new RRB(tred, this, quantity);

zahtevaniBlokovi.add(noviResursBlok);
noviResursBlok.grant();

// osvezavam liste
osvezavanjeListe(tred, quantity, noviResursBlok.getResource().getID());

// vracam noviResursBlok
return noviResursBlok;
}

// Deadlock izbegavanje
// U trenutku zahtevanja resurasa se odlučuje da li će se oni i dodeliti.
// Brine se o tome da li će dodela resursa ostaviti sistem u sigurnom stanju.
// Sigurno stanje je stanje u kom se mogu izvršiti svi procesi nekim redom, bez pojave deadlocka.

// Ako se koristi deadlock izbegavanje,
// onda ovde morate implementirati neki od  odgovarajućih algoritama
else if (deadlockMetod == Avoidance)
{
// Implementiram Banker's Algorithm.
// Ako pomoću algoritma zaključite da je sigurno dodeliti resurse,
// onda to i uradite u suprotnom se nit suspenduje i status zahteva se postavlja na Suspended.
// Metoda na kraju vraća napravljeni RRB objekat.

ThreadCB tredovi[] = Tredovi.toArray(new ThreadCB[0]);
int[][] maksimum = new int[Tredovi.size()][ResourceTable.getSize()];
int[][] alokacija = new int[Tredovi.size()][ResourceTable.getSize()];
int[][] potrebni = new int[Tredovi.size()][ResourceTable.getSize()];
int[] dostupni = new int[ResourceTable.getSize()];

int size = ResourceTable.getSize();

for (int i = 0; i < size; i++)
{
dostupni[i] = ResourceTable.getResourceCB(i).getAvailable();
for (int j = 0; j < Tredovi.size(); j++)
{
if (Maximum[i].containsKey(tredovi[j]))
maksimum[j][i] = Maximum[i].get(tredovi[j]);
else
maksimum[j][i] = 0;

if (alokacionaLista[i].containsKey(tredovi[j]))
alokacija[j][i] = alokacionaLista[i].get(tredovi[j]);
else
alokacija[j][i] = 0;

potrebni[j][i] = maksimum[j][i] - alokacija[j][i];
}
}

int p = ResourceTable.getSize();
int q = Tredovi.size();

int[] radni = Arrays.copyOf(dostupni, p);
int[] kraj = new int[q];

for (int i = 0; i < kraj.length; i++)
{
if (kraj[i] == 0)
for (int j = 0; j < p; j++)
if (potrebni[i][j] <= radni[j])
{
radni[j] += alokacija[i][j];
kraj[i] = 1;
}
}

// u suprotnom se nit suspenduje i status zahteva se postavlja na Suspended
int duzina = kraj.length;
for (int i = 0; i < duzina; i++)
if (kraj[i] == 0)
{
RRB noviResursBlok = new RRB(tred, this, quantity);
zahtevaniBlokovi.add(noviResursBlok);

// suspendovanje treda
tred.suspend(noviResursBlok);

// suspendovanje statusa zahteva
noviResursBlok.setStatus(Suspended);

return noviResursBlok;
}

// Ako pomoću algoritma zaključite da je sigurno dodeliti resurse,
// onda to i uradite
RRB noviResursBlok = new RRB(tred, this, quantity);
zahtevaniBlokovi.add(noviResursBlok);

noviResursBlok.grant();

osvezavanjeListe(tred, quantity, noviResursBlok.getResource().getID());

return noviResursBlok;
}

return null;
}

public static Vector do_deadlockDetection()
{

/*Vector deadlockTredovi = new Vector();
for (int i = zahtevaniBlokovi.size() - 1; i >=0; i--){
ThreadCB tred = zahtevaniBlokovi.get(i).getThread();
if ((tred == )) argggghhhhh
}*/


return null;

}

public static void do_giveupResources(ThreadCB thread)
{
// Ovaj metod se poziva od strane OSPa kada se određena nit ubija
// kako bi se oslobodili svi resursi koje je ona zauzela
for (int i = zahtevaniBlokovi.size() - 1; i >= 0; i--)

{
// U ovoj metodi trebate da prođete kroz sve resurse koje je zauzela ta nit i da osvežite,
// kao i u pređašnjim metodama, brojke koje označavaju zauzeće i raspoloživost resursa
RRB zahtevaniResursBlok = zahtevaniBlokovi.get(i);
if (zahtevaniResursBlok.getThread().equals(thread))
{
ResourceCB resurs = zahtevaniResursBlok.getResource();
int quantity = zahtevaniResursBlok.getQuantity();
int slobodniResursi = resurs.getAvailable();
int noviSlobodanResurs = slobodniResursi + resurs.getAllocated(thread);
resurs.setAvailable(noviSlobodanResurs);

// Broj resursa koje zauzima nit se postavlja na 0.
resurs.setAllocated(thread, 0);

// oslobađam resurse
alokacionaLista[zahtevaniResursBlok.getResource().getID()].remove(thread);
Maximum[zahtevaniResursBlok.getResource().getID()].remove(thread);
zahtevaniBlokovi.remove(zahtevaniResursBlok);
}
}

// Opet, pošto se oslobađaju resursi,
// potrebno je proveriti da li je moguće nastaviti sa izvršavanjem nekih od blokiranih niti.

for (RRB zahtevaniResursBlok : zahtevaniBlokovi)
{
// inicijalizacija slobodnog resursa
int slobodanResurs = zahtevaniResursBlok.getResource().getAvailable();

// proveravam da li je moguce i ukoliko jeste nastavim sa izvrsavanjem
if ((zahtevaniResursBlok.getQuantity() <= slobodanResurs)
&& (zahtevaniResursBlok.getStatus() == Suspended))
{
zahtevaniResursBlok.grant();
slobodanResurs -= zahtevaniResursBlok.getQuantity();

// osvezavanje liste
osvezavanjeListe(zahtevaniResursBlok.getThread(), zahtevaniResursBlok.getQuantity(), zahtevaniResursBlok.getResource().getID());
}
}
}

public void do_release(int quantity)
{
// OSP poziva ovaj metod kada nit treba da osloboti 'quantity' broj resursa tog tipa.
ThreadCB tred = MMU.getPTBR().getTask().getCurrentThread();

// Prvo kao i ranije osvežiti brojke u kojima se čuva koliko je resurasa tog tipa slobodno,
// kao i koliko resursa sada zauzima nit koja oslobađa resurse.

int slobodniResursi = getAvailable();
int noviSlobodanResurs = slobodniResursi + quantity;
setAvailable(noviSlobodanResurs);

int alociraniResursi = getAllocated(tred);
int noviAlociraniResurs = alociraniResursi - quantity;
setAllocated(tred, noviAlociraniResurs);

// S obzirom da su neki resursi oslobođeni,
// moguće je da neke niti nakon toga mogu da nastave sa svojim izvršavanjem,
// tako da je to sledeći korak,
// proveriti da li je moguće nastaviti izvršavanje nekih niti
for (RRB zahtevaniResursBlok : zahtevaniBlokovi)
{
if ((zahtevaniResursBlok.getStatus() == Suspended)
&&
(zahtevaniResursBlok.getResource().getID() == getID())
&&
(zahtevaniResursBlok.getQuantity() <= getAvailable()))
{
// i ako je moguće uraditi to pozivom metode grant()
zahtevaniResursBlok.grant();

osvezavanjeListe(zahtevaniResursBlok.getThread(), zahtevaniResursBlok.getQuantity(), zahtevaniResursBlok.getResource().getID());
}
}
}

public static void atError()
{

}

public static void atWarning()
{

}

}

#################################################################################
KLASA RESOURCE TABLE
#################################################################################
package osp.Resources;

import osp.Utilities.*;
import osp.IFLModules.*;

/**
* @author Mihajlo
*
*/

@SuppressWarnings("unused")
public class ResourceTable extends IflResourceTable
{

public ResourceTable()
{
// Kao i uvek pozvati super().
// Dalje po potrebi, ako vaša implementacija problema to zahteva,
// inicijalizovati dodatno neke instancne promenljive
super();

}

}

#################################################################################
KLASA RRB
#################################################################################

package osp.Resources;

import java.util.*;

import osp.IFLModules.*;
import osp.Threads.*;

/**
* @author Mihajlo
*
*/

@SuppressWarnings("unused")
public class RRB extends IflRRB
{

public RRB(ThreadCB thread, ResourceCB resource,int quantity)
{
// mora se pozvati super
super(thread, resource, quantity);
}

public void do_grant()
{
// Metod simulira davanje resursa niti.
// Ovde se ne vrši provera da li ovo treba uraditi, samo se uradi.
// Treba dekrementirati broj dostupnih resursa zahtevanog tipa,

int slobodniResursi = getResource().getAvailable();
int noviSlobodniResurs = slobodniResursi - getQuantity();
getResource().setAvailable(noviSlobodniResurs);

// i povećati broj koji predstavlja broj alociranih resursa.
int alociraniResursi = getResource().getAllocated(getThread());
int noviAlociraniResursi = alociraniResursi + getQuantity();
getResource().setAllocated(getThread(), noviAlociraniResursi);

// Na kraju stanje niti koja je napravila taj zahtev se mora postaviti na Granted
setStatus(Granted);

// i nit se treba odblokirati metodom notifyThreads().
notifyThreads();
}


}
##############################################

Нема коментара:

Постави коментар