47
Introdução à programação em Ada 2005 Luís Miguel Pinho Instituto Superior de Engenharia do Porto Outubro de 2006

Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Embed Size (px)

Citation preview

Page 1: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005

Luís Miguel Pinho

Instituto Superior de Engenharia do Porto

Outubro de 2006

Page 2: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 1

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

Índice

ÍNDICE.......................................................................................................................................................... 1

1. BREVES NOTAS...................................................................................................................................... 2

2. TIPOS DE DADOS................................................................................................................................... 4

3. OPERADORES......................................................................................................................................... 8

4. BLOCOS.................................................................................................................................................... 9

5. DECISÕES .............................................................................................................................................. 10

6. CICLOS................................................................................................................................................... 12

7. SUBPROGRAMAS ................................................................................................................................ 14

8. EXCEPÇÕES.......................................................................................................................................... 17

9. ESTRUTURA DE PROGRAMAS ........................................................................................................ 19

10. ENTRADA E SAÍDA............................................................................................................................ 22

11. MODELO DE CONCORRÊNCIA ..................................................................................................... 25

12. TAREFAS.............................................................................................................................................. 27

13. RENDEZVOUS..................................................................................................................................... 31

14. RELÓGIOS E TEMPORIZADORES ................................................................................................ 35

15. ATRASOS ............................................................................................................................................. 36

16. SYNCHRONOUS/ASYNCHRONOUS TASK CONTROL.............................................................. 38

17. INTERFACES....................................................................................................................................... 39

18. O PERFIL RAVENSCAR.................................................................................................................... 40

19. BIBLIOGRAFIA E RECURSOS ONLINE........................................................................................ 46

Page 3: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 2

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

1. Breves notas

- Em 1973 o Departamento de Defesa Norte-Americano (DoD), recenseou 450 linguagens diferentes.

- Da avaliação das linguagens existentes em 1976 contra um conjunto de requisitos encontrados resultou:

- Nenhuma cumpria os requisitos

- Uma única linguagem era desejável

- O desenvolvimento era possível e devia começar de uma linguagem existente, sendo as recomendadas: Pascal, PL/I e ALGOL 68 (note-se a ausência do C)

- Foi escolhida a linguagem Pascal

- Em 1983 foi normalizada a linguagem Ada, verificando-se, no entanto, alguma desilusão com o seu suporte a Sistemas de Tempo Real.

- A linguagem não incorporava alguns dos avanços da altura em termos de escalonamento de Sistemas de Tempo Real.

- Portanto, em 1995 a primeira revisão da linguagem foi ao encontro das críticas e foi normalizada a linguagem Ada 95.

- Foi a primeira linguagem normalizada com suporte a orientado a objectos e sistemas de tempo-real

- Em 2000 iniciaram-se os trabalho de uma nova revisão da linguagem para incorporar avanços em diversas áreas (principalmente OO e STR)

- Suporte ao perfil Ravenscar (eficiência, simplicidade e previsibilidade), a prioridades dinâmicas e hierárquicas, interfaces

- Embora o nome seja Ada 2005, não é uma nova norma mas sim um “Amendment” (Ada 95 Amendment 1).

- O nome da linguagem é uma homenagem a Ada Lovelace (filha de Lord Byron), que foi assistente de Charles Babbage, o homem que inventou o primeiro computador (computador mecânico).

- Existe uma certa celeuma se foi Ada Lovelace ou Charles Babbage a primeira pessoa programadora da história. No entanto, Ada Lovelace foi de certeza a primeira mulher programadora da história.

- A norma (ISO/ANSI) impõe um núcleo da linguagem, mais um conjunto de Anexos especializados (Sistemas de Tempo Real, Sistemas Distribuídos, Sistemas de Informação, etc.).

- Os anexos definem bibliotecas e características de implementação, não acrescentam sintaxe nem vocabulário)

- Qualquer compilador de Ada tem que ser validado por empresas certificadas, tendo que cumprir a norma, mas podendo não cumprir certos anexos.

- A linguagem especifica também o seu próprio executivo, permitindo utilização mesmo sem Sistema Operativo.

Page 4: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 3

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

- O compilador GNAT é talvez compilador mais utilizado (GNAT significa GNAT - não é um acrónimo)

- É de graça

- Existe para várias plataformas (Windows, Linux, etc..)

- É bastante eficiente (o backend é o GCC)

- Os identificadores podem conter letras, dígitos, ou o caracter “underscore” ( ‘_’ )

- Não podem começar por dígitos

- Podem ter palavras acentuadas

- Não existe distinção entre maiúsculas e minusculas

- If é igual a if e igual a IF

- Os números podem ter o caracter ‘_’, para ajudar a leitura

- Por exemplo 1234567 pode ser representado 1_234_567

- Os comentários começam com -- e são até ao final da linha

- Todas as instruções têm que levar ponto-e-vírgula (;) no fim

- Várias instruções podem vir na mesma linha, desde que separadas por ;

- Não há diferença entre um espaço, ou 20 espaços, ou um fim de linha

Nota: A partir deste momento a palavra Ada será utilizada para referir-se à norma de 1995, com os acrescentos de 2005. Se necessário, quando se referir à norma de 1983, será utilizado Ada 83 e a de 1995 será utilizada Ada 95.

Page 5: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 4

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

2. Tipos de dados

- Um tipo de dados é um conjunto de valores com um conjunto de operações primitivas associadas

- Pode-se criar um novo tipo

- Pode-se criar um novo tipo derivado de outro

- O novo tipo “herda” as operações do outro

- Mas os tipos são completamente independentes

• Por exemplo não se pode comparar varáveis de um com variáveis do outro

- Pode-se criar um subtipo

- O subtipo pode ser utilizado conjuntamente com o Pai

• Mas há restrições

• Geralmente é utilizado para efectuar restrições de gama ou precisão

- Tipos discretos

- Enumerados:

- Boolean (predefinido)

- Character (predefinido) -> não é um inteiro, mas sim uma enumeração

- type Modo is (Manual, Automatico);

- type All_Days is (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday);

- subtype Week_Days is All_Days range Monday .. Friday;

- Inteiros com sinal

- Integer (predefinido)

- type Index is range 1..10;

- Inteiros modulares

- Ada não tem inteiros sem sinal, pois facilmente se pode criar um com o range

- Ada tem os chamados tipos modulares em que se especifica o valor máximo, e que fazem “wrap” automaticamente

- type Byte is mod 256;

• Qualquer valor do tipo Byte vai de 0 a 255 ( wrap: 255 + 1 dá 0, tal como 0 - 1 dá 255)

- Tipos Reais

- Vírgula flutuante

- Float (predefinido)

- type Length is digits 5 range 0.0 .. 100.0;

- Vírgula Fixa

- type Voltage is delta 0.125 range 0.0 .. 5.25;

- type Money is delta 0.01 digits 15;

Page 6: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 5

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

- Ada é uma linguagem fortemente tipificada

- Significa que não é flexível como o C/C++

