• Nenhum resultado encontrado

Um Mecanismo de Reexecução de Aplicações PVM

N/A
N/A
Protected

Academic year: 2021

Share "Um Mecanismo de Reexecução de Aplicações PVM"

Copied!
20
0
0

Texto

(1)

                

  

         

Ana Paula Cláudio

Rui Tavares

DI-FCUL

TR–99–6

            ! " #  $ "  %  & $ '  ! # ( " ) * + *   % %  %  , ) - $ * ) . % / $ ) 0  ! . ) % %  %  1 ) . 2  , #   3 ! $ %  4  5 6 6 1 ) . 2  7  ! "  8  9 : ; < = >; ? @ A : B C A D E ? A : ? F ? >@? G @: ? D http://www.di.fc.ul.pt/biblioteca/tech-reportsH 9 < : I>@: E ? A : E D C A : J >= K L M N O >D < D < : A : B C A D = P Q G : A ? E I> @: = ? Q : H R @D : A = ? D >F : @S N A : B C A DE ? A : ? F ? >@? G @ : G S B C E D IA C Q D < : ? G C F : ? J J A : E E H

(2)
(3)

T U V W X Y Z [ \ U ] ^ W _ W W ` W X a b c ] ^ W d e f [ X Y b g W \ h i V

Julho de 1999 Ana Paula Cláudio

Departamento de Informática

Faculdade de Ciências - Universidade de Lisboa [email protected]

Rui Tavares

Departamento de Matemática Universidade de Évora / Laboratório de Sistemas Evolutivos e Engenharia Biomédica – Instituto de Sistemas e

Robótica – I.S.T.

[email protected]; [email protected]

j k l m n o

Apresentamos uma ferramenta de reexecução para aplicações desenvolvidas no ambiente PVM (p q r q sst s u vr wx q s

y

q z { v| t ), as quais são aplicações paralelas que comunicam por troca de mensagens. A técnica descrita e

implementada é constituída por duas fases: a fase de traço (}~  €  ) e a de reexecução (‚ ƒ„ …† ‡ ). A fase de traço tem

lugar numa execução livre da aplicação, durante a qual é registado um conjunto de informações com base no qual se controla uma execução posterior -a reexecução- de forma a que, em ambas, se verifiquem as mesmas relações de ordem causal entre os eventos de comunicação. A informação guardada na primeira fase é, por um lado, mínima para que o efeito de sonda (ˆ ‰Š ‹ Œ Œ Œ Ž ) produzido seja tão diminuto quanto possível, mas, por outro lado, suficiente para

garantir, nomeadamente, que as condições de corrida ( ‘ ’ “ ’ ” • – —˜—” • ™) entre os processos sejam resolvidas numa

reexecução da mesma forma que na execução. A ferramenta descrita, AVTRPL -š › › œž Ÿ  ¡ ¢ £ ¤¥ Ÿ œ¦ § ¨ © ª ¨ Ÿ ž § Ÿ ¢ «

¬

§› œŸ ­ - é uma das componentes de uma ferramenta mais abrangente, vocacionada para o depuramento de aplicações

(4)

® ¯ ° ± ² ³ ´ µ ¶ · ¸¹ º » ¼ ½ ¾ º ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ À Á µ  à Äà ¸Å Æ Ç È É Ê ËÈ Ç ¹ Ç ÌÌ Å Ì É Ä¹ ¸¼ Ç Ì Ê Ç Í Î Ä · Å Ï ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ ¿ Ð Ñ ÒÓ Ô Õ Ö × ØÙÚ Û Õ Ü Ý Ú Þ Û ß à Ú Ø Û Ù Õ á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á â ã ä å æ ç è éê ë ì æ í æ î é è ï ç ðñ î æ í é ò é é ó é è ô ë ì æ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ õ ö ÷ øù ú û ü ý þÿ     ý    þý                                                              ÷ ø ý      ý þ þû   þ    ÷ ø                                                 3.2.1 Iniciação / pvmbeatask() _______________________________________________________________9 3.2.2 pvm_spawn() ________________________________________________________________________9 3.2.3 pvm_mkbuf() / pvm_initsend() __________________________________________________________9 3.2.4 pvm_[n|t]recv() ______________________________________________________________________9 3.2.5 Terminação / pvm_exit() _______________________________________________________________9          !   " "   #$   % & ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ( )  *        !   " "   +  ,  -   # $  %  , & ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ( (  . /  $    0 1  2 " " 3 $    " 4 5 6   # 7 7 & ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ( ( 3.5.1 Iniciação / replay_init() _______________________________________________________________12 3.5.2 pvm_spawn(), pvm_mkbuf() / pvm_initsend(), e pvm_exit() __________________________________12 3.5.3 pvm_[n|t]recv() _____________________________________________________________________13 8 9 : ; < = ; > ? @ = AB >B C ; D E F G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G H I J KL M N O P QRS T U N V S W X Y Y S O X Z [ S \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ L ] J K^ M N O P QRS T U N V S _ S P RQ` S T a X _ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ L ] J K] b c X ` d T U N V S _ S P RQ ` S T a X _ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ L J 4.3.1 Traço _____________________________________________________________________________14 4.3.2 Reexecução ________________________________________________________________________14 e fe g h i j k l mnk o p h i q q k h r s h l t u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u v e e fw g h i j k l mnk o p h i q q k h x m y mo z k h r s h l t l my u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u v w { | } ~ €  ~ ‚ ƒ „ … … … † { ‡ ˆ‰ Š ‹ Œ  Ž   ‘ ‹ ‹ ’ ’  Ž “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ ‰ ‡ ‡ ˆ” • ’ – — ‹ ˜ ™‹ Ž š ’ – › › ‹ ’ œ ’ ˜ Œ  “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ ‰ ž ‡ ˆŸ   — ¡ ‹ ’  Ž ‘ ‹  ’ – ¢  ‹ £ – ’ ¤ ˜ ™‹ Ž “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ ‰ ž ‡ ˆ¥ ¦  £ ‹ ‘ ‹ § £ £ – ’ ¤ ˜ ™‹ – Ž Ž  — – ‘  – § £ ˜— ¡ ‹  ’  ‘ ‹ ’ – ¢  “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ ‰ ž ‡ ˆ‡ ¨ © ’ – ‘ – Ž ©  Ž ˜ — ¡ ‹ ’  Ž ‘ ‹ ’ – ¢  “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ “ ‰ ª « ¬ ­ ® ¯ °± ²³ ´ ® ¯ ® µ ¶ ·¸ ¶ ¯ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ º » ¼ ¬ ½ ¾ ¿ À ·Á ¯ ´ ® ¯ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ º »  ¬ ­ ®Ã ® ± Ä ¿ À ² ¶ ¯ ® Å ²Æ ·² ¾ Ç ± ¶Ã ² ¶ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ È É

(5)

Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Ð

Neste relatório apresenta-se uma ferramenta de traço e reexecução, concebida e implementada sobre o sistema PVM (Parallel Virtual Machine) para aplicações distribuídas constituídas por colecções de processos que comunicam entre si utilizando o paradigma da troca de mensagens. Descrevemos a filosofia e a arquitectura por detrás da concepção do mecanismo, bem como alguns aspectos essenciais da sua implementação.

Esta ferramenta foi concebida como uma das componentes de um depurador de aplicações distribuídas por troca de mensagens, do qual falaremos adiante.

As aplicações paralelas podem ser não determinísticas devido à ocorrência de condições de corrida (Õ Ö × Ø × Ù Ú Û ÜÝ ÜÙ Ú Þ ). Tal característica impossibilita a aplicação do depuramento cíclico,

uma técnica largamente utilizada em aplicações sequenciais as quais são, na sua maioria, determinísticas. A única forma de tornar viável o depuramento cíclico para aplicações paralelas é disponibilizar um mecanismo de reexecução.

Um dos modelos para construção de aplicações distribuídas baseia-se na definição de um conjunto de processos que comunicam explicitamente entre si por troca de mensagens. Neste modelo da aplicações distribuídas, uma condição de corrida ocorre quando duas mensagens enviadas ao mesmo processo são por este consumidas tendo em conta apenas a sua ordem de chegada. Uma inversão na ordem de chegada das mensagens implica uma inversão dos consumos podendo levar a uma diferente progressão no comportamento do processo consumidor e, eventualmente, dos processos a quem este em seguida envie mensagens.

É pois necessário que qualquer mecanismo de reexecução garanta que estas condições sejam resolvidas da mesma forma na execução original e na reexecução.

O mecanismo de reexecução adoptado foi o ß à á â ã à â ä å æ çã è [Leblanc87] destinado a

aplicações paralelas que comunicam por partilha de memória, com a devida adaptação para aplicações que comunicam por troca de mensagens. Este mecanismo é baseado no seguinte princípio: supondo que os processos sequenciais envolvidos na aplicação paralela contêm apenas instruções determinísticas se, em sucessivas execuções, cada processo receber os mesmos dados de entrada pela mesma ordem, vai certamente produzir os mesmos dados de saída pela mesma ordem. Ou seja, são mantidas, nas sucessivas execuções, as relações de ordem causal [Lamport78] entre os eventos de comunicação desencadeados pelos processos. Este facto, no conjunto de todos os processos garante um meio de repetir comportamentos, ou seja, de obter determinismo. O mecanismo envolve duas fases distintas: a primeira, o traço (é ê ë ì í ), que tem

lugar durante uma execução da aplicação e durante a qual é guardada a informação necessária para que na segunda fase, a reexecução (î ï ð ñ ò ó ), os processos recebam os mesmos dados pela

mesma ordem. A fim de minimizar o efeito de sonda (ô õ ö ÷ ø øù ù ø ú û ), armazena-se o menor

volume de informação possível. Assim, para cada recepção de mensagem são guardados o identificador do processo origem e o número de ordem do correspondente envio neste processo. Estes dados são suficientes para que, na fase de reexecução, as condições de corrida sejam resolvidas exactamente da mesma forma que na execução original, garantindo assim uma réplica daquela execução.

O mecanismo AVTRPL está integrado na ferramenta MPVisualizer üý þ ÿ ÿ  þ  ÿ ÿ  



(6)

que comunicam por troca de mensagens. Esta ferramenta é constituída por três componentes: o mecanismo de reexecução descrito neste relatório, a interface gráfica e a aplicação visualizadora. Esta última, o cerne da ferramenta, é a componente de     que serve de charneira entre a

aplicação distribuída e a interface gráfica onde é produzida uma sua representação (figura 1). Enquanto o mecanismo de reexecução e a interface gráfica dependem de modo intrínseco do suporte de troca de mensagens e do        gráfico utilizados, respectivamente, o núcleo da

aplicação visualizadora é genérico. De facto, durante a reexecução, a aplicação visualizadora constrói, usando o paradigma da orientação por objectos, um modelo da aplicação em estudo. As classes do modelo agrupam-se em classes do núcleo e classes gráficas. As primeiras são as classes básicas que não dependem nem do suporte de comunicação utilizado nem do      !

gráfico, mas apenas do facto de se modelizar aplicações paralelas que comunicam por troca de mensagens; as segundas são subclasses das anteriores e encapsulam todas as dependências do

" # $ %& ' ( )

gráfico. Uma eventual mudança deste * + , - . / 0 1 terá repercussões exclusivamente ao

nível destas subclasses.

Os dados produzidos pelo mecanismo de reexecução são encaminhados, de acordo com um determinado formato, para a aplicação visualizadora que constrói o referido modelo; por invocação dos métodos de desenho de objectos do modelo é gerada a representação gráfica. Assim, a aplicação visualizadora é uma componente de 2 3 4 5 6 7 8 9 com a qual podem ser

combinadas, por um lado, aplicações que se executam sobre suportes de troca de mensagens diferentes e, por outro lado, distintos : ; < => ? @ A : gráficos.

O utilizador, através dos dispositivos gráficos de entrada habituais, pode interactuar com a representação gráfica por forma a obter informação diversa acerca da aplicação em estudo.

Aplicação

Visualizadora

Mecanismo de Reexecução Interface Gráfica B C D E FE G H I J K L M N K J O J P PH P L F O G Q J P M J R S F T H U

O sistema PVM é um pacote de V W X YZ [ \ ] concebido para o desenvolvimento de aplicações

paralelas executáveis numa rede de computadores Unix. Este pacote permite o uso de uma colecção heterogénea de computadores numa rede como um recurso computacional paralelo único (a Máquina Virtual - MV), acessível com vários níveis de transparência. É de referir que o pacote existe para um número significativo de arquitecturas de computadores, e que os problemas da heterogeneidade daí resultantes são resolvidos transparentemente para o programador de aplicações. Através de uma interface simples, mas bastante completa, é dada ao programador a possibilidade de estruturar os seus programas com um elevado grau de flexibilidade. Uma aplicação PVM é uma colecção de ^_ ` a ` (uma task é, em geral, um processo

(7)

Unix), que comunicam entre si por troca de mensagens, através das primitivas fornecidas. O sistema PVM, para além das rotinas relacionadas com mensagens, contém rotinas para criação e terminação de bc d e d , para envio de sinais Unix de uma fg h i a outra, para construção de aplicações

baseadas em grupos, para reconfiguração da MV (útil para garantir tolerância a faltas), e para obtenção de variada informação sobre a MV como o estado das máquinas que a constituam ou das jk l m l em execução.

O sistema PVM tem ganho cada vez mais utilizadores [Skillicorn98] e alguns autores consideram-no um produto normalizado n o p q r st [Geist96].

Do ponto de vista do trabalho aqui descrito, as rotinas mais importantes são as rotinas associadas aos eventos de comunicação bem como de início e fim de uv w x . De seguida

descrevemos sinteticamente estas rotinas.

y z { | } ~  € ‚ ƒ } „ … ‚ † ƒ ‡ ˆ ‚ € ƒ }

