Revisione segmenti memoria condivisa SysV IPC
authorSimone Piccardi <piccardi@gnulinux.it>
Wed, 2 Oct 2013 15:29:10 +0000 (15:29 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Wed, 2 Oct 2013 15:29:10 +0000 (15:29 +0000)
filedir.tex
ipc.tex
process.tex

index b0e42ac6c1b1a910504a180b7a0cf182babe0d55..2ac0f153e4b6d07ae661531a741a709f46973c01 100644 (file)
@@ -6877,7 +6877,8 @@ opportuno dettagliare maggiormente.
                               funzioni \func{mlock}, \func{mlockall},
                               \func{shmctl}, \func{mmap} (vedi
                               sez.~\ref{sec:proc_mem_lock} e 
-                              sez.~\ref{sec:file_memory_map}). \\  
+                              sez.~\ref{sec:file_memory_map}). \\ 
+% TODO verificare l'interazione con SHM_HUGETLB
     \const{CAP\_IPC\_OWNER} & Evitare il controllo dei permessi
                               per le operazioni sugli oggetti di
                               intercomunicazione fra processi (vedi
diff --git a/ipc.tex b/ipc.tex
index 6bfab48e4e48563d08932b5ea2637f442dbcf754..69c67608adf68d9d8cca93f5c97194bc6060fd5f 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -1,4 +1,4 @@
-%% ipc.tex
+<%% ipc.tex
 %%
 %% Copyright (C) 2000-2013 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
@@ -2573,19 +2573,47 @@ memoria condivisa. La funzione di sistema che permette di ottenerne uno è
       già esiste \param{size} è maggiore delle sue dimensioni.
     \item[\errcode{ENOMEM}] il sistema non ha abbastanza memoria per poter
       contenere le strutture per un nuovo segmento di memoria condivisa.
+    \item[\errcode{ENOMEM}] si è specificato \const{IPC\_HUGETLB} ma non si
+      hanno i privilegi di amministratore.
    \end{errlist}
    ed inoltre \errval{EACCES}, \errval{ENOENT}, \errval{EEXIST},
    \errval{EIDRM}, con lo stesso significato che hanno per \func{msgget}.}
 \end{funcproto}
 
 
-La funzione, come \func{semget}, è del tutto analoga a \func{msgget}, ed
-identico è l'uso degli argomenti \param{key} e \param{flag} per cui non
-ripeteremo quanto detto al proposito in sez.~\ref{sec:ipc_sysv_mq}. L'argomento
-\param{size} specifica invece la dimensione, in byte, del segmento, che viene
-comunque arrotondata al multiplo superiore di \const{PAGE\_SIZE}.
-
-% TODO aggiungere l'uso di SHM_HUGETLB introdotto con il kernel 2.6.0
+La funzione, come \func{semget}, è analoga a \func{msgget}, ed identico è
+l'uso degli argomenti \param{key} e \param{flag} per cui non ripeteremo quanto
+detto al proposito in sez.~\ref{sec:ipc_sysv_mq}.  A partire dal kernel 2.6
+però sono stati introdotti degli ulteriori bit di controllo per
+l'argomento \param{flag}, specifici di \func{shmget}, attinenti alle modalità
+di gestione del segmento di memoria condivisa in relazione al sistema della
+memoria virtuale.
+
+Il primo dei due flag è \const{SHM\_HUGETLB} che consente di richiedere la
+creazione del segmento usando una \itindex{huge~page} \textit{huge page}, le
+pagine di memoria di grandi dimensioni introdotte con il kernel 2.6 per
+ottimizzare le prestazioni nei sistemi più recenti che hanno grandi quantità
+di memoria. L'operazione è privilegiata e richiede che il processo abbia la
+\itindex{capability} \textit{capability} \const{CAP\_IPC\_LOCK}. Questa
+funzionalità è specifica di Linux e non è portabile.
+
+Il secondo flag aggiuntivo, introdotto a partire dal kernel 2.6.15, è
+\const{SHM\_NORESERVE}, ed ha lo stesso scopo del flag \const{MAP\_NORESERVE}
+di \func{mmap} (vedi sez.~\ref{sec:file_memory_map}): non vengono riservate
+delle pagine di swap ad uso del meccanismo del \textit{copy on write}
+\itindex{copy~on~write} per mantenere le modifiche fatte sul segmento. Questo
+significa che caso di scrittura sul segmento quando non c'è più memoria
+disponibile, si avrà l'emissione di un \signal{SIGSEGV}.
+
+% TODO verificare i privilegi necessari per SHM_HUGETLB
+
+Infine l'argomento \param{size} specifica la dimensione del segmento di
+memoria condivisa; il valore deve essere specificato in byte, ma verrà
+comunque arrotondato al multiplo superiore di \const{PAGE\_SIZE}. Il valore
+deve essere specificato quando si crea un nuovo segmento di memoria con
+\const{IPC\_CREAT} o \const{IPC\_PRIVATE}, se invece si accede ad un segmento
+di memoria condivisa esistente non può essere maggiore del valore con cui esso
+è stato creato.
 
 La memoria condivisa è la forma più veloce di comunicazione fra due processi,
 in quanto permette agli stessi di vedere nel loro spazio di indirizzi una
