• Nenhum resultado encontrado

5.4.1

M´aquina Abstrata

O desenvolvimento desta m´aquina segue a arquitetura descrita no apˆendice C.1. Para representar o estado da m´aquina abstrata foram criadas duas classes e um vetor. As classes s˜aoHeap, que representa o amontoado, eThreadPool, que representa uma piscina para os fios de execuc¸˜ao suspensos. O vetor representa os processadores que a m´aquina possui.

A classe Heap implementa uma tabela de etiquetas para c´odigo. Inicialmente, s˜ao carregadas, na tabela, a etiquetaprintLock, que cont´em o trincoconsoleLock, e a etiqueta

console. Estas etiquetas s˜ao entradas especiais do interpretador que permitem apresen- tar os resultados na consola. A classe disponibiliza m´etodos como put, get, newTuple,

newTupleROenewLock. Estes m´etodos s˜ao sincronizados, pois a mem´oria principal ´e par- tilhada por todos os processadores e pode haver v´arios processadores a tentar aceder ao amontoado em simultˆaneo. O m´etodoput e o m´etodoget inserem e obtˆem entradas da tabela, respetivamente. O m´etodonewTuplegera uma nova etiqueta, cria um novo tuplo de valores com o tamanho do tuplo de tipos que recebe e coloca na tabela o tuplo de va- lores associado `a etiqueta gerada. Cada entrada do tuplo de valores fica com o tipo n˜ao inicializado. O m´etodonewTupleRO ´e idˆentico ao m´etodonewTuple, mas recebe um tuplo de valores e guarda na tabela o tuplo recebido, associado `a etiqueta gerada. Por fim, no m´etodonewLock ´e gerada uma nova etiqueta e esta ´e guardada na tabela com o valor 1 associado, porque quando ´e criado um novo trinco, este fica fechado.

A classe ThreadPool ´e constitu´ıda por uma fila de ThreadPoolItem, que representa um fio de execuc¸˜ao suspenso. Cada fio de execuc¸˜ao suspenso ´e caraterizado por uma etiqueta e um vetor de registos. O vetor de registos tem tantas entradas quanto o n´umero infe- rido inicialmente. Os m´etodos da classeThreadPools˜ao tamb´em sincronizados, pois pode haver v´arios processadores a tentar manipular a fila de ThreadPoolItem em simultˆaneo. Os m´etodos da classe ThreadPool tˆem o objetivo de coordenar os fios de execuc¸˜ao, ou seja, guardar e atribuir um processador aos fios suspensos; quando um processador est´a suspenso, deve ser avisado de que existe um novo elemento na fila. O m´etodoget(imple- mentado atrav´es do uso do m´etodo wait da classe Object do Java) indica ao processador o primeiro elemento da fila para este o executar. No caso da fila estar vazia, o processa- dor fica em espera at´e que haja um novo elemento na fila. O m´etodoput(implementado, nomeadamente, atrav´es do m´etodo notifyAll da classeObject do Java) adiciona um novo elemento `a fila e avisa todos os processadores que h´a um novo fio de execuc¸˜ao suspenso. O vetor de processadores ´e um vetor deThreadsdo Java. Este tem tantos processadores quantos o parˆametroNindicado no arranque da m´aquina. Um processador cont´em o vetor de registos e uma sequˆencia de instruc¸˜oes.

5.4.2

Interpretador

Para a implementac¸˜ao do interpretador foi criada a classe Interpreter. Esta classe executa a etiquetamaindo programa MIL num processador.

Quando o interpretador ´e executado, s˜ao criadas as estruturas da m´aquina abstrata: o vetor de processadores, o amontoado e a piscina de fios de execuc¸˜ao. Antes de executar a m´aquina abstrata, ´e aplicado, sobre a ´arvore sint´atica abstrata, o visitanteLoadVisitor, que preenche o amontoado (Heap) da m´aquina abstrata com as etiquetas do programa MIL. Depois, ´e adicionada a etiquetamain `a piscina de fios de execuc¸˜ao, o ponto de entrada de execuc¸˜ao do programa. Por fim, s˜ao criados e executados osNprocessadores. Em cada processador ´e executado o visitanteExecVisitor, que percorre a sequˆencia de instruc¸˜oes que este cont´em. Este visitante implementa as regras da figura C.2 e a func¸˜ao de avaliac¸˜ao