A rotina usada para lançar uma nova ‰Š ‹ Œ (ou várias) é pvm_spawn(); os seus parâmetros

incluem o nome do ficheiro executável, o número de Ž    que se pretende lançar, e várias

opções relacionadas com o grau de transparência com que se usa a MV. Por exemplo, quanto à máquina em que as ‘ ’ “ ” “ lançadas vão ser executadas, é possível excluir ou escolher uma

determinada máquina, escolher as máquinas com uma dada arquitectura ou dar ao sistema plena liberdade. As •– — ˜ — que são lançadas sem indicação da máquina específica em que devem ser

executadas, recebem, no âmbito da ferramenta apresentada, a designação de ™š › œ ›  ž Ÿ š  › ¡

O PVM disponibiliza ainda outras opções como sejam, por exemplo, lançar a ¢£ ¤ ¥ usando

um depurador sequencial, ou activar a opção de traço do próprio PVM.

A principal rotina de envio de mensagens é ¦ § ¨ © ª « ¬ ­ ; esta rotina indica a ® ¯ ° da mensagem

(um inteiro a que o programador é livre de atribuir um valor com significado), e o ±² ³ ´ µ¶ (· ¸¹ ) da

º» ¼ ½

destino. Estes identificadores são atribuídos pelo sistema PVM e devem ser vistos pelo programador como inteiros opacos. O conteúdo das mensagens é construído (e também obtido depois da sua recepção) pelas rotinas de empacotamento (¾ ¿ À Á ) e desempacotamento (Â Ã Ä Å Æ Ç ).