- Mas é muito mais seguro

- Não se pode usar valores de um tipo em operações de outro tipo sem efectuar uma conversão de tipo explícita

- Regras para subtipos são mais relaxadas

- Exemplos:

I: Integer := 2;

F: Float := 1.2;

-- ...

F:= F * I; -- incorrecto, tem que ser:

F := F * Float(I);

F: Float := 1; -- é incorrecto, tem que ser:

F. Float := 1.0; -- ou

F. Float := Float(1);

type Int is new Integer;

A: Integer;

B: Int;

-- …

A := B; -- incorrecto, tem que ser

A := Integer(B);

subtype Int is Integer range 1..10;

A: Integer;

B: Int;

-- …

A := B; -- não há problema

B := A; -- pode dar excepção, se A estiver -- fora da gama de valores -- de Int (1 .. 10)

- Tipos Compostos

- Arrays

- String (predefinido)

- type Matrix is array (1 .. 4, 1 .. 4) of Integer;

- Não há índice obrigatório para o início do Array (estilo o 0 em C)

- Pode-se usar others para referenciar os restantes elementos de um array

- Exemplo:

S: String(1..10);

S1: String(2..6);

M: Matrix;

-- ...

S := “1234567890”;

S1 := S(5..9); -- Desde que o número de elementos bata certo

M := ((1,2,3,4),(2,3,4,5),(3,4,5,6),(4,5,6,7));

M(1,2) := 3;

S1(3) := ‘X’;

S := (1 => ‘a’ , 5 => ‘z’, others => ‘0’);

Page 7: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 6

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

- Outro exemplo:

type Teacher is (Pinho, Tovar);

type Module is ( introduction, scheduling, languages,

dist_scheduling, fault_tolerance, development);

type Modules is array (Module) of Teacher;

STR: Modules;

-- …

STR := (languages => Pinho, development => Pinho,

fault_tolerance => Pinho , others => Tovar);

- Records (estruturas)

type Module is record

Prof: Teacher;

Duration: Positive;

end record;

M3: Module;

-- …

M3.Prof := Pinho;

M3 := (Pinho, 3);

M3 := (Duration => 3 , Prof => Pinho);

- Tipos de acesso

- Parecidos com apontadores (mas não são como os apontadores do C/C++ – não são inteiros)

- As variáveis a que se podem aceder têm que ser criadas dinamicamente

- Utiliza-se o . (ponto) tal como se não fosse tipo de acesso

- Excepto na atribuição do record todo de uma vez, em que se usa o .all

type Module is record

Prof: Teacher;

Duration: Positive;

end record;

type Access_Module is access Module;

access_M2 : Access_Module := new Module;

-- …

access_M2.Prof := Tovar;

access_M2.all := (Duration => 2 , Prof => Tovar);

Page 8: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 7

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

- Atributos

- Certos tipos têm atributos que podem ser utilizados para obter informação sobre o tipo

- Os atributos são referenciados através do caracter plica (‘)

- Atributos existentes que podem ser aplicados a tipos e variáveis

- Size (tamanho do tipo em bits)

- Length (tamanho do tipo em elementos - só para arrays)

- Range (gama - só para tipos discretos, reais e arrays)

– Este é interessante mas veremos apenas nos ciclos

- Atributos existentes que apenas podem ser aplicados ao tipo

- First(primeiro elemento - só para tipos discretos, reais e arrays)

- Last (último elemento - só para tipos discretos, reais e arrays)

- Pred (elemento anterior - só para enumerações)

- Succ (próximo elemento - só para enumerações)

- Val (Valor numa determinada posição - só para enumerações)

- Pos (Posição de um determinado valor - só para enumerações)

I: Positive;

type String_10 is new String(1..10);

S: String(1..10);

-- …

I := Positive’First; -- I fica com 1

I := Integer’Size; -- I fica com 32

I:= S’Length; -- I fica com 10

I := String_10’Size; -- I fica com

-- 10*8 = 80

type All_Days is (Monday, Tuesday, Wednesday,

Thursday, Friday, Saturday, Sunday);

subtype Week_Days is All_Days

range Monday .. Friday;

subtype Weekend is All_Days

range Saturday .. Sunday;

-- …

All_Days'Succ(Monday) = Tuesday

All_Days'Pred(Tuesday) = Monday

All_Days'Val(0) = Monday

All_Days'First = Monday

All_Days'Val(2) = Wednesday

All_Days'Last = Sunday

All_Days'Succ(All_Days'Pred(Tuesday)) = Tuesday

Page 9: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 8

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

3. Operadores

Nome Símbolo Exemplo

Atribuição := A := B

Aritméticos

Módulo Divisão mod B := A mod 2 Resto Divisão rem B := A rem 2 Valor absoluto abs B := abs A Exponenciação ** A := 2**8 Multiplicação * B := A * 2 Divisão / B := A / 2 Soma + B := A + 2 Subtracção - B := A – 2 Sinal positivo + A := + B Sinal negativo - A := - B;

Relacionais

Igualdade = if A = 3 Diferença /= if A /= 3 Maior > if A > 3 Menor < if A < 3 Maior ou Igual >= if A >= 3 Menor ou Igual <= if A <= 3

Lógicos

E lógico and if A>1 and B<2 and then if A>1 and then B<2 Ou lógico or if A>1 or B<2 or else if A>1 or else B<2 Ou lógico exclusivo xor if A>1 xor B<2 Negação not if A and not B

Outros

Pertença in if A in 1 .. 20 Concatenação & S := “A” & “BCD” Gama de valores .. 1 .. 10

Page 10: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 9

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

4. Blocos

- Blocos de instruções

- É possível definir em qualquer parte um bloco de instruções, que contém uma zona de declarações própria

bloco ::= [identificador :]

[declare

{declarações}]

begin

instruções;

end [identificador];

- Exemplos:

declare

F: Float; -- F é local ao bloco

begin

F := Obtem_valor();

F1 := F * 2.5; -- F1 vem de fora do bloco

end; -- F deixa de existir aqui

bloco_exterior: -- cada bloco pode ser identificado

declare

F: Float; -- F é local ao bloco exterior

begin

F := Obtem_valor();

bloco_interior:

declare

F2: Float := 3.0; -- F2 é local ao bloco interior

begin

F1 := F * F2; -- F1 vem de fora do bloco

end bloco_interior;

F1 := F1 + F2 * 2.0; -- Erro: F2 já não existe aqui

end bloco_exterior; -- F deixa de existir aqui

Page 11: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 10

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

5. Decisões

- Decisão se

Decisão-if ::=

if expressão-booleana then

instruções;

{elsif expressão-booleana then

instruções;}

[else

instruções;]

end if;

- Exemplos

if T <= 100.0 then

P := Max_ Power;

elsif T >= 180.0 then

P := 0. 0;

T := 180.0;

else

P := Control( R, t);

end if;

if estudei = true and then exame = facil then

Passei;

Festejar;

else

Estou_ca_para_o_ano;

end if;