@@ -2679,7 +2707,9 @@ che permettono di cambiarne il valore.
                                             pagina di memoria).\\
     \const{SHMSEG}&   ---   &     ---     & Numero massimo di segmenti di
                                             memoria condivisa per ciascun
-                                            processo.\\
+                                            processo (l'implementazione non
+                                            prevede l'esistenza di questo
+                                            limite).\\
 
 
     \hline
@@ -2690,39 +2720,43 @@ che permettono di cambiarne il valore.
   \label{tab:ipc_shm_limits}
 \end{table}
 
-Al solito la funzione che permette di effettuare le operazioni di controllo su
-un segmento di memoria condivisa è \funcd{shmctl}; il suo prototipo è:
-\begin{functions}
-  \headdecl{sys/ipc.h} 
-  \headdecl{sys/shm.h}
-  
-  \funcdecl{int shmctl(int shmid, int cmd, struct shmid\_ds *buf)}
-  
-  Esegue le operazioni di controllo su un segmento di memoria condivisa.
-  
-  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
-    errore, nel qual caso \var{errno} assumerà i valori:
-    \begin{errlist}
+Al solito la funzione di sistema che permette di effettuare le operazioni di
+controllo su un segmento di memoria condivisa è \funcd{shmctl}; il suo
+prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/ipc.h}
+\fhead{sys/shm.h}
+\fdecl{int shmctl(int shmid, int cmd, struct shmid\_ds *buf)}
+
+\fdesc{Esegue le operazioni di controllo su un segmento di memoria condivisa.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
     \item[\errcode{EACCES}] si è richiesto \const{IPC\_STAT} ma i permessi non
       consentono l'accesso in lettura al segmento.
-    \item[\errcode{EINVAL}] o \param{shmid} non è un identificatore valido o
-      \param{cmd} non è un comando valido.
+    \item[\errcode{EFAULT}] l'indirizzo specificato con \param{buf} non è
+      valido.
     \item[\errcode{EIDRM}] l'argomento \param{shmid} fa riferimento ad un
       segmento che è stato cancellato.
-    \item[\errcode{EPERM}] si è specificato un comando con \const{IPC\_SET} o
-      \const{IPC\_RMID} senza i permessi necessari.
+    \item[\errcode{EINVAL}] o \param{shmid} non è un identificatore valido o
+      \param{cmd} non è un comando valido.
+    \item[\errcode{ENOMEM}] si è richiesto un \textit{memory lock} di
+      dimensioni superiori al massimo consentito.
     \item[\errcode{EOVERFLOW}] si è tentato il comando \const{IPC\_STAT} ma il
       valore del \ids{GID} o dell'\ids{UID} è troppo grande per essere
       memorizzato nella struttura puntata da \param{buf}.
-    \item[\errcode{EFAULT}] l'indirizzo specificato con \param{buf} non è
-      valido.
-    \end{errlist}
-}
-\end{functions}
+    \item[\errcode{EPERM}] si è specificato un comando con \const{IPC\_SET} o
+      \const{IPC\_RMID} senza i permessi necessari.
+  \end{errlist}
+}  
+\end{funcproto}
 
 Il comando specificato attraverso l'argomento \param{cmd} determina i diversi
-effetti della funzione; i possibili valori che esso può assumere, ed il
-corrispondente comportamento della funzione, sono i seguenti:
+effetti della funzione. Nello standard POSIX.1-2001 i valori che esso può
+assumere, ed il corrispondente comportamento della funzione, sono i seguenti:
 
 \begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
 \item[\const{IPC\_STAT}] Legge le informazioni riguardo il segmento di memoria
@@ -2738,17 +2772,29 @@ corrispondente comportamento della funzione, sono i seguenti:
   \var{shm\_perm.uid} e \var{shm\_perm.gid} occorre essere il proprietario o
   il creatore del segmento, oppure l'amministratore. Compiuta l'operazione
   aggiorna anche il valore del campo \var{shm\_ctime}.