As rotinas para recepção são de quatro variedades diferentes e todas têm como parâmetro tanto a È É Ê da mensagem que desejam receber, como o identificador da Ë Ì Í Î emissora. Para

ambos os parâmetros, ao valor (Ï Ð ) é atribuído o significado de "qualquer". Quando, num mesmo

processo, em duas invocações sucessivas de rotinas de recepção, o valor (-1) é passado como identificador de ÑÒ Ó Ô emissora e os ÕÖ × Ø das mensagens coincidem

1

, pode ocorrer uma condição de corrida. As quatro rotinas de recepção de mensagens são: Ù Ú Û Ü Ý Þ ß Ú , rotina bloqueante que só

retorna quando uma mensagem nas condições especificadas nos parâmetros de entrada estiver disponível, à á â ã ä å æ ç á , rotina não bloqueante que retorna imediatamente quer haja ou não

mensagem, indicando a situação ocorrida no valor retornado, è é ê ë ì í î ï é , rotina temporizada que

bloqueia durante um período de tempo -passado como parâmetro- findo o qual, se não houver nenhuma mensagem disponível, retorna indicando esse facto, e ð ñ ò ó ð ô õ ö ñ , que permite de uma

só vez receber e desempacotar os dados e que no essencial é idêntica à rotina ÷ ø ù ú û ü ý ø .

A rotina þ ÿ   

 

é invocada por um processo quando este deixa de ser uma    PVM.

Estas rotinas constam de uma biblioteca,     , que deve ser ligada às aplicações se

estas forem escritas em C ou C++. Para aplicações escritas em FORTRAN 77, a outra linguagem para a qual existe interface PVM, existem rotinas equivalentes, e a sua implementação, aliás, não

1

(8)

é mais que a chamada à rotina correspondente em C com o devido ajuste de parâmetros. No entanto, as rotinas PVM para FORTRAN 77 não foram incluídas na ferramenta de reexecução.

                  !     "   #   $   

% & ' ( ) * + ,- . / 0 1 2 . + 3 . / 0 ,+

O mecanismo consiste na execução das aplicações em duas etapas: traço (45 6 7 8 ) e

reexecução (9 : ; <= > ). Para qualquer uma delas, a aplicação deve ser ligada com versões alteradas

da biblioteca base do PVM, ?@ A B C D E FG . Estas versões contêm as mesmas chamadas ao sistema

PVM, mas instrumentadas com o código necessário a cada etapa. A biblioteca alterada de traço é

HIJ K L M N O P L O Q R P S T UP