- Nota: não se podem fazer atribuições dentro dos testes, só se pode ter expressões que dêem true ou false

estudei : Integer := 1;

if estudei and then exame = facil then -- errado, estudei não é booleano

Passei;

Festejar;

else

Estou_ca_para_o_ano;

end if;

Page 12: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 11

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

- Decisão caso

decisão-case ::=

case expressão-discreta is

alternativa

{alternativa}

end case;

alternativa ::= when lista => înstruções;

lista ::= opção {| opção}

opção::= expressão | intervalo | others

- Exemplo

case Dia is

when Segunda => Levantar_mal_disposto;

Inicio_Trabalho;

when Terça .. Quinta => Continuar_Trabalho;

when Sexta => Fim_Trabalho;

when others => Farra

end case;

- Nota: Tem que se prever todos os valores possíveis da variável. Ou então usar a alternativa others. Se não dá erro de compilação.

Page 13: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 12

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

6. Ciclos

- Há três tipos de ciclos

ciclo ::= [identificador :]

[esquema- de-iteração] loop

instruções;

end loop [identificador];

esquema- de-iteração ::=

for índice in [reverse] intervalo-discreto

|while expressão- booleana

- Exemplos

loop - - ciclo infinito

Adquire_valor_sensor;

Calcula_Controlo:

Actua;

end loop;

V: array(1 .. 10) of Integer;

-- ...

for I in 1 .. 10 loop

V(I) := Adquire_valor();

end loop;

V: array(1 .. 10) of Integer;

I : Integer := 1;

-- ...

while I <= 10 loop

Adquire_valor(V(I));

I := I + 1;

end loop;

- Notas:

- A variável I no ciclo for apenas existe dentro do ciclo for. E não é declarada.

- O atributo ‘Range (que já foi apresentado) pode ser utilizado num ciclo for para fornecer a gama de valores de um vector

• for I in V’Range loop

• Isso quer dizer que o mesmo ciclo pode ser utilizado para vectores de tamanhos diferentes, sem ser necessário guardarmos o tamanho do vector

Page 14: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 13

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

- Pode-se ter condições dentro do ciclo para sair

V: array(1 .. 10) of Integer;

-- ...

for I in 1 .. 10 loop

Valor:=Adquire_valor();

exit when Valor < 0;

V(I):=Valor;

end loop;

loop - - ciclo infinito

Adquire_valor_sensor;

Calcula_Controlo:

exit when controlo_incorrecto;

Actua;

end loop;

- O exit força a saída do ciclo para a primeira instrução seguinte

- Se tivermos ciclos encadeados

- O exit faz sair do ciclo mais próximo

- Ou então pode ser utilizado para indicar de qual ciclo queremos sair

• podemos dar nomes aos ciclos

V: array(1 .. 10) of Integer;

-- ...

ciclo_exterior:

loop - - ciclo infinito

for I in 1 .. 10 loop

Valor:=Adquire_valor();

exit ciclo_exterior when Valor < 0;

V(I):=Valor;

end loop;

Calcula_Controlo:

Actua;

end loop;

- Não existe continue em Ada

- Não há forma de continuar um ciclo saltando certas instruções

- Mas pode usar-se um if

- Existe goto, mas se quiserem passar à disciplina ...

Page 15: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 14

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

7. Subprogramas

- Existem dois tipos de subprogramas

- Procedimento (abstracção de uma acção)

- Função (abstracção de um valor)

- Ambos podem ter parâmetros

- Apenas as funções retornam valor

- E têm que retornar

- Um subprograma tem duas partes

- A especificação (define a interface - nome e parâmetros)

- O corpo (define a acção ou o algoritmo que é executado quando se invoca o subprograma)

- Se não for precisa a especificação pode ser omitida

- Neste caso o próprio corpo serve de especificação

declaração-de-subprograma ::=

especificação- de- subprograma;

especificação-de-subprograma ::=

procedure nome [parâmetros]

| function nome [parâmetros] return tipo_retorno

parâmetros::= (definição{; definição})

definição::= lista : modo tipo [:= valor_por_defeito]

lista ::= nome{, nome}

modo ::= [in] | out | in out

valor-por-defeito ::= expressão

- Exemplos de especificação

procedure Reset; -- Sem parâmetros

procedure Incrementa( Value : in out Integer;

Step : in Integer := 1);

function Minimo(X, Y : Integer) return Integer;

- Existem três formas de passar parâmetros

- in O parâmetro não é modificado dentro do subprograma

- (pode ter um valor por defeito)

- out O subprograma tem que atribui um valor ao parâmetro

- in out O subprograma pode modificar o parâmetro

Page 16: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 15

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

- As funções só podem ter parâmetros do tipo in

- Por defeito os parâmetros são do tipo in

- As formas de passar parâmetros não têm nada que ver com o método de passagem de parâmetros

- Parâmetros in podem ser passados por referência

- O compilador garante que não há alterações

- Parâmetros in out podem ser passados por cópia

- O compilador faz a cópia no início e no fim

- Temos que tomar algum cuidado com os parâmetros

- Se o parâmetro for do tipo out ou in out temos que passar uma variável para o subprograma (não pode ser um valor fixo)

- Se o parâmetro for do tipo in não o podemos modificar no subprograma

- Podem existir subprogramas com o mesmo nome

- Mas têm que se destinguir pelos parâmetros

- Ou, nas funções, também pelo tipo de retorno

- Corpo de subprogramas

corpo-de-subprograma ::=

especificação-de-subprograma is

{declaração}

begin

instruções;

end nome;

- O corpo tem uma parte inicial declarativa, onde se podem declarar variáveis locais ao subprograma

- Ou outros subprogramas, porque ao contrário do C/C++ (mas tal como o Pascal) em Ada pode-se declarar subprogramas dentro de subprogramas

- Uma função tem que ter pelo menos um return, e todos os caminhos possíveis dentro da função têm que atingir um return

Page 17: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 16

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

- Exemplos de corpos de subprogramas

type int_array is array(1..100) of Integer;

-- …

procedure Minimo_vector( vec: in int_array; Min: out Integer) is

function Minimo(X, Y : Integer) return Integer is

begin

if X < Y then

return X;

else

return Y;

end Minimo;

m: Integer := vec(vec’First);

begin

for I in vec’First +1 .. vec’Last loop

m := Minimo(vec(I) , m );

end loop;

end Minimo_vector;

- Invocação de subprogramas

- É uma simples expressão:

procedure Reset; -- Sem parâmetros

procedure Incrementa( Value : in out Integer;

Step : in Integer := 1);

function Minimo(X, Y : Integer) return Integer;

-- …

X : Integer := 1;

begin

Incrementa(X,2); --> associação posicional

Incrementa( Step => 2, Value => X); --> associação por nome

-- parâmetros podem ter qualquer ordem

Incrementa(X); -- > parâmetros por defeito

Reset; -- > se não tiver parâmetros

-- não é necessário colocar parênteses

Incrementa(X, Minimo(2,3) ); -- >funções podem ser usadas