+\end{basedescript}
+
+Oltre ai precedenti su Linux sono definiti anche degli ulteriori comandi, che
+consentono di estendere le funzionalità, ovviamente non devono essere usati se
+si ha a cuore la portabilità. Questi comandi aggiuntivi sono:
+
+\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
 \item[\const{SHM\_LOCK}] Abilita il \itindex{memory~locking} \textit{memory
-    locking}\footnote{impedisce cioè che la memoria usata per il segmento
-    venga salvata su disco dal meccanismo della \index{memoria~virtuale}
-    memoria virtuale; si ricordi quanto trattato in
-    sez.~\ref{sec:proc_mem_lock}.} sul segmento di memoria condivisa. Solo
-  l'amministratore può utilizzare questo comando.
+    locking} sul segmento di memoria condivisa, impedendo che la memoria usata
+  per il segmento venga salvata su disco dal meccanismo della
+  \index{memoria~virtuale} memoria virtuale. Come illustrato in
+  sez.~\ref{sec:proc_mem_lock} fino al kernel 2.6.9 solo l'amministratore
+  poteva utilizzare questa capacità,\footnote{che richiedeva la
+    \textit{capability} \const{CAP\_IPC\_LOCK}.} a partire dal dal kernel
+  2.6.10 anche gli utenti normali possono farlo fina al limite massimo
+  determinato da \const{RLIMIT\_MEMLOCK} (vedi
+  sez.~\ref{sec:sys_resource_limit}).
 \item[\const{SHM\_UNLOCK}] Disabilita il \itindex{memory~locking}
-  \textit{memory locking} sul segmento di memoria condivisa.  Solo
-  l'amministratore può utilizzare questo comando.
+  \textit{memory locking} sul segmento di memoria condivisa.  Fino al kernel
+  2.6.9 solo l'amministratore poteva utilizzare questo comando. 
 \end{basedescript}
-i primi tre comandi sono gli stessi già visti anche per le code di messaggi e
+
+I primi tre comandi sono gli stessi già visti anche per le code di messaggi e
 gli insiemi di semafori, gli ultimi due sono delle estensioni specifiche
 previste da Linux, che permettono di abilitare e disabilitare il meccanismo
 della \index{memoria~virtuale} memoria virtuale per il segmento.
@@ -4861,11 +4907,11 @@ testo alla terminazione di quest'ultimo.
 % LocalWords:  for now it's break Berlin sources Let's an accidental feature
 % LocalWords:  Larry Wall Escape the Hell William ipctestid Identifier segment
 % LocalWords:  violation dell'I SIGINT setter Fri Dec Sleeping seconds ECHILD
+% LocalWords:  SysV capability short RESOURCE INFO UNDEFINED EFBIG semtimedop
+% LocalWords:  scan
 
 
 %%% Local Variables: 
 %%% mode: latex
 %%% TeX-master: "gapil"
 %%% End: 
-% LocalWords:  SysV capability short RESOURCE INFO UNDEFINED EFBIG semtimedop
-% LocalWords:  scan
index a43b81005e19a3d65055cb881dc364177937c05e..994c2f656740638daf05ab149892abc8f64fa5e6 100644 (file)
@@ -656,13 +656,13 @@ necessariamente adiacenti.
 Per la gestione da parte del kernel la memoria viene divisa in pagine di
 dimensione fissa. Inizialmente queste pagine erano di 4kb sulle macchine a 32
 bit e di 8kb sulle alpha. Con le versioni più recenti del kernel è possibile
-anche utilizzare pagine di dimensioni maggiori (di 4Mb, dette \textit{huge
-  page}), per sistemi con grandi quantitativi di memoria in cui l'uso di
-pagine troppo piccole comporta una perdita di prestazioni. In alcuni sistemi
-la costante \const{PAGE\_SIZE}, definita in \headfile{limits.h}, indica la
-dimensione di una pagina in byte, con Linux questo non avviene e per ottenere
-questa dimensione si deve ricorrere alla funzione \func{getpagesize} (vedi
-sez.~\ref{sec:sys_memory_res}).
+anche utilizzare pagine di dimensioni maggiori (di 4Mb, dette
+\itindex{huge~page} \textit{huge page}), per sistemi con grandi quantitativi
+di memoria in cui l'uso di pagine troppo piccole comporta una perdita di
+prestazioni. In alcuni sistemi la costante \const{PAGE\_SIZE}, definita in
+\headfile{limits.h}, indica la dimensione di una pagina in byte, con Linux
+questo non avviene e per ottenere questa dimensione si deve ricorrere alla
+funzione \func{getpagesize} (vedi sez.~\ref{sec:sys_memory_res}).
 
 Ciascuna pagina di memoria nello spazio di indirizzi virtuale è associata ad
 un supporto che può essere una pagina di memoria reale o ad un dispositivo di