; e a de reexecução é VWX Y Z [ \ ] ^ Z ] _ ` Y V^ a b^ . É importante realçar que o

código das aplicações PVM não precisa ser alterado, basta proceder à ligação com a correspondente biblioteca instrumentada.

Um aspecto importante a ter em conta num mecanismo deste género é a interferência que o próprio processo de traço causa nas aplicações. Assim, determinados erros que dependam de temporização, como as condições de corrida, podem deixar de se revelar apenas por se perderem alguns ciclos de processador em instruções da actividade de traço. Como um dos objectivos era minimizar aquela interferência, isso excluiu logo à partida qualquer solução que implicasse o envio de mensagens quando dos eventos de traço, pois estas são operações que têm um peso não desprezável no tempo total de uma cd e f . Assim, a escolha recaiu na escrita de um ficheiro de

traço por cada gh i j , na sua máquina (com uma excepção explicada mais adiante); este ficheiro é

usado na reexecução por uma outra k l m n que vá assumir o papel da primeira e que se designa por

op q r

réplica.

O problema principal com esta solução prende-se com as st u v u ditas gerais: aquelas que não

são lançadas numa máquina específica. Deste modo, a mesma wx y z geral pode, em reexecuções

sucessivas duma aplicação, ser lançada em máquinas distintas, onde não esteja disponível nenhum ficheiro de traço. Para isto, foi necessário adicionar uma outra componente ao sistema (chamada { | } ~  € ‚  ƒ „ | } … …  | - † ‡ ˆ ‰ ) que recolhe os ficheiros de traço das Š ‹ Œ  Œ gerais após esta

fase, e que os entrega às respectivas Ž   ‘  réplica durante a reexecução.

Em ambas as versões alteradas da biblioteca, a cada evento está associado um contador de eventos que é registado no ficheiro de traço para verificação na reexecução. Supõe-se que a única causa de não determinismo interno nas ’“ ” • ” são as condições de corrida na recepção de

mensagens. O – —˜ (™ š › œ  ž ž Ÿ   ) de uma ¡¢ £ ¤ durante o traço é utilizado pelo mecanismo para

identificar a sua réplica durante a reexecução.

Como hipótese simplificativa mas sem perda de generalidade, consideramos que em todas as aplicações existe uma só ¥¦ § ¨ que não é lançada por © ª « ¬ ­ © ® ¯ ° ; a esta chamamos ± ² ³ ´ µ ¶ ´² ³ · ,

e será esta portanto a única ¸ ¹ º » a ser lançada directamente pelo utilizador. Supomos ainda que,

quando um processo deixa de ser ¼½ ¾ ¿ PVM (por invocação da rotina À Á Â Ã Ä Å Æ Ç ), não o voltará a

ser até ao final da sua execução.

O mecanismo implementado segue de perto as ideias base do mecanismo È É Ê Ë Ì É Ë Í Î Ï ÐÌ Ñ

proposto por Leblanc e Mellor-Crummey [Leblanc87]. Este apresenta a vantagem de não ser necessário armazenar todo o conteúdo da mensagem para se conseguir reproduzir o

(9)

comportamento de uma aplicação distribuída, o que, de acordo com medidas apresentadas pelos autores, diminui substancialmente a interferência sobre o desenrolar da aplicação original.

Ò Ó Ô Õ Ö × ØÙ Ú Û× Ü Ý Ú Ö Þ ß àß Øàá Ù Ú â × Ø àß ã ä å Ò Ó× æ çè

Neste parágrafo são descritas as alterações efectuadas a rotinas da biblioteca base do PVM, relativas à fase de traço.

é êë ê ì í î ï ð ïñ ò ó ô õ ö ÷ ø ù ú ñ û ñ ü ý þ ÿ

Esta rotina, que normalmente não é usada de forma directa pelas aplicações PVM, é invocada automaticamente a primeira vez que uma    chama uma rotina PVM, e serve para

inicializar o estado desta como    PVM. No final do código da rotina, foi acrescentado um

certo número de tarefas relacionadas com a actividade de traço. Nomeadamente, determina-se se a  que está a executar a rotina é ou não geral, regista-se a passagem a   PVM no ficheiro

de traço entretanto criado e, se fôr          , é lançado o     .

     ! "  # $ % & '

Regista-se o evento correspondente no ficheiro de traço, e passa-se à () * + o seguinte

conjunto de informação: o seu tipo (geral ou não geral), variáveis de ambiente Unix utilizadas na actividade de traço e o , -. (/ 0 1 2 34 ) do processo 5 6 7 8 , o qual tem de ser conhecido de todas as

tasks da aplicação.

9 :; :9 < = > ? > @ A B C D E F < = > ? G H G I J K H L D E

Nestas rotinas, responsáveis pela criação dos M N O O P Q R (espaços onde são empacotados os

dados das mensagens), assegura-se que o S T U da VW X Y origem é também empacotado a fim de se

proceder ao seu envio para o processo destino, juntamente com a mensagem PVM.

Z [\ [] ^ _ ` a bc de fg h i _ j k

Regista-se no ficheiro de traço o evento de l m n m op m de mensagem e o respectivo consumo ou

ausência deste (só para o caso não bloqueante).

O q r s da tu v w emissora da mensagem é desempacotado de forma transparente. É este

identificador da proveniência da mensagem que permitirá às x y z { z durante a reexecução seguir o

mesmo caminho na resolução das condições de corrida.

| }~ } €  ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ ƒ   Ž „  ‘

Esta rotina é invocada por um processo quando termina o seu papel de ’“ ” • PVM. Se a –— ˜ ™

for geral, este é o momento de informar o š › œ  da localização do seu ficheiro de traço na MV.

Note-se que não é enviado o ficheiro de traço, apenas a sua localização, pois de contrário poder-se-ia interferir demasiado com outras žŸ   ¡   ainda em execução. Será o próprio ¢ £ ¤ ¥ ,

(10)

Tal como já referimos, supomos que quando um processo invoca esta rotina, não voltará a ser ¦§ ¨ © PVM.

ª « ª ¬ ­ ® ¯ ° ± ²³° ´ µ ­ ® ¶ ¶ ° ­ · ¸ ­ ± ¹ º

O » ¼ ½ ¾ ¿ À Á¿ Ã Ä ¼ ½ Å Å ¿ ¼ é uma componente lançada, durante o traço, pela Æ Ç È É Ê Ë ÉÇ È Ì da

aplicação na mesma máquina em que esta se executa e é responsável por manter uma lista das localizações dos ficheiros de traço na MV, informação que as ÍÎ Ï Ð Ï gerais lhe enviam no decorrer

desta fase. Encarrega-se igualmente de recolher esses ficheiros para a sua máquina após o traço e de os atribuir, durante a reexecução, às ÑÒ Ó Ô Ó gerais que lho solicitem.

O trfg é uma ÕÖ × Ø PVM lançada quando a rotina pvmbeatask() é executada por uma

Ù Ú Û ÜÝ Þ ÜÚ Û ß

em fase de traço. Porém, pode também ser lançada manualmente quando se inicia uma sessão de reexecução em que o à á â ã da fase de traço já não está activo.

Como esta componente é executada também durante a fase de traço, foi projectada de modo a interferir o menos possível com as aplicações. Em particular, depois de receber e processar cada mensagem, envia a si mesma um sinal Unix para "dormir". Cabe então às äå æ ç æ que com ela

comuniquem, o envio de um sinal para a "acordar". Também por esta razão, quando uma aplicação termina, é normal o è é ê ë continuar “adormecido”. Se logo de seguida se pretender

efectuar uma reexecução, este processo é acordado passando a recolher os ficheiros de traço; caso contrário, executa-se o comando ì í î ï î ðñ (ver 3.5) que acorda o ò ó ô õ o qual procede à

referida recolha de ficheiros e, em seguida, termina.

Só quando recebe uma mensagem cujo primeiro inteiro (a sua ö ÷ ø ) é ù ú û ü ý þ ÿ þ ü ù ou

              

, o     procede à recolha dos ficheiros de traço que constam da

lista de localizações construída durante o     . Os ficheiros de traço são copiados para a

máquina onde está a ser executado o     , através de um        ! " (# $ % ), presente na

generalidade dos sistemas UNIX. É também por & ' ( que os ficheiros de traço são entregues às

)* + , +

durante a reexecução. Se, ao iniciar o processo de reexecução, os ficheiros de traço ainda não tiverem sido recolhidos, o primeiro pedido de um ficheiro de traço para uma -. / 0 ,