-- em expressões (procedimentos não)

end;

Page 18: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 17

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

8. Excepções

- A linguagem Ada providencia mecanismos para processar erros em tempo de execução

- A acção por defeito quando uma excepção é levantada é terminar o programa (ou terminar a tarefa, se a excepção não for na tarefa principal)

- Se não queremos que termine temos que ter um processador de excepções (exception handler)

- Especifica quais as excepções a processar, e o que fazer quando ocorrem

- As excepções não devem ser utilizadas para situações normais e previstas, porque tornam o programa mais lento e imprevisível

- O sítio onde a excepção ocorre não pode ser facilmente determinado, o que pode obrigar a código muito complexo

- É possível desactivar as verificações em tempo de execução (utilizando a pragma Supress), o que deve apenas ser feito depois do programa estar completamente verificado (isto é possível?)

- Excepções predefinidas

- Constraint_Error

- Quando se tenta atribuir um valor for a do intervalo declarado

- Quando o índice de um array está fora dos limites

- Quando se usa um apontador nulo

- Quando se produz um erro numérico (por exemplo divisão por zero)

- Storage_Error

- Quando se tenta reservar memória dinâmica e não existe disponível

- Tasking_Error

- Quando uma tarefa tenta fazer rendezvous com outra que já terminou

- Quando existe uma excepção na elaboração de uma tarefa, a tarefa que criou essa tarefa recebe a excepção Tasking_Error

- Program_Error

- Quando existe um select em que todas as opções estão fechadas (as guardas dão falso)

- Quando uma tarefa fica bloqueada durante a execução de um subprograma de um objecto protegido

- Quando um objecto protegido é destruído, mas ainda existem tarefas nas filas de espera desse objecto, essas tarefas recebem a excepção

- Quando a avaliação de uma barreira numa entry de um objecto protegido resulta numa excepção, todas as tarefas bloqueadas no objecto recebem Program_Error

Page 19: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 18

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

- Processamento de excepções

- Define-se um “exception handler” no bloco do qual queremos processar as excepções

- Um bloco pode ser:

- Um subprograma

- Uma tarefa

- Um ciclo/if/etc…

- Blocos declarados no código

- when others é usado para apanhar todas as outras excepções

- Se o bloco onde ocorre a excepção não a processar esta é enviada ao bloco mais englobante

- E assim sucessivamente (o limite é a tarefa)

- Podemos dar um nome à ocorrência da excepção, para saber mais sobre ela

- A package Ada.Exceptions tem vários subprogramas para obter informação sobre excepções

begin -- incio do bloco -- …. exception -- exception handler when Contraint_Error => Processa_Excepcao; when Program_Error => Outro_Processamento; when Nome: others => Put(“Excepção sem nome:”); Put(Ada.Exceptions.Exception_Information(Nome)); end Teste; -- fim do bloco

Page 20: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 19

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

9. Estrutura de programas

- Os subprogramas são unidades de programa

- Existem outras: packages, tarefas e objectos protegidos

- Um package, é um módulo que contém declaração de tipos, variáveis, subprogramas e outros packages

- Os subprogramas também são unidades de compilação

- packages também são

- Um ficheiro fonte pode conter mais do que uma unidade de compilação

- O GNAT só permite uma unidade de compilação por ficheiro

- Os subprogramas e packages já compilados formam uma biblioteca de compilação

- Um programa executável forma-se a partir de uma biblioteca que inclua um procedimento principal

- O nome do procedimento não é fixo (no caso do GNAT é o nome do ficheiro fonte)

- Um programa Ada compõe-se de

- Um procedimento principal

- Outros subprogramas e packages escritas pelo utilizador

- Subprogramas e packages predefinidos (possivelmente já compilados)

- Quando se pretende utilizar um package é necessário utilizar cláusulas de contexto logo no início do ficheiro fonte

- Cláusula with (with nome_da_package;)

- Serve para assinalar que pretendemos utilizar aquela package

- Cláusula use (use nome_da_package;)

- Serve para assinalar que não queremos referenciar o caminho todo até aos elementos da package

- Como já referido packages podem conter outros packages

- Aos últimos chama-se filhos dos primeiros

- O nome do package é constituído pelo nome dos seus ascendentes separados por ponto

- Exemplo:

- Existe uma package Ada

- Tem uma package filha chamada Text_IO que contém os subprogramas de interface com a consola (para texto)

- Assim para referenciar a package Texto_IO da package Ada usa-se:

Ada.Text_IO

Page 21: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 20

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

-- O seguinte programa utiliza o procedimento Put da package Ada.Text_IO

-- para escrever uma String (“Hello World”) no monitor

with Ada.Text_IO;

use Ada.Text_IO;

procedure Hello_World is

begin

Put(“Hello World”);

end Hello_World;

-- Se não quisermos referenciar directamente o procedimento Put, podemos

-- omitir a cláusula use (agora temos que usar o caminho todo para Put)

with Ada.Text_IO;

procedure Hello_World is

begin

Ada.Text_IO.Put(“Hello World”);

end Hello_World;

- Ok, mas e agora? Como executar?

- A resposta depende um bocado de cada compilador

- como em qualquer linguagem

- No caso do GNAT a resposta é simples:

- O ficheiro fonte tem que ter a extensão .adb

- O ficheiro fonte só pode ter um procedimento (pode ter vários, desde que os outros estejam dentro do primeiro)

- O nome do procedimento tem que ser o nome do ficheiro

- Estas regras não são completamente obrigatórias, mas para já servem :)

-

- Portanto para executar o programa anterior (Hello World) utilizando o GNAT:

- Escrever aquele código num ficheiro de texto chamado hello_world.adb

- Executar o compilador: gnatmake hello_world

- Correr o programa: ./hello_world

Page 22: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 21

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

- Não é preciso passar ao compilador a extensão .adb (mas tem que existir)

- O compilador cria um executável com o nome do ficheiro fonte (sem o .adb)

- Para apenas compilar : gnatmake -c hello_world

- O compilador tem três fases:

• A fase de compilação propriamente dita (gnat1)

o Cria dois ficheiros: um .o (código objecto) e um .ali que contém informação que vai ser utilizada nas fases seguintes (conteúdo dos ficheiros fontes, relação entre ficheiros, timestamp, etc…)

• A fase de binding (gnatbind)

o Serve para verificar as relações entre ficheiros de compilação

• A fase de linkagem (gnatlink)

o Serve para criar o executável

Page 23: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 22

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

10. Entrada e Saída

- Como já referido existe um package que contém subprogramas para entrada/saída de texto (Ada.Text_IO)

- Put(Item: in String);

- Put_Line(Item: in String);

- Get(Item: out String);

- Get_Line(Item: out String; Last: out Integer);

- New_Line;

- Existem outras duas packages para Integer e Float

- Ada.Integer_Text_IO

- Put(Item: in Integer);

- Get(Item: out Integer);

- Ada.Float_Text_IO;

- Put(Item: in Float);