ˆ

R(v) (representada na figura C.3). Esta func¸˜ao extrai o valor de registos do construtor

packe da aplicac¸˜ao de valores. O m´etodo que representa esta func¸˜ao ´e oeval.

Por fim, apresentamos os m´etodos que concretizam o interpretador. As regras R-

HALTe R-SCHEDULEs˜ao executadas quando o n´o visitado ´e odone. O m´etodo a rede- finir ´e o public void caseADoneInstruction(ADoneIns truction node); ambas as regras est˜ao implementadas no mesmo m´etodo. No caso da piscina de fios de execuc¸˜ao estar vazia, ´e lanc¸ada uma excec¸˜ao e, assim, o processador em quest˜ao para. A classe Interpreter ve- rifica se todos os processadores est˜ao em espera e, no caso de estarem, ent˜ao a m´aquina para (R-HALT). No caso de ainda existirem fios de execuc¸˜ao na piscina, ´e retirado um fio de execuc¸˜ao e o processador passa a executar o novo bloco de instruc¸˜oes (R-SCHEDULE).

Em relac¸˜ao `a regra R-FORK redefine-se o m´etodo public void caseAForkInstruction(A ForkInstruction node). Esta adiciona um novo fio de execuc¸˜ao `a piscina, o par (etiqueta l e o vetor de registos).

Para a regra R-NEWTUPLEe R-NEWLOCK´e necess´ario redefinir o m´etodopublic void caseANewInstruction(ANewInstruction node). Em primeiro lugar, ´e preciso criar uma nova etiqueta. Seguidamente verifica-se se o tipo ´e um tuplo ou um trinco. No caso de ser um tuplo, ´e colocada no amontoado a etiqueta gerada com o tuplo de valores, respetivo ao tuplo de tipos, usando o m´etodonewTupleda classe Heap. No caso de ser um trinco, ´e colocada no amontoado a etiqueta gerada com valor 1, pois o trinco quando ´e criado fecha-se de imediato. A etiqueta ´e gerada atrav´es do m´etodo newLock da classe Heap, mencionado anteriormente. Por fim, no vetor de registos, ´e atribu´ıda a etiqueta l ao registo r.

Em relac¸˜ao `as regras R-GSL0 e R-GSL1, ´e necess´ario redefinir o m´etodo public void caseAGetsetlockInstruction(AGetsetlockInstruction node). Primeiramente, verifica-se se o va- lor que o registo r’ cont´em ´e 0 ou 1. No caso de ser 1 ´e atribu´ıdo 1 ao registo r. No caso de ser 0, ´e atribu´ıdo 0 ao registo r e ´e alterado o valor no amontoado, passando a ser 1.

Por fim, na regra R-STORE ´e necess´ario redefinir o m´etodo public void caseAStore Instruction (AStoreInstruction node). Inicialmente, s˜ao obtidos os valores do tuplo que r

cont´em. De seguida, o ´ındice n do tuplo ´e alterado para o valor do registo r’. O valor do registo ´e obtido pelo m´etodoeval, referido anteriormente.

Para a implementac¸˜ao do interpretador foram criadas 9 classes com cerca de 870 li- nhas de c´odigo.

MOOL

A linguagem de programac¸˜ao MOOL, introduzida por Joana Campos e Vasco Vascon- celos [7], ´e uma linguagem orientada a objetos concorrentes que formaliza a noc¸˜ao de interac¸˜ao com objetos. A linguagem inclui as primitivas usuais da maioria das linguagens orientadas a objetos mas, adicionalmente, permite especificar como um objeto deve ser usado. Nesta tese, estamos focados nas primitivas de concorrˆencia desta linguagem, que permitem a criac¸˜ao de fios de execuc¸˜ao e a sincronizac¸˜ao de m´etodos, quando a execuc¸˜ao destes ´e efetuada em exclus˜ao m´utua.

O MOOL inicia a execuc¸˜ao de uma aplicac¸˜ao invocando o m´etodo main, da classe

Main.

Documentos relacionados