despoletará a recolha dos ficheiros de traço pendentes.

Como efeito lateral da sua execução, cria um ficheiro temporário na sua máquina contendo o seu 12 3 4 5 6 , para que outras 78 9 : 9 desejando enviar-lhe uma mensagem PVM saibam endereçá-la.

Se terminar de forma não abrupta, remove esse ficheiro.

As ; < = > = que enviem mensagens para o ? @ A B devem enviar-lhe um sinal SIGCONT depois da

mensagem, para que a CD E F "acorde" e a possa processar.

A estrutura do G H I J consiste num ciclo infinito aqui apresentado resumidamente:

LOOP {

kill(mypid, SIGSTOP); /* dormir para não ocupar recursos */

/* receive com timeout para diminuir as probabilidades de se perderem mensagens*/

while( trecv(-1, AVTRFG_PTR_MSG, timeOut) ) { switch( ... upkint(action) ... )

case AVTRFG_GIVE_ME: /* duma KL M N na reexecução */

{ if( ainda há ficheiros de traço por recolher ) recolher ficheiros de traço;

(11)

rcp um ficheiro de traço e responder à task; } break;

/* controle de concorrência */

case AVTRFG_CHECK_MARK:

if( nenhum markfile existe e é possível criá-lo ) responder OK;

break;

case AVTRFG_PTR: /* localização de um ficheiro de traço */

guardar localização para mais tarde; break;

case AVTRFG_GRAB:

{ recolher ficheiros de traço;

limpar a lista de localizações; } break;

case AVTRFG_GRAB_AND_EXIT: {

{ recolher ficheiros de traço;

limpar a lista de localizações; }

case AVTRFG_EXIT: pvm_exit(); etc. }

} /* LOOP */

O P Q R S T U V W XYV Z [ S T \ \ V S ] X^ XZ _ V S ` a S W b W X ^ c

É um pequeno programa que envia uma mensagem AVTRFG_GRAB_AND_EXIT (e respectivo sinal para acordar) ao d e f g , para que este recolha os ficheiros de traço que estejam na

sua lista, e termine. Útil para o final de uma fase de hi j k l em que não haja a intenção de

prosseguir para a respectiva reexecução.

m n o p q r st u vr w x u q y z {z s{| t u } r s {z ~  € m nr  ‚‚ ƒ

Neste parágrafo são descritas as alterações efectuadas a rotinas da biblioteca base do PVM, relativas à fase de reexecução.

Pressupõe-se que, numa reexecução, a „ … † ‡ˆ ‰ ‡… † Š da aplicação é lançada na mesma

(12)

 ‘  ’ “ ” • – •— ˜ ™ š › œ  ž Ÿ —   ¡ •” •¢ £ ¤

A tarefa principal de uma ¥ ¦ § ¨ quando se inicia na fase de reexecução, é assumir o seu papel

de ©ª « ¬ réplica. Isso é conseguido usando o mesmo ficheiro executável e o ficheiro de traço

gerado pela ­® ¯ ° que está a ser replicada.

Para que a reexecução se processe correctamente é necessário que cada ±² ³ ´ siga os eventos

de um e um só ficheiro de traço. Contudo, várias µ¶ · ¸ · podem competir pelo mesmo ficheiro de

traço.

No caso de ¹ º » ¼ » não gerais, isto é, que são lançadas numa máquina específica, a procura de

um ficheiro de traço é exclusivamente local. No caso de ½ ¾ ¿ À ¿ gerais, aquela busca implica a

colaboração do Á Â Ã Ä .

Em qualquer dos casos, ÅÆ Ç È Ç gerais ou não gerais, a procura é feita localmente na directoria

dos ficheiros de traço usando a combinação de dois mecanismos; um, a colocação de trincos nos ficheiros de traço na sua abertura -se já estiverem trancados, estão ocupados, e devem ser ignorados-, e o outro é a criação de um ficheiro "marca" (doravante É Ê Ë ÌÍ ÎÏÐ ), sempre que se

consiga colocar um trinco num ficheiro de traço correspondente à Ñ Ò Ó Ô . Este último mecanismo

garante que um ficheiro de traço que já foi libertado (por exemplo, porque a ÕÖ × Ø já terminou)

não é atribuído a nenhuma outra Ù Ú Û Ü na mesma reexecução.

Mesmo que se consiga colocar um trinco num ficheiro de traço, este só fica atribuído se não existir já o respectivo Ý Þ ß àá âãä , e se fôr possível criá-lo. Depois de libertar o trinco a existência

do å æ ç èé êë ì para o ficheiro de traço encontrado garante que este não será atribuído a nenhuma

outra í î ï ð .

Para diferenciar entre ñ ò ó ô õ ö÷ ø ù de reexecuções diferentes, usa-se um identificador de

reexecução, ú û ü ýþ ÿ  , que não é mais que uma marca temporal conhecida de todas as     

durante a respectiva reexecução.

Para o caso das     gerais, estas procuram também nas suas máquinas um ficheiro de traço

adequado, mas ao contrário de se limitarem a verificar se o respectivo   existe, interrogam

o     sobre a sua existência, apenas criando o       em caso de resposta negativa, pois tal

significa que nenhuma outra   ! geral obteve ainda aquele ficheiro de traço. Desta forma, a

atribuição de ficheiros de traço a " # $ % $ gerais é centralizada no & ' ( ) que segue localmente todos

os passos relativos à atribuição de trincos e verificação da existência de * + , -. /01 2 .

Se não encontrarem localmente um ficheiro de traço adequado, as 34 5 6 5 gerais pedem então

ao 7 8 9 : um ficheiro de traço que o coloca na máquina da ;< = > , mas com o nome do respectivo

? @ A BC DEF

. Restará então à GH I J copiar o conteúdo desse K L M NO PQR para o respectivo ficheiro de

traço, e esvaziar o S T U VW X YZ . Com este artifício, garante-se que, numa reexecução, não existem

ficheiros de traço atribuídos a [\ ] ^ ] sem a existência dos respectivos _ ` a b c de f g .

h ij ik l m n o p l q r s t u v l m n o n w x y z t u { l m n o |s |} p ~ s  t u v ~ l m n o ~ € |} t u

O comportamento é idêntico às rotinas correspondentes de ‚ ƒ „ … , mas neste caso é verificado

o evento contra o ficheiro de traço, e a informação passada por † ‡ ˆ ‰ Š † ‹ Œ  inclui o Ž   ‘’ “ ” • .

(13)

£ ¤¥ ¤£ ¦ § ¨ © ª« ¬­ ®¯ ° ± § ² ³