- Get(Item: out Float);

- Parece muita coisa (e é porque temos que referenciar cada uma em separado), mas o objectivo da linguagem Ada não é o de poupar na escrita de código :) mas sim poupar na manutenção (o mais caro)

with Ada.TexT_IO; use Ada.Text_IO;

with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

procedure Teste is

I: Integer;

begin

Put(“Introduza um número: ”); -- package Ada.Text_IO;

Get(I); -- package Ada.Integer_Text_IO;;

Put(“O número introduzido foi “); -- package Ada.Text_IO;

Put(I); -- package Ada.Integer_Text_IO;;

New_Line; -- package Ada.Text_IO;

end Teste;

Page 24: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 23

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

- Existe um problema quando se quer ler Strings do teclado

- Quando se cria uma String é necessário especificar qual o tamanho da String

- Quando se lê uma String (tem um tamanho) com o Get somos obrigados a ler tantos caracteres como o tamanho da String

- Para resolver isto é necessário utilizar Get_Line, não Get

- Get_Line devolve também qual o tamanho da String lida (o segundo parâmetro). A partir desse momento utilizamos sempre esse tamanho

-- O seguinte programa utiliza o procedimento Get_Line da package

-- Ada.Text_IO para ler uma String (do teclado) e depois utiliza

-- Put, para a colocar no monitor

with Ada.Text_IO;

use Ada.Text_IO;

procedure Hello_Utilizador is

S: String(1..80);

Fim: Integer;

begin

Put(“Introduza o seu nome (< 80 caracteres): “);

Get_Line( S , Fim );

Put(“Hello “);

Put_Line( S( 1 .. Fim ) );

end Hello_Utilizador;

- Para utilizarmos Strings sem tamanho predefinido existe um tipo de dados Unbounded_String

- Os arrays podem não ter limites

- Se por acaso o utilizados entrar mais de 80 caracteres os restantes caracteres ficam no buffer do teclado, o que pode originar erro nas leituras seguintes do teclado

- Mas não na leitura actual. O Get_Line nunca tenta colocar na String mais caracteres do que o tamanho desta

- Existe um problema quando se lê uma String do teclado após se ter lido um número

- O problema não tem a ver com a linguagem, nem com o compilador (é o célebre problema do getch())

- Para resolver isso, sempre que vamos ler uma string, o melhor é utilizaro o procedimento Skip_Line da package Ada.Text_IO

Page 25: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 24

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

-- O seguinte programa é semelhante ao anterior, mas antes de ler o nome,

-- lê a idade. Logo, é necessário colocar o procedimento Skip_Line

with Ada.Text_IO;

use Ada.Text_IO;

procedure Hello_Utilizador is

S: String(1..80);

Fim: Integer;

Idade: Integer;

begin

Put(“Introduza a sua idade: “);

Get(Idade);

Skip_Line;

Put(“Introduza o seu nome (< 80 caracteres): “);

Get_Line( S , Fim );

Put(“Hello “);

Put_Line( S( 1 .. Fim ) );

Put(“A sua idade é “);

Put(Idade);

Put(“ anos”);

end Hello_Utilizador;

Page 26: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 25

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

11. Modelo de Concorrência

- Ada permite a especificação de tarefas / tipo de tarefas, as quais iniciam execução sem necessidade de activação explícita.

- Para comunicação / sincronização entre tarefas temos disponíveis vários mecanismos:

- Rendezvous (Comunicação síncrona)

- Objectos protegidos (Recursos partilhados - mecanismo de alto nível)

- Objectos de sincronização (mecanismo de baixo nível)

- Existe a possibilidade de definição de alternativas de comunicação/sincronização (select)

- No rendezvous

- No acesso a objectos protegidos

- Relógio

- No Ada, além de um relógio normal (Calendar) existe um relógio de tempo-real, com precisão mínima de 1µS

- Existe um mecanismo de suspensão de uma tarefa por um tempo determinado

- Atraso relativo (delay)

- Atraso absoluto (delay until)

- Prioridades

- Em Ada podemos especificar prioridades para tarefas, e para o tecto de prioridades de objectos protegidos

- As prioridades podem ser dinâmicas

- Despacho das tarefas

- Podemos especificar a forma pretendida para o despacho das tarefas.

- O anexo de sistemas de tempo-real especifica que tem que existir pelo menos FIFO_Within_Priorities (despacho por prioridades, com FIFO na mesma prioridade

pragma Task_Dispatching_Policy(FIFO_Within_Priorities);

- Interacção com recursos

- Podemos especificar como se comporta a interacção entre as tarefas e os recursos partilhados.

- O anexo de sistemas de tempo-real especifica que tem que existir pelo menos Ceiling_Locking (implementa o protocolo de Immediate Ceiling Protocol para resolver a inversão de prioridades)

pragma Locking_Policy(Ceiling_Locking);

Page 27: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 26

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

- Filas de espera no acesso a recursos

- O anexo de sistemas de tempo-real especifica que têm que existir duas formas possíveis de espera no acesso a recursos: FIFO_Queuing e Priority_Queuing.

pragma Queuing_Policy(Priority_Queuing);

- Quando se pretende um programa que implemente o modelo de escalonamento por prioridades, que resolva o problema da inversão de prioridades é necessário especificar

- FIFO_Within_Priorities para o tipo de despacho, Ceiling_Locking para o acesso a recursos partilhados e Priority_Queuing para acesso a filas de espera

- A linguagem permite a especificação de outros modelos, para a implementação de modelos de escalonamento diferentes (e.g. EDF, Round Robin e escalonamento hierárquico)

- Implementação da Concorrência

- A questão é: Como é que o Ada implementa a concorrência

- A resposta é: depende :)

- O compilador pode mapear a concorrência nos serviços disponibilizados pelo Sistema Operativo (por exemplo GNAT para Windows/Linux)

- Quer dizer que o modelo de concorrência só pode ser cumprido se o SO for de tempo-real (por exemplo GNAT para VxWorks/RTEMS)

- É fácil de implementar se o SO for de tempo-real e suporte interface POSIX

- O compilador pode implementar o seu próprio runtime (por exemplo DCCI Tartan Ada Compilar ou GNAT NRT)

- Directamente em cima do hardware

- Geralmente é para arquitecturas específicas

- Ou uma mistura dos dois

- O compilador disponibiliza uma camada entre o programa e o sistema operativo para implementar mecanismos que o SO não suporte (por exemplo GNAT para DOS, ou GNAT + Florist para Linux)

- Um exemplo interessante é o A#, que compila Ada para a plataforma .Net

http://www.usafa.af.mil/df/dfcs/bios/mcc_html/a_sharp.cfm

Page 28: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 27

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

12. Tarefas

- São a unidade de concorrência

- Declaram-se como variáveis ou tipos de dados na zona de declaração dos blocos.

- Podemos especificar prioridades para tarefas (podem ser dinâmicas)

- As prioridades definem-se através de pragmas

- Podemos criar tarefas dentro de tarefas (hierarquia)

