X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=ipc.tex;h=e76fd7b06e7a4c25dd0dec87ce97535845ad18fd;hp=c86697143c8eef82abe367598b2a509e31e0e0bf;hb=041fde8aba0e18bb746653a060619b32ea9240ce;hpb=5b8f42ef99d2884ca02331ee61649ce3b6ec18f5 diff --git a/ipc.tex b/ipc.tex index c866971..e76fd7b 100644 --- a/ipc.tex +++ b/ipc.tex @@ -1,6 +1,6 @@ %% ipc.tex %% -%% Copyright (C) 2000-2004 Simone Piccardi. Permission is granted to +%% Copyright (C) 2000-2005 Simone Piccardi. Permission is granted to %% copy, distribute and/or modify this document under the terms of the GNU Free %% Documentation License, Version 1.1 or any later version published by the %% Free Software Foundation; with the Invariant Sections being "Un preambolo", @@ -2179,7 +2179,7 @@ a queste strutture restano per compatibilit vecchie versioni delle librerie del C, come le libc5.} \begin{figure}[htb] - \centering \includegraphics[width=15cm]{img/semtruct} + \centering \includegraphics[width=13cm]{img/semtruct} \caption{Schema della struttura di un insieme di semafori.} \label{fig:ipc_sem_schema} \end{figure} @@ -2191,12 +2191,13 @@ possono avere successo; se una di esse comporta il blocco del processo il kernel crea una struttura \struct{sem\_queue} che viene aggiunta in fondo alla coda di attesa associata a ciascun insieme di semafori\footnote{che viene referenziata tramite i campi \var{sem\_pending} e \var{sem\_pending\_last} - di \struct{semid\_ds}.}. Nella struttura viene memorizzato il riferimento -alle operazioni richieste (nel campo \var{sops}, che è un puntatore ad una -struttura \struct{sembuf}) e al processo corrente (nel campo \var{sleeper}) -poi quest'ultimo viene messo stato di attesa e viene invocato lo -scheduler\index{\textit{scheduler}} per passare all'esecuzione di un altro -processo. + di \struct{semid\_ds}.}. + +Nella struttura viene memorizzato il riferimento alle operazioni richieste +(nel campo \var{sops}, che è un puntatore ad una struttura \struct{sembuf}) e +al processo corrente (nel campo \var{sleeper}) poi quest'ultimo viene messo +stato di attesa e viene invocato lo scheduler\index{\textit{scheduler}} per +passare all'esecuzione di un altro processo. Se invece tutte le operazioni possono avere successo queste vengono eseguite immediatamente, dopo di che il kernel esegue una scansione della coda di @@ -2205,13 +2206,12 @@ operazioni sospese in precedenza pu struttura \struct{sem\_queue} viene rimossa e lo stato del processo associato all'operazione (\var{sleeper}) viene riportato a \textit{running}; il tutto viene ripetuto fin quando non ci sono più operazioni eseguibili o si è -svuotata la coda. - -Per gestire il meccanismo del ripristino tutte le volte che per un'operazione -si è specificato il flag \const{SEM\_UNDO} viene mantenuta per ciascun insieme -di semafori una apposita struttura \struct{sem\_undo} che contiene (nel vettore -puntato dal campo \var{semadj}) un valore di aggiustamento per ogni semaforo -cui viene sommato l'opposto del valore usato per l'operazione. +svuotata la coda. Per gestire il meccanismo del ripristino tutte le volte che +per un'operazione si è specificato il flag \const{SEM\_UNDO} viene mantenuta +per ciascun insieme di semafori una apposita struttura \struct{sem\_undo} che +contiene (nel vettore puntato dal campo \var{semadj}) un valore di +aggiustamento per ogni semaforo cui viene sommato l'opposto del valore usato +per l'operazione. Queste strutture sono mantenute in due liste,\footnote{rispettivamente attraverso i due campi \var{id\_next} e \var{proc\_next}.} una associata @@ -2221,20 +2221,21 @@ operazione con \func{semctl}; l'altra associata al processo che ha eseguito l'operazione;\footnote{attraverso il campo \var{semundo} di \struct{task\_struct}, come mostrato in \ref{fig:ipc_sem_schema}.} quando un processo termina, la lista ad esso associata viene scandita e le operazioni -applicate al semaforo. - -Siccome un processo può accumulare delle richieste di ripristino per semafori -differenti chiamate attraverso diverse chiamate a \func{semop}, si pone il -problema di come eseguire il ripristino dei semafori all'uscita del processo, -ed in particolare se questo può essere fatto atomicamente. Il punto è cosa -succede quando una delle operazioni previste per il ripristino non può essere -eseguita immediatamente perché ad esempio il semaforo è occupato; in tal caso -infatti, se si pone il processo in stato di \textit{sleep} aspettando la -disponibilità del semaforo (come faceva l'implementazione originaria) si perde -l'atomicità dell'operazione. La scelta fatta dal kernel è pertanto quella di -effettuare subito le operazioni che non prevedono un blocco del processo e di -ignorare silenziosamente le altre; questo però comporta il fatto che il -ripristino non è comunque garantito in tutte le occasioni. +applicate al semaforo. Siccome un processo può accumulare delle richieste di +ripristino per semafori differenti chiamate attraverso diverse chiamate a +\func{semop}, si pone il problema di come eseguire il ripristino dei semafori +all'uscita del processo, ed in particolare se questo può essere fatto +atomicamente. + +Il punto è cosa succede quando una delle operazioni previste per il ripristino +non può essere eseguita immediatamente perché ad esempio il semaforo è +occupato; in tal caso infatti, se si pone il processo in stato di +\textit{sleep} aspettando la disponibilità del semaforo (come faceva +l'implementazione originaria) si perde l'atomicità dell'operazione. La scelta +fatta dal kernel è pertanto quella di effettuare subito le operazioni che non +prevedono un blocco del processo e di ignorare silenziosamente le altre; +questo però comporta il fatto che il ripristino non è comunque garantito in +tutte le occasioni. Come esempio di uso dell'interfaccia dei semafori vediamo come implementare con essa dei semplici \textit{mutex} (cioè semafori binari), tutto il codice