Para além de verificar o evento à entrada da rotina (no ficheiro de traço correspondente), antes do consumo, estas rotinas obtêm do ficheiro de traço o ´ µ¶ da · ¸ ¹ º emissora da mensagem

original. Assim, só será aceite a mensagem da »¼ ½ ¾ réplica que corresponda à mensagem da ¿À Á Â

emissora original. Quando é consumida uma mensagem, é então desempacotado o à ÄÅ da ÆÇ È É

origem, empacotado nas rotinas instrumentadas, e a mensagem só é aceite se o Ê ËÌ coincidir com

o da entrada no ficheiro de traço. Caso contrário, a mensagem não é consumida e a rotina continuará à espera da mensagem adequada. Se no traço não tiver havido consumo de mensagem, o que pode ser usual numa recepção não bloqueante, o mesmo acontecerá na reexecução.

Í Î Ï Ð Ñ Ò Ð Ó Ô Õ Ò Ö ×Ó ×Ø Ð Ù Ú Û

A definição das seguintes variáveis de ambiente é fundamental: Ü Ý Þ ß à á á â , que indica a

raíz da distribuição do PVM, e ã ä å æ ç è é ê , que indica qual a arquitectura da máquina -de

acordo com a respectiva designação no ambiente PVM. Poderá ser também necessário alterar a definição da variável de ambiente ë ì í î ï ð ð ñ no ficheiro Makefile.aimk existente na

directoria src/.

Uma maneira comum de ter estas variáveis de ambiente definidas, é colocar a sua definição num ficheiro do tipo .profile (consoante a ò ó ô õõ usada).

ö ÷ ø ù ú û ü ý þÿ  ú  ÿ    ÿ û    ÿ

A ferramenta é distribuída num ficheiro comprimido, que deve ser descomprimido para uma directoria à escolha do utilizador. A distribuição imita, tanto quanto necessário, a estrutura da distribuição do próprio PVM. Na directoria src/, abaixo da raíz da directoria escolhida, dever-se-á executar aimk2 all para recompilar a ferramenta, ou aimk install para recompilar e instalar. A instalação das bibliotecas é feita na directoria lib/$PVM_ARCH abaixo da raíz da directoria escolhida para a ferramenta.

                

Para recompilar qualquer aplicação que utilize as bibliotecas PVM, há a considerar duas etapas: as fases de traço e reexecução. Em qualquer dos casos, bastará ligar a aplicação à biblioteca adequada a cada etapa, em vez da biblioteca base      ! . Assim, para a etapa de

traço, a biblioteca é " #$ % & ' ( ) * & ) + , * - . /* , e para a reexecução, 01 2 3 4 5 6 7 8 4 7 9 : 3 08 ; <8 . Estas

bibliotecas são instaladas na directoria lib/$PVM_ARCH abaixo da raíz da directoria escolhida para a ferramenta.

2

(14)

G H I J K L M N O P Q R S T S U VWM S O X L T

Y Z[ Z \ ] ^ _ ` a

É aconselhável dar um nome aos traços, atribuindo um valor à variavel de ambiente

b c d e f g b h i

, para que não sejam atribuídos ficheiros sem sentido (isto é, de outras aplicações) a jk l m l da fase de reexecução.

• É importante, mas não essencial, que todos os executáveis corram na directoria n o p q r de

cada máquina, para que a variável de ambiente s t u v w x y z w (que indica onde são escritos

os ficheiros de traço) faça sentido em todas as máquinas. Uma alternativa é usar para

{ | } ~  €  ‚ 

um valor da forma ″/tmp/...″.

• Para que uma variável de ambiente possa passar do ambiente da ƒ „ … †‡ ˆ ‰ Š ‹ Œ para o ambiente

das Ž    lançadas, é necessário não só que esteja definida, como também que seja incluída

na definição da variável de ambiente ‘ ’ “ ” • – ‘ — ˜ ™ . Exemplo: para a variável de ambiente

š › œ

, é necessário fazer PVM_EXPORT=ABC. As variáveis  ž Ÿ    ¡ ¢ £ ¤ , ¥ ¦ § ¨ © ª ¥ « ¬

e ­ ® ¯ ° ± ² ³ ´ ± são sempre passadas.

• Em particular, a variável de ambiente µ ¶ · ¸ µ ¹ º » ¼ tem de ser nula (″″), de forma a que a

½ ¾ ¿ ÀÁ Â À ¾ ¿ Ã

saiba que não foi lançada por pvm_spawn(). • Executar a Ä Å Æ ÇÈ É ÊË Ì Í , na directoria Î Ï Ð Ñ Ò .

• Quando a aplicação terminar em condições “normais” (isto é, sem erros que impliquem a terminação de ÓÔ Õ Ö Õ ou suspensão do processo de × Ø Ù Ú Û nalguma delas), só será necessário

terminar o Ü Ý Þ ß a partir da linha de comando, para que este recolha as localizações pendentes

dos ficheiros de traço das à á â ã â gerais, se não se proceder de imediato à etapa de reexecução.

ä åæ åç è é é ê é ë ì í î ï

• É necessário ligar a aplicação à biblioteca PVM instrumentada ðñò ó ô õ ö ÷ ø ô ÷ ù ú ó ðø û üø .

• É necessário que o ý þ ÿ  þ (    ) esteja em execução, pois este é responsável por entregar os

ficheiros de traço às    gerais que o solicitem. Assim, se o tiver sido terminado após o

fim da etapa de traço, é necessário lançá-lo manualmente na máquina onde será lançada a

    

   . No entanto, é possível lançar o     em qualquer máquina da MV, desde que

existam permissões de execução de    , nessa máquina, sobre todas as outras máquinas da

MV.

• Executar a aplicação.

  ! " # $ % & '(% ) * " # + + % " , - " & .

Esta componente é automaticamente lançada na etapa de traço após a qual continua activa. Assim é comum ter-se o mesmo processo / 0 1 2 num traço e numa reexecução consecutivos.

Quando estas fases não são consecutivas, o 3 4 5 6 é terminado após a primeira e lançado antes da

segunda.

(15)

trfg tracename hostname|NONE [localTraceFilesDirectory]

• tracename é o nome associado ao traço.

• hostname ou NONE indica o nome da máquina onde o 7 8 9 : se executou na etapa de traço,

ou simplesmente se não foi possível obter o nome da máquina naquela etapa.

• localTraceFilesDirectory é a directoria onde estão recolhidos os ficheiros de traço.

; < = > ? @ A B C DEB F G ? @ H H B ? I DJ DF K B ? L M ?C N C DJ

Esta componente -que é também uma OP Q R PVM- procura o S T U V W X YZ W [ \ ] ^ _ _ ` ] (a b c d ), através