Declaração ::= task [type] nome [Discriminantes] [is {task_item} [private {task_item}] end [nome]];

Discriminantes::=

(Nome: Tipo [{;Nome: Tipo}]) task_item::=

entry|pragma Corpo::=

task body nome is [{declarações}] begin {instruções} end [nome];

Page 29: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 28

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

with Ada.Text_IO; procedure Uma_Tarefa is -- Declaração de uma tarefa task tarefa ; -- Corpo da tarefa task body tarefa is begin for Count in 1..5 loop Ada.Text_IO.Put_Line(Item => "Tarefa "); end loop; end tarefa; begin -- Inicio da tarefa principal -- A outra tarefa é activada ao mesmo tempo que o corpo -- do bloco em que foi declarada for Count in 1..5 loop Ada.Text_IO.Put(Item => "Tarefa principal"); Ada.Text_IO.New_Line; end loop; end Uma_Tarefa;

Page 30: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 29

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

with Ada.Text_IO; procedure Tarefas is -- Declaração de um tipo de tarefas task type tarefa (Msg: Character); -- Podemos utilizar discriminates nas tarefas, para poder

identificar cada uma -- das tarefas -- Corpo das tarefas deste tipo task body tarefa is begin for Count in 1..5 loop Ada.Text_IO.Put_Line(Item => "Tarefa " & Msg); end loop; end tarefa; Task_A: tarefa(Msg => 'A'); Task_B: tarefa(Msg => 'B'); begin -- Inicio da tarefa principal -- As outras tarefas são activadas ao mesmo tempo que o corpo -- do bloco em que foram declaradas for Count in 1..5 loop Ada.Text_IO.Put(Item => "Tarefa principal"); Ada.Text_IO.New_Line; end loop; end Tarefas;

Page 31: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 30

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

