-
Adicionar uma entrada a lista de chamadas do sistema, nos arquivos
/usr/src/include/minix/callnr.h
#define SEM_GET 114 #define SEM_P 115 #define SEM_V 116
-
Adicionar o protótipo da função responsável pela chamada a
/usr/src/servers/pm/table.c
com o índice correspondente ao utilizado no primeiro passodo_sem_get, /* 114 = sem_get */, do_sem_p, /* 115 = sem_p */, do_sem_v, /* 116 = sem_v */
-
Criar o arquivo /usr/src/server/pm/semaphore.c, que conterá as funções
do_sem_get()
,do_sem_p()
edo_sem_v()
, e toda a lógica de funcionamento dos semáforos, despachando trabalho com base nas mensagens recebidas.
A struct sem
, que será o tipo das entradas da tabela de semáforos, pode ser algo do tipo:
struct sem {
const char *name; /* para debug? */
int val;
pid_t owner_pid;
pid_list wait_list; /* lista ligada */
};
A parte da implementação corresponde aos programas de usuário deve enviar a mensagem da chamada de sistema,
e aguardar por uma resposta (usando sendrec()
, por exemplo), que só será emitida pelo sistema, acordando o processo,
quando o semáforo mais não estiver zerado. Tentativas de down no semáforo quando ele está zerado colocam o processo na lista de espera (o envio da mensagem já causa o bloqueio), que é atendida em ordem first-in-first-out, quando um up ocorre.
Para garantir que o envio de mensagens por parte dos semáforos não possa causar uma deadlock devido a um processo de usuário que não chama o receive()
no momento correto, é possível usar sendnb()
assíncrono para acordá-los em vez de send()
.
A limpeza dos semáforos criados por um processo deve ser feita adicionando uma chamada a uma função do semaphore.c
na função exit_proc()
do arquivo /usr/src/servers/pm/forkexit.c
, iterando sobre a tabela de semáforos, e liberando aqueles cujo PID corresponda ao processo que acabou de terminar. Quanto a semáforos orfãos, excluídos por seu processo criador, seria razoável definir um outro valor de erro, que seria então retornado a todos os processos da lista de espera, indicando que o semáforo não é mais válido.
A atribuição de handles aos semáforos pode ser feita através de uma tabela de hash, mapeando um inteiro aleatoriamente gerado à um índice na tabela/ponteiro para um struct sem
.