do seu e f g , envia-lhe uma mensagem com o código h i j k l m n m k h o n h p q n r s t j , indicando

que é necessário recolher os ficheiros de traço pendentes das várias u v w x w e terminar.

A sintaxe da linha de comando desta componente é a seguinte:

trfgfin [-?|-help] [-xtid HEXTID] [-tid TID] [-host HOSTNAME] [-trname TRACENAME]

• Se -xtid ou -tid forem dados na linha de comando (representando o y z { do | } ~  ),

HOSTNAME e TRACENAME , se fornecidos serão ignorados, pois estes são necessários apenas

para encontrar o ficheiro do €  ‚ ƒ que contém o seu „ … † .

‡ ˆ ‰ Š‹ Œ  Š Ž  

São vários os ficheiros gerados pelas várias componentes envolvidas no processo de traço e reexecução. Nesta secção são descritos detalhadamente os vários ficheiros.

‘ ’ “ ” • – —˜ ™ š › • • œ œš ˜

Em cada máquina, existe um ficheiro que regista os erros das várias aplicações que correm como ž Ÿ   Ÿ PVM, naquela máquina. Mais concretamente, o ficheiro regista o stderr daquelas

¡¢ £ ¤ £

. O nome deste ficheiro é

/tmp/avtrpl[.hostname].userid

• É neste ficheiro que se registam os erros relacionados com a actividade de traço: impossibilidade de registar um evento no ficheiro de traço, impossibilidade de obter algum elemento necessário à actividade de traço (getlogin(), gethostname(), por exemplo), entre outros.

• Se não for possível criar ou escrever para este ficheiro, os conteúdos das mensagens que nele deveriam ser registadas são enviados para o stderr do processo.

• O hostname não estará presente se for impossível obtê-lo do sistema (gethostname()).

• userid é o do utilizador onde é executado o ¥ ¦ § ¨ © ª PVM (« ¬ ­ ® ).

(16)

¯ ° ± ² ³ ´ µ ¶ · ¸¹¶ º » ³ ´ ¼ ¼ ¶ ³ ½ ¾ ³ · ¿ À

Esta componente cria um ficheiro, que só existe enquanto está a ser executado, e que contém apenas o seu ÁÂ Ã Ä Å Æ (Ç ÈÉ ). Quando termina sem erros, elimina o ficheiro. O nome completo deste

ficheiro é:

/tmp/trfg.[$AV_TRNAME|AVAN].[hostname.]userid

• AVAN aparece no lugar do nome do traço sempre que a variável de ambiente Ê Ë Ì Í Î Ï Ê Ð Ñ

não esteja definida.

• O hostname não estará presente se for impossível obtê-lo do sistema (gethostname()).

• userid é o Ò Ó Ô Õ Ö× do utilizador onde está a correr o Ø Ù Ú Û Ü Ý PVM.

• Estes ficheiros existem apenas durante a execução de um processo Þ ß à á âã äåâ æ ç è é ê ê ë è (ì í î ï ),

a não ser que este termine abruptamente.

• O conteúdo deste ficheiro é apenas o ðñ ò ó ôõ do processo ö ÷ ø ù que o escreve, em formato

hexadecimal.

ú û ü ý þÿ  þ            þ  

Os ficheiros de traço tem o seguinte nome:

tracedir/tr.tracename-[hostname-][processName-]pid

• tracedir é o valor da variável de ambiente          , caso esteja definida, ou

/tmp/av_tracefiles ou . (directoria onde é executado o processo).

• tracename é o valor da variável de ambiente           , caso esteja definida, ou

AVAN. AVAN representa um  ! " # sem nome atribuído (anónimo).

• O hostname não estará presente se for impossível obtê-lo do sistema (gethostname()).

• processName é o nome do ficheiro executável da $% & ' (de acordo com a visão do PVM,

obtida por pvm_tasks()), ou XMANX, se a visao do PVM for "" (cadeia de caracteres vazia), indicando que aquela () * + foi lançada sem ser por pvm_spawn(). Como não é

alterado nenhum código de aplicação que se ligue com estas bibliotecas, não é possível às suas rotinas acederem a argv[0] das , - . / . , e daí o recurso a pvm_tasks().

• Se a 01 2 3 for "geral", processName tem o prefixo GEN_ (exemplo : GEN_dowork).

• 4 5 6 é o 7 8 9 : ; < < = > do processo executado (obtido por getpid()).

? @ A B C D E F E G D D H I J K LME H N N C O LH F C H G D K LO P E LI C F E Q I H R C

O nome de um S T U VW XYZ é idêntico ao de um [ \] ^ _ \ ` a b _ c` d e a , mas com o prefixo replayID.

(incluindo o “.”).

• replayID é o identificador de reexecução, calculado pela f g h ij k l m n o (é um pq r s t u vw x w y

indicando o tempo corrente), e passado sempre por pvm_spawn() na variável de ambiente

z { | } z ~  € 

(17)

‚ ƒ ‚ „ … † ‡ ˆ ‰ ˆ Š … ‹ Š Œ Ž   ‡ ‹ Š ‰  † ‡ˆ ‘ ‹

Descrevemos agora o formato das entradas que as ’ “ ” • ” escrevem nos ficheiros de traço, para

os vários eventos registados. No ficheiro de traço cada linha começa com o – — – ˜ ™ š › œ ˜ ™–  (ž Ÿ ) do

processo. Este contador é incrementado sempre que é invocada uma das rotinas instrumentadas. As entradas são apresentadas de acordo com a rotina de biblioteca onde ocorrem. Algumas rotinas escrevem mais do que uma entrada. Por conveniência textual, algumas entradas são apresentadas em duas linhas; no entanto, no ficheiro de traço, cada entrada ocupa apenas uma linha.

• pvmbeatask():

ec: PVM enrollment successful.\n

- Esta rotina não é visível às aplicações, mas é executada sempre que um processo se torna numa  ¡ ¢ £ PVM).

• pvm_mytid():

ec: pvm_mytid [tid=TID]\n

- TID indica a ¤¥ ¦ § ¨© da ª« ¬ ­ , em formato hexadecimal.

• pvm_spawn():

ec: pvm_spawn HOWMANY*[PROC] [flags=FLAGS] [COMPL] [PLACE = WHERE]...SUC successful.\n

- HOWMANY é o número de cópias pedidas da ®¯ ° ± (decimal).

- PROC é o nome do processo a lançar.

- FLAGS são as ² ³´ µ ¶ passadas a pvm_spawn() (hexadecimal).

