Relatório


1. Introdução

A garantia da exclusividade de acesso ou de execução de um recurso compartilhado é uma premissa importante em cenários de processos concorrentes. A exclusão mútua visa controlar o compartilhamento de tais recursos, determinando estratégias para que tais recursos possam ser adequadamente controlados. Nesse contexto, um recurso (que, na verdade corresponde a um trecho de código) é designado como Região Crítica (RC). Entretanto, em um cenário distribuído, é imperativo que todos os processos cheguem a um acordo sobre a ordem de acesso à RC. Ou seja, todos os processos precisam interagir e a partir dessa interação sincronizar seus acessos ao recurso que se mantém compartilhado. No entanto, quaisquer soluções de exclusão mútua distribuída precisam considerar, minimanente, três propriedades: Safety (Segurança): no máximo, um processo executa a cada momento na RC, Liveness (Progressão): todo pedido de entrada e/ou saida da RC é atendido em algum momento e Fairness (Justiça): em que todos os processos têm a mesma chance de acessar a RC, incorrendo, dessa forma, em não priorização.

O algoritmo de Ricart-Agrawala é uma categoria de solução baseada em permissões (ou replies), sendo uma simplificação da proposta de Lamport, por eliminar estruturas tais como o vetor de timestamps e a necessidade de lidar o canal de comunicação do processo com base em ordenação FIFO. Além disso, as permissões não necessitam mais ser baseadas em mensagens de release, ou seja, um processo só executa a RC se obtiver as permissões (designadas como replies) de todos os demais.

2. Objetivos

O propósito desse trabalho é a implementação de uma solução de exclusão mútua distribuída baseada no algoritmo de Ricart-Agrawala. Para a implementação é utilizada a biblioteca de recursos de simulação de eventos discretos SmPL. Para a avaliação dos resultados obtidos foram escolhidos dois cenários principais de execução: com 2 e 3 nodos(ou processos). Em cada caso são fornecidos os instantes de requisição de entrada na RC. A partir do registro dessas intenções, eventos de envio e recepção de mensagens (que permitem a construção das permissões) são gerados. As permissões, no entanto, são baseadas em um relógio lógico global, implementado para ordenar as requisições. Tais eventos, de acordo com o requisitado, são programados para ocorrer conforme uma distribuição aleatória de tempo (de 1 a 5 unidades de tempo). Ao final, todos os processos deverão ter obtido permissão para acesso à RC.

3. Sobre a implementação

A implementação dos objetivos traçados anteriormente é baseada nas estruturas de dados apresentadas na Figura 1. O tipo tmsg é usado tanto para registrar as mensagens que são enviadas por algum nodo como para facilitar lidar com as respostas. Dessa forma, quaisquer requisições como quaisquer respostas têm como ser analisadas. Além dessas estruturas que permitem lidar com as atividades de comunicação entre os nodos, tem-se o tipo tnodo , cujo objetivo é registrar dados que facilitam as decisões de cada nodo.

estruturas de dados

Figura 1. Estruturas de dados


No entanto, para lidar com a simulação da execução do algoritmo, um aspecto é vital e norteador para as decisões de implementação: a escolha dos eventos.

Eventos
Como decisão de implementação foram escolhidos 6 possíveis eventos: Uma atividade que merece ser ressaltada, para a condução desse trabalho, é a sincronização das atividades escalonadas pelo simulador com o código propriamente dito. Para que uma impressão clara da sequência de execução pudesse ser percebida foram criados 12 exemplos diferentes de saída. Foi possível constatar que essa necessária reorganização das saídas são decorrentes das atividades programadas para um evento e seus respectivos tempos de execução que são, obviamente, rígidos quanto ao seu escalonamento. Ou seja, ínterins entre um evento ou para a execução de um evento deveriam ser claramente organizados sob pena de produzir um resultado distinto do que efetivamente deveria ocorrer.

Por fim, para esclarecimento do modo de uso do código disponível a seguir, deve-se, portanto, seguir o seguinte modo de uso:
./ricAgr [quantidade de nodos (2 ou 3)] [tempos de requisição da RC de cada nodo]. Por exemplo: ./ricAgr 3 2 3 9.


Código Fonte:
ricAgr.c.txt
Makefile


Alguns logs:

Considerando 2 nodos de entrada Considerando 3 nodos de entrada