pragma Task_Dispatching_Policy(FIFO_Within_Priorities); -- serve para referir que este programa faz o despacho de tarefas -- por prioridades e FIFO dentro da mesma prioridade. -- É uma pragma de configuração, porque aplica-se -- ao programa todo. Por isso é colocada no início with System; -- Aqui está declarado o tipo Priority with Ada.Text_Io; procedure Tarefas_Prioridades is pragma Priority(System.Priority'First); -- serve para referir que a tarefa principal tem prioridade -- igual à mais baixa -- É o único sítio onde se pode utilizar esta pragma na -- declaração de um subprograma -- Declaração de um tipo de tarefas task type tarefa (Msg: Character; Prio: System.Priority) is pragma Priority(Prio); -- serve para referir que este tipo de tarefa tem -- prioridade igual a Prio. Como Prio é um discriminante -- que pode ser diferente para cada tarefa, a prioridade -- pode ser diferente para cada tarefa end tarefa; -- Corpo das tarefas deste tipo task body tarefa is begin for Count in 1..5 loop Ada.Text_Io.Put_Line(Item => "Tarefa " & Msg); end loop; end tarefa; Task_A: tarefa(Msg => 'A', Prio => System.Priority'First+1); Task_B: tarefa(Msg => 'B', Prio => System.Priority'First+2); begin -- Inicio da tarefa principal null; end Tarefas_Prioridades;

Page 32: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 31

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

13. Rendezvous

- Tarefas podem comunicar de forma síncrona entre elas

- Uma é o cliente e outra o servidor

- O rendezvous pode (ou não) servir para trocar informação

- A tarefa servidora declara na sua interface quais os serviços que disponibiliza (entries)

- O cliente tem que saber o nome do servidor para poder ligar

- Como a ligação é síncrona o cliente fica bloqueado enquanto não acaba o serviço no servidor

- Como a ligação é síncrona o cliente fica bloqueado enquanto não acaba o serviço no servidor

- Rendezvous pode ser usado para troca de dados, ou para que o servidor efectue uma acção em benefício do cliente

- Esta forma de interacção é parecida com o RPC

task servidor is entry serviço; end servidor; task body servidor is begin -- ... accept serviço; -- ... end servidor;

Page 33: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 32

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

with Ada.Text_IO; use Ada.Text_IO; procedure Tarefas_Rendezvous is -- tarefa servidora task servidor is entry start; -- Declaração do ponto de ligação end servidor; -- Corpo da tarefa servidora task body servidor is begin accept start; -- Aqui o servidor fica bloqueado à espera for Count in 1..5 loop Put_Line(Item => "Servidor"); end loop; end servidor; -- tarefa cliente task cliente; -- Corpo da tarefa cliente task body cliente is begin Put_Line("Pressione Enter para iniciar o servidor"); Skip_Line; servidor.start; -- Aqui o cliente fica bloqueado à espera -- se o servidor não estiver já à espera -- na entry end cliente; begin -- Inicio da tarefa principal null; end Tarefas_Rendezvous;

Page 34: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 33

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

task servidor is entry servico1(Dados: in Tipo; Result: out Tipo); entry servico2(Dados: in Tipo); end servidor; task body servidor is begin -- ... accept servico1(Dados:in Tipo; Result: out Tipo) do -- … Result:= Qualquer_coisa; end servico1; -- … accept servico2(Dados: in tipo) do -- … end servico2; -- ... end servidor;

Page 35: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 34

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

with Ada.Text_IO; use Ada.Text_IO; with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; procedure Tarefas_Rendezvous2 is -- tarefa servidora task Servidor is entry Start; -- Declaração do ponto de ligação entry Serviço1(Result: out Integer); entry Serviço2(dados: Integer); end Servidor; -- Corpo da tarefa servidora task body Servidor is Valor: Integer := 0; begin accept Start; -- Aqui o servidor fica bloqueado à espera for Count in 1..5 loop accept Serviço2(dados: Integer) do Put(Item => "Servidor recebeu "); Put(dados); New_Line; Valor:= Valor + dados; end Serviço2; end loop; accept Serviço1(Result: out Integer) do Result:= Valor; end Serviço1; end Servidor; -- tarefa cliente task Cliente; -- Corpo da tarefa cliente task body Cliente is Val: Integer; begin Put_Line("Pressione Enter para iniciar o servidor"); Skip_Line; Servidor.Start; -- Aqui o servidor fica bloqueado à espera for Count in 1..5 loop Put_Line("Entre valor inteiro para enviar ao servidor: "); Get(Val); Servidor.Serviço2(Val); end loop; Servidor.Serviço1(Val); Put("O servidor enviou-me a soma dos valores entrados: "); Put(Val); New_Line; end Cliente; begin -- Inicio da tarefa principal null; end Tarefas_Rendezvous2;

Page 36: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 35

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

14. Relógios e Temporizadores

- Existem dois tipos de relógios

- Um relógio normal (Ada.Calendar.Clock), como se fosse um relógio de parede

- Um relógio de tempo real (Ada.Real_Time.Clock)

- Geralmente são o mesmo relógio de hardware, mas são utilizados de forma diferente

- Ada.Calendar

- O tipo Time pode representar qualquer coisa (geralmente representa segundos desde as 0 horas do dia 1/1/70, como em Unix, mas não se pode garantir)

- A função Clock retorna o Time actual

- O tipo Duration representa uma diferença de instantes. Não pertence à package Ada.Calendar, mas existe globalmente (package Standard)

- Existem funções para retirar Ano/Mês/Dia a partir do Time

- Ada.Real_Time

- O tipo Time pode representar qualquer coisa (geralmente é o mesmo de Calendar, mas não se pode garantir)

- A função Clock retorna o Time actual

- O tipo Time_Span representa uma diferença de instantes

- Existem funções para converter ms/µs/ns em Time_Span

- É preciso ter cuidado para não misturar estes dois relógios

- Existem dois tipos de temporizadores

- Temporizadores de tempo de execução (Ada.Execution_Time)

- Permitem contabilizar o tempo de execução de uma tarefa

- Alarme no caso de “overrun”

- Disponíveis para uma tarefa ou grupo de tarefas (Ada.Execution_Time.Timers e Ada.Execution_Time.Group_Budgets)

- Alarmes de tempo real (Ada.Real_Time.Timing_Events)

- Permite “disparar” eventos em tempos específicos

- Não utiliza tarefas

- Tempo é dado pelo Time de Ada.Real_Time

Page 37: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 36

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

15. Atrasos

- Existem dois tipos de atrasos

- Absoluto (delay until)

- Serve para indicar que a tarefa deve ficar suspensa até um determinado instante

- A tarefa pode ser libertada apenas depois desse tempo, depende do escalonamento

- Usa-se:

delay until Tempo;

Tempo tem que ser do tipo Time (pode ser Calendar Time, ou Real_Time Time)

- Relativo (delay)

- Serve para indicar que a tarefa deve ficar suspensa durante um determinado instante

- A tarefa pode ficar bloqueada mais do que esse tempo, depende do escalonamento

- Usa-se:

delay Intervalo;

Intervalo tem que ser do tipo Duration (não pode ser Real_Time)

- Quando se quer usar delay com Real_Time.Time_Span existe uma função que converte Time_Span em Duration

- Embora o atraso relativo (delay) possa ser usado, também pode dar problemas

- O problema é que a instrução “delay (Start + 10.0) – Clock” não é indivisível. A tarefa pode ser interrompida após ter calculado um intervalo de 8 segundos, e quando executa outra vez já podem ter passado vários segundos, mas o intervalo será na mesma de 8 segundos

Start:= Clock; Faz_Acção; delay (Start + 10.0) - Clock;

Page 38: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 37

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

-- Este programa atrasa a execução durante três segundos -- Utilizando o tipo Duration with Ada.Text_IO; use Ada.Text_IO; procedure Relogio is Interval: Duration:= 3.0; -- Como Duration baseia-se em

-- vírgula flutuante -- não pode ser := 3,

-- tem que ser := 3.0 begin Put_Line("Começou o programa"); delay Interval; Put_Line("Supostamente passaram 3 segundos"); end Relogio; -- Este programa atrasa a execução durante três segundos -- Utilizando o tipo Ada.Real_Time.Time_Span with Ada.Text_IO; use Ada.Text_IO; with Ada.Real_Time; use Ada.Real_Time; procedure Relogio1 is Interval: Time_Span := Milliseconds(3000); -- temos que usar as -- funções de conversão begin Put_Line("Começou o programa"); delay To_Duration(Interval); Put_Line("Supostamente passaram 3 segundos"); end Relogio1;

Page 39: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 38

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

16. Synchronous/Asynchronous Task Control

- Synchronous Task Control

- Um semáforo básico, que pode ser usado para suspensão ou para implementar mecanismos mais complexos.

- Especificação (simplificada):

package Ada.Synchronous_Task_Control is type Suspension_Object is private; procedure Set_True(S : in out Suspension_Object); procedure Set_False(S : in out Suspension_Object); function Current_State(S : Suspension_Object) return Boolean; procedure Suspend_Until_True(S : in out Suspension_Object); private ... -- a implementação depende do compilador end Ada.Synchronous_Task_Control;

- Um objecto tem dois estados: verdadeiro e falso. Inicialmente está a falso.

- O procedimento Suspend_Until_True bloqueia a tarefa no objecto até outra tarefa executar Set_True.

- Apenas uma tarefa pode estar suspensa num objecto (dá excepção se uma segunda tentar)

- Asynchronous Task Control

- No mecanismo anterior, apenas a própria tarefa se pode suspende.

- O mecanismo assíncrono permite que uma tarefa seja suspensa por outra:

with Ada.Task_Identification; package Ada.Asynchronous_Task_Control is pragma Preelaborate(Asynchronous_Task_Control); procedure Hold(T : in Ada.Task_Identification.Task_Id); procedure Continue(T : in Ada.Task_Identification.Task_Id); function Is_Held(T : Ada.Task_Identification.Task_Id) return Boolean; end Ada.Asynchronous_Task_Control;

Page 40: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 39

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

17. Interfaces

- Uma novidade do Ada 2005 foi a introdução de Interfaces (como Java).

- Como não existe integração de OO com concorrência (não se pode herdar de/para tarefas), as Interfaces podem ser usadas para permitir uma integração limitada

- São permitidos 2 tipos de interfaces para serem utilizados com concorrência:

- Synchronised:Pode ser implementada por tarefas e objectos protegidos

- Task: Pode ser implementada apenas por tarefas

- Protected: Pode ser implementada apenas por objectos protegidos

-- A interface TI package Pkg is

type TI is task interface; procedure P(X: in TI) is abstract; procedure Q(X: in TI; I: in Integer) is null;

end Pkg;

-- pode ser implementada por: package PT1 is

task type TT1 is new TI with entry P; -- P e Q são entries entry Q(I: in Integer);

end TT1; end PT1; -- ou por package PT2 is

task type TT2 is new TI with entry P; -- P é entry

end TT2; -- Q é uma procedure procedure Q(X: in TT2; I: in Integer);

end PT2;

Page 41: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 40

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

18. O Perfil Ravenscar

- Os mecanismos de Concorrência do Ada são muito complexos

- Em 1997 chegou-se à conclusão que era necessário restringir a sua utilização para:

- Aumentar a eficiência dos executivos de tempo-real, removendo mecanismos com grandes overheads

- Reduzir o não determinismo para aplicações críticas

- Simplificar os executivos de tempo-real, para aplicações de alta integridade

- Remover mecanismos que não podem ser formalizados

- Remover mecanismos que impedem a análise de resposta temporal das aplicações

- Foi então criado o perfil Ravenscar (Reliable Ada Verifiable Executive Needed for Scheduling Critical Applications in Real-time!)

- Ravenscar é uma pequena terra no norte de Inglaterra, onde decorreu a reunião

- O perfil tem muitas restrições

- No entanto, tem o suficiente para implementar aplicações de tempo-real, segundo o modelo de escalonamento preemptivo por prioridades fixas

- Este perfil foi introduzido na Norma em 2005

- Pragma de configuração

pragma Profile(Ravenscar);

Page 42: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 41

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

- A pragma Ravenscar é equivalente a:

pragma Task_Dispatching_Policy(FIFO_Within_Priorities);

pragma Locking_Policy(Ceiling_Locking);

pragma Detect_Blocking;

pragma Restrictions(

No_Abort_Statements, No_Dynamic_Attachment, No_Dynamic_Priorities, No_Implicit_Heap_Allocations, No_Local_Protected_Objects, No_Local_Timing_Events, No_Protected_Type_Allocators, No_Relative_Delay, No_Requeue_Statements, No_Select_Statements, No_Specific_Termination_Handlers, No_Task_Allocators, No_Task_Hierarchy, No_Task_Termination, Simple_Barriers, Max_Entry_Queue_Length => 1, Max_Protected_Entries => 1, Max_Task_Entries => 0, No_Dependence => Ada.Asynchronous_Task_Control, No_Dependence => Ada.Calendar, No_Dependence => Ada.Execution_Time.Group_Budget, No_Dependence => Ada.Execution_Time.Timers, No_Dependence => Ada.Task_Attributes);

- Restrições

- Tarefas e objectos protegidos apenas ao nível das bibliotecas (nada de hierarquias)

- Não é permitido:

- reservar/libertar dinamicamente tarefas/objectos protegidos

- requeue, ATC, Abort

- entries nas tarefas

- Prioridades dinâmicas

- Ada.Calendar, Delays relativos

- entries nos objectos protegidos, em que a barreira não é uma variável booleana declarada dentro do próprio objecto

- Uma tarefa tentar executar uma entry de um objecto protegido, em que já lá está outra tarefa

- Asynchronous Task Control

- Todas as formas do select

- Atributos de tarefas definidos pelo utilizador

Page 43: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 42

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

- Ficou ainda

- Tarefas e objectos protegidos (com as restrições)

- pragmas Atomic e Volatile

- delay until

- Ceiling_Locking e FIFO_Within_Priorities

- Atributo Count (mas não nas barreiras)

- Identificadores das tarefas

- Synchronous Task Control

- Descriminantes nas tarefas

- package Real_Time

- Protected procedures como processamento de interrupções

- O modelo de escalonamento preemptivo por prioridades fixas é:

- Um número fixo de actividades (tarefas)

- Não há criação/destruição de tarefas

- Cada tarefa é libertada apenas por um evento, mas que pode acontecer um número ilimitado de vezes

- Este evento pode ser temporal (para uma tarefa periódica) ou esporádico (de uma outra tarefa ou do ambiente). Uma aplicação critica pode restringir-se apenas a eventos temporais

- Tarefas apenas interagem através de memória partilhada, em que as actualizações nessa memória têm que ser atómicas

- Depois de iniciar execução uma tarefa não pode suspender ou ficar bloqueada

- Para isso o perfil Ravenscar permite:

- Tarefas para as actividades

- delay until para libertar tarefas periódicas

- Synchronous Task Control para libertar tarefas esporádicas

- Objectos protegidos para libertar tarefas esporádicas, com passagem de informação

- Objectos protegidos para memória partilhada

- Estes dois tipos de objectos protegidos têm que ser independentes, não convém usar um só objecto para duas operações diferentes

- O que faz com que seja fácil definir templates

Page 44: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 43

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

- Tarefas periódicas

- Tarefas esporádicas

task body Cyclic is Next_Period : Ada.Real_Time.Time := First_Release; Period : Ada.Real_Time.Time_Span :=

Ada.Real_Time.Milliseconds(50); -- declaracoes begin -- Inicializacao loop delay until Next_Period; -- Codigo para a tarefa Next_Period := Next_Period + Period; end loop; end Cyclic;

So: Ada.Synchronous_Task_Control.Suspensaion_Object; -- tem que ser declarado com with task body Sporadic is -- Declaracoes begin -- Inicializacao loop Ada.Synchronous_Task_Control.Suspend_Until_True (So); -- Codigo da tarefa end loop; end Sporadic;

Page 45: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 44

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

- Dados partilhados

- Esporádico com dados

protected Shared_Data is function Get return Data; procedure Put (D : in Data ); private Current : Data; end Shared_Data; protected body Shared_Data is function Get return Data is begin return Current; end Get; procedure Put (D : in Data ) is begin Current := D; end Put; end Shared_Data;

protected type Event is entry Wait (D : out Data); procedure Signal (D : in Data ); private Current : Data; Signalled : Boolean := False; end Event; protected body Event is entry Wait ( D : out Data ) when Signalled is begin D := Current; Signalled := False; end Wait; procedure Signal ( D : in Data ) is begin Current := D; Signalled := True; end Signal; end Event;

E: Event; task body Sporadic is D: Data; begin -- Inicializacao loop E.Wait(D); -- Codigo da tarefa end loop; end Sporadic;

Page 46: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 45

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

- Para o 3º módulo de COMPA deve ser analisado o documento (também fornecido):

Alan Burns, Brian Dobbing, George Romanski, “The Ravenscar Tasking Profile for High Integrity Real-Time Programs”, Reliable Software Technologies - Ada-Europe 1998 (http://www.aonix.com/pdf/ravensc.pdf)

- Este documento é importante para perceber os objectivos e restrições do perfil Ravenscar. Está desactualizado na definição de perfil (é anterior à introdução da pragma Profile), mas o que não invalida a discussão do perfil em si.

Page 47: Introdução à programação em Ada 2005emt/COMPA/Modulo3/Teoricas/ada2005.pdfIntrodução à programação em Ada 2005 Pág. 1 Luís Miguel Pinho – Instituto Superior de Engenharia

Introdução à programação em Ada 2005 Pág. 46

Luís Miguel Pinho – Instituto Superior de Engenharia do Porto Outubro de 2006

19. Bibliografia e recursos online

- Bibliografia

1. Introduction to Concurrent Programming, capítulo do livro:

M.B. Feldman, “Software Construction and Data Structures with Ada 95”, Addison-Wesley, 1997 (http://www.seas.gwu.edu/~mfeldman/cs2-book/)

2. Ada 2005 Rationale (http://adaic.org/standards/05rat/html/Rat-

TOC.html) 3. Alan Burns, Brian Dobbing, George Romanski, “The Ravenscar

Tasking Profile for High Integrity Real-Time Programs”, Reliable Software Technologies - Ada-Europe 1998 (http://www.aonix.com/pdf/ravensc.pdf)

4. Burns & Wellings, “Concurrency in Ada 95”, Cambridge Press,

1998

5. Programming in Ada 2005, John Barnes, Addison Wesley, 2006

- Outros recursos online

- Ada Tools and resources: http://www.adapower.com/

- Normas: http://www.adaic.org/standards/

- Ada Annotated Reference Manual (a norma anotada)

- Ada Rationale (explicação das decisões tomadas na linguagem)

- Compilador GNAT: http://libre.adacore.com/