- COMPL, tem o valor Compl ou "" (sem as aspas), conforme em FLAGS o bit

correspondente a PvmHostCompl esteja · ¸ ¹ ou não, respectivamente.

- PLACE reflecte o tipo de FLAGS: será Host, Arch ou Default.

- WHERE é o parâmetro where de pvm_spawn() ou, sendo este nulo, "?".

- SUC é o número de cópias da º » ¼ ½ que o PVM conseguiu lançar (decimal).

• pvm_[p]recv():

- Tem sempre duas entradas:

ec: pvm_recv [requested tid=RTID] [requested tag=RTAG]...\n

ec: ... pvm_recv failure(CODE)\n ou

(18)

ec: ... pvm_recv [pid=SPID] [tid=STID] [tag=STAG]\n

- RTID, RTAG, SPID, SPROC, STID, STAG e CODE são decimais.

- SPID é o ¾ ¿ À Á Â Ã Ã Ä Å da ÆÇ È É origem da mensagam.

- Para os restantes parâmetros, consultar o manual PVM.

• pvm_nrecv():

- Tem sempre duas entradas:

ec: pvm_nrecv [requested tid=RTID] [requested tag=RTAG]...\n

ec: ... pvm_nrecv failure(CODE)\n ou

ec: ... pvm_nrecv 0\n ou

ec: ... pvm_nrecv [pid=SPID] [tid=STID] [tag=STAG]\n

- RTID, RTAG, SPID, SPROC, STID, STAG e CODE são decimais.

- SPID é o Ê Ë Ì Í Î Ï Ï Ð Ñ da ÒÓ Ô Õ origem da mensagam.

- Para os restantes parâmetros, consultar o manual PVM.

-A segunda alternativa da segunda entrada dá-se quando no momento da chamada não tiver chegado nenhuma mensagem que satisfaça RTID e RTAG.

• pvm_trecv():

- Tem sempre duas entradas:

ec: pvm_trecv [requested tid=RTID] [requested tag=RTAG] [timeout=SEC.MSEC]...\n

ec: ... pvm_trecv failure(CODE)\n ou

ec: ... pvm_trecv 0\n ou

ec: ... pvm_trecv [pid=SPID] [tid=STID] [tag=STAG]\n

- RTID, RTAG, SEC, MSEC, SPID, SPROC, STID, STAG e CODE são decimais.

- SPID é o Ö × Ø Ù Ú Û Û Ü Ý da Þß à á origem da mensagam.

- Para os restantes parâmetros, consultar o manual PVM.

- A segunda alternativa da segunda entrada dá-se quando passado o tempo limite não tiver chegado nenhuma mensagem que satisfaça RTID e RTAG.

(19)

• pvm_exit():

ec: pvm_exit failure(CODE)\n ou

ec: pvm_exit PvmOk\n

- CODE é o código de erro (decimal).

â ã ä å æ ç è éê ë å æ å ì í îï í æ

A nível da implementação da ferramenta consideramos que existem as seguintes restrições e falhas:

• Os nomes das ðñ ò ó ò passadas para pvm_spawn() não devem conter caminhos, mas

apenas um nome inteiro.

• Deve existir ô õ ö ÷ øõ ù ú û ü (ý þ ÿ ) padrão nas máquinas onde se corram as aplicações.

Mais ainda, a(s) máquina(s) onde correr o    devem ter (permissões de) acesso por

  

a todas as outras máquinas.

• Quando ocorra qualquer erro que impossibilite a continuidade seja do  como do

reexecução, a aplicação muito provavelmente falhará, pois poderão ainda existir mensagens não recebidas com o  empacotado pelas rotinas instrumentadas, e que

serão consumidas por rotinas que não estão à espera de o encontrar.

• Nas maquinas onde getlogin() não devolve nada, o     pode não funcionar

correctamente se as      nelas lançadas forem gerais, e o         do PVM nessa

máquina for diferente do   ! " # $ da % & ' () * + , - . da aplicação.

• Na impossibilidade de obtenção dum / 0 1 23 4 5 6 (gethostname()), tanto o 78 9 : ;

como a reexecução podem não funcionar correctamente.

• < = > ? : se chegar um sinal Unix SIGCONT (para "acordar") quando esta @ A B C está

acordada, e a correspondente mensagem chegar antes de ir "dormir", esta só será consumida quando chegar outro sinal.

D E F G H I JK L M N L

Como já foi referido, o mecanismo de reexecução apresentado é uma das componentes de uma ferramenta de apoio ao depuramento de aplicações distribuídas constituídas por colecções de processos que comunicam entre si utilizando o paradigma da troca de mensagens. Assegurando a resolução correcta das condições de corrida, consegue-se reproduzir tantas vezes quantas as necessárias uma execução original de uma aplicação, facilitando assim o complexo processo de depuração.

Tal como se encontra implementado, o mecanismo descrito permite que o processo de depuração seja efectuado em tempo de reexecução ou em modo O P Q R ST P U RV T W

(20)

X Y Z [ \ [ ] ^ _ ` ab c [ d a e f ag h ] b \ ab

[Cláudio98] Cláudio, A., Cunha, J., Carmo, M.: Debugging of Message Passing Parallel Applications: a General Tool. Proceedings of VECPAR ’98 - 3rd International Meeting on Vector Parallel Processing, Porto, June 1998

[Cláudio99] Cláudio, A., Cunha, J., Carmo, M.: MPVisualizer: A General Tool to Debug Message Passing Parallel Applications. Proceedings of HPCN’99 (LNCS 1593), Amsterdam, Abril 1999

[Curry89] Curry, D.: Using C on the UNIX System. O'Reilly & Associates, Inc., 1989

[Lamport78] Lamport, L.: Time, Clocks, and the Ordering of Events in a Distributed System. Communications of the ACM, Vol. 21, No. 7, Julho 1978

[Leblanc87] Leblanc, T., Mellor-Crummey, J.: Debugging Parallel Programs with Instant Replay. IEEE Transactions on Computers, Vol C-36, No. 4, Abril 1987

[Geist94] Geist, A. et al: PVM 3 User’s Guide and Reference Manual. Oak Ridge National Laboratory, ORNL/TM-12187, May 1994

[Geist96] Geist, A.,Kohl, J., Papodopoulos, P.: PVM and MPI: a comparison of features. Calculateurs Paralleles, Volume 8(2), 1996

[Skillicorn98] Skillicorn, D., Talia, D.: Models and Languages for Parallel Computation. ACM Computing Surveys, Vol. 30, No.2, June 1998

Imagem

Figura 1- As três componentes da ferramenta MPVisualizer.

Referências

Documentos relacionados