sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextEnglish}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget/kernel-hacking/lockingmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Simplified)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/zh_CN/kernel-hacking/lockingmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hChinese (Traditional)}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/zh_TW/kernel-hacking/lockingmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/ja_JP/kernel-hacking/lockingmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/ko_KR/kernel-hacking/lockingmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/sp_SP/kernel-hacking/lockingmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageItalianuh1h hh _documenthsourceNlineNubhwarning)}(hIn caso di dubbi sulla correttezza del contenuto di questa traduzione, l'unico riferimento valido è la documentazione ufficiale in inglese. Per maggiori informazioni consultate le :ref:`avvertenze `.h]h paragraph)}(hIn caso di dubbi sulla correttezza del contenuto di questa traduzione, l'unico riferimento valido è la documentazione ufficiale in inglese. Per maggiori informazioni consultate le :ref:`avvertenze `.h](hIn caso di dubbi sulla correttezza del contenuto di questa traduzione, l’unico riferimento valido è la documentazione ufficiale in inglese. Per maggiori informazioni consultate le }(hhhhhNhNubh)}(h!:ref:`avvertenze `h]hinline)}(hhh]h avvertenze}(hhhhhNhNubah}(h]h ](xrefstdstd-refeh"]h$]h&]uh1hhhubah}(h]h ]h"]h$]h&]refdoc)translations/it_IT/kernel-hacking/locking refdomainhŒreftyperef refexplicitrefwarn reftarget it_disclaimeruh1hh3Documentation/translations/it_IT/disclaimer-ita.rsthKhhubh.}(hhhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubh field_list)}(hhh](hfield)}(hhh](h field_name)}(hOriginalh]hOriginal}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhW/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking.rsthKubh field_body)}(hE:ref:`Documentation/kernel-hacking/locking.rst `h]h)}(hjh]h)}(hjh]h)}(hjh]h(Documentation/kernel-hacking/locking.rst}(hjhhhNhNubah}(h]h ](hstdstd-refeh"]h$]h&]uh1hhj ubah}(h]h ]h"]h$]h&]refdochΌ refdomainjreftyperef refexplicitrefwarnhԌkernel_hacking_lockuh1hhjhKhjubah}(h]h ]h"]h$]h&]uh1hhjhKhjubah}(h]h ]h"]h$]h&]uh1jhhubeh}(h]h ]h"]h$]h&]uh1hhjhKhhhhubh)}(hhh](h)}(h Translatorh]h Translator}(hj?hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj<hjhKubj)}(h)Federico Vaga h]h)}(h(Federico Vaga h](hFederico Vaga <}(hjQhhhNhNubh reference)}(hfederico.vaga@vaga.pv.ith]hfederico.vaga@vaga.pv.it}(hj[hhhNhNubah}(h]h ]h"]h$]h&]refurimailto:federico.vaga@vaga.pv.ituh1jYhjQubh>}(hjQhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhKhjMubah}(h]h ]h"]h$]h&]uh1jhj<ubeh}(h]h ]h"]h$]h&]uh1hhjhKhhhhubeh}(h]h ]h"]h$]h&]uh1hhhhhhjhKubhtarget)}(h.. _it_kernel_hacking_lock:h]h}(h]h ]h"]h$]h&]refidit-kernel-hacking-lockuh1jhKhhhhhjubhsection)}(hhh](htitle)}(h*L'inaffidabile guida alla sincronizzazioneh]h,L’inaffidabile guida alla sincronizzazione}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhK ubh)}(hhh]h)}(hhh](h)}(hAuthorh]hAuthor}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhjhKubj)}(hRusty Russell h]h)}(h Rusty Russellh]h Rusty Russell}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1hhjhKhjhhubah}(h]h ]h"]h$]h&]uh1hhjhhhjhKubj)}(hhh](j)}(h Introduzioneh]h Introduzione}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhKubh)}(hBenvenuto, alla notevole ed inaffidabile guida ai problemi di sincronizzazione (locking) nel kernel. Questo documento descrive il sistema di sincronizzazione nel kernel Linux 2.6.h]hBenvenuto, alla notevole ed inaffidabile guida ai problemi di sincronizzazione (locking) nel kernel. Questo documento descrive il sistema di sincronizzazione nel kernel Linux 2.6.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjhhubh)}(hDato il largo utilizzo del multi-threading e della prelazione nel kernel Linux, chiunque voglia dilettarsi col kernel deve conoscere i concetti fondamentali della concorrenza e della sincronizzazione nei sistemi multi-processore.h]hDato il largo utilizzo del multi-threading e della prelazione nel kernel Linux, chiunque voglia dilettarsi col kernel deve conoscere i concetti fondamentali della concorrenza e della sincronizzazione nei sistemi multi-processore.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjhhubeh}(h] introduzioneah ]h"] introduzioneah$]h&]uh1jhjhhhjhKubj)}(hhh](j)}(hIl problema con la concorrenzah]hIl problema con la concorrenza}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhKubh)}(h4(Saltatelo se sapete già cos'è una corsa critica).h]h6(Saltatelo se sapete già cos’è una corsa critica).}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjhhubh)}(hLIn un normale programma, potete incrementare un contatore nel seguente modo:h]hLIn un normale programma, potete incrementare un contatore nel seguente modo:}(hj6hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK!hjhhubh literal_block)}(h contatore++;h]h contatore++;}hjFsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1jDhjhK%hjhhubh)}(h7Questo è quello che vi aspettereste che accada sempre:h]h7Questo è quello che vi aspettereste che accada sempre:}(hjVhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK'hjhhubhtable)}(hhh](j)}(hRisultati attesih]hRisultati attesi}(hjihhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhK*hjfubhtgroup)}(hhh](hcolspec)}(hhh]h}(h]h ]h"]h$]h&]colwidthK$uh1j|hjyubj})}(hhh]h}(h]h ]h"]h$]h&]colwidthK$uh1j|hjyubhthead)}(hhh]hrow)}(hhh](hentry)}(hhh]h)}(h Istanza 1h]h Istanza 1}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK-hjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(h Istanza 2h]h Istanza 2}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK-hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1jhjyubhtbody)}(hhh](j)}(hhh](j)}(hhh]h)}(hleggi contatore (5)h]hleggi contatore (5)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK/hjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(haggiungi 1 (6)h]haggiungi 1 (6)}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK1hj ubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(hscrivi contatore (6)h]hscrivi contatore (6)}(hj5hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK3hj2ubah}(h]h ]h"]h$]h&]uh1jhj/ubj)}(hhh]h}(h]h ]h"]h$]h&]uh1jhj/ubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h}(h]h ]h"]h$]h&]uh1jhjXubj)}(hhh]h)}(hleggi contatore (6)h]hleggi contatore (6)}(hjghhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK5hjdubah}(h]h ]h"]h$]h&]uh1jhjXubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(haggiungi 1 (7)h]haggiungi 1 (7)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK7hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(hscrivi contatore (7)h]hscrivi contatore (7)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK9hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjyubeh}(h]h ]h"]h$]h&]colsKuh1jwhjfubeh}(h]id1ah ]h"]h$]h&]uh1jdhjhhhjhNubh)}(h3Questo è quello che potrebbe succedere in realtà:h]h3Questo è quello che potrebbe succedere in realtà:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjubjx)}(hhh](j})}(hhh]h}(h]h ]h"]h$]h&]colwidthK$uh1j|hjubj})}(hhh]h}(h]h ]h"]h$]h&]colwidthK$uh1j|hjubj)}(hhh]j)}(hhh](j)}(hhh]h)}(h Istanza 1h]h Istanza 1}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKAhj#ubah}(h]h ]h"]h$]h&]uh1jhj ubj)}(hhh]h)}(h Istanza 2h]h Istanza 2}(hj=hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKAhj:ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh](j)}(hhh]h)}(hleggi contatore (5)h]hleggi contatore (5)}(hjfhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKChjcubah}(h]h ]h"]h$]h&]uh1jhj`ubj)}(hhh]h}(h]h ]h"]h$]h&]uh1jhj`ubeh}(h]h ]h"]h$]h&]uh1jhj]ubj)}(hhh](j)}(hhh]h}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(hleggi contatore (5)h]hleggi contatore (5)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKEhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhj]ubj)}(hhh](j)}(hhh]h)}(haggiungi 1 (6)h]haggiungi 1 (6)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKGhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhj]ubj)}(hhh](j)}(hhh]h}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(haggiungi 1 (6)h]haggiungi 1 (6)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKIhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhj]ubj)}(hhh](j)}(hhh]h)}(hscrivi contatore (6)h]hscrivi contatore (6)}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKKhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhj]ubj)}(hhh](j)}(hhh]h}(h]h ]h"]h$]h&]uh1jhj-ubj)}(hhh]h)}(hscrivi contatore (6)h]hscrivi contatore (6)}(hj<hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKMhj9ubah}(h]h ]h"]h$]h&]uh1jhj-ubeh}(h]h ]h"]h$]h&]uh1jhj]ubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]colsKuh1jwhjubeh}(h]id2ah ]h"]h$]h&]uh1jdhjhhhjhNubj)}(hhh](j)}(h!Corse critiche e sezioni criticheh]h!Corse critiche e sezioni critiche}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjjhhhjhKRubh)}(hXQuesta sovrapposizione, ovvero quando un risultato dipende dal tempo che intercorre fra processi diversi, è chiamata corsa critica. La porzione di codice che contiene questo problema è chiamata sezione critica. In particolar modo da quando Linux ha incominciato a girare su macchine multi-processore, le sezioni critiche sono diventate uno dei maggiori problemi di progettazione ed implementazione del kernel.h]hXQuesta sovrapposizione, ovvero quando un risultato dipende dal tempo che intercorre fra processi diversi, è chiamata corsa critica. La porzione di codice che contiene questo problema è chiamata sezione critica. In particolar modo da quando Linux ha incominciato a girare su macchine multi-processore, le sezioni critiche sono diventate uno dei maggiori problemi di progettazione ed implementazione del kernel.}(hj{hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKThjjhhubh)}(hXLa prelazione può sortire gli stessi effetti, anche se c'è una sola CPU: interrompendo un processo nella sua sezione critica otterremo comunque la stessa corsa critica. In questo caso, il thread che si avvicenda nell'esecuzione potrebbe eseguire anch'esso la sezione critica.h]hXLa prelazione può sortire gli stessi effetti, anche se c’è una sola CPU: interrompendo un processo nella sua sezione critica otterremo comunque la stessa corsa critica. In questo caso, il thread che si avvicenda nell’esecuzione potrebbe eseguire anch’esso la sezione critica.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK[hjjhhubh)}(hX1La soluzione è quella di riconoscere quando avvengono questi accessi simultanei, ed utilizzare i *lock* per accertarsi che solo un'istanza per volta possa entrare nella sezione critica. Il kernel offre delle buone funzioni a questo scopo. E poi ci sono quelle meno buone, ma farò finta che non esistano.h](hbLa soluzione è quella di riconoscere quando avvengono questi accessi simultanei, ed utilizzare i }(hjhhhNhNubhemphasis)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh per accertarsi che solo un’istanza per volta possa entrare nella sezione critica. Il kernel offre delle buone funzioni a questo scopo. E poi ci sono quelle meno buone, ma farò finta che non esistano.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhK`hjjhhubeh}(h]!corse-critiche-e-sezioni-criticheah ]h"]!corse critiche e sezioni criticheah$]h&]uh1jhjhhhjhKRubeh}(h]il-problema-con-la-concorrenzaah ]h"]il problema con la concorrenzaah$]h&]uh1jhjhhhjhKubj)}(hhh](j)}(h!Sincronizzazione nel kernel Linuxh]h!Sincronizzazione nel kernel Linux}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhKgubh)}(hRSe dovessi darvi un suggerimento sulla sincronizzazione: **mantenetela semplice**.h](h9Se dovessi darvi un suggerimento sulla sincronizzazione: }(hjhhhNhNubhstrong)}(h**mantenetela semplice**h]hmantenetela semplice}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhKihjhhubh)}(h3Siate riluttanti nell'introduzione di nuovi *lock*.h](h.Siate riluttanti nell’introduzione di nuovi }(hjhhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhKlhjhhubj)}(hhh](j)}(hDovreste verificare sempre la sincronizzazione con le opzioni }(hjhhhNhNubjZ)}(h``CONFIG_SMP``h]h CONFIG_SMP}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubh e }(hjhhhNhNubjZ)}(h``CONFIG_PREEMPT``h]hCONFIG_PREEMPT}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubh abilitate, anche quando non avete un sistema multi-processore, questo vi permetterà di identificare alcuni problemi di sincronizzazione.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhKhjhhubh)}(hCome vedremo di seguito, i mutex continuano ad esistere perché sono necessari per la sincronizzazione fra processi in contesto utente.h]hCome vedremo di seguito, i mutex continuano ad esistere perché sono necessari per la sincronizzazione fra processi in contesto utente.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjhhubeh}(h],i-lock-e-i-kernel-per-sistemi-monoprocessoreah ]h"],i lock e i kernel per sistemi monoprocessoreah$]h&]uh1jhjhhhjhKubj)}(hhh](j)}(h#Sincronizzazione in contesto utenteh]h#Sincronizzazione in contesto utente}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhKubh)}(hXSe avete una struttura dati che verrà utilizzata solo dal contesto utente, allora, per proteggerla, potete utilizzare un semplice mutex (``include/linux/mutex.h``). Questo è il caso più semplice: inizializzate il mutex; invocate mutex_lock_interruptible() per trattenerlo e mutex_unlock() per rilasciarlo. C'è anche mutex_lock() ma questa dovrebbe essere evitata perché non ritorna in caso di segnali.h](hSe avete una struttura dati che verrà utilizzata solo dal contesto utente, allora, per proteggerla, potete utilizzare un semplice mutex (}(hjhhhNhNubjZ)}(h``include/linux/mutex.h``h]hinclude/linux/mutex.h}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubh). Questo è il caso più semplice: inizializzate il mutex; invocate mutex_lock_interruptible() per trattenerlo e mutex_unlock() per rilasciarlo. C’è anche mutex_lock() ma questa dovrebbe essere evitata perché non ritorna in caso di segnali.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhKhjhhubh)}(hXKPer esempio: ``net/netfilter/nf_sockopt.c`` permette la registrazione di nuove chiamate per setsockopt() e getsockopt() usando la funzione nf_register_sockopt(). La registrazione e la rimozione vengono eseguite solamente quando il modulo viene caricato o scaricato (e durante l'avvio del sistema, qui non abbiamo concorrenza), e la lista delle funzioni registrate viene consultata solamente quando setsockopt() o getsockopt() sono sconosciute al sistema. In questo caso ``nf_sockopt_mutex`` è perfetto allo scopo, in particolar modo visto che setsockopt e getsockopt potrebbero dormire.h](h Per esempio: }(hjhhhNhNubjZ)}(h``net/netfilter/nf_sockopt.c``h]hnet/netfilter/nf_sockopt.c}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubhX permette la registrazione di nuove chiamate per setsockopt() e getsockopt() usando la funzione nf_register_sockopt(). La registrazione e la rimozione vengono eseguite solamente quando il modulo viene caricato o scaricato (e durante l’avvio del sistema, qui non abbiamo concorrenza), e la lista delle funzioni registrate viene consultata solamente quando setsockopt() o getsockopt() sono sconosciute al sistema. In questo caso }(hjhhhNhNubjZ)}(h``nf_sockopt_mutex``h]hnf_sockopt_mutex}(hj2hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubha è perfetto allo scopo, in particolar modo visto che setsockopt e getsockopt potrebbero dormire.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhKhjhhubeh}(h]#sincronizzazione-in-contesto-utenteah ]h"]#sincronizzazione in contesto utenteah$]h&]uh1jhjhhhjhKubj)}(hhh](j)}(h3Sincronizzazione fra il contesto utente e i softirqh]h3Sincronizzazione fra il contesto utente e i softirq}(hjUhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjRhhhjhKubh)}(hXcSe un softirq condivide dati col contesto utente, avete due problemi. Primo, il contesto utente corrente potrebbe essere interroto da un softirq, e secondo, la sezione critica potrebbe essere eseguita da un altro processore. Questo è quando spin_lock_bh() (``include/linux/spinlock.h``) viene utilizzato. Questo disabilita i softirq sul processore e trattiene il *lock*. Invece, spin_unlock_bh() fa l'opposto. (Il suffisso '_bh' è un residuo storico che fa riferimento al "Bottom Halves", il vecchio nome delle interruzioni software. In un mondo perfetto questa funzione si chiamerebbe 'spin_lock_softirq()').h](hXSe un softirq condivide dati col contesto utente, avete due problemi. Primo, il contesto utente corrente potrebbe essere interroto da un softirq, e secondo, la sezione critica potrebbe essere eseguita da un altro processore. Questo è quando spin_lock_bh() (}(hjchhhNhNubjZ)}(h``include/linux/spinlock.h``h]hinclude/linux/spinlock.h}(hjkhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjcubhN) viene utilizzato. Questo disabilita i softirq sul processore e trattiene il }(hjchhhNhNubj)}(h*lock*h]hlock}(hj}hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjcubh. Invece, spin_unlock_bh() fa l’opposto. (Il suffisso ‘_bh’ è un residuo storico che fa riferimento al “Bottom Halves”, il vecchio nome delle interruzioni software. In un mondo perfetto questa funzione si chiamerebbe ‘spin_lock_softirq()’).}(hjchhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhKhjRhhubh)}(hDa notare che in questo caso potete utilizzare anche spin_lock_irq() o spin_lock_irqsave(), queste fermano anche le interruzioni hardware: vedere `Contesto di interruzione hardware`_.h](hDa notare che in questo caso potete utilizzare anche spin_lock_irq() o spin_lock_irqsave(), queste fermano anche le interruzioni hardware: vedere }(hjhhhNhNubjZ)}(h$`Contesto di interruzione hardware`_h]h!Contesto di interruzione hardware}(hjhhhNhNubah}(h]h ]h"]h$]h&]name!Contesto di interruzione hardwarej!contesto-di-interruzione-hardwareuh1jYhjjKubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhKhjRhhubh)}(hQuesto funziona alla perfezione anche sui sistemi monoprocessore: gli spinlock svaniscono e questa macro diventa semplicemente local_bh_disable() (``include/linux/interrupt.h``), la quale impedisce ai softirq d'essere eseguiti.h](hQuesto funziona alla perfezione anche sui sistemi monoprocessore: gli spinlock svaniscono e questa macro diventa semplicemente local_bh_disable() (}(hjhhhNhNubjZ)}(h``include/linux/interrupt.h``h]hinclude/linux/interrupt.h}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubh5), la quale impedisce ai softirq d’essere eseguiti.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhKhjRhhubeh}(h]3sincronizzazione-fra-il-contesto-utente-e-i-softirqah ]h"]3sincronizzazione fra il contesto utente e i softirqah$]h&]uh1jhjhhhjhKubj)}(hhh](j)}(h0Sincronizzazione fra contesto utente e i taskleth]h0Sincronizzazione fra contesto utente e i tasklet}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhKubh)}(hMQuesto caso è uguale al precedente, un tasklet viene eseguito da un softirq.h]hMQuesto caso è uguale al precedente, un tasklet viene eseguito da un softirq.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjhhubeh}(h]0sincronizzazione-fra-contesto-utente-e-i-taskletah ]h"]0sincronizzazione fra contesto utente e i taskletah$]h&]uh1jhjhhhjhKubj)}(hhh](j)}(h.Sincronizzazione fra contesto utente e i timerh]h.Sincronizzazione fra contesto utente e i timer}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj hhhjhKubh)}(hAnche questo caso è uguale al precedente, un timer viene eseguito da un softirq. Dal punto di vista della sincronizzazione, tasklet e timer sono identici.h]hAnche questo caso è uguale al precedente, un timer viene eseguito da un softirq. Dal punto di vista della sincronizzazione, tasklet e timer sono identici.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhj hhubeh}(h].sincronizzazione-fra-contesto-utente-e-i-timerah ]h"].sincronizzazione fra contesto utente e i timerah$]h&]uh1jhjhhhjhKubj)}(hhh](j)}(h$Sincronizzazione fra tasklet e timerh]h$Sincronizzazione fra tasklet e timer}(hj1 hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj. hhhjhKubh)}(h_Qualche volta un tasklet od un timer potrebbero condividere i dati con un altro tasklet o timerh]h_Qualche volta un tasklet od un timer potrebbero condividere i dati con un altro tasklet o timer}(hj? hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhj. hhubj)}(hhh](j)}(hLo stesso tasklet/timerh]hLo stesso tasklet/timer}(hjP hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjM hhhjhKubh)}(hDato che un tasklet non viene mai eseguito contemporaneamente su due processori, non dovete preoccuparvi che sia rientrante (ovvero eseguito più volte in contemporanea), perfino su sistemi multi-processore.h]hDato che un tasklet non viene mai eseguito contemporaneamente su due processori, non dovete preoccuparvi che sia rientrante (ovvero eseguito più volte in contemporanea), perfino su sistemi multi-processore.}(hj^ hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjM hhubeh}(h]lo-stesso-tasklet-timerah ]h"]lo stesso tasklet/timerah$]h&]uh1jhj. hhhjhKubj)}(hhh](j)}(hDifferenti tasklet/timerh]hDifferenti tasklet/timer}(hjw hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjt hhhjhKubh)}(hXSe un altro tasklet/timer vuole condividere dati col vostro tasklet o timer, allora avrete bisogno entrambe di spin_lock() e spin_unlock(). Qui spin_lock_bh() è inutile, siete già in un tasklet ed avete la garanzia che nessun altro verrà eseguito sullo stesso processore.h]hXSe un altro tasklet/timer vuole condividere dati col vostro tasklet o timer, allora avrete bisogno entrambe di spin_lock() e spin_unlock(). Qui spin_lock_bh() è inutile, siete già in un tasklet ed avete la garanzia che nessun altro verrà eseguito sullo stesso processore.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjt hhubeh}(h]differenti-tasklet-timerah ]h"]differenti tasklet/timerah$]h&]uh1jhj. hhhjhKubeh}(h]$sincronizzazione-fra-tasklet-e-timerah ]h"]$sincronizzazione fra tasklet e timerah$]h&]uh1jhjhhhjhKubj)}(hhh](j)}(hSincronizzazione fra softirqh]hSincronizzazione fra softirq}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj hhhjhKubh)}(hMSpesso un softirq potrebbe condividere dati con se stesso o un tasklet/timer.h]hMSpesso un softirq potrebbe condividere dati con se stesso o un tasklet/timer.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhj hhubj)}(hhh](j)}(hLo stesso softirqh]hLo stesso softirq}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj hhhjhKubh)}(hXjLo stesso softirq può essere eseguito su un diverso processore: allo scopo di migliorare le prestazioni potete utilizzare dati riservati ad ogni processore (vedere `Dati per processore`_). Se siete arrivati fino a questo punto nell'uso dei softirq, probabilmente tenete alla scalabilità delle prestazioni abbastanza da giustificarne la complessità aggiuntiva.h](hLo stesso softirq può essere eseguito su un diverso processore: allo scopo di migliorare le prestazioni potete utilizzare dati riservati ad ogni processore (vedere }(hj hhhNhNubjZ)}(h`Dati per processore`_h]hDati per processore}(hj hhhNhNubah}(h]h ]h"]h$]h&]nameDati per processorejdati-per-processoreuh1jYhj jKubh). Se siete arrivati fino a questo punto nell’uso dei softirq, probabilmente tenete alla scalabilità delle prestazioni abbastanza da giustificarne la complessità aggiuntiva.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhKhj hhubh)}(hNDovete utilizzare spin_lock() e spin_unlock() per proteggere i dati condivisi.h]hNDovete utilizzare spin_lock() e spin_unlock() per proteggere i dati condivisi.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhj hhubeh}(h]lo-stesso-softirqah ]h"]lo stesso softirqah$]h&]uh1jhj hhhjhKubj)}(hhh](j)}(hDiversi Softirqsh]hDiversi Softirqs}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj hhhjhKubh)}(hDovete utilizzare spin_lock() e spin_unlock() per proteggere i dati condivisi, che siano timer, tasklet, diversi softirq o lo stesso o altri softirq: uno qualsiasi di essi potrebbe essere in esecuzione su un diverso processore.h]hDovete utilizzare spin_lock() e spin_unlock() per proteggere i dati condivisi, che siano timer, tasklet, diversi softirq o lo stesso o altri softirq: uno qualsiasi di essi potrebbe essere in esecuzione su un diverso processore.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhj hhubj)}(h.. _`it_hardirq-context`:h]h}(h]h ]h"]h$]h&]jit-hardirq-contextuh1jhMhj hhhjubeh}(h]diversi-softirqsah ]h"]diversi softirqsah$]h&]uh1jhj hhhjhKubeh}(h]sincronizzazione-fra-softirqah ]h"]sincronizzazione fra softirqah$]h&]uh1jhjhhhjhKubeh}(h]!sincronizzazione-nel-kernel-linuxah ]h"]!sincronizzazione nel kernel linuxah$]h&]uh1jhjhhhjhKgubj)}(hhh](j)}(h!Contesto di interruzione hardwareh]h!Contesto di interruzione hardware}(hjQ hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjN hhhjhMubh)}(hSolitamente le interruzioni hardware comunicano con un tasklet o un softirq. Spesso questo si traduce nel mettere in coda qualcosa da fare che verrà preso in carico da un softirq.h]hSolitamente le interruzioni hardware comunicano con un tasklet o un softirq. Spesso questo si traduce nel mettere in coda qualcosa da fare che verrà preso in carico da un softirq.}(hj_ hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjN hhubj)}(hhh](j)}(hhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMZhj;ubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhj ubj)}(hhh](j)}(hhh]h)}(hTimer Bh]hTimer B}(hjyhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM[hjvubah}(h]h ]h"]h$]h&]uh1jhjsubj)}(hhh]h)}(hSLIh]hSLI}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM[hjubah}(h]h ]h"]h$]h&]uh1jhjsubj)}(hhh]h)}(hSLIh]hSLI}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM[hjubah}(h]h ]h"]h$]h&]uh1jhjsubj)}(hhh]h)}(hSLh]hSL}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM[hjubah}(h]h ]h"]h$]h&]uh1jhjsubj)}(hhh]h)}(hSLh]hSL}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM[hjubah}(h]h ]h"]h$]h&]uh1jhjsubj)}(hhh]h)}(hSLh]hSL}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM[hjubah}(h]h ]h"]h$]h&]uh1jhjsubj)}(hhh]h)}(hSLh]hSL}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM[hjubah}(h]h ]h"]h$]h&]uh1jhjsubj)}(hhh]h)}(hSLh]hSL}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM[hjubah}(h]h ]h"]h$]h&]uh1jhjsubj)}(hhh]h)}(hNoneh]hNone}(hj1hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM[hj.ubah}(h]h ]h"]h$]h&]uh1jhjsubj)}(hhh]h}(h]h ]h"]h$]h&]uh1jhjsubj)}(hhh]h}(h]h ]h"]h$]h&]uh1jhjsubeh}(h]h ]h"]h$]h&]uh1jhj ubj)}(hhh](j)}(hhh]h)}(hUser Context Ah]hUser Context A}(hjchhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM\hj`ubah}(h]h ]h"]h$]h&]uh1jhj]ubj)}(hhh]h)}(hSLIh]hSLI}(hjzhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM\hjwubah}(h]h ]h"]h$]h&]uh1jhj]ubj)}(hhh]h)}(hSLIh]hSLI}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM\hjubah}(h]h ]h"]h$]h&]uh1jhj]ubj)}(hhh]h)}(hSLBHh]hSLBH}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM\hjubah}(h]h ]h"]h$]h&]uh1jhj]ubj)}(hhh]h)}(hSLBHh]hSLBH}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM\hjubah}(h]h ]h"]h$]h&]uh1jhj]ubj)}(hhh]h)}(hSLBHh]hSLBH}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM\hjubah}(h]h ]h"]h$]h&]uh1jhj]ubj)}(hhh]h)}(hSLBHh]hSLBH}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM\hjubah}(h]h ]h"]h$]h&]uh1jhj]ubj)}(hhh]h)}(hSLBHh]hSLBH}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM\hjubah}(h]h ]h"]h$]h&]uh1jhj]ubj)}(hhh]h)}(hSLBHh]hSLBH}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM\hjubah}(h]h ]h"]h$]h&]uh1jhj]ubj)}(hhh]h)}(hNoneh]hNone}(hj2hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM\hj/ubah}(h]h ]h"]h$]h&]uh1jhj]ubj)}(hhh]h}(h]h ]h"]h$]h&]uh1jhj]ubeh}(h]h ]h"]h$]h&]uh1jhj ubj)}(hhh](j)}(hhh]h)}(hUser Context Bh]hUser Context B}(hj[hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM]hjXubah}(h]h ]h"]h$]h&]uh1jhjUubj)}(hhh]h)}(hSLIh]hSLI}(hjrhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM]hjoubah}(h]h ]h"]h$]h&]uh1jhjUubj)}(hhh]h)}(hSLIh]hSLI}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM]hjubah}(h]h ]h"]h$]h&]uh1jhjUubj)}(hhh]h)}(hSLBHh]hSLBH}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM]hjubah}(h]h ]h"]h$]h&]uh1jhjUubj)}(hhh]h)}(hSLBHh]hSLBH}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM]hjubah}(h]h ]h"]h$]h&]uh1jhjUubj)}(hhh]h)}(hSLBHh]hSLBH}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM]hjubah}(h]h ]h"]h$]h&]uh1jhjUubj)}(hhh]h)}(hSLBHh]hSLBH}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM]hjubah}(h]h ]h"]h$]h&]uh1jhjUubj)}(hhh]h)}(hSLBHh]hSLBH}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM]hjubah}(h]h ]h"]h$]h&]uh1jhjUubj)}(hhh]h)}(hSLBHh]hSLBH}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM]hjubah}(h]h ]h"]h$]h&]uh1jhjUubj)}(hhh]h)}(hMLIh]hMLI}(hj*hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM]hj'ubah}(h]h ]h"]h$]h&]uh1jhjUubj)}(hhh]h)}(hNoneh]hNone}(hjAhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM]hj>ubah}(h]h ]h"]h$]h&]uh1jhjUubeh}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]colsK uh1jwhj ubah}(h]h ]h"]h$]h&]uh1jdhj hhhjhNubh)}(h4Table: Tabella dei requisiti per la sincronizzazioneh]h4Table: Tabella dei requisiti per la sincronizzazione}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM`hj hhubje)}(hhh]jx)}(hhh](j})}(hhh]h}(h]h ]h"]h$]h&]colwidthKuh1j|hjubj})}(hhh]h}(h]h ]h"]h$]h&]colwidthKuh1j|hjubj)}(hhh](j)}(hhh](j)}(hhh]h)}(hSLISh]hSLIS}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMchjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(hspin_lock_irqsaveh]hspin_lock_irqsave}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMchjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(hSLIh]hSLI}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMehjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(h spin_lock_irqh]h spin_lock_irq}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMehjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(hSLh]hSL}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMghj ubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(h spin_lockh]h spin_lock}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMghj!ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(hSLBHh]hSLBH}(hjDhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMihjAubah}(h]h ]h"]h$]h&]uh1jhj>ubj)}(hhh]h)}(h spin_lock_bhh]h spin_lock_bh}(hj[hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMihjXubah}(h]h ]h"]h$]h&]uh1jhj>ubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(hMLIh]hMLI}(hj{hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMkhjxubah}(h]h ]h"]h$]h&]uh1jhjuubj)}(hhh]h)}(hmutex_lock_interruptibleh]hmutex_lock_interruptible}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMkhjubah}(h]h ]h"]h$]h&]uh1jhjuubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]colsKuh1jwhj|ubah}(h]h ]h"]h$]h&]uh1jdhj hhhjhNubh)}(hCTable: Legenda per la tabella dei requisiti per la sincronizzazioneh]hCTable: Legenda per la tabella dei requisiti per la sincronizzazione}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMnhj hhubeh}(h]tabella-dei-requisiti-minimiah ]h"]tabella dei requisiti minimiah$]h&]uh1jhj6 hhhjhMDubeh}(h]bigino-della-sincronizzazioneah ]h"]bigino della sincronizzazioneah$]h&]uh1jhjhhhjhM4ubj)}(hhh](j)}(hLe funzioni *trylock*h](h Le funzioni }(hjhhhNhNubj)}(h *trylock*h]htrylock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhhhjhMqubh)}(hXCi sono funzioni che provano a trattenere un *lock* solo una volta e ritornano immediatamente comunicato il successo od il fallimento dell'operazione. Posso essere usate quando non serve accedere ai dati protetti dal *lock* quando qualche altro thread lo sta già facendo trattenendo il *lock*. Potrete acquisire il *lock* più tardi se vi serve accedere ai dati protetti da questo *lock*.h](h-Ci sono funzioni che provano a trattenere un }(hjhhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh solo una volta e ritornano immediatamente comunicato il successo od il fallimento dell’operazione. Posso essere usate quando non serve accedere ai dati protetti dal }(hjhhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh@ quando qualche altro thread lo sta già facendo trattenendo il }(hjhhhNhNubj)}(h*lock*h]hlock}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh. Potrete acquisire il }(hjhhhNhNubj)}(h*lock*h]hlock}(hj:hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh< più tardi se vi serve accedere ai dati protetti da questo }(hjhhhNhNubj)}(h*lock*h]hlock}(hjLhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMshjhhubh)}(hXRLa funzione spin_trylock() non ritenta di acquisire il *lock*, se ci riesce al primo colpo ritorna un valore diverso da zero, altrimenti se fallisce ritorna 0. Questa funzione può essere utilizzata in un qualunque contesto, ma come spin_lock(): dovete disabilitare i contesti che potrebbero interrompervi e quindi trattenere lo spinlock.h](h7La funzione spin_trylock() non ritenta di acquisire il }(hjdhhhNhNubj)}(h*lock*h]hlock}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjdubhX, se ci riesce al primo colpo ritorna un valore diverso da zero, altrimenti se fallisce ritorna 0. Questa funzione può essere utilizzata in un qualunque contesto, ma come spin_lock(): dovete disabilitare i contesti che potrebbero interrompervi e quindi trattenere lo spinlock.}(hjdhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMzhjhhubh)}(hX6La funzione mutex_trylock() invece di sospendere il vostro processo ritorna un valore diverso da zero se è possibile trattenere il lock al primo colpo, altrimenti se fallisce ritorna 0. Nonostante non dorma, questa funzione non può essere usata in modo sicuro in contesti di interruzione hardware o software.h]hX6La funzione mutex_trylock() invece di sospendere il vostro processo ritorna un valore diverso da zero se è possibile trattenere il lock al primo colpo, altrimenti se fallisce ritorna 0. Nonostante non dorma, questa funzione non può essere usata in modo sicuro in contesti di interruzione hardware o software.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjhhubeh}(h]le-funzioni-trylockah ]h"]le funzioni trylockah$]h&]uh1jhjhhhjhMqubj)}(hhh](j)}(hEsempi più comunih]hEsempi più comuni}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhMubh)}(hGuardiamo un semplice esempio: una memoria che associa nomi a numeri. La memoria tiene traccia di quanto spesso viene utilizzato ogni oggetto; quando è piena, l'oggetto meno usato viene eliminato.h]hGuardiamo un semplice esempio: una memoria che associa nomi a numeri. La memoria tiene traccia di quanto spesso viene utilizzato ogni oggetto; quando è piena, l’oggetto meno usato viene eliminato.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjhhubj)}(hhh](j)}(hTutto in contesto utenteh]hTutto in contesto utente}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhMubh)}(hXNel primo esempio, supponiamo che tutte le operazioni avvengano in contesto utente (in soldoni, da una chiamata di sistema), quindi possiamo dormire. Questo significa che possiamo usare i mutex per proteggere la nostra memoria e tutti gli oggetti che contiene. Ecco il codice::h]hXNel primo esempio, supponiamo che tutte le operazioni avvengano in contesto utente (in soldoni, da una chiamata di sistema), quindi possiamo dormire. Questo significa che possiamo usare i mutex per proteggere la nostra memoria e tutti gli oggetti che contiene. Ecco il codice:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjhhubjE)}(hX#include #include #include #include #include struct object { struct list_head list; int id; char name[32]; int popularity; }; /* Protects the cache, cache_num, and the objects within it */ static DEFINE_MUTEX(cache_lock); static LIST_HEAD(cache); static unsigned int cache_num = 0; #define MAX_CACHE_SIZE 10 /* Must be holding cache_lock */ static struct object *__cache_find(int id) { struct object *i; list_for_each_entry(i, &cache, list) if (i->id == id) { i->popularity++; return i; } return NULL; } /* Must be holding cache_lock */ static void __cache_delete(struct object *obj) { BUG_ON(!obj); list_del(&obj->list); kfree(obj); cache_num--; } /* Must be holding cache_lock */ static void __cache_add(struct object *obj) { list_add(&obj->list, &cache); if (++cache_num > MAX_CACHE_SIZE) { struct object *i, *outcast = NULL; list_for_each_entry(i, &cache, list) { if (!outcast || i->popularity < outcast->popularity) outcast = i; } __cache_delete(outcast); } } int cache_add(int id, const char *name) { struct object *obj; if ((obj = kmalloc(sizeof(*obj), GFP_KERNEL)) == NULL) return -ENOMEM; strscpy(obj->name, name, sizeof(obj->name)); obj->id = id; obj->popularity = 0; mutex_lock(&cache_lock); __cache_add(obj); mutex_unlock(&cache_lock); return 0; } void cache_delete(int id) { mutex_lock(&cache_lock); __cache_delete(__cache_find(id)); mutex_unlock(&cache_lock); } int cache_find(int id, char *name) { struct object *obj; int ret = -ENOENT; mutex_lock(&cache_lock); obj = __cache_find(id); if (obj) { ret = 0; strcpy(name, obj->name); } mutex_unlock(&cache_lock); return ret; }h]hX#include #include #include #include #include struct object { struct list_head list; int id; char name[32]; int popularity; }; /* Protects the cache, cache_num, and the objects within it */ static DEFINE_MUTEX(cache_lock); static LIST_HEAD(cache); static unsigned int cache_num = 0; #define MAX_CACHE_SIZE 10 /* Must be holding cache_lock */ static struct object *__cache_find(int id) { struct object *i; list_for_each_entry(i, &cache, list) if (i->id == id) { i->popularity++; return i; } return NULL; } /* Must be holding cache_lock */ static void __cache_delete(struct object *obj) { BUG_ON(!obj); list_del(&obj->list); kfree(obj); cache_num--; } /* Must be holding cache_lock */ static void __cache_add(struct object *obj) { list_add(&obj->list, &cache); if (++cache_num > MAX_CACHE_SIZE) { struct object *i, *outcast = NULL; list_for_each_entry(i, &cache, list) { if (!outcast || i->popularity < outcast->popularity) outcast = i; } __cache_delete(outcast); } } int cache_add(int id, const char *name) { struct object *obj; if ((obj = kmalloc(sizeof(*obj), GFP_KERNEL)) == NULL) return -ENOMEM; strscpy(obj->name, name, sizeof(obj->name)); obj->id = id; obj->popularity = 0; mutex_lock(&cache_lock); __cache_add(obj); mutex_unlock(&cache_lock); return 0; } void cache_delete(int id) { mutex_lock(&cache_lock); __cache_delete(__cache_find(id)); mutex_unlock(&cache_lock); } int cache_find(int id, char *name) { struct object *obj; int ret = -ENOENT; mutex_lock(&cache_lock); obj = __cache_find(id); if (obj) { ret = 0; strcpy(name, obj->name); } mutex_unlock(&cache_lock); return ret; }}hjsbah}(h]h ]h"]h$]h&]jTjUuh1jDhjhMhjhhubh)}(hXCDa notare che ci assicuriamo sempre di trattenere cache_lock quando aggiungiamo, rimuoviamo od ispezioniamo la memoria: sia la struttura della memoria che il suo contenuto sono protetti dal *lock*. Questo caso è semplice dato che copiamo i dati dall'utente e non permettiamo mai loro di accedere direttamente agli oggetti.h](hDa notare che ci assicuriamo sempre di trattenere cache_lock quando aggiungiamo, rimuoviamo od ispezioniamo la memoria: sia la struttura della memoria che il suo contenuto sono protetti dal }(hjhhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh. Questo caso è semplice dato che copiamo i dati dall’utente e non permettiamo mai loro di accedere direttamente agli oggetti.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjhhubh)}(hC'è una piccola ottimizzazione qui: nella funzione cache_add() impostiamo i campi dell'oggetto prima di acquisire il *lock*. Questo è sicuro perché nessun altro potrà accedervi finché non lo inseriremo nella memoria.h](hzC’è una piccola ottimizzazione qui: nella funzione cache_add() impostiamo i campi dell’oggetto prima di acquisire il }(hjhhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubha. Questo è sicuro perché nessun altro potrà accedervi finché non lo inseriremo nella memoria.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjhhubeh}(h]tutto-in-contesto-utenteah ]h"]tutto in contesto utenteah$]h&]uh1jhjhhhjhMubj)}(hhh](j)}(hAccesso dal contesto utenteh]hAccesso dal contesto utente}(hj1hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj.hhhjhMubh)}(hOra consideriamo il caso in cui cache_find() può essere invocata dal contesto d'interruzione: sia hardware che software. Un esempio potrebbe essere un timer che elimina oggetti dalla memoria.h]hOra consideriamo il caso in cui cache_find() può essere invocata dal contesto d’interruzione: sia hardware che software. Un esempio potrebbe essere un timer che elimina oggetti dalla memoria.}(hj?hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj.hhubh)}(hQui di seguito troverete la modifica nel formato *patch*: le righe ``-`` sono quelle rimosse, mentre quelle ``+`` sono quelle aggiunte.h](h1Qui di seguito troverete la modifica nel formato }(hjMhhhNhNubj)}(h*patch*h]hpatch}(hjUhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjMubh : le righe }(hjMhhhNhNubjZ)}(h``-``h]h-}(hjghhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjMubh$ sono quelle rimosse, mentre quelle }(hjMhhhNhNubjZ)}(h``+``h]h+}(hjyhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjMubh sono quelle aggiunte.}(hjMhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj.hhubjE)}(hX'--- cache.c.usercontext 2003-12-09 13:58:54.000000000 +1100 +++ cache.c.interrupt 2003-12-09 14:07:49.000000000 +1100 @@ -12,7 +12,7 @@ int popularity; }; -static DEFINE_MUTEX(cache_lock); +static DEFINE_SPINLOCK(cache_lock); static LIST_HEAD(cache); static unsigned int cache_num = 0; #define MAX_CACHE_SIZE 10 @@ -55,6 +55,7 @@ int cache_add(int id, const char *name) { struct object *obj; + unsigned long flags; if ((obj = kmalloc(sizeof(*obj), GFP_KERNEL)) == NULL) return -ENOMEM; @@ -63,30 +64,33 @@ obj->id = id; obj->popularity = 0; - mutex_lock(&cache_lock); + spin_lock_irqsave(&cache_lock, flags); __cache_add(obj); - mutex_unlock(&cache_lock); + spin_unlock_irqrestore(&cache_lock, flags); return 0; } void cache_delete(int id) { - mutex_lock(&cache_lock); + unsigned long flags; + + spin_lock_irqsave(&cache_lock, flags); __cache_delete(__cache_find(id)); - mutex_unlock(&cache_lock); + spin_unlock_irqrestore(&cache_lock, flags); } int cache_find(int id, char *name) { struct object *obj; int ret = -ENOENT; + unsigned long flags; - mutex_lock(&cache_lock); + spin_lock_irqsave(&cache_lock, flags); obj = __cache_find(id); if (obj) { ret = 0; strcpy(name, obj->name); } - mutex_unlock(&cache_lock); + spin_unlock_irqrestore(&cache_lock, flags); return ret; }h]hX'--- cache.c.usercontext 2003-12-09 13:58:54.000000000 +1100 +++ cache.c.interrupt 2003-12-09 14:07:49.000000000 +1100 @@ -12,7 +12,7 @@ int popularity; }; -static DEFINE_MUTEX(cache_lock); +static DEFINE_SPINLOCK(cache_lock); static LIST_HEAD(cache); static unsigned int cache_num = 0; #define MAX_CACHE_SIZE 10 @@ -55,6 +55,7 @@ int cache_add(int id, const char *name) { struct object *obj; + unsigned long flags; if ((obj = kmalloc(sizeof(*obj), GFP_KERNEL)) == NULL) return -ENOMEM; @@ -63,30 +64,33 @@ obj->id = id; obj->popularity = 0; - mutex_lock(&cache_lock); + spin_lock_irqsave(&cache_lock, flags); __cache_add(obj); - mutex_unlock(&cache_lock); + spin_unlock_irqrestore(&cache_lock, flags); return 0; } void cache_delete(int id) { - mutex_lock(&cache_lock); + unsigned long flags; + + spin_lock_irqsave(&cache_lock, flags); __cache_delete(__cache_find(id)); - mutex_unlock(&cache_lock); + spin_unlock_irqrestore(&cache_lock, flags); } int cache_find(int id, char *name) { struct object *obj; int ret = -ENOENT; + unsigned long flags; - mutex_lock(&cache_lock); + spin_lock_irqsave(&cache_lock, flags); obj = __cache_find(id); if (obj) { ret = 0; strcpy(name, obj->name); } - mutex_unlock(&cache_lock); + spin_unlock_irqrestore(&cache_lock, flags); return ret; }}hjsbah}(h]h ]h"]h$]h&]jTjUuh1jDhjhM hj.hhubh)}(hDa notare che spin_lock_irqsave() disabiliterà le interruzioni se erano attive, altrimenti non farà niente (quando siamo già in un contesto d'interruzione); dunque queste funzioni possono essere chiamante in sicurezza da qualsiasi contesto.h]hDa notare che spin_lock_irqsave() disabiliterà le interruzioni se erano attive, altrimenti non farà niente (quando siamo già in un contesto d’interruzione); dunque queste funzioni possono essere chiamante in sicurezza da qualsiasi contesto.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMGhj.hhubh)}(hSfortunatamente, cache_add() invoca kmalloc() con l'opzione ``GFP_KERNEL`` che è permessa solo in contesto utente. Ho supposto che cache_add() venga chiamata dal contesto utente, altrimenti questa opzione deve diventare un parametro di cache_add().h](h>Sfortunatamente, cache_add() invoca kmalloc() con l’opzione }(hjhhhNhNubjZ)}(h``GFP_KERNEL``h]h GFP_KERNEL}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubh che è permessa solo in contesto utente. Ho supposto che cache_add() venga chiamata dal contesto utente, altrimenti questa opzione deve diventare un parametro di cache_add().}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMLhj.hhubeh}(h]accesso-dal-contesto-utenteah ]h"]accesso dal contesto utenteah$]h&]uh1jhjhhhjhMubj)}(hhh](j)}(h(Esporre gli oggetti al di fuori del fileh]h(Esporre gli oggetti al di fuori del file}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhMRubh)}(hXSe i vostri oggetti contengono più informazioni, potrebbe non essere sufficiente copiare i dati avanti e indietro: per esempio, altre parti del codice potrebbero avere un puntatore a questi oggetti piuttosto che cercarli ogni volta. Questo introduce due problemi.h]hXSe i vostri oggetti contengono più informazioni, potrebbe non essere sufficiente copiare i dati avanti e indietro: per esempio, altre parti del codice potrebbero avere un puntatore a questi oggetti piuttosto che cercarli ogni volta. Questo introduce due problemi.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMThjhhubh)}(hIl primo problema è che utilizziamo ``cache_lock`` per proteggere gli oggetti: dobbiamo renderlo dinamico così che il resto del codice possa usarlo. Questo rende la sincronizzazione più complicata dato che non avviene più in un unico posto.h](h%Il primo problema è che utilizziamo }(hjhhhNhNubjZ)}(h``cache_lock``h]h cache_lock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubh per proteggere gli oggetti: dobbiamo renderlo dinamico così che il resto del codice possa usarlo. Questo rende la sincronizzazione più complicata dato che non avviene più in un unico posto.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMYhjhhubh)}(hXrIl secondo problema è il problema del ciclo di vita: se un'altra struttura mantiene un puntatore ad un oggetto, presumibilmente si aspetta che questo puntatore rimanga valido. Sfortunatamente, questo è garantito solo mentre si trattiene il *lock*, altrimenti qualcuno potrebbe chiamare cache_delete() o peggio, aggiungere un oggetto che riutilizza lo stesso indirizzo.h](hIl secondo problema è il problema del ciclo di vita: se un’altra struttura mantiene un puntatore ad un oggetto, presumibilmente si aspetta che questo puntatore rimanga valido. Sfortunatamente, questo è garantito solo mentre si trattiene il }(hjhhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhz, altrimenti qualcuno potrebbe chiamare cache_delete() o peggio, aggiungere un oggetto che riutilizza lo stesso indirizzo.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhM^hjhhubh)}(hwDato che c'è un solo *lock*, non potete trattenerlo a vita: altrimenti nessun altro potrà eseguire il proprio lavoro.h](hDato che c’è un solo }(hj4hhhNhNubj)}(h*lock*h]hlock}(hj<hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj4ubh[, non potete trattenerlo a vita: altrimenti nessun altro potrà eseguire il proprio lavoro.}(hj4hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMehjhhubh)}(hX%La soluzione a questo problema è l'uso di un contatore di riferimenti: chiunque punti ad un oggetto deve incrementare il contatore, e decrementarlo quando il puntatore non viene più usato. Quando il contatore raggiunge lo zero significa che non è più usato e l'oggetto può essere rimosso.h]hX)La soluzione a questo problema è l’uso di un contatore di riferimenti: chiunque punti ad un oggetto deve incrementare il contatore, e decrementarlo quando il puntatore non viene più usato. Quando il contatore raggiunge lo zero significa che non è più usato e l’oggetto può essere rimosso.}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhhjhhubh)}(hEcco il codice::h]hEcco il codice:}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMmhjhhubjE)}(hX--- cache.c.interrupt 2003-12-09 14:25:43.000000000 +1100 +++ cache.c.refcnt 2003-12-09 14:33:05.000000000 +1100 @@ -7,6 +7,7 @@ struct object { struct list_head list; + unsigned int refcnt; int id; char name[32]; int popularity; @@ -17,6 +18,35 @@ static unsigned int cache_num = 0; #define MAX_CACHE_SIZE 10 +static void __object_put(struct object *obj) +{ + if (--obj->refcnt == 0) + kfree(obj); +} + +static void __object_get(struct object *obj) +{ + obj->refcnt++; +} + +void object_put(struct object *obj) +{ + unsigned long flags; + + spin_lock_irqsave(&cache_lock, flags); + __object_put(obj); + spin_unlock_irqrestore(&cache_lock, flags); +} + +void object_get(struct object *obj) +{ + unsigned long flags; + + spin_lock_irqsave(&cache_lock, flags); + __object_get(obj); + spin_unlock_irqrestore(&cache_lock, flags); +} + /* Must be holding cache_lock */ static struct object *__cache_find(int id) { @@ -35,6 +65,7 @@ { BUG_ON(!obj); list_del(&obj->list); + __object_put(obj); cache_num--; } @@ -63,6 +94,7 @@ strscpy(obj->name, name, sizeof(obj->name)); obj->id = id; obj->popularity = 0; + obj->refcnt = 1; /* The cache holds a reference */ spin_lock_irqsave(&cache_lock, flags); __cache_add(obj); @@ -79,18 +111,15 @@ spin_unlock_irqrestore(&cache_lock, flags); } -int cache_find(int id, char *name) +struct object *cache_find(int id) { struct object *obj; - int ret = -ENOENT; unsigned long flags; spin_lock_irqsave(&cache_lock, flags); obj = __cache_find(id); - if (obj) { - ret = 0; - strcpy(name, obj->name); - } + if (obj) + __object_get(obj); spin_unlock_irqrestore(&cache_lock, flags); - return ret; + return obj; }h]hX--- cache.c.interrupt 2003-12-09 14:25:43.000000000 +1100 +++ cache.c.refcnt 2003-12-09 14:33:05.000000000 +1100 @@ -7,6 +7,7 @@ struct object { struct list_head list; + unsigned int refcnt; int id; char name[32]; int popularity; @@ -17,6 +18,35 @@ static unsigned int cache_num = 0; #define MAX_CACHE_SIZE 10 +static void __object_put(struct object *obj) +{ + if (--obj->refcnt == 0) + kfree(obj); +} + +static void __object_get(struct object *obj) +{ + obj->refcnt++; +} + +void object_put(struct object *obj) +{ + unsigned long flags; + + spin_lock_irqsave(&cache_lock, flags); + __object_put(obj); + spin_unlock_irqrestore(&cache_lock, flags); +} + +void object_get(struct object *obj) +{ + unsigned long flags; + + spin_lock_irqsave(&cache_lock, flags); + __object_get(obj); + spin_unlock_irqrestore(&cache_lock, flags); +} + /* Must be holding cache_lock */ static struct object *__cache_find(int id) { @@ -35,6 +65,7 @@ { BUG_ON(!obj); list_del(&obj->list); + __object_put(obj); cache_num--; } @@ -63,6 +94,7 @@ strscpy(obj->name, name, sizeof(obj->name)); obj->id = id; obj->popularity = 0; + obj->refcnt = 1; /* The cache holds a reference */ spin_lock_irqsave(&cache_lock, flags); __cache_add(obj); @@ -79,18 +111,15 @@ spin_unlock_irqrestore(&cache_lock, flags); } -int cache_find(int id, char *name) +struct object *cache_find(int id) { struct object *obj; - int ret = -ENOENT; unsigned long flags; spin_lock_irqsave(&cache_lock, flags); obj = __cache_find(id); - if (obj) { - ret = 0; - strcpy(name, obj->name); - } + if (obj) + __object_get(obj); spin_unlock_irqrestore(&cache_lock, flags); - return ret; + return obj; }}hjpsbah}(h]h ]h"]h$]h&]jTjUuh1jDhjhMohjhhubh)}(hXAbbiamo incapsulato il contatore di riferimenti nelle tipiche funzioni di 'get' e 'put'. Ora possiamo ritornare l'oggetto da cache_find() col vantaggio che l'utente può dormire trattenendo l'oggetto (per esempio, copy_to_user() per copiare il nome verso lo spazio utente).h]hXAbbiamo incapsulato il contatore di riferimenti nelle tipiche funzioni di ‘get’ e ‘put’. Ora possiamo ritornare l’oggetto da cache_find() col vantaggio che l’utente può dormire trattenendo l’oggetto (per esempio, copy_to_user() per copiare il nome verso lo spazio utente).}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjhhubh)}(hX)Un altro punto da notare è che ho detto che il contatore dovrebbe incrementarsi per ogni puntatore ad un oggetto: quindi il contatore di riferimenti è 1 quando l'oggetto viene inserito nella memoria. In altre versione il framework non trattiene un riferimento per se, ma diventa più complicato.h]hX+Un altro punto da notare è che ho detto che il contatore dovrebbe incrementarsi per ogni puntatore ad un oggetto: quindi il contatore di riferimenti è 1 quando l’oggetto viene inserito nella memoria. In altre versione il framework non trattiene un riferimento per se, ma diventa più complicato.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjhhubj)}(hhh](j)}(h9Usare operazioni atomiche per il contatore di riferimentih]h9Usare operazioni atomiche per il contatore di riferimenti}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhMubh)}(hXRIn sostanza, :c:type:`atomic_t` viene usato come contatore di riferimenti. Ci sono un certo numbero di operazioni atomiche definite in ``include/asm/atomic.h``: queste sono garantite come atomiche su qualsiasi processore del sistema, quindi non sono necessari i *lock*. In questo caso è più semplice rispetto all'uso degli spinlock, benché l'uso degli spinlock sia più elegante per casi non banali. Le funzioni atomic_inc() e atomic_dec_and_test() vengono usate al posto dei tipici operatori di incremento e decremento, e i *lock* non sono più necessari per proteggere il contatore stesso.h](h In sostanza, }(hjhhhNhNubh)}(h:c:type:`atomic_t`h]jZ)}(hjh]hatomic_t}(hjhhhNhNubah}(h]h ](hcc-typeeh"]h$]h&]uh1jYhjubah}(h]h ]h"]h$]h&]refdochΌ refdomainjreftypetype refexplicitrefwarn c:parent_keysphinx.domains.c LookupKey)}data]j ASTIdentifier)} identifierit_ITsbNasbhԌatomic_tuh1hhjhMhjubhh viene usato come contatore di riferimenti. Ci sono un certo numbero di operazioni atomiche definite in }(hjhhhNhNubjZ)}(h``include/asm/atomic.h``h]hinclude/asm/atomic.h}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubhg: queste sono garantite come atomiche su qualsiasi processore del sistema, quindi non sono necessari i }(hjhhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhX. In questo caso è più semplice rispetto all’uso degli spinlock, benché l’uso degli spinlock sia più elegante per casi non banali. Le funzioni atomic_inc() e atomic_dec_and_test() vengono usate al posto dei tipici operatori di incremento e decremento, e i }(hjhhhNhNubj)}(h*lock*h]hlock}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh< non sono più necessari per proteggere il contatore stesso.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjhhubjE)}(hXg--- cache.c.refcnt 2003-12-09 15:00:35.000000000 +1100 +++ cache.c.refcnt-atomic 2003-12-11 15:49:42.000000000 +1100 @@ -7,7 +7,7 @@ struct object { struct list_head list; - unsigned int refcnt; + atomic_t refcnt; int id; char name[32]; int popularity; @@ -18,33 +18,15 @@ static unsigned int cache_num = 0; #define MAX_CACHE_SIZE 10 -static void __object_put(struct object *obj) -{ - if (--obj->refcnt == 0) - kfree(obj); -} - -static void __object_get(struct object *obj) -{ - obj->refcnt++; -} - void object_put(struct object *obj) { - unsigned long flags; - - spin_lock_irqsave(&cache_lock, flags); - __object_put(obj); - spin_unlock_irqrestore(&cache_lock, flags); + if (atomic_dec_and_test(&obj->refcnt)) + kfree(obj); } void object_get(struct object *obj) { - unsigned long flags; - - spin_lock_irqsave(&cache_lock, flags); - __object_get(obj); - spin_unlock_irqrestore(&cache_lock, flags); + atomic_inc(&obj->refcnt); } /* Must be holding cache_lock */ @@ -65,7 +47,7 @@ { BUG_ON(!obj); list_del(&obj->list); - __object_put(obj); + object_put(obj); cache_num--; } @@ -94,7 +76,7 @@ strscpy(obj->name, name, sizeof(obj->name)); obj->id = id; obj->popularity = 0; - obj->refcnt = 1; /* The cache holds a reference */ + atomic_set(&obj->refcnt, 1); /* The cache holds a reference */ spin_lock_irqsave(&cache_lock, flags); __cache_add(obj); @@ -119,7 +101,7 @@ spin_lock_irqsave(&cache_lock, flags); obj = __cache_find(id); if (obj) - __object_get(obj); + object_get(obj); spin_unlock_irqrestore(&cache_lock, flags); return obj; }h]hXg--- cache.c.refcnt 2003-12-09 15:00:35.000000000 +1100 +++ cache.c.refcnt-atomic 2003-12-11 15:49:42.000000000 +1100 @@ -7,7 +7,7 @@ struct object { struct list_head list; - unsigned int refcnt; + atomic_t refcnt; int id; char name[32]; int popularity; @@ -18,33 +18,15 @@ static unsigned int cache_num = 0; #define MAX_CACHE_SIZE 10 -static void __object_put(struct object *obj) -{ - if (--obj->refcnt == 0) - kfree(obj); -} - -static void __object_get(struct object *obj) -{ - obj->refcnt++; -} - void object_put(struct object *obj) { - unsigned long flags; - - spin_lock_irqsave(&cache_lock, flags); - __object_put(obj); - spin_unlock_irqrestore(&cache_lock, flags); + if (atomic_dec_and_test(&obj->refcnt)) + kfree(obj); } void object_get(struct object *obj) { - unsigned long flags; - - spin_lock_irqsave(&cache_lock, flags); - __object_get(obj); - spin_unlock_irqrestore(&cache_lock, flags); + atomic_inc(&obj->refcnt); } /* Must be holding cache_lock */ @@ -65,7 +47,7 @@ { BUG_ON(!obj); list_del(&obj->list); - __object_put(obj); + object_put(obj); cache_num--; } @@ -94,7 +76,7 @@ strscpy(obj->name, name, sizeof(obj->name)); obj->id = id; obj->popularity = 0; - obj->refcnt = 1; /* The cache holds a reference */ + atomic_set(&obj->refcnt, 1); /* The cache holds a reference */ spin_lock_irqsave(&cache_lock, flags); __cache_add(obj); @@ -119,7 +101,7 @@ spin_lock_irqsave(&cache_lock, flags); obj = __cache_find(id); if (obj) - __object_get(obj); + object_get(obj); spin_unlock_irqrestore(&cache_lock, flags); return obj; }}hj"sbah}(h]h ]h"]h$]h&]jTjUuh1jDhjhMhjhhubeh}(h]9usare-operazioni-atomiche-per-il-contatore-di-riferimentiah ]h"]9usare operazioni atomiche per il contatore di riferimentiah$]h&]uh1jhjhhhjhMubeh}(h](esporre-gli-oggetti-al-di-fuori-del-fileah ]h"](esporre gli oggetti al di fuori del fileah$]h&]uh1jhjhhhjhMRubj)}(hhh](j)}(hProteggere l'oggetto stessoh]hProteggere l’oggetto stesso}(hjChhhNhNubah}(h]h ]h"]h$]h&]uh1jhj@hhhjhM+ubh)}(hIn questo esempio, assumiamo che gli oggetti (ad eccezione del contatore di riferimenti) non cambino mai dopo la loro creazione. Se vogliamo permettere al nome di cambiare abbiamo tre possibilità:h]hIn questo esempio, assumiamo che gli oggetti (ad eccezione del contatore di riferimenti) non cambino mai dopo la loro creazione. Se vogliamo permettere al nome di cambiare abbiamo tre possibilità:}(hjQhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM-hj@hhubjV )}(hhh](j[ )}(hSi può togliere static da ``cache_lock`` e dire agli utenti che devono trattenere il *lock* prima di modificare il nome di un oggetto. h]h)}(hSi può togliere static da ``cache_lock`` e dire agli utenti che devono trattenere il *lock* prima di modificare il nome di un oggetto.h](hSi può togliere static da }(hjfhhhNhNubjZ)}(h``cache_lock``h]h cache_lock}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjfubh- e dire agli utenti che devono trattenere il }(hjfhhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjfubh+ prima di modificare il nome di un oggetto.}(hjfhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhM1hjbubah}(h]h ]h"]h$]h&]uh1jZ hj_hhhjhNubj[ )}(hSi può fornire una funzione cache_obj_rename() che prende il *lock* e cambia il nome per conto del chiamante; si dirà poi agli utenti di usare questa funzione. h]h)}(hSi può fornire una funzione cache_obj_rename() che prende il *lock* e cambia il nome per conto del chiamante; si dirà poi agli utenti di usare questa funzione.h](h>Si può fornire una funzione cache_obj_rename() che prende il }(hjhhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh] e cambia il nome per conto del chiamante; si dirà poi agli utenti di usare questa funzione.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhM4hjubah}(h]h ]h"]h$]h&]uh1jZ hj_hhhjhNubj[ )}(hSi può decidere che ``cache_lock`` protegge solo la memoria stessa, ed un altro *lock* è necessario per la protezione del nome. h]h)}(hSi può decidere che ``cache_lock`` protegge solo la memoria stessa, ed un altro *lock* è necessario per la protezione del nome.h](hSi può decidere che }(hjhhhNhNubjZ)}(h``cache_lock``h]h cache_lock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubh. protegge solo la memoria stessa, ed un altro }(hjhhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh* è necessario per la protezione del nome.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhM8hjubah}(h]h ]h"]h$]h&]uh1jZ hj_hhhjhNubeh}(h]h ]h"]h$]h&]j j uh1jU hjhM1hj@hhubh)}(hsTeoricamente, possiamo avere un *lock* per ogni campo e per ogni oggetto. In pratica, le varianti più comuni sono:h](h Teoricamente, possiamo avere un }(hj hhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubhM per ogni campo e per ogni oggetto. In pratica, le varianti più comuni sono:}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhM;hj@hhubjV )}(hhh](j[ )}(hun *lock* che protegge l'infrastruttura (la lista ``cache`` di questo esempio) e gli oggetti. Questo è quello che abbiamo fatto finora. h]h)}(hun *lock* che protegge l'infrastruttura (la lista ``cache`` di questo esempio) e gli oggetti. Questo è quello che abbiamo fatto finora.h](hun }(hj1hhhNhNubj)}(h*lock*h]hlock}(hj9hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj1ubh+ che protegge l’infrastruttura (la lista }(hj1hhhNhNubjZ)}(h ``cache``h]hcache}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj1ubhM di questo esempio) e gli oggetti. Questo è quello che abbiamo fatto finora.}(hj1hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhM>hj-ubah}(h]h ]h"]h$]h&]uh1jZ hj*hhhjhNubj[ )}(hun *lock* che protegge l'infrastruttura (inclusi i puntatori alla lista negli oggetti), e un *lock* nell'oggetto per proteggere il resto dell'oggetto stesso. h]h)}(hun *lock* che protegge l'infrastruttura (inclusi i puntatori alla lista negli oggetti), e un *lock* nell'oggetto per proteggere il resto dell'oggetto stesso.h](hun }(hjmhhhNhNubj)}(h*lock*h]hlock}(hjuhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjmubhV che protegge l’infrastruttura (inclusi i puntatori alla lista negli oggetti), e un }(hjmhhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjmubh> nell’oggetto per proteggere il resto dell’oggetto stesso.}(hjmhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMAhjiubah}(h]h ]h"]h$]h&]uh1jZ hj*hhhjhNubj[ )}(h*lock* multipli per proteggere l'infrastruttura (per esempio un *lock* per ogni lista), possibilmente con un *lock* per oggetto. h]h)}(h*lock* multipli per proteggere l'infrastruttura (per esempio un *lock* per ogni lista), possibilmente con un *lock* per oggetto.h](j)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh< multipli per proteggere l’infrastruttura (per esempio un }(hjhhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh' per ogni lista), possibilmente con un }(hjhhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh per oggetto.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMEhjubah}(h]h ]h"]h$]h&]uh1jZ hj*hhhjhNubeh}(h]h ]h"]h$]h&]j j uh1jU hjhM>hj@hhubh)}(hid = id; obj->popularity = 0; atomic_set(&obj->refcnt, 1); /* The cache holds a reference */ + spin_lock_init(&obj->lock); spin_lock_irqsave(&cache_lock, flags); __cache_add(obj);h]hX--- cache.c.refcnt-atomic 2003-12-11 15:50:54.000000000 +1100 +++ cache.c.perobjectlock 2003-12-11 17:15:03.000000000 +1100 @@ -6,11 +6,17 @@ struct object { + /* These two protected by cache_lock. */ struct list_head list; + int popularity; + atomic_t refcnt; + + /* Doesn't change once created. */ int id; + + spinlock_t lock; /* Protects the name */ char name[32]; - int popularity; }; static DEFINE_SPINLOCK(cache_lock); @@ -77,6 +84,7 @@ obj->id = id; obj->popularity = 0; atomic_set(&obj->refcnt, 1); /* The cache holds a reference */ + spin_lock_init(&obj->lock); spin_lock_irqsave(&cache_lock, flags); __cache_add(obj);}hjsbah}(h]h ]h"]h$]h&]jTjUuh1jDhjhMLhj@hhubh)}(hXwDa notare che ho deciso che il contatore di popolarità dovesse essere protetto da ``cache_lock`` piuttosto che dal *lock* dell'oggetto; questo perché è logicamente parte dell'infrastruttura (come :c:type:`struct list_head ` nell'oggetto). In questo modo, in __cache_add(), non ho bisogno di trattenere il *lock* di ogni oggetto mentre si cerca il meno popolare.h](hSDa notare che ho deciso che il contatore di popolarità dovesse essere protetto da }(hjhhhNhNubjZ)}(h``cache_lock``h]h cache_lock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubh piuttosto che dal }(hjhhhNhNubj)}(h*lock*h]hlock}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhQ dell’oggetto; questo perché è logicamente parte dell’infrastruttura (come }(hjhhhNhNubh)}(h&:c:type:`struct list_head `h]jZ)}(hj?h]hstruct list_head}(hjAhhhNhNubah}(h]h ](hjc-typeeh"]h$]h&]uh1jYhj=ubah}(h]h ]h"]h$]h&]refdochΌ refdomainjreftypetype refexplicitrefwarnjjhԌ list_headuh1hhjhMjhjubhT nell’oggetto). In questo modo, in __cache_add(), non ho bisogno di trattenere il }(hjhhhNhNubj)}(h*lock*h]hlock}(hj`hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh2 di ogni oggetto mentre si cerca il meno popolare.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMjhj@hhubh)}(hHo anche deciso che il campo id è immutabile, quindi non ho bisogno di trattenere il lock dell'oggetto quando si usa __cache_find() per leggere questo campo; il *lock* dell'oggetto è usato solo dal chiamante che vuole leggere o scrivere il campo name.h](hHo anche deciso che il campo id è immutabile, quindi non ho bisogno di trattenere il lock dell’oggetto quando si usa __cache_find() per leggere questo campo; il }(hjxhhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjxubhW dell’oggetto è usato solo dal chiamante che vuole leggere o scrivere il campo name.}(hjxhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMqhj@hhubh)}(hX2Inoltre, da notare che ho aggiunto un commento che descrive i dati che sono protetti dal *lock*. Questo è estremamente importante in quanto descrive il comportamento del codice, che altrimenti sarebbe di difficile comprensione leggendo solamente il codice. E come dice Alan Cox: “Lock data, not code”.h](hYInoltre, da notare che ho aggiunto un commento che descrive i dati che sono protetti dal }(hjhhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh. Questo è estremamente importante in quanto descrive il comportamento del codice, che altrimenti sarebbe di difficile comprensione leggendo solamente il codice. E come dice Alan Cox: “Lock data, not code”.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMvhj@hhubeh}(h]proteggere-l-oggetto-stessoah ]h"]proteggere l'oggetto stessoah$]h&]uh1jhjhhhjhM+ubeh}(h]esempi-piu-comuniah ]h"]esempi più comuniah$]h&]uh1jhjhhhjhMubj)}(hhh](j)}(hProblemi comunih]hProblemi comuni}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhM|ubj)}(hhh](j)}(hStallo: semplice ed avanzatoh]hStallo: semplice ed avanzato}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhMubh)}(hX\Esiste un tipo di baco dove un pezzo di codice tenta di trattenere uno spinlock due volte: questo rimarrà in attesa attiva per sempre aspettando che il *lock* venga rilasciato (in Linux spinlocks, rwlocks e mutex non sono ricorsivi). Questo è facile da diagnosticare: non è uno di quei problemi che ti tengono sveglio 5 notti a parlare da solo.h](hEsiste un tipo di baco dove un pezzo di codice tenta di trattenere uno spinlock due volte: questo rimarrà in attesa attiva per sempre aspettando che il }(hjhhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh venga rilasciato (in Linux spinlocks, rwlocks e mutex non sono ricorsivi). Questo è facile da diagnosticare: non è uno di quei problemi che ti tengono sveglio 5 notti a parlare da solo.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjhhubh)}(hX]Un caso un pochino più complesso; immaginate d'avere una spazio condiviso fra un softirq ed il contesto utente. Se usate spin_lock() per proteggerlo, il contesto utente potrebbe essere interrotto da un softirq mentre trattiene il lock, da qui il softirq rimarrà in attesa attiva provando ad acquisire il *lock* già trattenuto nel contesto utente.h](hX4Un caso un pochino più complesso; immaginate d’avere una spazio condiviso fra un softirq ed il contesto utente. Se usate spin_lock() per proteggerlo, il contesto utente potrebbe essere interrotto da un softirq mentre trattiene il lock, da qui il softirq rimarrà in attesa attiva provando ad acquisire il }(hj hhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh% già trattenuto nel contesto utente.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjhhubh)}(hX:Questi casi sono chiamati stalli (*deadlock*), e come mostrato qui sopra, può succedere anche con un solo processore (Ma non sui sistemi monoprocessore perché gli spinlock spariscano quando il kernel è compilato con ``CONFIG_SMP``\ =n. Nonostante ciò, nel secondo caso avrete comunque una corruzione dei dati).h](h"Questi casi sono chiamati stalli (}(hj*hhhNhNubj)}(h *deadlock*h]hdeadlock}(hj2hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj*ubh), e come mostrato qui sopra, può succedere anche con un solo processore (Ma non sui sistemi monoprocessore perché gli spinlock spariscano quando il kernel è compilato con }(hj*hhhNhNubjZ)}(h``CONFIG_SMP``h]h CONFIG_SMP}(hjDhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj*ubhQ =n. Nonostante ciò, nel secondo caso avrete comunque una corruzione dei dati).}(hj*hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjhhubh)}(hQuesti casi sono facili da diagnosticare; sui sistemi multi-processore il supervisione (*watchdog*) o l'opzione di compilazione ``DEBUG_SPINLOCK`` (``include/linux/spinlock.h``) permettono di scovare immediatamente quando succedono.h](hXQuesti casi sono facili da diagnosticare; sui sistemi multi-processore il supervisione (}(hj\hhhNhNubj)}(h *watchdog*h]hwatchdog}(hjdhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj\ubh ) o l’opzione di compilazione }(hj\hhhNhNubjZ)}(h``DEBUG_SPINLOCK``h]hDEBUG_SPINLOCK}(hjvhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj\ubh (}(hj\hhhNhNubjZ)}(h``include/linux/spinlock.h``h]hinclude/linux/spinlock.h}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj\ubh8) permettono di scovare immediatamente quando succedono.}(hj\hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjhhubh)}(hXEsiste un caso più complesso che è conosciuto come l'abbraccio della morte; questo coinvolge due o più *lock*. Diciamo che avete un vettore di hash in cui ogni elemento è uno spinlock a cui è associata una lista di elementi con lo stesso hash. In un gestore di interruzioni software, dovete modificare un oggetto e spostarlo su un altro hash; quindi dovrete trattenete lo spinlock del vecchio hash e di quello nuovo, quindi rimuovere l'oggetto dal vecchio ed inserirlo nel nuovo.h](hlEsiste un caso più complesso che è conosciuto come l’abbraccio della morte; questo coinvolge due o più }(hjhhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhXv. Diciamo che avete un vettore di hash in cui ogni elemento è uno spinlock a cui è associata una lista di elementi con lo stesso hash. In un gestore di interruzioni software, dovete modificare un oggetto e spostarlo su un altro hash; quindi dovrete trattenete lo spinlock del vecchio hash e di quello nuovo, quindi rimuovere l’oggetto dal vecchio ed inserirlo nel nuovo.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjhhubh)}(hXhQui abbiamo due problemi. Primo, se il vostro codice prova a spostare un oggetto all'interno della stessa lista, otterrete uno stallo visto che tenterà di trattenere lo stesso *lock* due volte. Secondo, se la stessa interruzione software su un altro processore sta tentando di spostare un altro oggetto nella direzione opposta, potrebbe accadere quanto segue:h](hQui abbiamo due problemi. Primo, se il vostro codice prova a spostare un oggetto all’interno della stessa lista, otterrete uno stallo visto che tenterà di trattenere lo stesso }(hjhhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh due volte. Secondo, se la stessa interruzione software su un altro processore sta tentando di spostare un altro oggetto nella direzione opposta, potrebbe accadere quanto segue:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjhhubje)}(hhh]jx)}(hhh](j})}(hhh]h}(h]h ]h"]h$]h&]colwidthK!uh1j|hjubj})}(hhh]h}(h]h ]h"]h$]h&]colwidthK!uh1j|hjubj)}(hhh]j)}(hhh](j)}(hhh]h)}(hCPU 1h]hCPU 1}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(hCPU 2h]hCPU 2}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh](j)}(hhh]h)}(hTrattiene *lock* A -> OKh](h Trattiene }(hjChhhNhNubj)}(h*lock*h]hlock}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjCubh A -> OK}(hjChhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj@ubah}(h]h ]h"]h$]h&]uh1jhj=ubj)}(hhh]h)}(hTrattiene *lock* B -> OKh](h Trattiene }(hjlhhhNhNubj)}(h*lock*h]hlock}(hjthhhNhNubah}(h]h ]h"]h$]h&]uh1jhjlubh B -> OK}(hjlhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjiubah}(h]h ]h"]h$]h&]uh1jhj=ubeh}(h]h ]h"]h$]h&]uh1jhj:ubj)}(hhh](j)}(hhh]h)}(hTrattiene *lock* B -> attesah](h Trattiene }(hjhhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh B -> attesa}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(hTrattiene *lock* A -> attesah](h Trattiene }(hjhhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh A -> attesa}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhj:ubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]colsKuh1jwhjubah}(h]h ]h"]h$]h&]uh1jdhjhhhjhNubh)}(hTable: Conseguenzeh]hTable: Conseguenze}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjhhubh)}(hEntrambe i processori rimarranno in attesa attiva sul *lock* per sempre, aspettando che l'altro lo rilasci. Sembra e puzza come un blocco totale.h](h6Entrambe i processori rimarranno in attesa attiva sul }(hjhhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhW per sempre, aspettando che l’altro lo rilasci. Sembra e puzza come un blocco totale.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjhhubeh}(h]jah ]h"]stallo: semplice ed avanzatoah$]h&]uh1jhjhhhjhMj5 Kubj)}(hhh](j)}(hPrevenire gli stallih]hPrevenire gli stalli}(hj>hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj;hhhjhMubh)}(hX8I libri di testo vi diranno che se trattenete i *lock* sempre nello stesso ordine non avrete mai un simile stallo. La pratica vi dirà che questo approccio non funziona all'ingrandirsi del sistema: quando creo un nuovo *lock* non ne capisco abbastanza del kernel per dire in quale dei 5000 *lock* si incastrerà.h](h0I libri di testo vi diranno che se trattenete i }(hjLhhhNhNubj)}(h*lock*h]hlock}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1jhjLubh sempre nello stesso ordine non avrete mai un simile stallo. La pratica vi dirà che questo approccio non funziona all’ingrandirsi del sistema: quando creo un nuovo }(hjLhhhNhNubj)}(h*lock*h]hlock}(hjfhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjLubhA non ne capisco abbastanza del kernel per dire in quale dei 5000 }(hjLhhhNhNubj)}(h*lock*h]hlock}(hjxhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjLubh si incastrerà.}(hjLhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj;hhubh)}(hXI *lock* migliori sono quelli incapsulati: non vengono esposti nei file di intestazione, e non vengono mai trattenuti fuori dallo stesso file. Potete rileggere questo codice e vedere che non ci sarà mai uno stallo perché non tenterà mai di trattenere un altro *lock* quando lo ha già. Le persone che usano il vostro codice non devono nemmeno sapere che voi state usando dei *lock*.h](hI }(hjhhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh migliori sono quelli incapsulati: non vengono esposti nei file di intestazione, e non vengono mai trattenuti fuori dallo stesso file. Potete rileggere questo codice e vedere che non ci sarà mai uno stallo perché non tenterà mai di trattenere un altro }(hjhhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhm quando lo ha già. Le persone che usano il vostro codice non devono nemmeno sapere che voi state usando dei }(hjhhhNhNubj)}(h*lock*h]hlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj;hhubh)}(hUn classico problema deriva dall'uso di *callback* e di *hook*: se li chiamate mentre trattenete un *lock*, rischiate uno stallo o un abbraccio della morte (chi lo sa cosa farà una *callback*?).h](h*Un classico problema deriva dall’uso di }(hjhhhNhNubj)}(h *callback*h]hcallback}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh e di }(hjhhhNhNubj)}(h*hook*h]hhook}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh&: se li chiamate mentre trattenete un }(hjhhhNhNubj)}(h*lock*h]hlock}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhL, rischiate uno stallo o un abbraccio della morte (chi lo sa cosa farà una }(hjhhhNhNubj)}(h *callback*h]hcallback}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh?).}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj;hhubj)}(hhh](j)}(h"Ossessiva prevenzione degli stallih]h"Ossessiva prevenzione degli stalli}(hj- hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj* hhhjhMubh)}(hXRGli stalli sono un problema, ma non così terribile come la corruzione dei dati. Un pezzo di codice trattiene un *lock* di lettura, cerca in una lista, fallisce nel trovare quello che vuole, quindi rilascia il *lock* di lettura, trattiene un *lock* di scrittura ed inserisce un oggetto; questo genere di codice presenta una corsa critica.h](hqGli stalli sono un problema, ma non così terribile come la corruzione dei dati. Un pezzo di codice trattiene un }(hj; hhhNhNubj)}(h*lock*h]hlock}(hjC hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj; ubh[ di lettura, cerca in una lista, fallisce nel trovare quello che vuole, quindi rilascia il }(hj; hhhNhNubj)}(h*lock*h]hlock}(hjU hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj; ubh di lettura, trattiene un }(hj; hhhNhNubj)}(h*lock*h]hlock}(hjg hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj; ubhZ di scrittura ed inserisce un oggetto; questo genere di codice presenta una corsa critica.}(hj; hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj* hhubeh}(h]"ossessiva-prevenzione-degli-stalliah ]h"]"ossessiva prevenzione degli stalliah$]h&]uh1jhj;hhhjhMubeh}(h]prevenire-gli-stalliah ]h"]prevenire gli stalliah$]h&]uh1jhjhhhjhMubj)}(hhh](j)}(h2corsa fra temporizzatori: un passatempo del kernelh]h2corsa fra temporizzatori: un passatempo del kernel}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj hhhjhMubh)}(hI temporizzatori potrebbero avere dei problemi con le corse critiche. Considerate una collezione di oggetti (liste, hash, eccetera) dove ogni oggetto ha un temporizzatore che sta per distruggerlo.Sh]hI temporizzatori potrebbero avere dei problemi con le corse critiche. Considerate una collezione di oggetti (liste, hash, eccetera) dove ogni oggetto ha un temporizzatore che sta per distruggerlo.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj hhubh)}(hhSe volete eliminare l'intera collezione (diciamo quando rimuovete un modulo), potreste fare come segue::h]hiSe volete eliminare l’intera collezione (diciamo quando rimuovete un modulo), potreste fare come segue:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj hhubjE)}(hX/* THIS CODE BAD BAD BAD BAD: IF IT WAS ANY WORSE IT WOULD USE HUNGARIAN NOTATION */ spin_lock_bh(&list_lock); while (list) { struct foo *next = list->next; timer_delete(&list->timer); kfree(list); list = next; } spin_unlock_bh(&list_lock);h]hX/* THIS CODE BAD BAD BAD BAD: IF IT WAS ANY WORSE IT WOULD USE HUNGARIAN NOTATION */ spin_lock_bh(&list_lock); while (list) { struct foo *next = list->next; timer_delete(&list->timer); kfree(list); list = next; } spin_unlock_bh(&list_lock);}hj sbah}(h]h ]h"]h$]h&]jTjUuh1jDhjhMhj hhubh)}(hX Primo o poi, questo esploderà su un sistema multiprocessore perché un temporizzatore potrebbe essere già partiro prima di spin_lock_bh(), e prenderà il *lock* solo dopo spin_unlock_bh(), e cercherà di eliminare il suo oggetto (che però è già stato eliminato).h](hPrimo o poi, questo esploderà su un sistema multiprocessore perché un temporizzatore potrebbe essere già partiro prima di spin_lock_bh(), e prenderà il }(hj hhhNhNubj)}(h*lock*h]hlock}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubhi solo dopo spin_unlock_bh(), e cercherà di eliminare il suo oggetto (che però è già stato eliminato).}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj hhubh)}(hQuesto può essere evitato controllando il valore di ritorno di timer_delete(): se ritorna 1, il temporizzatore è stato già rimosso. Se 0, significa (in questo caso) che il temporizzatore è in esecuzione, quindi possiamo fare come segue::h]hQuesto può essere evitato controllando il valore di ritorno di timer_delete(): se ritorna 1, il temporizzatore è stato già rimosso. Se 0, significa (in questo caso) che il temporizzatore è in esecuzione, quindi possiamo fare come segue:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj hhubjE)}(hXretry: spin_lock_bh(&list_lock); while (list) { struct foo *next = list->next; if (!timer_delete(&list->timer)) { /* Give timer a chance to delete this */ spin_unlock_bh(&list_lock); goto retry; } kfree(list); list = next; } spin_unlock_bh(&list_lock);h]hXretry: spin_lock_bh(&list_lock); while (list) { struct foo *next = list->next; if (!timer_delete(&list->timer)) { /* Give timer a chance to delete this */ spin_unlock_bh(&list_lock); goto retry; } kfree(list); list = next; } spin_unlock_bh(&list_lock);}hj sbah}(h]h ]h"]h$]h&]jTjUuh1jDhjhMhj hhubh)}(hX:Un altro problema è l'eliminazione dei temporizzatori che si riavviano da soli (chiamando add_timer() alla fine della loro esecuzione). Dato che questo è un problema abbastanza comune con una propensione alle corse critiche, dovreste usare timer_delete_sync() (``include/linux/timer.h``) per gestire questo caso.h](hX Un altro problema è l’eliminazione dei temporizzatori che si riavviano da soli (chiamando add_timer() alla fine della loro esecuzione). Dato che questo è un problema abbastanza comune con una propensione alle corse critiche, dovreste usare timer_delete_sync() (}(hj!hhhNhNubjZ)}(h``include/linux/timer.h``h]hinclude/linux/timer.h}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj!ubh) per gestire questo caso.}(hj!hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj hhubh)}(hPrima di rilasciare un temporizzatore dovreste chiamare la funzione timer_shutdown() o timer_shutdown_sync() di modo che non venga più riarmato. Ogni successivo tentativo di riarmare il temporizzatore verrà silenziosamente ignorato.h]hPrima di rilasciare un temporizzatore dovreste chiamare la funzione timer_shutdown() o timer_shutdown_sync() di modo che non venga più riarmato. Ogni successivo tentativo di riarmare il temporizzatore verrà silenziosamente ignorato.}(hj&!hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj hhubeh}(h]1corsa-fra-temporizzatori-un-passatempo-del-kernelah ]h"]2corsa fra temporizzatori: un passatempo del kernelah$]h&]uh1jhjhhhjhMubeh}(h]problemi-comuniah ]h"]problemi comuniah$]h&]uh1jhjhhhjhM|ubj)}(hhh](j)}(h Velocità della sincronizzazioneh]h Velocità della sincronizzazione}(hjG!hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjD!hhhjhMubh)}(hXCi sono tre cose importanti da tenere in considerazione quando si valuta la velocità d'esecuzione di un pezzo di codice che necessita di sincronizzazione. La prima è la concorrenza: quante cose rimangono in attesa mentre qualcuno trattiene un *lock*. La seconda è il tempo necessario per acquisire (senza contese) e rilasciare un *lock*. La terza è di usare meno *lock* o di più furbi. Immagino che i *lock* vengano usati regolarmente, altrimenti, non sareste interessati all'efficienza.h](hCi sono tre cose importanti da tenere in considerazione quando si valuta la velocità d’esecuzione di un pezzo di codice che necessita di sincronizzazione. La prima è la concorrenza: quante cose rimangono in attesa mentre qualcuno trattiene un }(hjU!hhhNhNubj)}(h*lock*h]hlock}(hj]!hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjU!ubhR. La seconda è il tempo necessario per acquisire (senza contese) e rilasciare un }(hjU!hhhNhNubj)}(h*lock*h]hlock}(hjo!hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjU!ubh. La terza è di usare meno }(hjU!hhhNhNubj)}(h*lock*h]hlock}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjU!ubh! o di più furbi. Immagino che i }(hjU!hhhNhNubj)}(h*lock*h]hlock}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjU!ubhR vengano usati regolarmente, altrimenti, non sareste interessati all’efficienza.}(hjU!hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjD!hhubh)}(hX9La concorrenza dipende da quanto a lungo un *lock* è trattenuto: dovreste trattenere un *lock* solo il tempo minimo necessario ma non un istante in più. Nella memoria dell'esempio precedente, creiamo gli oggetti senza trattenere il *lock*, poi acquisiamo il *lock* quando siamo pronti per inserirlo nella lista.h](h,La concorrenza dipende da quanto a lungo un }(hj!hhhNhNubj)}(h*lock*h]hlock}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj!ubh' è trattenuto: dovreste trattenere un }(hj!hhhNhNubj)}(h*lock*h]hlock}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj!ubh solo il tempo minimo necessario ma non un istante in più. Nella memoria dell’esempio precedente, creiamo gli oggetti senza trattenere il }(hj!hhhNhNubj)}(h*lock*h]hlock}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj!ubh, poi acquisiamo il }(hj!hhhNhNubj)}(h*lock*h]hlock}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj!ubh/ quando siamo pronti per inserirlo nella lista.}(hj!hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjD!hhubh)}(hXIl tempo di acquisizione di un *lock* dipende da quanto danno fa l'operazione sulla *pipeline* (ovvero stalli della *pipeline*) e quant'è probabile che il processore corrente sia stato anche l'ultimo ad acquisire il *lock* (in pratica, il *lock* è nella memoria cache del processore corrente?): su sistemi multi-processore questa probabilità precipita rapidamente. Consideriamo un processore Intel Pentium III a 700Mhz: questo esegue un'istruzione in 0.7ns, un incremento atomico richiede 58ns, acquisire un *lock* che è nella memoria cache del processore richiede 160ns, e un trasferimento dalla memoria cache di un altro processore richiede altri 170/360ns (Leggetevi l'articolo di Paul McKenney's `Linux Journal RCU article `__).h](hIl tempo di acquisizione di un }(hj"hhhNhNubj)}(h*lock*h]hlock}(hj "hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj"ubh1 dipende da quanto danno fa l’operazione sulla }(hj"hhhNhNubj)}(h *pipeline*h]hpipeline}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj"ubh (ovvero stalli della }(hj"hhhNhNubj)}(h *pipeline*h]hpipeline}(hj-"hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj"ubh_) e quant’è probabile che il processore corrente sia stato anche l’ultimo ad acquisire il }(hj"hhhNhNubj)}(h*lock*h]hlock}(hj?"hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj"ubh (in pratica, il }(hj"hhhNhNubj)}(h*lock*h]hlock}(hjQ"hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj"ubhX  è nella memoria cache del processore corrente?): su sistemi multi-processore questa probabilità precipita rapidamente. Consideriamo un processore Intel Pentium III a 700Mhz: questo esegue un’istruzione in 0.7ns, un incremento atomico richiede 58ns, acquisire un }(hj"hhhNhNubj)}(h*lock*h]hlock}(hjc"hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj"ubh che è nella memoria cache del processore richiede 160ns, e un trasferimento dalla memoria cache di un altro processore richiede altri 170/360ns (Leggetevi l’articolo di Paul McKenney’s }(hj"hhhNhNubjZ)}(hP`Linux Journal RCU article `__h]hLinux Journal RCU article}(hju"hhhNhNubah}(h]h ]h"]h$]h&]nameLinux Journal RCU articlerefuri0http://www.linuxjournal.com/article.php?sid=6993uh1jYhj"ubh).}(hj"hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjD!hhubh)}(hXQuesti due obiettivi sono in conflitto: trattenere un *lock* per il minor tempo possibile potrebbe richiedere la divisione in più *lock* per diverse parti (come nel nostro ultimo esempio con un *lock* per ogni oggetto), ma questo aumenta il numero di acquisizioni di *lock*, ed il risultato spesso è che tutto è più lento che con un singolo *lock*. Questo è un altro argomento in favore della semplicità quando si parla di sincronizzazione.h](h6Questi due obiettivi sono in conflitto: trattenere un }(hj"hhhNhNubj)}(h*lock*h]hlock}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj"ubhG per il minor tempo possibile potrebbe richiedere la divisione in più }(hj"hhhNhNubj)}(h*lock*h]hlock}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj"ubh: per diverse parti (come nel nostro ultimo esempio con un }(hj"hhhNhNubj)}(h*lock*h]hlock}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj"ubhC per ogni oggetto), ma questo aumenta il numero di acquisizioni di }(hj"hhhNhNubj)}(h*lock*h]hlock}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj"ubhG, ed il risultato spesso è che tutto è più lento che con un singolo }(hj"hhhNhNubj)}(h*lock*h]hlock}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj"ubh_. Questo è un altro argomento in favore della semplicità quando si parla di sincronizzazione.}(hj"hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhM*hjD!hhubh)}(hIl terzo punto è discusso di seguito: ci sono alcune tecniche per ridurre il numero di sincronizzazioni che devono essere fatte.h]hIl terzo punto è discusso di seguito: ci sono alcune tecniche per ridurre il numero di sincronizzazioni che devono essere fatte.}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM1hjD!hhubj)}(hhh](j)}(hRead/Write Lock Variantsh]hRead/Write Lock Variants}(hj #hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj#hhhjhM5ubh)}(hXSia gli spinlock che i mutex hanno una variante per la lettura/scrittura (read/write): ``rwlock_t`` e :c:type:`struct rw_semaphore `. Queste dividono gli utenti in due categorie: i lettori e gli scrittori. Se state solo leggendo i dati, potete acquisire il *lock* di lettura, ma per scrivere avrete bisogno del *lock* di scrittura. Molti possono trattenere il *lock* di lettura, ma solo uno scrittore alla volta può trattenere quello di scrittura.h](hWSia gli spinlock che i mutex hanno una variante per la lettura/scrittura (read/write): }(hj#hhhNhNubjZ)}(h ``rwlock_t``h]hrwlock_t}(hj #hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj#ubh e }(hj#hhhNhNubh)}(h,:c:type:`struct rw_semaphore `h]jZ)}(hj4#h]hstruct rw_semaphore}(hj6#hhhNhNubah}(h]h ](hjc-typeeh"]h$]h&]uh1jYhj2#ubah}(h]h ]h"]h$]h&]refdochΌ refdomainjreftypetype refexplicitrefwarnjjhԌ rw_semaphoreuh1hhjhM7hj#ubh}. Queste dividono gli utenti in due categorie: i lettori e gli scrittori. Se state solo leggendo i dati, potete acquisire il }(hj#hhhNhNubj)}(h*lock*h]hlock}(hjU#hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj#ubh0 di lettura, ma per scrivere avrete bisogno del }(hj#hhhNhNubj)}(h*lock*h]hlock}(hjg#hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj#ubh+ di scrittura. Molti possono trattenere il }(hj#hhhNhNubj)}(h*lock*h]hlock}(hjy#hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj#ubhR di lettura, ma solo uno scrittore alla volta può trattenere quello di scrittura.}(hj#hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhM7hj#hhubh)}(hXgSe il vostro codice si divide chiaramente in codice per lettori e codice per scrittori (come nel nostro esempio), e il *lock* dei lettori viene trattenuto per molto tempo, allora l'uso di questo tipo di *lock* può aiutare. Questi sono leggermente più lenti rispetto alla loro versione normale, quindi nella pratica l'uso di ``rwlock_t`` non ne vale la pena.h](hwSe il vostro codice si divide chiaramente in codice per lettori e codice per scrittori (come nel nostro esempio), e il }(hj#hhhNhNubj)}(h*lock*h]hlock}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj#ubhP dei lettori viene trattenuto per molto tempo, allora l’uso di questo tipo di }(hj#hhhNhNubj)}(h*lock*h]hlock}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj#ubhw può aiutare. Questi sono leggermente più lenti rispetto alla loro versione normale, quindi nella pratica l’uso di }(hj#hhhNhNubjZ)}(h ``rwlock_t``h]hrwlock_t}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj#ubh non ne vale la pena.}(hj#hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhM?hj#hhubeh}(h]read-write-lock-variantsah ]h"]read/write lock variantsah$]h&]uh1jhjD!hhhjhM5ubj)}(hhh](j)}(h"Evitare i *lock*: Read Copy Updateh](h Evitare i }(hj#hhhNhNubj)}(h*lock*h]hlock}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj#ubh: Read Copy Update}(hj#hhhNhNubeh}(h]h ]h"]h$]h&]uh1jhj#hhhjhMFubh)}(hXoEsiste un metodo di sincronizzazione per letture e scritture detto Read Copy Update. Con l'uso della tecnica RCU, i lettori possono scordarsi completamente di trattenere i *lock*; dato che nel nostro esempio ci aspettiamo d'avere più lettore che scrittori (altrimenti questa memoria sarebbe uno spreco) possiamo dire che questo meccanismo permette un'ottimizzazione.h](hEsiste un metodo di sincronizzazione per letture e scritture detto Read Copy Update. Con l’uso della tecnica RCU, i lettori possono scordarsi completamente di trattenere i }(hj$hhhNhNubj)}(h*lock*h]hlock}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj$ubh; dato che nel nostro esempio ci aspettiamo d’avere più lettore che scrittori (altrimenti questa memoria sarebbe uno spreco) possiamo dire che questo meccanismo permette un’ottimizzazione.}(hj$hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMHhj#hhubh)}(hXCome facciamo a sbarazzarci dei *lock* di lettura? Sbarazzarsi dei *lock* di lettura significa che uno scrittore potrebbe cambiare la lista sotto al naso dei lettori. Questo è abbastanza semplice: possiamo leggere una lista concatenata se lo scrittore aggiunge elementi alla fine e con certe precauzioni. Per esempio, aggiungendo ``new`` ad una lista concatenata chiamata ``list``::h](h Come facciamo a sbarazzarci dei }(hj $hhhNhNubj)}(h*lock*h]hlock}(hj($hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj $ubh di lettura? Sbarazzarsi dei }(hj $hhhNhNubj)}(h*lock*h]hlock}(hj:$hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj $ubhX di lettura significa che uno scrittore potrebbe cambiare la lista sotto al naso dei lettori. Questo è abbastanza semplice: possiamo leggere una lista concatenata se lo scrittore aggiunge elementi alla fine e con certe precauzioni. Per esempio, aggiungendo }(hj $hhhNhNubjZ)}(h``new``h]hnew}(hjL$hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj $ubh# ad una lista concatenata chiamata }(hj $hhhNhNubjZ)}(h``list``h]hlist}(hj^$hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj $ubh:}(hj $hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMOhj#hhubjE)}(h0new->next = list->next; wmb(); list->next = new;h]h0new->next = list->next; wmb(); list->next = new;}hjv$sbah}(h]h ]h"]h$]h&]jTjUuh1jDhjhMVhj#hhubh)}(hXLa funzione wmb() è una barriera di sincronizzazione delle scritture. Questa garantisce che la prima operazione (impostare l'elemento ``next`` del nuovo elemento) venga completata e vista da tutti i processori prima che venga eseguita la seconda operazione (che sarebbe quella di mettere il nuovo elemento nella lista). Questo è importante perché i moderni compilatori ed i moderni processori possono, entrambe, riordinare le istruzioni se non vengono istruiti altrimenti: vogliamo che i lettori non vedano completamente il nuovo elemento; oppure che lo vedano correttamente e quindi il puntatore ``next`` deve puntare al resto della lista.h](hLa funzione wmb() è una barriera di sincronizzazione delle scritture. Questa garantisce che la prima operazione (impostare l’elemento }(hj$hhhNhNubjZ)}(h``next``h]hnext}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj$ubhX del nuovo elemento) venga completata e vista da tutti i processori prima che venga eseguita la seconda operazione (che sarebbe quella di mettere il nuovo elemento nella lista). Questo è importante perché i moderni compilatori ed i moderni processori possono, entrambe, riordinare le istruzioni se non vengono istruiti altrimenti: vogliamo che i lettori non vedano completamente il nuovo elemento; oppure che lo vedano correttamente e quindi il puntatore }(hj$hhhNhNubjZ)}(h``next``h]hnext}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj$ubh# deve puntare al resto della lista.}(hj$hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMZhj#hhubh)}(hFortunatamente, c'è una funzione che fa questa operazione sulle liste :c:type:`struct list_head `: list_add_rcu() (``include/linux/list.h``).h](hIFortunatamente, c’è una funzione che fa questa operazione sulle liste }(hj$hhhNhNubh)}(h&:c:type:`struct list_head `h]jZ)}(hj$h]hstruct list_head}(hj$hhhNhNubah}(h]h ](hjc-typeeh"]h$]h&]uh1jYhj$ubah}(h]h ]h"]h$]h&]refdochΌ refdomainjreftypetype refexplicitrefwarnjjhԌ list_headuh1hhjhMdhj$ubh: list_add_rcu() (}(hj$hhhNhNubjZ)}(h``include/linux/list.h``h]hinclude/linux/list.h}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj$ubh).}(hj$hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMdhj#hhubh)}(hRimuovere un elemento dalla lista è anche più facile: sostituiamo il puntatore al vecchio elemento con quello del suo successore, e i lettori vedranno l'elemento o lo salteranno.h]hRimuovere un elemento dalla lista è anche più facile: sostituiamo il puntatore al vecchio elemento con quello del suo successore, e i lettori vedranno l’elemento o lo salteranno.}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhhj#hhubjE)}(hlist->next = old->next;h]hlist->next = old->next;}hj%sbah}(h]h ]h"]h$]h&]jTjUuh1jDhjhMnhj#hhubh)}(hLa funzione list_del_rcu() (``include/linux/list.h``) fa esattamente questo (la versione normale corrompe il vecchio oggetto, e non vogliamo che accada).h](hLa funzione list_del_rcu() (}(hj%hhhNhNubjZ)}(h``include/linux/list.h``h]hinclude/linux/list.h}(hj%hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj%ubhe) fa esattamente questo (la versione normale corrompe il vecchio oggetto, e non vogliamo che accada).}(hj%hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMphj#hhubh)}(hX Anche i lettori devono stare attenti: alcuni processori potrebbero leggere attraverso il puntatore ``next`` il contenuto dell'elemento successivo troppo presto, ma non accorgersi che il contenuto caricato è sbagliato quando il puntatore ``next`` viene modificato alla loro spalle. Ancora una volta c'è una funzione che viene in vostro aiuto list_for_each_entry_rcu() (``include/linux/list.h``). Ovviamente, gli scrittori possono usare list_for_each_entry() dato che non ci possono essere due scrittori in contemporanea.h](hcAnche i lettori devono stare attenti: alcuni processori potrebbero leggere attraverso il puntatore }(hj5%hhhNhNubjZ)}(h``next``h]hnext}(hj=%hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj5%ubh il contenuto dell’elemento successivo troppo presto, ma non accorgersi che il contenuto caricato è sbagliato quando il puntatore }(hj5%hhhNhNubjZ)}(h``next``h]hnext}(hjO%hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj5%ubh~ viene modificato alla loro spalle. Ancora una volta c’è una funzione che viene in vostro aiuto list_for_each_entry_rcu() (}(hj5%hhhNhNubjZ)}(h``include/linux/list.h``h]hinclude/linux/list.h}(hja%hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj5%ubh). Ovviamente, gli scrittori possono usare list_for_each_entry() dato che non ci possono essere due scrittori in contemporanea.}(hj5%hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMthj#hhubh)}(hXIl nostro ultimo dilemma è il seguente: quando possiamo realmente distruggere l'elemento rimosso? Ricordate, un lettore potrebbe aver avuto accesso a questo elemento proprio ora: se eliminiamo questo elemento ed il puntatore ``next`` cambia, il lettore salterà direttamente nella spazzatura e scoppierà. Dobbiamo aspettare finché tutti i lettori che stanno attraversando la lista abbiano finito. Utilizziamo call_rcu() per registrare una funzione di richiamo che distrugga l'oggetto quando tutti i lettori correnti hanno terminato. In alternative, potrebbe essere usata la funzione synchronize_rcu() che blocca l'esecuzione finché tutti i lettori non terminano di ispezionare la lista.h](hIl nostro ultimo dilemma è il seguente: quando possiamo realmente distruggere l’elemento rimosso? Ricordate, un lettore potrebbe aver avuto accesso a questo elemento proprio ora: se eliminiamo questo elemento ed il puntatore }(hjy%hhhNhNubjZ)}(h``next``h]hnext}(hj%hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjy%ubhX cambia, il lettore salterà direttamente nella spazzatura e scoppierà. Dobbiamo aspettare finché tutti i lettori che stanno attraversando la lista abbiano finito. Utilizziamo call_rcu() per registrare una funzione di richiamo che distrugga l’oggetto quando tutti i lettori correnti hanno terminato. In alternative, potrebbe essere usata la funzione synchronize_rcu() che blocca l’esecuzione finché tutti i lettori non terminano di ispezionare la lista.}(hjy%hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhM}hj#hhubh)}(hXMa come fa l'RCU a sapere quando i lettori sono finiti? Il meccanismo è il seguente: innanzi tutto i lettori accedono alla lista solo fra la coppia rcu_read_lock()/rcu_read_unlock() che disabilita la prelazione così che i lettori non vengano sospesi mentre stanno leggendo la lista.h]hXMa come fa l’RCU a sapere quando i lettori sono finiti? Il meccanismo è il seguente: innanzi tutto i lettori accedono alla lista solo fra la coppia rcu_read_lock()/rcu_read_unlock() che disabilita la prelazione così che i lettori non vengano sospesi mentre stanno leggendo la lista.}(hj%hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj#hhubh)}(hXyPoi, l'RCU aspetta finché tutti i processori non abbiano dormito almeno una volta; a questo punto, dato che i lettori non possono dormire, possiamo dedurre che un qualsiasi lettore che abbia consultato la lista durante la rimozione abbia già terminato, quindi la *callback* viene eseguita. Il vero codice RCU è un po' più ottimizzato di così, ma questa è l'idea di fondo.h](hX Poi, l’RCU aspetta finché tutti i processori non abbiano dormito almeno una volta; a questo punto, dato che i lettori non possono dormire, possiamo dedurre che un qualsiasi lettore che abbia consultato la lista durante la rimozione abbia già terminato, quindi la }(hj%hhhNhNubj)}(h *callback*h]hcallback}(hj%hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj%ubhj viene eseguita. Il vero codice RCU è un po’ più ottimizzato di così, ma questa è l’idea di fondo.}(hj%hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj#hhubjE)}(hX--- cache.c.perobjectlock 2003-12-11 17:15:03.000000000 +1100 +++ cache.c.rcupdate 2003-12-11 17:55:14.000000000 +1100 @@ -1,15 +1,18 @@ #include #include #include +#include #include #include struct object { - /* These two protected by cache_lock. */ + /* This is protected by RCU */ struct list_head list; int popularity; + struct rcu_head rcu; + atomic_t refcnt; /* Doesn't change once created. */ @@ -40,7 +43,7 @@ { struct object *i; - list_for_each_entry(i, &cache, list) { + list_for_each_entry_rcu(i, &cache, list) { if (i->id == id) { i->popularity++; return i; @@ -49,19 +52,25 @@ return NULL; } +/* Final discard done once we know no readers are looking. */ +static void cache_delete_rcu(void *arg) +{ + object_put(arg); +} + /* Must be holding cache_lock */ static void __cache_delete(struct object *obj) { BUG_ON(!obj); - list_del(&obj->list); - object_put(obj); + list_del_rcu(&obj->list); cache_num--; + call_rcu(&obj->rcu, cache_delete_rcu); } /* Must be holding cache_lock */ static void __cache_add(struct object *obj) { - list_add(&obj->list, &cache); + list_add_rcu(&obj->list, &cache); if (++cache_num > MAX_CACHE_SIZE) { struct object *i, *outcast = NULL; list_for_each_entry(i, &cache, list) { @@ -104,12 +114,11 @@ struct object *cache_find(int id) { struct object *obj; - unsigned long flags; - spin_lock_irqsave(&cache_lock, flags); + rcu_read_lock(); obj = __cache_find(id); if (obj) object_get(obj); - spin_unlock_irqrestore(&cache_lock, flags); + rcu_read_unlock(); return obj; }h]hX--- cache.c.perobjectlock 2003-12-11 17:15:03.000000000 +1100 +++ cache.c.rcupdate 2003-12-11 17:55:14.000000000 +1100 @@ -1,15 +1,18 @@ #include #include #include +#include #include #include struct object { - /* These two protected by cache_lock. */ + /* This is protected by RCU */ struct list_head list; int popularity; + struct rcu_head rcu; + atomic_t refcnt; /* Doesn't change once created. */ @@ -40,7 +43,7 @@ { struct object *i; - list_for_each_entry(i, &cache, list) { + list_for_each_entry_rcu(i, &cache, list) { if (i->id == id) { i->popularity++; return i; @@ -49,19 +52,25 @@ return NULL; } +/* Final discard done once we know no readers are looking. */ +static void cache_delete_rcu(void *arg) +{ + object_put(arg); +} + /* Must be holding cache_lock */ static void __cache_delete(struct object *obj) { BUG_ON(!obj); - list_del(&obj->list); - object_put(obj); + list_del_rcu(&obj->list); cache_num--; + call_rcu(&obj->rcu, cache_delete_rcu); } /* Must be holding cache_lock */ static void __cache_add(struct object *obj) { - list_add(&obj->list, &cache); + list_add_rcu(&obj->list, &cache); if (++cache_num > MAX_CACHE_SIZE) { struct object *i, *outcast = NULL; list_for_each_entry(i, &cache, list) { @@ -104,12 +114,11 @@ struct object *cache_find(int id) { struct object *obj; - unsigned long flags; - spin_lock_irqsave(&cache_lock, flags); + rcu_read_lock(); obj = __cache_find(id); if (obj) object_get(obj); - spin_unlock_irqrestore(&cache_lock, flags); + rcu_read_unlock(); return obj; }}hj%sbah}(h]h ]h"]h$]h&]jTjUuh1jDhjhMhj#hhubh)}(hXiDa notare che i lettori modificano il campo popularity nella funzione __cache_find(), e ora non trattiene alcun *lock*. Una soluzione potrebbe essere quella di rendere la variabile ``atomic_t``, ma per l'uso che ne abbiamo fatto qui, non ci interessano queste corse critiche perché un risultato approssimativo è comunque accettabile, quindi non l'ho cambiato.h](hpDa notare che i lettori modificano il campo popularity nella funzione __cache_find(), e ora non trattiene alcun }(hj%hhhNhNubj)}(h*lock*h]hlock}(hj%hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj%ubh?. Una soluzione potrebbe essere quella di rendere la variabile }(hj%hhhNhNubjZ)}(h ``atomic_t``h]hatomic_t}(hj%hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj%ubh, ma per l’uso che ne abbiamo fatto qui, non ci interessano queste corse critiche perché un risultato approssimativo è comunque accettabile, quindi non l’ho cambiato.}(hj%hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj#hhubh)}(hIl risultato è che la funzione cache_find() non ha bisogno di alcuna sincronizzazione con le altre funzioni, quindi è veloce su un sistema multi-processore tanto quanto lo sarebbe su un sistema mono-processore.h]hIl risultato è che la funzione cache_find() non ha bisogno di alcuna sincronizzazione con le altre funzioni, quindi è veloce su un sistema multi-processore tanto quanto lo sarebbe su un sistema mono-processore.}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj#hhubh)}(hXEsiste un'ulteriore ottimizzazione possibile: vi ricordate il codice originale della nostra memoria dove non c'erano contatori di riferimenti e il chiamante semplicemente tratteneva il *lock* prima di accedere ad un oggetto? Questo è ancora possibile: se trattenete un *lock* nessuno potrà cancellare l'oggetto, quindi non avete bisogno di incrementare e decrementare il contatore di riferimenti.h](hEsiste un’ulteriore ottimizzazione possibile: vi ricordate il codice originale della nostra memoria dove non c’erano contatori di riferimenti e il chiamante semplicemente tratteneva il }(hj&hhhNhNubj)}(h*lock*h]hlock}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj&ubhO prima di accedere ad un oggetto? Questo è ancora possibile: se trattenete un }(hj&hhhNhNubj)}(h*lock*h]hlock}(hj/&hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj&ubh| nessuno potrà cancellare l’oggetto, quindi non avete bisogno di incrementare e decrementare il contatore di riferimenti.}(hj&hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj#hhubh)}(hXOra, dato che il '*lock* di lettura' di un RCU non fa altro che disabilitare la prelazione, un chiamante che ha sempre la prelazione disabilitata fra le chiamate cache_find() e object_put() non necessita di incrementare e decrementare il contatore di riferimenti. Potremmo esporre la funzione __cache_find() dichiarandola non-static, e quel chiamante potrebbe usare direttamente questa funzione.h](hOra, dato che il ‘}(hjG&hhhNhNubj)}(h*lock*h]hlock}(hjO&hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjG&ubhXu di lettura’ di un RCU non fa altro che disabilitare la prelazione, un chiamante che ha sempre la prelazione disabilitata fra le chiamate cache_find() e object_put() non necessita di incrementare e decrementare il contatore di riferimenti. Potremmo esporre la funzione __cache_find() dichiarandola non-static, e quel chiamante potrebbe usare direttamente questa funzione.}(hjG&hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj#hhubh)}(hIl beneficio qui sta nel fatto che il contatore di riferimenti no viene scritto: l'oggetto non viene alterato in alcun modo e quindi diventa molto più veloce su sistemi molti-processore grazie alla loro memoria cache.h]hIl beneficio qui sta nel fatto che il contatore di riferimenti no viene scritto: l’oggetto non viene alterato in alcun modo e quindi diventa molto più veloce su sistemi molti-processore grazie alla loro memoria cache.}(hjg&hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj#hhubeh}(h]evitare-i-lock-read-copy-updateah ]h"] evitare i lock: read copy updateah$]h&]uh1jhjD!hhhjhMFubj)}(hhh](j)}(hDati per processoreh]hDati per processore}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj}&hhhjhMubh)}(hXUn'altra tecnica comunemente usata per evitare la sincronizzazione è quella di duplicare le informazioni per ogni processore. Per esempio, se volete avere un contatore di qualcosa, potreste utilizzare uno spinlock ed un singolo contatore. Facile e pulito.h]hXUn’altra tecnica comunemente usata per evitare la sincronizzazione è quella di duplicare le informazioni per ogni processore. Per esempio, se volete avere un contatore di qualcosa, potreste utilizzare uno spinlock ed un singolo contatore. Facile e pulito.}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj}&hhubh)}(hX'Se questo dovesse essere troppo lento (solitamente non lo è, ma se avete dimostrato che lo è devvero), potreste usare un contatore per ogni processore e quindi non sarebbe più necessaria la mutua esclusione. Vedere DEFINE_PER_CPU(), get_cpu_var() e put_cpu_var() (``include/linux/percpu.h``).h](hX Se questo dovesse essere troppo lento (solitamente non lo è, ma se avete dimostrato che lo è devvero), potreste usare un contatore per ogni processore e quindi non sarebbe più necessaria la mutua esclusione. Vedere DEFINE_PER_CPU(), get_cpu_var() e put_cpu_var() (}(hj&hhhNhNubjZ)}(h``include/linux/percpu.h``h]hinclude/linux/percpu.h}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj&ubh).}(hj&hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj}&hhubh)}(hIl tipo di dato ``local_t``, la funzione cpu_local_inc() e tutte le altre funzioni associate, sono di particolare utilità per semplici contatori per-processore; su alcune architetture sono anche più efficienti (``include/asm/local.h``).h](hIl tipo di dato }(hj&hhhNhNubjZ)}(h ``local_t``h]hlocal_t}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj&ubh, la funzione cpu_local_inc() e tutte le altre funzioni associate, sono di particolare utilità per semplici contatori per-processore; su alcune architetture sono anche più efficienti (}(hj&hhhNhNubjZ)}(h``include/asm/local.h``h]hinclude/asm/local.h}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj&ubh).}(hj&hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhM hj}&hhubh)}(hDa notare che non esiste un modo facile ed affidabile per ottenere il valore di un simile contatore senza introdurre altri *lock*. In alcuni casi questo non è un problema.h](h{Da notare che non esiste un modo facile ed affidabile per ottenere il valore di un simile contatore senza introdurre altri }(hj&hhhNhNubj)}(h*lock*h]hlock}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj&ubh+. In alcuni casi questo non è un problema.}(hj&hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj}&hhubeh}(h]j ah ]h"]dati per processoreah$]h&]uh1jhjD!hhhjhMj5 Kubj)}(hhh](j)}(h>Dati che sono usati prevalentemente dai gestori d'interruzionih]h@Dati che sono usati prevalentemente dai gestori d’interruzioni}(hj'hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj'hhhjhMubh)}(hSe i dati vengono utilizzati sempre dallo stesso gestore d'interruzioni, allora i *lock* non vi servono per niente: il kernel già vi garantisce che il gestore d'interruzione non verrà eseguito in contemporanea su diversi processori.h](hTSe i dati vengono utilizzati sempre dallo stesso gestore d’interruzioni, allora i }(hj&'hhhNhNubj)}(h*lock*h]hlock}(hj.'hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj&'ubh non vi servono per niente: il kernel già vi garantisce che il gestore d’interruzione non verrà eseguito in contemporanea su diversi processori.}(hj&'hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj'hhubh)}(hXManfred Spraul fa notare che potreste comunque comportarvi così anche se i dati vengono occasionalmente utilizzati da un contesto utente o da un'interruzione software. Il gestore d'interruzione non utilizza alcun *lock*, e tutti gli altri accessi verranno fatti così::h](hManfred Spraul fa notare che potreste comunque comportarvi così anche se i dati vengono occasionalmente utilizzati da un contesto utente o da un’interruzione software. Il gestore d’interruzione non utilizza alcun }(hjF'hhhNhNubj)}(h*lock*h]hlock}(hjN'hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjF'ubh1, e tutti gli altri accessi verranno fatti così:}(hjF'hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj'hhubjE)}(hNmutex_lock(&lock); disable_irq(irq); ... enable_irq(irq); mutex_unlock(&lock);h]hNmutex_lock(&lock); disable_irq(irq); ... enable_irq(irq); mutex_unlock(&lock);}hjf'sbah}(h]h ]h"]h$]h&]jTjUuh1jDhjhM#hj'hhubh)}(hXaLa funzione disable_irq() impedisce al gestore d'interruzioni d'essere eseguito (e aspetta che finisca nel caso fosse in esecuzione su un altro processore). Lo spinlock, invece, previene accessi simultanei. Naturalmente, questo è più lento della semplice chiamata spin_lock_irq(), quindi ha senso solo se questo genere di accesso è estremamente raro.h]hXeLa funzione disable_irq() impedisce al gestore d’interruzioni d’essere eseguito (e aspetta che finisca nel caso fosse in esecuzione su un altro processore). Lo spinlock, invece, previene accessi simultanei. Naturalmente, questo è più lento della semplice chiamata spin_lock_irq(), quindi ha senso solo se questo genere di accesso è estremamente raro.}(hjt'hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM)hj'hhubeh}(h]>dati-che-sono-usati-prevalentemente-dai-gestori-d-interruzioniah ]h"]>dati che sono usati prevalentemente dai gestori d'interruzioniah$]h&]uh1jhjD!hhhjhMubeh}(h]velocita-della-sincronizzazioneah ]h"] velocità della sincronizzazioneah$]h&]uh1jhjhhhjhMubj)}(hhh](j)}(hIQuali funzioni possono essere chiamate in modo sicuro dalle interruzioni?h]hIQuali funzioni possono essere chiamate in modo sicuro dalle interruzioni?}(hj'hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj'hhhjhM2ubh)}(hX:Molte funzioni del kernel dormono (in sostanza, chiamano schedule()) direttamente od indirettamente: non potete chiamarle se trattenere uno spinlock o avete la prelazione disabilitata, mai. Questo significa che dovete necessariamente essere nel contesto utente: chiamarle da un contesto d'interruzione è illegale.h]hX<Molte funzioni del kernel dormono (in sostanza, chiamano schedule()) direttamente od indirettamente: non potete chiamarle se trattenere uno spinlock o avete la prelazione disabilitata, mai. Questo significa che dovete necessariamente essere nel contesto utente: chiamarle da un contesto d’interruzione è illegale.}(hj'hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM4hj'hhubj)}(hhh](j)}(hAlcune funzioni che dormonoh]hAlcune funzioni che dormono}(hj'hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj'hhhjhM;ubh)}(hXoLe più comuni sono elencate qui di seguito, ma solitamente dovete leggere il codice per scoprire se altre chiamate sono sicure. Se chiunque altro le chiami dorme, allora dovreste poter dormire anche voi. In particolar modo, le funzioni di registrazione e deregistrazione solitamente si aspettano d'essere chiamante da un contesto utente e quindi che possono dormire.h]hXqLe più comuni sono elencate qui di seguito, ma solitamente dovete leggere il codice per scoprire se altre chiamate sono sicure. Se chiunque altro le chiami dorme, allora dovreste poter dormire anche voi. In particolar modo, le funzioni di registrazione e deregistrazione solitamente si aspettano d’essere chiamante da un contesto utente e quindi che possono dormire.}(hj'hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM=hj'hhubjV )}(hhh](j[ )}(hbAccessi allo spazio utente: - copy_from_user() - copy_to_user() - get_user() - put_user() h](h)}(hAccessi allo spazio utente:h]hAccessi allo spazio utente:}(hj'hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMDhj'ubjV )}(hhh](j[ )}(hcopy_from_user() h]h)}(hcopy_from_user()h]hcopy_from_user()}(hj'hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMFhj'ubah}(h]h ]h"]h$]h&]uh1jZ hj'ubj[ )}(hcopy_to_user() h]h)}(hcopy_to_user()h]hcopy_to_user()}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMHhj(ubah}(h]h ]h"]h$]h&]uh1jZ hj'ubj[ )}(h get_user() h]h)}(h get_user()h]h get_user()}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMJhj(ubah}(h]h ]h"]h$]h&]uh1jZ hj'ubj[ )}(h put_user() h]h)}(h put_user()h]h put_user()}(hj4(hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMLhj0(ubah}(h]h ]h"]h$]h&]uh1jZ hj'ubeh}(h]h ]h"]h$]h&]j j uh1jU hjhMFhj'ubeh}(h]h ]h"]h$]h&]uh1jZ hj'hhhNhNubj[ )}(hkmalloc(GFP_KERNEL) ` h]h)}(hkmalloc(GFP_KERNEL) `h]hkmalloc(GFP_KERNEL) `}(hjX(hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMNhjT(ubah}(h]h ]h"]h$]h&]uh1jZ hj'hhhjhNubj[ )}(hXmutex_lock_interruptible() and mutex_lock() C'è anche mutex_trylock() che però non dorme. Comunque, non deve essere usata in un contesto d'interruzione dato che la sua implementazione non è sicura in quel contesto. Anche mutex_unlock() non dorme mai. Non può comunque essere usata in un contesto d'interruzione perché un mutex deve essere rilasciato dallo stesso processo che l'ha acquisito. h](h)}(h+mutex_lock_interruptible() and mutex_lock()h]h+mutex_lock_interruptible() and mutex_lock()}(hjp(hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMPhjl(ubh)}(hX`C'è anche mutex_trylock() che però non dorme. Comunque, non deve essere usata in un contesto d'interruzione dato che la sua implementazione non è sicura in quel contesto. Anche mutex_unlock() non dorme mai. Non può comunque essere usata in un contesto d'interruzione perché un mutex deve essere rilasciato dallo stesso processo che l'ha acquisito.h]hXhC’è anche mutex_trylock() che però non dorme. Comunque, non deve essere usata in un contesto d’interruzione dato che la sua implementazione non è sicura in quel contesto. Anche mutex_unlock() non dorme mai. Non può comunque essere usata in un contesto d’interruzione perché un mutex deve essere rilasciato dallo stesso processo che l’ha acquisito.}(hj~(hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMShjl(ubeh}(h]h ]h"]h$]h&]uh1jZ hj'hhhjhNubeh}(h]h ]h"]h$]h&]j j uh1jU hjhMDhj'hhubeh}(h]alcune-funzioni-che-dormonoah ]h"]alcune funzioni che dormonoah$]h&]uh1jhj'hhhjhM;ubj)}(hhh](j)}(hAlcune funzioni che non dormonoh]hAlcune funzioni che non dormono}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj(hhhjhM[ubh)}(hqAlcune funzioni possono essere chiamate tranquillamente da qualsiasi contesto, o trattenendo un qualsiasi *lock*.h](hjAlcune funzioni possono essere chiamate tranquillamente da qualsiasi contesto, o trattenendo un qualsiasi }(hj(hhhNhNubj)}(h*lock*h]hlock}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj(ubh.}(hj(hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhM]hj(hhubjV )}(hhh](j[ )}(h printk() h]h)}(hprintk()h]hprintk()}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM`hj(ubah}(h]h ]h"]h$]h&]uh1jZ hj(hhhjhNubj[ )}(hkfree() h]h)}(hkfree()h]hkfree()}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMbhj(ubah}(h]h ]h"]h$]h&]uh1jZ hj(hhhjhNubj[ )}(hadd_timer() e timer_delete() h]h)}(hadd_timer() e timer_delete()h]hadd_timer() e timer_delete()}(hj)hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMdhj)ubah}(h]h ]h"]h$]h&]uh1jZ hj(hhhjhNubeh}(h]h ]h"]h$]h&]j j uh1jU hjhM`hj(hhubeh}(h]alcune-funzioni-che-non-dormonoah ]h"]alcune funzioni che non dormonoah$]h&]uh1jhj'hhhjhM[ubeh}(h]jah ]h"]Iquali funzioni possono essere chiamate in modo sicuro dalle interruzioni?ah$]h&]uh1jhjhhhjhM2j5 Kubj)}(hhh](j)}(hRiferimento per l'API dei Mutexh]h!Riferimento per l’API dei Mutex}(hj4)hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj1)hhhjhMgubhindex)}(hhh]h}(h]h ]h"]h$]h&]entries](singleit_IT.mutex_init (C macro)c.it_IT.mutex_inithNtauh1jB)hj1)hhhNhNubhdesc)}(hhh](hdesc_signature)}(h mutex_inith]hdesc_signature_line)}(h mutex_inith]h desc_name)}(h mutex_inith]h desc_sig_name)}(hj\)h]h mutex_init}(hjl)hhhNhNubah}(h]h ]nah"]h$]h&]uh1jj)hjf)ubah}(h]h ](sig-namedescnameeh"]h$]h&]jTjUuh1jd)hj`)hhhq/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1395: ./include/linux/mutex.hhKhj1)hhubh block_quote)}(hinitialize the mutex h]h)}(hinitialize the mutexh]hinitialize the mutex}(hj)hhhNhNubah}(h]h ]h"]h$]h&]uh1hhq/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1395: ./include/linux/mutex.hhK5hj)ubah}(h]h ]h"]h$]h&]uh1j)hj)hK5hj1)hhubh container)}(h**Parameters** ``mutex`` the mutex to be initialized **Description** Initialize the mutex to unlocked state. It is not allowed to initialize an already locked mutex.h](h)}(h**Parameters**h]j)}(hj)h]h Parameters}(hj)hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj)ubah}(h]h ]h"]h$]h&]uh1hhq/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1395: ./include/linux/mutex.hhK9hj)ubhdefinition_list)}(hhh]hdefinition_list_item)}(h&``mutex`` the mutex to be initialized h](hterm)}(h ``mutex``h]jZ)}(hj*h]hmutex}(hj*hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj *ubah}(h]h ]h"]h$]h&]uh1j *hq/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1395: ./include/linux/mutex.hhK6hj*ubh definition)}(hhh]h)}(hthe mutex to be initializedh]hthe mutex to be initialized}(hj**hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj$*hK6hj'*ubah}(h]h ]h"]h$]h&]uh1j%*hj*ubeh}(h]h ]h"]h$]h&]uh1j*hj$*hK6hj*ubah}(h]h ]h"]h$]h&]uh1j*hj)ubh)}(h**Description**h]j)}(hjL*h]h Description}(hjN*hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjJ*ubah}(h]h ]h"]h$]h&]uh1hhq/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1395: ./include/linux/mutex.hhK8hj)ubh)}(h'Initialize the mutex to unlocked state.h]h'Initialize the mutex to unlocked state.}(hjb*hhhNhNubah}(h]h ]h"]h$]h&]uh1hhq/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1395: ./include/linux/mutex.hhK8hj)ubh)}(h8It is not allowed to initialize an already locked mutex.h]h8It is not allowed to initialize an already locked mutex.}(hjq*hhhNhNubah}(h]h ]h"]h$]h&]uh1hhq/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1395: ./include/linux/mutex.hhK:hj)ubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj1)hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)#it_IT.mutex_init_with_key (C macro)c.it_IT.mutex_init_with_keyhNtauh1jB)hj1)hhhNhNubjT))}(hhh](jY))}(hmutex_init_with_keyh]j_))}(hmutex_init_with_keyh]je))}(hmutex_init_with_keyh]jk))}(hj*h]hmutex_init_with_key}(hj*hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj*ubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hj*hhhq/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1395: ./include/linux/mutex.hhKLubah}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj*hhhj*hKLubah}(h]j*ah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hj*hKLhj*hhubj))}(hhh]h}(h]h ]h"]h$]h&]uh1j)hj*hhhj*hKLubeh}(h]h ](jmacroeh"]h$]h&]j)jj)j*j)j*j)j)j)uh1jS)hhhj1)hNhNubh)}(h$``mutex_init_with_key (mutex, key)``h]jZ)}(hj*h]h mutex_init_with_key (mutex, key)}(hj*hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj*ubah}(h]h ]h"]h$]h&]uh1hhq/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1395: ./include/linux/mutex.hhKNhj1)hhubj))}(h,initialize a mutex with a given lockdep key h]h)}(h+initialize a mutex with a given lockdep keyh]h+initialize a mutex with a given lockdep key}(hj*hhhNhNubah}(h]h ]h"]h$]h&]uh1hhq/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1395: ./include/linux/mutex.hhKDhj*ubah}(h]h ]h"]h$]h&]uh1j)hj*hKDhj1)hhubj))}(h**Parameters** ``mutex`` the mutex to be initialized ``key`` the lockdep key to be associated with the mutex **Description** Initialize the mutex to the unlocked state. It is not allowed to initialize an already locked mutex.h](h)}(h**Parameters**h]j)}(hj +h]h Parameters}(hj +hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj +ubah}(h]h ]h"]h$]h&]uh1hhq/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1395: ./include/linux/mutex.hhKHhj+ubj*)}(hhh](j*)}(h&``mutex`` the mutex to be initialized h](j *)}(h ``mutex``h]jZ)}(hj*+h]hmutex}(hj,+hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj(+ubah}(h]h ]h"]h$]h&]uh1j *hq/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1395: ./include/linux/mutex.hhKEhj$+ubj&*)}(hhh]h)}(hthe mutex to be initializedh]hthe mutex to be initialized}(hjC+hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj?+hKEhj@+ubah}(h]h ]h"]h$]h&]uh1j%*hj$+ubeh}(h]h ]h"]h$]h&]uh1j*hj?+hKEhj!+ubj*)}(h8``key`` the lockdep key to be associated with the mutex h](j *)}(h``key``h]jZ)}(hjc+h]hkey}(hje+hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhja+ubah}(h]h ]h"]h$]h&]uh1j *hq/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1395: ./include/linux/mutex.hhKFhj]+ubj&*)}(hhh]h)}(h/the lockdep key to be associated with the mutexh]h/the lockdep key to be associated with the mutex}(hj|+hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjx+hKFhjy+ubah}(h]h ]h"]h$]h&]uh1j%*hj]+ubeh}(h]h ]h"]h$]h&]uh1j*hjx+hKFhj!+ubeh}(h]h ]h"]h$]h&]uh1j*hj+ubh)}(h**Description**h]j)}(hj+h]h Description}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj+ubah}(h]h ]h"]h$]h&]uh1hhq/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1395: ./include/linux/mutex.hhKHhj+ubh)}(h+Initialize the mutex to the unlocked state.h]h+Initialize the mutex to the unlocked state.}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1hhq/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1395: ./include/linux/mutex.hhKHhj+ubh)}(h8It is not allowed to initialize an already locked mutex.h]h8It is not allowed to initialize an already locked mutex.}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1hhq/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1395: ./include/linux/mutex.hhKJhj+ubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj1)hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)"it_IT.mutex_is_locked (C function)c.it_IT.mutex_is_lockedhNtauh1jB)hj1)hhhNhNubjT))}(hhh](jY))}(h)bool mutex_is_locked (struct mutex *lock)h]j_))}(h(bool mutex_is_locked(struct mutex *lock)h](hdesc_sig_keyword_type)}(hboolh]hbool}(hj+hhhNhNubah}(h]h ]ktah"]h$]h&]uh1j+hj+hhhq/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1395: ./include/linux/mutex.hhKbubhdesc_sig_space)}(h h]h }(hj,hhhNhNubah}(h]h ]wah"]h$]h&]uh1j,hj+hhhj,hKbubje))}(hmutex_is_lockedh]jk))}(hmutex_is_lockedh]hmutex_is_locked}(hj,hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj,ubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hj+hhhj,hKbubhdesc_parameterlist)}(h(struct mutex *lock)h]hdesc_parameter)}(hstruct mutex *lockh](hdesc_sig_keyword)}(hstructh]hstruct}(hj;,hhhNhNubah}(h]h ]kah"]h$]h&]uh1j9,hj5,ubj,)}(h h]h }(hjJ,hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj5,ubh)}(hhh]jk))}(hmutexh]hmutex}(hj[,hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjX,ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj],modnameN classnameNjj)}j](jNj)}jj,sbc.it_IT.mutex_is_lockedesbuh1hhj5,ubj,)}(h h]h }(hj|,hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj5,ubhdesc_sig_punctuation)}(h*h]h*}(hj,hhhNhNubah}(h]h ]pah"]h$]h&]uh1j,hj5,ubjk))}(hlockh]hlock}(hj,hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj5,ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj/,ubah}(h]h ]h"]h$]h&]jTjUuh1j-,hj+hhhj,hKbubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj+hhhj,hKbubah}(h]j+ah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hj,hKbhj+hhubj))}(hhh]h)}(his the mutex lockedh]his the mutex locked}(hj,hhhNhNubah}(h]h ]h"]h$]h&]uh1hhq/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1395: ./include/linux/mutex.hhK]hj,hhubah}(h]h ]h"]h$]h&]uh1j)hj+hhhj,hKbubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)j,j)j,j)j)j)uh1jS)hhhj1)hNhNubj))}(h**Parameters** ``struct mutex *lock`` the mutex to be queried **Description** Returns true if the mutex is locked, false if unlocked.h](h)}(h**Parameters**h]j)}(hj,h]h Parameters}(hj,hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj,ubah}(h]h ]h"]h$]h&]uh1hhq/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1395: ./include/linux/mutex.hhKahj,ubj*)}(hhh]j*)}(h/``struct mutex *lock`` the mutex to be queried h](j *)}(h``struct mutex *lock``h]jZ)}(hj-h]hstruct mutex *lock}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj-ubah}(h]h ]h"]h$]h&]uh1j *hq/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1395: ./include/linux/mutex.hhK^hj-ubj&*)}(hhh]h)}(hthe mutex to be queriedh]hthe mutex to be queried}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj-hK^hj-ubah}(h]h ]h"]h$]h&]uh1j%*hj-ubeh}(h]h ]h"]h$]h&]uh1j*hj-hK^hj,ubah}(h]h ]h"]h$]h&]uh1j*hj,ubh)}(h**Description**h]j)}(hjA-h]h Description}(hjC-hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj?-ubah}(h]h ]h"]h$]h&]uh1hhq/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1395: ./include/linux/mutex.hhK`hj,ubh)}(h7Returns true if the mutex is locked, false if unlocked.h]h7Returns true if the mutex is locked, false if unlocked.}(hjW-hhhNhNubah}(h]h ]h"]h$]h&]uh1hhq/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1395: ./include/linux/mutex.hhK`hj,ubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj1)hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)it_IT.mutex_lock (C function)c.it_IT.mutex_lockhNtauh1jB)hj1)hhhNhNubjT))}(hhh](jY))}(h$void mutex_lock (struct mutex *lock)h]j_))}(h#void mutex_lock(struct mutex *lock)h](j+)}(hvoidh]hvoid}(hj-hhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hj-hhhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chMubj,)}(h h]h }(hj-hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj-hhhj-hMubje))}(h mutex_lockh]jk))}(h mutex_lockh]h mutex_lock}(hj-hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj-ubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hj-hhhj-hMubj.,)}(h(struct mutex *lock)h]j4,)}(hstruct mutex *lockh](j:,)}(hj=,h]hstruct}(hj-hhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hj-ubj,)}(h h]h }(hj-hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj-ubh)}(hhh]jk))}(hmutexh]hmutex}(hj-hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj-ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj-modnameN classnameNjj)}j](jNj)}jj-sbc.it_IT.mutex_lockesbuh1hhj-ubj,)}(h h]h }(hj.hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj-ubj,)}(hj,h]h*}(hj.hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj-ubjk))}(hlockh]hlock}(hj.hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj-ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj-ubah}(h]h ]h"]h$]h&]jTjUuh1j-,hj-hhhj-hMubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj~-hhhj-hMubah}(h]jy-ah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hj-hMhj{-hhubj))}(hhh]h)}(hacquire the mutexh]hacquire the mutex}(hjG.hhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.c hKhjD.hhubah}(h]h ]h"]h$]h&]uh1j)hj{-hhhj-hMubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)j_.j)j_.j)j)j)uh1jS)hhhj1)hNhNubj))}(hX**Parameters** ``struct mutex *lock`` the mutex to be acquired **Description** Lock the mutex exclusively for this task. If the mutex is not available right now, it will sleep until it can get it. The mutex must later on be released by the same task that acquired it. Recursive locking is not allowed. The task may not exit without first unlocking the mutex. Also, kernel memory where the mutex resides must not be freed with the mutex still locked. The mutex must first be initialized (or statically defined) before it can be locked. memset()-ing the mutex to 0 is not allowed. (The CONFIG_DEBUG_MUTEXES .config option turns on debugging checks that will enforce the restrictions and will also do deadlock debugging) This function is similar to (but not equivalent to) down().h](h)}(h**Parameters**h]j)}(hji.h]h Parameters}(hjk.hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjg.ubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chMhjc.ubj*)}(hhh]j*)}(h0``struct mutex *lock`` the mutex to be acquired h](j *)}(h``struct mutex *lock``h]jZ)}(hj.h]hstruct mutex *lock}(hj.hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj.ubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chKhj.ubj&*)}(hhh]h)}(hthe mutex to be acquiredh]hthe mutex to be acquired}(hj.hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj.hKhj.ubah}(h]h ]h"]h$]h&]uh1j%*hj.ubeh}(h]h ]h"]h$]h&]uh1j*hj.hKhj.ubah}(h]h ]h"]h$]h&]uh1j*hjc.ubh)}(h**Description**h]j)}(hj.h]h Description}(hj.hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj.ubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chKhjc.ubh)}(huLock the mutex exclusively for this task. If the mutex is not available right now, it will sleep until it can get it.h]huLock the mutex exclusively for this task. If the mutex is not available right now, it will sleep until it can get it.}(hj.hhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chKhjc.ubh)}(hX}The mutex must later on be released by the same task that acquired it. Recursive locking is not allowed. The task may not exit without first unlocking the mutex. Also, kernel memory where the mutex resides must not be freed with the mutex still locked. The mutex must first be initialized (or statically defined) before it can be locked. memset()-ing the mutex to 0 is not allowed.h]hX}The mutex must later on be released by the same task that acquired it. Recursive locking is not allowed. The task may not exit without first unlocking the mutex. Also, kernel memory where the mutex resides must not be freed with the mutex still locked. The mutex must first be initialized (or statically defined) before it can be locked. memset()-ing the mutex to 0 is not allowed.}(hj.hhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chMhjc.ubh)}(h(The CONFIG_DEBUG_MUTEXES .config option turns on debugging checks that will enforce the restrictions and will also do deadlock debugging)h]h(The CONFIG_DEBUG_MUTEXES .config option turns on debugging checks that will enforce the restrictions and will also do deadlock debugging)}(hj.hhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chM hjc.ubh)}(h;This function is similar to (but not equivalent to) down().h]h;This function is similar to (but not equivalent to) down().}(hj/hhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chMhjc.ubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj1)hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)it_IT.mutex_unlock (C function)c.it_IT.mutex_unlockhNtauh1jB)hj1)hhhNhNubjT))}(hhh](jY))}(h&void mutex_unlock (struct mutex *lock)h]j_))}(h%void mutex_unlock(struct mutex *lock)h](j+)}(hvoidh]hvoid}(hj5/hhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hj1/hhhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chMubj,)}(h h]h }(hjD/hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj1/hhhjC/hMubje))}(h mutex_unlockh]jk))}(h mutex_unlockh]h mutex_unlock}(hjV/hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjR/ubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hj1/hhhjC/hMubj.,)}(h(struct mutex *lock)h]j4,)}(hstruct mutex *lockh](j:,)}(hj=,h]hstruct}(hjr/hhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjn/ubj,)}(h h]h }(hj/hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjn/ubh)}(hhh]jk))}(hmutexh]hmutex}(hj/hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj/ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj/modnameN classnameNjj)}j](jNj)}jjX/sbc.it_IT.mutex_unlockesbuh1hhjn/ubj,)}(h h]h }(hj/hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjn/ubj,)}(hj,h]h*}(hj/hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjn/ubjk))}(hlockh]hlock}(hj/hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjn/ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjj/ubah}(h]h ]h"]h$]h&]jTjUuh1j-,hj1/hhhjC/hMubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj-/hhhjC/hMubah}(h]j(/ah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjC/hMhj*/hhubj))}(hhh]h)}(hrelease the mutexh]hrelease the mutex}(hj/hhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chMhj/hhubah}(h]h ]h"]h$]h&]uh1j)hj*/hhhjC/hMubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)j0j)j0j)j)j)uh1jS)hhhj1)hNhNubj))}(hX4**Parameters** ``struct mutex *lock`` the mutex to be released **Description** Unlock a mutex that has been locked by this task previously. This function must not be used in interrupt context. Unlocking of a not locked mutex is not allowed. The caller must ensure that the mutex stays alive until this function has returned - mutex_unlock() can NOT directly be used to release an object such that another concurrent task can free it. Mutexes are different from spinlocks & refcounts in this aspect. This function is similar to (but not equivalent to) up().h](h)}(h**Parameters**h]j)}(hj0h]h Parameters}(hj0hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj0ubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chM hj0ubj*)}(hhh]j*)}(h0``struct mutex *lock`` the mutex to be released h](j *)}(h``struct mutex *lock``h]jZ)}(hj70h]hstruct mutex *lock}(hj90hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj50ubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chMhj10ubj&*)}(hhh]h)}(hthe mutex to be releasedh]hthe mutex to be released}(hjP0hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjL0hMhjM0ubah}(h]h ]h"]h$]h&]uh1j%*hj10ubeh}(h]h ]h"]h$]h&]uh1j*hjL0hMhj.0ubah}(h]h ]h"]h$]h&]uh1j*hj0ubh)}(h**Description**h]j)}(hjr0h]h Description}(hjt0hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjp0ubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chM hj0ubh)}(h8h]hReturn}(hj@8hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj<8ubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chMhj7ubh)}(hP0 if the lock was successfully acquired or ``-EINTR`` if a fatal signal arrived.h](h+0 if the lock was successfully acquired or }(hjT8hhhNhNubjZ)}(h ``-EINTR``h]h-EINTR}(hj\8hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjT8ubh if a fatal signal arrived.}(hjT8hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chMhj7ubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj1)hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO) it_IT.mutex_lock_io (C function)c.it_IT.mutex_lock_iohNtauh1jB)hj1)hhhNhNubjT))}(hhh](jY))}(h'void mutex_lock_io (struct mutex *lock)h]j_))}(h&void mutex_lock_io(struct mutex *lock)h](j+)}(hvoidh]hvoid}(hj8hhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hj8hhhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chMubj,)}(h h]h }(hj8hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj8hhhj8hMubje))}(h mutex_lock_ioh]jk))}(h mutex_lock_ioh]h mutex_lock_io}(hj8hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj8ubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hj8hhhj8hMubj.,)}(h(struct mutex *lock)h]j4,)}(hstruct mutex *lockh](j:,)}(hj=,h]hstruct}(hj8hhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hj8ubj,)}(h h]h }(hj8hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj8ubh)}(hhh]jk))}(hmutexh]hmutex}(hj8hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj8ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj8modnameN classnameNjj)}j](jNj)}jj8sbc.it_IT.mutex_lock_ioesbuh1hhj8ubj,)}(h h]h }(hj9hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj8ubj,)}(hj,h]h*}(hj9hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj8ubjk))}(hlockh]hlock}(hj,9hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj8ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj8ubah}(h]h ]h"]h$]h&]jTjUuh1j-,hj8hhhj8hMubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj8hhhj8hMubah}(h]j8ah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hj8hMhj8hhubj))}(hhh]h)}(h9Acquire the mutex and mark the process as waiting for I/Oh]h9Acquire the mutex and mark the process as waiting for I/O}(hjV9hhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chMhjS9hhubah}(h]h ]h"]h$]h&]uh1j)hj8hhhj8hMubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jn9j)jn9j)j)j)uh1jS)hhhj1)hNhNubj))}(hX**Parameters** ``struct mutex *lock`` The mutex to be acquired. **Description** Lock the mutex like mutex_lock(). While the task is waiting for this mutex, it will be accounted as being in the IO wait state by the scheduler. **Context** Process context.h](h)}(h**Parameters**h]j)}(hjx9h]h Parameters}(hjz9hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjv9ubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chMhjr9ubj*)}(hhh]j*)}(h1``struct mutex *lock`` The mutex to be acquired. h](j *)}(h``struct mutex *lock``h]jZ)}(hj9h]hstruct mutex *lock}(hj9hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj9ubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chMhj9ubj&*)}(hhh]h)}(hThe mutex to be acquired.h]hThe mutex to be acquired.}(hj9hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj9hMhj9ubah}(h]h ]h"]h$]h&]uh1j%*hj9ubeh}(h]h ]h"]h$]h&]uh1j*hj9hMhj9ubah}(h]h ]h"]h$]h&]uh1j*hjr9ubh)}(h**Description**h]j)}(hj9h]h Description}(hj9hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj9ubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chMhjr9ubh)}(hLock the mutex like mutex_lock(). While the task is waiting for this mutex, it will be accounted as being in the IO wait state by the scheduler.h]hLock the mutex like mutex_lock(). While the task is waiting for this mutex, it will be accounted as being in the IO wait state by the scheduler.}(hj9hhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chMhjr9ubh)}(h **Context**h]j)}(hj9h]hContext}(hj9hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj9ubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chMhjr9ubh)}(hProcess context.h]hProcess context.}(hj:hhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chMhjr9ubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj1)hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO) it_IT.mutex_trylock (C function)c.it_IT.mutex_trylockhNtauh1jB)hj1)hhhNhNubjT))}(hhh](jY))}(h&int mutex_trylock (struct mutex *lock)h]j_))}(h%int mutex_trylock(struct mutex *lock)h](j+)}(hinth]hint}(hj>:hhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hj::hhhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chM7ubj,)}(h h]h }(hjM:hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj::hhhjL:hM7ubje))}(h mutex_trylockh]jk))}(h mutex_trylockh]h mutex_trylock}(hj_:hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj[:ubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hj::hhhjL:hM7ubj.,)}(h(struct mutex *lock)h]j4,)}(hstruct mutex *lockh](j:,)}(hj=,h]hstruct}(hj{:hhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjw:ubj,)}(h h]h }(hj:hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjw:ubh)}(hhh]jk))}(hmutexh]hmutex}(hj:hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj:ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj:modnameN classnameNjj)}j](jNj)}jja:sbc.it_IT.mutex_trylockesbuh1hhjw:ubj,)}(h h]h }(hj:hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjw:ubj,)}(hj,h]h*}(hj:hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjw:ubjk))}(hlockh]hlock}(hj:hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjw:ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjs:ubah}(h]h ]h"]h$]h&]jTjUuh1j-,hj::hhhjL:hM7ubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj6:hhhjL:hM7ubah}(h]j1:ah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjL:hM7hj3:hhubj))}(hhh]h)}(h)try to acquire the mutex, without waitingh]h)try to acquire the mutex, without waiting}(hj:hhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chM*hj:hhubah}(h]h ]h"]h$]h&]uh1j)hj3:hhhjL:hM7ubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)j;j)j;j)j)j)uh1jS)hhhj1)hNhNubj))}(hX**Parameters** ``struct mutex *lock`` the mutex to be acquired **Description** Try to acquire the mutex atomically. Returns 1 if the mutex has been acquired successfully, and 0 on contention. This function must not be used in interrupt context. The mutex must be released by the same task that acquired it. **NOTE** this function follows the spin_trylock() convention, so it is negated from the down_trylock() return values! Be careful about this when converting semaphore users to mutexes.h](h)}(h**Parameters**h]j)}(hj!;h]h Parameters}(hj#;hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj;ubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chM.hj;ubj*)}(hhh]j*)}(h0``struct mutex *lock`` the mutex to be acquired h](j *)}(h``struct mutex *lock``h]jZ)}(hj@;h]hstruct mutex *lock}(hjB;hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj>;ubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chM+hj:;ubj&*)}(hhh]h)}(hthe mutex to be acquiredh]hthe mutex to be acquired}(hjY;hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjU;hM+hjV;ubah}(h]h ]h"]h$]h&]uh1j%*hj:;ubeh}(h]h ]h"]h$]h&]uh1j*hjU;hM+hj7;ubah}(h]h ]h"]h$]h&]uh1j*hj;ubh)}(h**Description**h]j)}(hj{;h]h Description}(hj};hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjy;ubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chM-hj;ubh)}(hpTry to acquire the mutex atomically. Returns 1 if the mutex has been acquired successfully, and 0 on contention.h]hpTry to acquire the mutex atomically. Returns 1 if the mutex has been acquired successfully, and 0 on contention.}(hj;hhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chM-hj;ubh)}(hrThis function must not be used in interrupt context. The mutex must be released by the same task that acquired it.h]hrThis function must not be used in interrupt context. The mutex must be released by the same task that acquired it.}(hj;hhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chM0hj;ubh)}(h**NOTE**h]j)}(hj;h]hNOTE}(hj;hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj;ubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chM3hj;ubh)}(hthis function follows the spin_trylock() convention, so it is negated from the down_trylock() return values! Be careful about this when converting semaphore users to mutexes.h]hthis function follows the spin_trylock() convention, so it is negated from the down_trylock() return values! Be careful about this when converting semaphore users to mutexes.}(hj;hhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chM0hj;ubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj1)hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO),it_IT.atomic_dec_and_mutex_lock (C function)!c.it_IT.atomic_dec_and_mutex_lockhNtauh1jB)hj1)hhhNhNubjT))}(hhh](jY))}(hAint atomic_dec_and_mutex_lock (atomic_t *cnt, struct mutex *lock)h]j_))}(h@int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock)h](j+)}(hinth]hint}(hj;hhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hj;hhhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chMqubj,)}(h h]h }(hj<hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj;hhhj<hMqubje))}(hatomic_dec_and_mutex_lockh]jk))}(hatomic_dec_and_mutex_lockh]hatomic_dec_and_mutex_lock}(hj<hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj<ubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hj;hhhj<hMqubj.,)}(h#(atomic_t *cnt, struct mutex *lock)h](j4,)}(h atomic_t *cnth](h)}(hhh]jk))}(hatomic_th]hatomic_t}(hj6<hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj3<ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj8<modnameN classnameNjj)}j](jNj)}jj<sb!c.it_IT.atomic_dec_and_mutex_lockesbuh1hhj/<ubj,)}(h h]h }(hjW<hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj/<ubj,)}(hj,h]h*}(hje<hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj/<ubjk))}(hcnth]hcnt}(hjr<hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj/<ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj+<ubj4,)}(hstruct mutex *lockh](j:,)}(hj=,h]hstruct}(hj<hhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hj<ubj,)}(h h]h }(hj<hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj<ubh)}(hhh]jk))}(hmutexh]hmutex}(hj<hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj<ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj<modnameN classnameNjj)}j](jNjS<!c.it_IT.atomic_dec_and_mutex_lockesbuh1hhj<ubj,)}(h h]h }(hj<hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj<ubj,)}(hj,h]h*}(hj<hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj<ubjk))}(hlockh]hlock}(hj<hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj<ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj+<ubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hj;hhhj<hMqubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj;hhhj<hMqubah}(h]j;ah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hj<hMqhj;hhubj))}(hhh]h)}(h#return holding mutex if we dec to 0h]h#return holding mutex if we dec to 0}(hj =hhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chMkhj =hhubah}(h]h ]h"]h$]h&]uh1j)hj;hhhj<hMqubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)j%=j)j%=j)j)j)uh1jS)hhhj1)hNhNubj))}(h**Parameters** ``atomic_t *cnt`` the atomic which we are to dec ``struct mutex *lock`` the mutex to return holding if we dec to 0 **Description** return true and hold lock if we dec to 0, return false otherwiseh](h)}(h**Parameters**h]j)}(hj/=h]h Parameters}(hj1=hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj-=ubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chMohj)=ubj*)}(hhh](j*)}(h1``atomic_t *cnt`` the atomic which we are to dec h](j *)}(h``atomic_t *cnt``h]jZ)}(hjN=h]h atomic_t *cnt}(hjP=hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjL=ubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chMlhjH=ubj&*)}(hhh]h)}(hthe atomic which we are to dech]hthe atomic which we are to dec}(hjg=hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjc=hMlhjd=ubah}(h]h ]h"]h$]h&]uh1j%*hjH=ubeh}(h]h ]h"]h$]h&]uh1j*hjc=hMlhjE=ubj*)}(hB``struct mutex *lock`` the mutex to return holding if we dec to 0 h](j *)}(h``struct mutex *lock``h]jZ)}(hj=h]hstruct mutex *lock}(hj=hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj=ubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chMmhj=ubj&*)}(hhh]h)}(h*the mutex to return holding if we dec to 0h]h*the mutex to return holding if we dec to 0}(hj=hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj=hMmhj=ubah}(h]h ]h"]h$]h&]uh1j%*hj=ubeh}(h]h ]h"]h$]h&]uh1j*hj=hMmhjE=ubeh}(h]h ]h"]h$]h&]uh1j*hj)=ubh)}(h**Description**h]j)}(hj=h]h Description}(hj=hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj=ubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chMohj)=ubh)}(h@return true and hold lock if we dec to 0, return false otherwiseh]h@return true and hold lock if we dec to 0, return false otherwise}(hj=hhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1398: ./kernel/locking/mutex.chMohj)=ubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj1)hhhNhNubeh}(h]riferimento-per-l-api-dei-mutexah ]h"]riferimento per l'api dei mutexah$]h&]uh1jhjhhhjhMgubj)}(hhh](j)}(hRiferimento per l'API dei Futexh]h!Riferimento per l’API dei Futex}(hj=hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj=hhhjhMpubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)it_IT.futex_hash (C function)c.it_IT.futex_hashhNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(hhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hj>hhho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKuubj,)}(h h]h }(hj.>hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj>hhhj->hKuubh)}(hhh]jk))}(hfutex_hash_bucketh]hfutex_hash_bucket}(hj?>hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj<>ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjA>modnameN classnameNjj)}j](jNj)}j futex_hashsbc.it_IT.futex_hashesbuh1hhj>hhhj->hKuubj,)}(h h]h }(hja>hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj>hhhj->hKuubj,)}(hj,h]h*}(hjo>hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj>hhhj->hKuubje))}(h futex_hashh]jk))}(hj^>h]h futex_hash}(hj>hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj|>ubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hj>hhhj->hKuubj.,)}(h(union futex_key *key)h]j4,)}(hunion futex_key *keyh](j:,)}(hunionh]hunion}(hj>hhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hj>ubj,)}(h h]h }(hj>hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj>ubh)}(hhh]jk))}(h futex_keyh]h futex_key}(hj>hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj>ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj>modnameN classnameNjj)}j](jNj\>c.it_IT.futex_hashesbuh1hhj>ubj,)}(h h]h }(hj>hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj>ubj,)}(hj,h]h*}(hj>hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj>ubjk))}(hkeyh]hkey}(hj>hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj>ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj>ubah}(h]h ]h"]h$]h&]jTjUuh1j-,hj>hhhj->hKuubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj>hhhj->hKuubah}(h]j>ah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hj->hKuhj>hhubj))}(hhh]h)}(h)Return the hash bucket in the global hashh]h)Return the hash bucket in the global hash}(hj?hhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKohj?hhubah}(h]h ]h"]h$]h&]uh1j)hj>hhhj->hKuubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)j6?j)j6?j)j)j)uh1jS)hhhj=hNhNubj))}(h**Parameters** ``union futex_key *key`` Pointer to the futex key for which the hash is calculated **Description** We hash on the keys returned from get_futex_key (see below) and return the corresponding hash bucket in the global hash.h](h)}(h**Parameters**h]j)}(hj@?h]h Parameters}(hjB?hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj>?ubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKshj:?ubj*)}(hhh]j*)}(hS``union futex_key *key`` Pointer to the futex key for which the hash is calculated h](j *)}(h``union futex_key *key``h]jZ)}(hj_?h]hunion futex_key *key}(hja?hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj]?ubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKphjY?ubj&*)}(hhh]h)}(h9Pointer to the futex key for which the hash is calculatedh]h9Pointer to the futex key for which the hash is calculated}(hjx?hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjt?hKphju?ubah}(h]h ]h"]h$]h&]uh1j%*hjY?ubeh}(h]h ]h"]h$]h&]uh1j*hjt?hKphjV?ubah}(h]h ]h"]h$]h&]uh1j*hj:?ubh)}(h**Description**h]j)}(hj?h]h Description}(hj?hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj?ubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKrhj:?ubh)}(hxWe hash on the keys returned from get_futex_key (see below) and return the corresponding hash bucket in the global hash.h]hxWe hash on the keys returned from get_futex_key (see below) and return the corresponding hash bucket in the global hash.}(hj?hhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKrhj:?ubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)$it_IT.futex_setup_timer (C function)c.it_IT.futex_setup_timerhNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(htstruct hrtimer_sleeper * futex_setup_timer (ktime_t *time, struct hrtimer_sleeper *timeout, int flags, u64 range_ns)h]j_))}(hrstruct hrtimer_sleeper *futex_setup_timer(ktime_t *time, struct hrtimer_sleeper *timeout, int flags, u64 range_ns)h](j:,)}(hj=,h]hstruct}(hj?hhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hj?hhho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKubj,)}(h h]h }(hj?hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj?hhhj?hKubh)}(hhh]jk))}(hhrtimer_sleeperh]hhrtimer_sleeper}(hj?hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj?ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj@modnameN classnameNjj)}j](jNj)}jfutex_setup_timersbc.it_IT.futex_setup_timeresbuh1hhj?hhhj?hKubj,)}(h h]h }(hj @hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj?hhhj?hKubj,)}(hj,h]h*}(hj.@hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj?hhhj?hKubje))}(hfutex_setup_timerh]jk))}(hj@h]hfutex_setup_timer}(hj?@hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj;@ubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hj?hhhj?hKubj.,)}(hI(ktime_t *time, struct hrtimer_sleeper *timeout, int flags, u64 range_ns)h](j4,)}(h ktime_t *timeh](h)}(hhh]jk))}(hktime_th]hktime_t}(hj]@hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjZ@ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj_@modnameN classnameNjj)}j](jNj@c.it_IT.futex_setup_timeresbuh1hhjV@ubj,)}(h h]h }(hj|@hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjV@ubj,)}(hj,h]h*}(hj@hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjV@ubjk))}(htimeh]htime}(hj@hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjV@ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjR@ubj4,)}(hstruct hrtimer_sleeper *timeouth](j:,)}(hj=,h]hstruct}(hj@hhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hj@ubj,)}(h h]h }(hj@hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj@ubh)}(hhh]jk))}(hhrtimer_sleeperh]hhrtimer_sleeper}(hj@hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj@ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj@modnameN classnameNjj)}j](jNj@c.it_IT.futex_setup_timeresbuh1hhj@ubj,)}(h h]h }(hj@hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj@ubj,)}(hj,h]h*}(hj@hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj@ubjk))}(htimeouth]htimeout}(hjAhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj@ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjR@ubj4,)}(h int flagsh](j+)}(hinth]hint}(hj!AhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjAubj,)}(h h]h }(hj/AhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjAubjk))}(hflagsh]hflags}(hj=AhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjAubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjR@ubj4,)}(h u64 range_nsh](h)}(hhh]jk))}(hu64h]hu64}(hjYAhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjVAubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj[AmodnameN classnameNjj)}j](jNj@c.it_IT.futex_setup_timeresbuh1hhjRAubj,)}(h h]h }(hjxAhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjRAubjk))}(hrange_nsh]hrange_ns}(hjAhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjRAubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjR@ubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hj?hhhj?hKubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj?hhhj?hKubah}(h]j?ah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hj?hKhj?hhubj))}(hhh]h)}(hset up the sleeping hrtimer.h]hset up the sleeping hrtimer.}(hjAhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhjAhhubah}(h]h ]h"]h$]h&]uh1j)hj?hhhj?hKubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jAj)jAj)j)j)uh1jS)hhhj=hNhNubj))}(hX7**Parameters** ``ktime_t *time`` ptr to the given timeout value ``struct hrtimer_sleeper *timeout`` the hrtimer_sleeper structure to be set up ``int flags`` futex flags ``u64 range_ns`` optional range in ns **Return** Initialized hrtimer_sleeper structure or NULL if no timeout value givenh](h)}(h**Parameters**h]j)}(hjAh]h Parameters}(hjAhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjAubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhjAubj*)}(hhh](j*)}(h1``ktime_t *time`` ptr to the given timeout value h](j *)}(h``ktime_t *time``h]jZ)}(hjAh]h ktime_t *time}(hjAhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjAubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhjAubj&*)}(hhh]h)}(hptr to the given timeout valueh]hptr to the given timeout value}(hj BhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjBhKhjBubah}(h]h ]h"]h$]h&]uh1j%*hjAubeh}(h]h ]h"]h$]h&]uh1j*hjBhKhjAubj*)}(hO``struct hrtimer_sleeper *timeout`` the hrtimer_sleeper structure to be set up h](j *)}(h#``struct hrtimer_sleeper *timeout``h]jZ)}(hj*Bh]hstruct hrtimer_sleeper *timeout}(hj,BhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj(Bubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhj$Bubj&*)}(hhh]h)}(h*the hrtimer_sleeper structure to be set uph]h*the hrtimer_sleeper structure to be set up}(hjCBhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj?BhKhj@Bubah}(h]h ]h"]h$]h&]uh1j%*hj$Bubeh}(h]h ]h"]h$]h&]uh1j*hj?BhKhjAubj*)}(h``int flags`` futex flags h](j *)}(h ``int flags``h]jZ)}(hjcBh]h int flags}(hjeBhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjaBubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhj]Bubj&*)}(hhh]h)}(h futex flagsh]h futex flags}(hj|BhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjxBhKhjyBubah}(h]h ]h"]h$]h&]uh1j%*hj]Bubeh}(h]h ]h"]h$]h&]uh1j*hjxBhKhjAubj*)}(h&``u64 range_ns`` optional range in ns h](j *)}(h``u64 range_ns``h]jZ)}(hjBh]h u64 range_ns}(hjBhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjBubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhjBubj&*)}(hhh]h)}(hoptional range in nsh]hoptional range in ns}(hjBhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjBhKhjBubah}(h]h ]h"]h$]h&]uh1j%*hjBubeh}(h]h ]h"]h$]h&]uh1j*hjBhKhjAubeh}(h]h ]h"]h$]h&]uh1j*hjAubh)}(h **Return**h]j)}(hjBh]hReturn}(hjBhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjBubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhjAubj*)}(hhh]j*)}(hGInitialized hrtimer_sleeper structure or NULL if no timeout value givenh](j *)}(h;Initialized hrtimer_sleeper structure or NULL if no timeouth]h;Initialized hrtimer_sleeper structure or NULL if no timeout}(hjBhhhNhNubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhjBubj&*)}(hhh]h)}(h value givenh]h value given}(hjChhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhjCubah}(h]h ]h"]h$]h&]uh1j%*hjBubeh}(h]h ]h"]h$]h&]uh1j*hjChKhjBubah}(h]h ]h"]h$]h&]uh1j*hjAubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO) it_IT.get_futex_key (C function)c.it_IT.get_futex_keyhNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(heint get_futex_key (u32 __user *uaddr, unsigned int flags, union futex_key *key, enum futex_access rw)h]j_))}(hdint get_futex_key(u32 __user *uaddr, unsigned int flags, union futex_key *key, enum futex_access rw)h](j+)}(hinth]hint}(hjGChhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjCChhho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKubj,)}(h h]h }(hjVChhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjCChhhjUChKubje))}(h get_futex_keyh]jk))}(h get_futex_keyh]h get_futex_key}(hjhChhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjdCubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjCChhhjUChKubj.,)}(hS(u32 __user *uaddr, unsigned int flags, union futex_key *key, enum futex_access rw)h](j4,)}(hu32 __user *uaddrh](h)}(hhh]jk))}(hu32h]hu32}(hjChhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjCubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjCmodnameN classnameNjj)}j](jNj)}jjjCsbc.it_IT.get_futex_keyesbuh1hhjCubj,)}(h h]h }(hjChhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjCubh__user}(hjChhhNhNubj,)}(h h]h }(hjChhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjCubj,)}(hj,h]h*}(hjChhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjCubjk))}(huaddrh]huaddr}(hjChhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjCubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj|Cubj4,)}(hunsigned int flagsh](j+)}(hunsignedh]hunsigned}(hjChhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjCubj,)}(h h]h }(hjChhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjCubj+)}(hinth]hint}(hj DhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjCubj,)}(h h]h }(hjDhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjCubjk))}(hflagsh]hflags}(hj&DhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjCubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj|Cubj4,)}(hunion futex_key *keyh](j:,)}(hj>h]hunion}(hj?DhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hj;Dubj,)}(h h]h }(hjLDhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj;Dubh)}(hhh]jk))}(h futex_keyh]h futex_key}(hj]DhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjZDubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj_DmodnameN classnameNjj)}j](jNjCc.it_IT.get_futex_keyesbuh1hhj;Dubj,)}(h h]h }(hj|DhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj;Dubj,)}(hj,h]h*}(hjDhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj;Dubjk))}(hkeyh]hkey}(hjDhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj;Dubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj|Cubj4,)}(henum futex_access rwh](j:,)}(henumh]henum}(hjDhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjDubj,)}(h h]h }(hjDhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjDubh)}(hhh]jk))}(h futex_accessh]h futex_access}(hjDhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjDubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjDmodnameN classnameNjj)}j](jNjCc.it_IT.get_futex_keyesbuh1hhjDubj,)}(h h]h }(hjDhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjDubjk))}(hrwh]hrw}(hjDhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjDubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj|Cubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hjCChhhjUChKubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj?ChhhjUChKubah}(h]j:Cah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjUChKhjEj)j>Ej)j)j)uh1jS)hhhj=hNhNubj))}(hX-**Parameters** ``u32 __user *uaddr`` virtual address of the futex ``unsigned int flags`` FLAGS_* ``union futex_key *key`` address where result is stored. ``enum futex_access rw`` mapping needs to be read/write (values: FUTEX_READ, FUTEX_WRITE) **Return** a negative error code or 0 **Description** The key words are stored in **key** on success. For shared mappings (when **fshared**), the key is: ( inode->i_sequence, page->index, offset_within_page ) [ also see get_inode_sequence_number() ] For private mappings (or when **!fshared**), the key is: ( current->mm, address, 0 ) This allows (cross process, where applicable) identification of the futex without keeping the page pinned for the duration of the FUTEX_WAIT. lock_page() might sleep, the caller should not hold a spinlock.h](h)}(h**Parameters**h]j)}(hjHEh]h Parameters}(hjJEhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjFEubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhjBEubj*)}(hhh](j*)}(h3``u32 __user *uaddr`` virtual address of the futex h](j *)}(h``u32 __user *uaddr``h]jZ)}(hjgEh]hu32 __user *uaddr}(hjiEhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjeEubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhjaEubj&*)}(hhh]h)}(hvirtual address of the futexh]hvirtual address of the futex}(hjEhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj|EhKhj}Eubah}(h]h ]h"]h$]h&]uh1j%*hjaEubeh}(h]h ]h"]h$]h&]uh1j*hj|EhKhj^Eubj*)}(h``unsigned int flags`` FLAGS_* h](j *)}(h``unsigned int flags``h]jZ)}(hjEh]hunsigned int flags}(hjEhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjEubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhjEubj&*)}(hhh]h)}(hFLAGS_*h]hFLAGS_*}(hjEhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjEhKhjEubah}(h]h ]h"]h$]h&]uh1j%*hjEubeh}(h]h ]h"]h$]h&]uh1j*hjEhKhj^Eubj*)}(h9``union futex_key *key`` address where result is stored. h](j *)}(h``union futex_key *key``h]jZ)}(hjEh]hunion futex_key *key}(hjEhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjEubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhjEubj&*)}(hhh]h)}(haddress where result is stored.h]haddress where result is stored.}(hjEhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjEhKhjEubah}(h]h ]h"]h$]h&]uh1j%*hjEubeh}(h]h ]h"]h$]h&]uh1j*hjEhKhj^Eubj*)}(hZ``enum futex_access rw`` mapping needs to be read/write (values: FUTEX_READ, FUTEX_WRITE) h](j *)}(h``enum futex_access rw``h]jZ)}(hjFh]henum futex_access rw}(hjFhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjFubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhj Fubj&*)}(hhh]h)}(h@mapping needs to be read/write (values: FUTEX_READ, FUTEX_WRITE)h]h@mapping needs to be read/write (values: FUTEX_READ, FUTEX_WRITE)}(hj+FhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhj(Fubah}(h]h ]h"]h$]h&]uh1j%*hj Fubeh}(h]h ]h"]h$]h&]uh1j*hj'FhKhj^Eubeh}(h]h ]h"]h$]h&]uh1j*hjBEubh)}(h **Return**h]j)}(hjNFh]hReturn}(hjPFhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjLFubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhjBEubh)}(ha negative error code or 0h]ha negative error code or 0}(hjdFhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhjBEubh)}(h**Description**h]j)}(hjuFh]h Description}(hjwFhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjsFubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhjBEubh)}(h/The key words are stored in **key** on success.h](hThe key words are stored in }(hjFhhhNhNubj)}(h**key**h]hkey}(hjFhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjFubh on success.}(hjFhhhNhNubeh}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhjBEubh)}(h3For shared mappings (when **fshared**), the key is:h](hFor shared mappings (when }(hjFhhhNhNubj)}(h **fshared**h]hfshared}(hjFhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjFubh), the key is:}(hjFhhhNhNubeh}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhjBEubj))}(h7( inode->i_sequence, page->index, offset_within_page ) h]h)}(h6( inode->i_sequence, page->index, offset_within_page )h]h6( inode->i_sequence, page->index, offset_within_page )}(hjFhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhjFubah}(h]h ]h"]h$]h&]uh1j)hjFhKhjBEubh)}(h([ also see get_inode_sequence_number() ]h]h([ also see get_inode_sequence_number() ]}(hjFhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhjBEubh)}(h8For private mappings (or when **!fshared**), the key is:h](hFor private mappings (or when }(hjFhhhNhNubj)}(h **!fshared**h]h!fshared}(hjFhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjFubh), the key is:}(hjFhhhNhNubeh}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhjBEubj))}(h( current->mm, address, 0 ) h]h)}(h( current->mm, address, 0 )h]h( current->mm, address, 0 )}(hjGhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhjGubah}(h]h ]h"]h$]h&]uh1j)hj(GhKhjBEubh)}(hThis allows (cross process, where applicable) identification of the futex without keeping the page pinned for the duration of the FUTEX_WAIT.h]hThis allows (cross process, where applicable) identification of the futex without keeping the page pinned for the duration of the FUTEX_WAIT.}(hj/GhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhjBEubh)}(h?lock_page() might sleep, the caller should not hold a spinlock.h]h?lock_page() might sleep, the caller should not hold a spinlock.}(hj>GhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhjBEubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)*it_IT.fault_in_user_writeable (C function)c.it_IT.fault_in_user_writeablehNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(h/int fault_in_user_writeable (u32 __user *uaddr)h]j_))}(h.int fault_in_user_writeable(u32 __user *uaddr)h](j+)}(hinth]hint}(hjmGhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjiGhhho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMubj,)}(h h]h }(hj|GhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjiGhhhj{GhMubje))}(hfault_in_user_writeableh]jk))}(hfault_in_user_writeableh]hfault_in_user_writeable}(hjGhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjGubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjiGhhhj{GhMubj.,)}(h(u32 __user *uaddr)h]j4,)}(hu32 __user *uaddrh](h)}(hhh]jk))}(hu32h]hu32}(hjGhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjGubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjGmodnameN classnameNjj)}j](jNj)}jjGsbc.it_IT.fault_in_user_writeableesbuh1hhjGubj,)}(h h]h }(hjGhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjGubh__user}(hjGhhhNhNubj,)}(h h]h }(hjGhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjGubj,)}(hj,h]h*}(hjGhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjGubjk))}(huaddrh]huaddr}(hjGhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjGubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjGubah}(h]h ]h"]h$]h&]jTjUuh1j-,hjiGhhhj{GhMubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjeGhhhj{GhMubah}(h]j`Gah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hj{GhMhjbGhhubj))}(hhh]h)}(h*Fault in user address and verify RW accessh]h*Fault in user address and verify RW access}(hj%HhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhj"Hhhubah}(h]h ]h"]h$]h&]uh1j)hjbGhhhj{GhMubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)j=Hj)j=Hj)j)j)uh1jS)hhhj=hNhNubj))}(hX**Parameters** ``u32 __user *uaddr`` pointer to faulting user space address **Description** Slow path to fixup the fault we just took in the atomic write access to **uaddr**. We have no generic implementation of a non-destructive write to the user address. We know that we faulted in the atomic pagefault disabled section so we can as well avoid the #PF overhead by calling get_user_pages() right away.h](h)}(h**Parameters**h]j)}(hjGHh]h Parameters}(hjIHhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjEHubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjAHubj*)}(hhh]j*)}(h=``u32 __user *uaddr`` pointer to faulting user space address h](j *)}(h``u32 __user *uaddr``h]jZ)}(hjfHh]hu32 __user *uaddr}(hjhHhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjdHubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhj`Hubj&*)}(hhh]h)}(h&pointer to faulting user space addressh]h&pointer to faulting user space address}(hjHhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj{HhMhj|Hubah}(h]h ]h"]h$]h&]uh1j%*hj`Hubeh}(h]h ]h"]h$]h&]uh1j*hj{HhMhj]Hubah}(h]h ]h"]h$]h&]uh1j*hjAHubh)}(h**Description**h]j)}(hjHh]h Description}(hjHhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjAHubh)}(hRSlow path to fixup the fault we just took in the atomic write access to **uaddr**.h](hHSlow path to fixup the fault we just took in the atomic write access to }(hjHhhhNhNubj)}(h **uaddr**h]huaddr}(hjHhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubh.}(hjHhhhNhNubeh}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjAHubh)}(hWe have no generic implementation of a non-destructive write to the user address. We know that we faulted in the atomic pagefault disabled section so we can as well avoid the #PF overhead by calling get_user_pages() right away.h]hWe have no generic implementation of a non-destructive write to the user address. We know that we faulted in the atomic pagefault disabled section so we can as well avoid the #PF overhead by calling get_user_pages() right away.}(hjHhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjAHubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)#it_IT.futex_top_waiter (C function)c.it_IT.futex_top_waiterhNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(hVstruct futex_q * futex_top_waiter (struct futex_hash_bucket *hb, union futex_key *key)h]j_))}(hTstruct futex_q *futex_top_waiter(struct futex_hash_bucket *hb, union futex_key *key)h](j:,)}(hj=,h]hstruct}(hjIhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjIhhho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMubj,)}(h h]h }(hjIhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjIhhhjIhMubh)}(hhh]jk))}(hfutex_qh]hfutex_q}(hj&IhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj#Iubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj(ImodnameN classnameNjj)}j](jNj)}jfutex_top_waitersbc.it_IT.futex_top_waiteresbuh1hhjIhhhjIhMubj,)}(h h]h }(hjHIhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjIhhhjIhMubj,)}(hj,h]h*}(hjVIhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjIhhhjIhMubje))}(hfutex_top_waiterh]jk))}(hjEIh]hfutex_top_waiter}(hjgIhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjcIubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjIhhhjIhMubj.,)}(h4(struct futex_hash_bucket *hb, union futex_key *key)h](j4,)}(hstruct futex_hash_bucket *hbh](j:,)}(hj=,h]hstruct}(hjIhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hj~Iubj,)}(h h]h }(hjIhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj~Iubh)}(hhh]jk))}(hfutex_hash_bucketh]hfutex_hash_bucket}(hjIhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjIubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjImodnameN classnameNjj)}j](jNjCIc.it_IT.futex_top_waiteresbuh1hhj~Iubj,)}(h h]h }(hjIhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj~Iubj,)}(hj,h]h*}(hjIhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj~Iubjk))}(hhbh]hhb}(hjIhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj~Iubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjzIubj4,)}(hunion futex_key *keyh](j:,)}(hj>h]hunion}(hjIhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjIubj,)}(h h]h }(hjJhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjIubh)}(hhh]jk))}(h futex_keyh]h futex_key}(hjJhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjJubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjJmodnameN classnameNjj)}j](jNjCIc.it_IT.futex_top_waiteresbuh1hhjIubj,)}(h h]h }(hj0JhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjIubj,)}(hj,h]h*}(hj>JhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjIubjk))}(hkeyh]hkey}(hjKJhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjIubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjzIubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hjIhhhjIhMubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjHhhhjIhMubah}(h]jHah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjIhMhjHhhubj))}(hhh]h)}(h-Return the highest priority waiter on a futexh]h-Return the highest priority waiter on a futex}(hjuJhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjrJhhubah}(h]h ]h"]h$]h&]uh1j)hjHhhhjIhMubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jJj)jJj)j)j)uh1jS)hhhj=hNhNubj))}(h**Parameters** ``struct futex_hash_bucket *hb`` the hash bucket the futex_q's reside in ``union futex_key *key`` the futex key (to distinguish it from other futex futex_q's) **Description** Must be called with the hb lock held.h](h)}(h**Parameters**h]j)}(hjJh]h Parameters}(hjJhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjJubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjJubj*)}(hhh](j*)}(hI``struct futex_hash_bucket *hb`` the hash bucket the futex_q's reside in h](j *)}(h ``struct futex_hash_bucket *hb``h]jZ)}(hjJh]hstruct futex_hash_bucket *hb}(hjJhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjJubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjJubj&*)}(hhh]h)}(h'the hash bucket the futex_q's reside inh]h)the hash bucket the futex_q’s reside in}(hjJhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjJhMhjJubah}(h]h ]h"]h$]h&]uh1j%*hjJubeh}(h]h ]h"]h$]h&]uh1j*hjJhMhjJubj*)}(hV``union futex_key *key`` the futex key (to distinguish it from other futex futex_q's) h](j *)}(h``union futex_key *key``h]jZ)}(hjJh]hunion futex_key *key}(hjJhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjJubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjJubj&*)}(hhh]h)}(hthe futex key (to distinguish it from other futex futex_q’s)}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjKhMhjKubah}(h]h ]h"]h$]h&]uh1j%*hjJubeh}(h]h ]h"]h$]h&]uh1j*hjKhMhjJubeh}(h]h ]h"]h$]h&]uh1j*hjJubh)}(h**Description**h]j)}(hj*Kh]h Description}(hj,KhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj(Kubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjJubh)}(h%Must be called with the hb lock held.h]h%Must be called with the hb lock held.}(hj@KhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjJubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO))it_IT.wait_for_owner_exiting (C function)c.it_IT.wait_for_owner_exitinghNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(hBvoid wait_for_owner_exiting (int ret, struct task_struct *exiting)h]j_))}(hAvoid wait_for_owner_exiting(int ret, struct task_struct *exiting)h](j+)}(hvoidh]hvoid}(hjoKhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjkKhhho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMubj,)}(h h]h }(hj~KhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjkKhhhj}KhMubje))}(hwait_for_owner_exitingh]jk))}(hwait_for_owner_exitingh]hwait_for_owner_exiting}(hjKhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjKubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjkKhhhj}KhMubj.,)}(h&(int ret, struct task_struct *exiting)h](j4,)}(hint reth](j+)}(hinth]hint}(hjKhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjKubj,)}(h h]h }(hjKhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjKubjk))}(hreth]hret}(hjKhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjKubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjKubj4,)}(hstruct task_struct *exitingh](j:,)}(hj=,h]hstruct}(hjKhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjKubj,)}(h h]h }(hjKhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjKubh)}(hhh]jk))}(h task_structh]h task_struct}(hjKhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjKubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjLmodnameN classnameNjj)}j](jNj)}jjKsbc.it_IT.wait_for_owner_exitingesbuh1hhjKubj,)}(h h]h }(hj LhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjKubj,)}(hj,h]h*}(hj.LhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjKubjk))}(hexitingh]hexiting}(hj;LhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjKubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjKubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hjkKhhhj}KhMubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjgKhhhj}KhMubah}(h]jbKah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hj}KhMhjdKhhubj))}(hhh]h)}(h Block until the owner has exitedh]h Block until the owner has exited}(hjeLhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjbLhhubah}(h]h ]h"]h$]h&]uh1j)hjdKhhhj}KhMubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)j}Lj)j}Lj)j)j)uh1jS)hhhj=hNhNubj))}(h**Parameters** ``int ret`` owner's current futex lock status ``struct task_struct *exiting`` Pointer to the exiting task **Description** Caller must hold a refcount on **exiting**.h](h)}(h**Parameters**h]j)}(hjLh]h Parameters}(hjLhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjLubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjLubj*)}(hhh](j*)}(h.``int ret`` owner's current futex lock status h](j *)}(h ``int ret``h]jZ)}(hjLh]hint ret}(hjLhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjLubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjLubj&*)}(hhh]h)}(h!owner's current futex lock statush]h#owner’s current futex lock status}(hjLhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjLhMhjLubah}(h]h ]h"]h$]h&]uh1j%*hjLubeh}(h]h ]h"]h$]h&]uh1j*hjLhMhjLubj*)}(h<``struct task_struct *exiting`` Pointer to the exiting task h](j *)}(h``struct task_struct *exiting``h]jZ)}(hjLh]hstruct task_struct *exiting}(hjLhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjLubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjLubj&*)}(hhh]h)}(hPointer to the exiting taskh]hPointer to the exiting task}(hjLhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjLhMhjLubah}(h]h ]h"]h$]h&]uh1j%*hjLubeh}(h]h ]h"]h$]h&]uh1j*hjLhMhjLubeh}(h]h ]h"]h$]h&]uh1j*hjLubh)}(h**Description**h]j)}(hjMh]h Description}(hjMhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjMubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjLubh)}(h+Caller must hold a refcount on **exiting**.h](hCaller must hold a refcount on }(hj0MhhhNhNubj)}(h **exiting**h]hexiting}(hj8MhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj0Mubh.}(hj0MhhhNhNubeh}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjLubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)"it_IT.__futex_unqueue (C function)c.it_IT.__futex_unqueuehNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(h(void __futex_unqueue (struct futex_q *q)h]j_))}(h'void __futex_unqueue(struct futex_q *q)h](j+)}(hvoidh]hvoid}(hjqMhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjmMhhho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMubj,)}(h h]h }(hjMhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjmMhhhjMhMubje))}(h__futex_unqueueh]jk))}(h__futex_unqueueh]h__futex_unqueue}(hjMhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjMubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjmMhhhjMhMubj.,)}(h(struct futex_q *q)h]j4,)}(hstruct futex_q *qh](j:,)}(hj=,h]hstruct}(hjMhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjMubj,)}(h h]h }(hjMhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjMubh)}(hhh]jk))}(hfutex_qh]hfutex_q}(hjMhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjMubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjMmodnameN classnameNjj)}j](jNj)}jjMsbc.it_IT.__futex_unqueueesbuh1hhjMubj,)}(h h]h }(hjMhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjMubj,)}(hj,h]h*}(hjMhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjMubjk))}(hqh]hq}(hjNhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjMubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjMubah}(h]h ]h"]h$]h&]jTjUuh1j-,hjmMhhhjMhMubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjiMhhhjMhMubah}(h]jdMah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjMhMhjfMhhubj))}(hhh]h)}(h-Remove the futex_q from its futex_hash_bucketh]h-Remove the futex_q from its futex_hash_bucket}(hj2NhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhj/Nhhubah}(h]h ]h"]h$]h&]uh1j)hjfMhhhjMhMubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jJNj)jJNj)j)j)uh1jS)hhhj=hNhNubj))}(h**Parameters** ``struct futex_q *q`` The futex_q to unqueue **Description** The q->lock_ptr must not be NULL and must be held by the caller.h](h)}(h**Parameters**h]j)}(hjTNh]h Parameters}(hjVNhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjRNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjNNubj*)}(hhh]j*)}(h-``struct futex_q *q`` The futex_q to unqueue h](j *)}(h``struct futex_q *q``h]jZ)}(hjsNh]hstruct futex_q *q}(hjuNhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjqNubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjmNubj&*)}(hhh]h)}(hThe futex_q to unqueueh]hThe futex_q to unqueue}(hjNhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjNhMhjNubah}(h]h ]h"]h$]h&]uh1j%*hjmNubeh}(h]h ]h"]h$]h&]uh1j*hjNhMhjjNubah}(h]h ]h"]h$]h&]uh1j*hjNNubh)}(h**Description**h]j)}(hjNh]h Description}(hjNhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjNNubh)}(h@The q->lock_ptr must not be NULL and must be held by the caller.h]h@The q->lock_ptr must not be NULL and must be held by the caller.}(hjNhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjNNubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO) it_IT.futex_unqueue (C function)c.it_IT.futex_unqueuehNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(h%int futex_unqueue (struct futex_q *q)h]j_))}(h$int futex_unqueue(struct futex_q *q)h](j+)}(hinth]hint}(hjNhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjNhhho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chM6ubj,)}(h h]h }(hjOhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjNhhhjOhM6ubje))}(h futex_unqueueh]jk))}(h futex_unqueueh]h futex_unqueue}(hjOhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjOubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjNhhhjOhM6ubj.,)}(h(struct futex_q *q)h]j4,)}(hstruct futex_q *qh](j:,)}(hj=,h]hstruct}(hj0OhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hj,Oubj,)}(h h]h }(hj=OhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj,Oubh)}(hhh]jk))}(hfutex_qh]hfutex_q}(hjNOhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjKOubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjPOmodnameN classnameNjj)}j](jNj)}jjOsbc.it_IT.futex_unqueueesbuh1hhj,Oubj,)}(h h]h }(hjoOhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj,Oubj,)}(hj,h]h*}(hj}OhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj,Oubjk))}(hj Nh]hq}(hjOhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj,Oubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj(Oubah}(h]h ]h"]h$]h&]jTjUuh1j-,hjNhhhjOhM6ubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjNhhhjOhM6ubah}(h]jNah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjOhM6hjNhhubj))}(hhh]h)}(h-Remove the futex_q from its futex_hash_bucketh]h-Remove the futex_q from its futex_hash_bucket}(hjOhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chM,hjOhhubah}(h]h ]h"]h$]h&]uh1j)hjNhhhjOhM6ubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jOj)jOj)j)j)uh1jS)hhhj=hNhNubj))}(hXj**Parameters** ``struct futex_q *q`` The futex_q to unqueue **Description** The q->lock_ptr must not be held by the caller. A call to futex_unqueue() must be paired with exactly one earlier call to futex_queue(). **Return** - 1 - if the futex_q was still queued (and we removed unqueued it); - 0 - if the futex_q was already removed by the waking threadh](h)}(h**Parameters**h]j)}(hjOh]h Parameters}(hjOhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjOubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chM0hjOubj*)}(hhh]j*)}(h-``struct futex_q *q`` The futex_q to unqueue h](j *)}(h``struct futex_q *q``h]jZ)}(hjOh]hstruct futex_q *q}(hjOhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjOubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chM-hjOubj&*)}(hhh]h)}(hThe futex_q to unqueueh]hThe futex_q to unqueue}(hj PhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj PhM-hj Pubah}(h]h ]h"]h$]h&]uh1j%*hjOubeh}(h]h ]h"]h$]h&]uh1j*hj PhM-hjOubah}(h]h ]h"]h$]h&]uh1j*hjOubh)}(h**Description**h]j)}(hj/Ph]h Description}(hj1PhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj-Pubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chM/hjOubh)}(hThe q->lock_ptr must not be held by the caller. A call to futex_unqueue() must be paired with exactly one earlier call to futex_queue().h]hThe q->lock_ptr must not be held by the caller. A call to futex_unqueue() must be paired with exactly one earlier call to futex_queue().}(hjEPhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chM/hjOubh)}(h **Return**h]j)}(hjVPh]hReturn}(hjXPhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjTPubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chM2hjOubj))}(h- 1 - if the futex_q was still queued (and we removed unqueued it); - 0 - if the futex_q was already removed by the waking threadh]jV )}(hhh](j[ )}(hA1 - if the futex_q was still queued (and we removed unqueued it);h]h)}(hjuPh]hA1 - if the futex_q was still queued (and we removed unqueued it);}(hjwPhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chM2hjsPubah}(h]h ]h"]h$]h&]uh1jZ hjpPubj[ )}(h;0 - if the futex_q was already removed by the waking threadh]h)}(hjPh]h;0 - if the futex_q was already removed by the waking thread}(hjPhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chM3hjPubah}(h]h ]h"]h$]h&]uh1jZ hjpPubeh}(h]h ]h"]h$]h&]j j uh1jU hjPhM2hjlPubah}(h]h ]h"]h$]h&]uh1j)hjPhM2hjOubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)'it_IT.futex_exit_recursive (C function)c.it_IT.futex_exit_recursivehNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(h3void futex_exit_recursive (struct task_struct *tsk)h]j_))}(h2void futex_exit_recursive(struct task_struct *tsk)h](j+)}(hvoidh]hvoid}(hjPhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjPhhho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMubj,)}(h h]h }(hjPhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjPhhhjPhMubje))}(hfutex_exit_recursiveh]jk))}(hfutex_exit_recursiveh]hfutex_exit_recursive}(hjPhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjPubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjPhhhjPhMubj.,)}(h(struct task_struct *tsk)h]j4,)}(hstruct task_struct *tskh](j:,)}(hj=,h]hstruct}(hj QhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjQubj,)}(h h]h }(hjQhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjQubh)}(hhh]jk))}(h task_structh]h task_struct}(hj*QhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj'Qubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj,QmodnameN classnameNjj)}j](jNj)}jjPsbc.it_IT.futex_exit_recursiveesbuh1hhjQubj,)}(h h]h }(hjKQhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjQubj,)}(hj,h]h*}(hjYQhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjQubjk))}(htskh]htsk}(hjfQhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjQubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjQubah}(h]h ]h"]h$]h&]jTjUuh1j-,hjPhhhjPhMubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjPhhhjPhMubah}(h]jPah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjPhMhjPhhubj))}(hhh]h)}(h-Set the tasks futex state to FUTEX_STATE_DEADh]h-Set the tasks futex state to FUTEX_STATE_DEAD}(hjQhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjQhhubah}(h]h ]h"]h$]h&]uh1j)hjPhhhjPhMubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jQj)jQj)j)j)uh1jS)hhhj=hNhNubj))}(hX**Parameters** ``struct task_struct *tsk`` task to set the state on **Description** Set the futex exit state of the task lockless. The futex waiter code observes that state when a task is exiting and loops until the task has actually finished the futex cleanup. The worst case for this is that the waiter runs through the wait loop until the state becomes visible. This is called from the recursive fault handling path in make_task_dead(). This is best effort. Either the futex exit code has run already or not. If the OWNER_DIED bit has been set on the futex then the waiter can take it over. If not, the problem is pushed back to user space. If the futex exit code did not run yet, then an already queued waiter might block forever, but there is nothing which can be done about that.h](h)}(h**Parameters**h]j)}(hjQh]h Parameters}(hjQhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjQubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjQubj*)}(hhh]j*)}(h5``struct task_struct *tsk`` task to set the state on h](j *)}(h``struct task_struct *tsk``h]jZ)}(hjQh]hstruct task_struct *tsk}(hjQhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjQubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjQubj&*)}(hhh]h)}(htask to set the state onh]htask to set the state on}(hjQhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjQhMhjQubah}(h]h ]h"]h$]h&]uh1j%*hjQubeh}(h]h ]h"]h$]h&]uh1j*hjQhMhjQubah}(h]h ]h"]h$]h&]uh1j*hjQubh)}(h**Description**h]j)}(hj Rh]h Description}(hjRhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj Rubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjQubh)}(hXSet the futex exit state of the task lockless. The futex waiter code observes that state when a task is exiting and loops until the task has actually finished the futex cleanup. The worst case for this is that the waiter runs through the wait loop until the state becomes visible.h]hXSet the futex exit state of the task lockless. The futex waiter code observes that state when a task is exiting and loops until the task has actually finished the futex cleanup. The worst case for this is that the waiter runs through the wait loop until the state becomes visible.}(hj"RhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjQubh)}(hJThis is called from the recursive fault handling path in make_task_dead().h]hJThis is called from the recursive fault handling path in make_task_dead().}(hj1RhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjQubh)}(hXYThis is best effort. Either the futex exit code has run already or not. If the OWNER_DIED bit has been set on the futex then the waiter can take it over. If not, the problem is pushed back to user space. If the futex exit code did not run yet, then an already queued waiter might block forever, but there is nothing which can be done about that.h]hXYThis is best effort. Either the futex exit code has run already or not. If the OWNER_DIED bit has been set on the futex then the waiter can take it over. If not, the problem is pushed back to user space. If the futex exit code did not run yet, then an already queued waiter might block forever, but there is nothing which can be done about that.}(hj@RhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjQubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)it_IT.futex_q (C struct)c.it_IT.futex_qhNtauh1jB)hj=hhhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhNubjT))}(hhh](jY))}(hfutex_qh]j_))}(hstruct futex_qh](j:,)}(hj=,h]hstruct}(hjpRhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjlRhhhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKubj,)}(h h]h }(hj~RhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjlRhhhj}RhKubje))}(hfutex_qh]jk))}(hjjRh]hfutex_q}(hjRhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjRubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjlRhhhj}RhKubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjhRhhhj}RhKubah}(h]jbRah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hj}RhKhjeRhhubj))}(hhh]h)}(h2The hashed futex queue entry, one per waiting taskh]h2The hashed futex queue entry, one per waiting task}(hjRhhhNhNubah}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjRhhubah}(h]h ]h"]h$]h&]uh1j)hjeRhhhj}RhKubeh}(h]h ](jstructeh"]h$]h&]j)jj)jRj)jRj)j)j)uh1jS)hhhj=hjdRhNubj))}(hX;**Definition**:: struct futex_q { struct plist_node list; struct task_struct *task; spinlock_t *lock_ptr; futex_wake_fn *wake; void *wake_data; union futex_key key; struct futex_pi_state *pi_state; struct rt_mutex_waiter *rt_waiter; union futex_key *requeue_pi_key; u32 bitset; atomic_t requeue_state; #ifdef CONFIG_PREEMPT_RT; struct rcuwait requeue_wait; #endif; }; **Members** ``list`` priority-sorted list of tasks waiting on this futex ``task`` the task waiting on the futex ``lock_ptr`` the hash bucket lock ``wake`` the wake handler for this queue ``wake_data`` data associated with the wake handler ``key`` the key the futex is hashed on ``pi_state`` optional priority inheritance state ``rt_waiter`` rt_waiter storage for use with requeue_pi ``requeue_pi_key`` the requeue_pi target futex key ``bitset`` bitset for the optional bitmasked wakeup ``requeue_state`` State field for futex_requeue_pi() ``requeue_wait`` RCU wait for futex_requeue_pi() (RT only)h](h)}(h**Definition**::h](j)}(h**Definition**h]h Definition}(hjRhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjRubh:}(hjRhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjRubjE)}(hXstruct futex_q { struct plist_node list; struct task_struct *task; spinlock_t *lock_ptr; futex_wake_fn *wake; void *wake_data; union futex_key key; struct futex_pi_state *pi_state; struct rt_mutex_waiter *rt_waiter; union futex_key *requeue_pi_key; u32 bitset; atomic_t requeue_state; #ifdef CONFIG_PREEMPT_RT; struct rcuwait requeue_wait; #endif; };h]hXstruct futex_q { struct plist_node list; struct task_struct *task; spinlock_t *lock_ptr; futex_wake_fn *wake; void *wake_data; union futex_key key; struct futex_pi_state *pi_state; struct rt_mutex_waiter *rt_waiter; union futex_key *requeue_pi_key; u32 bitset; atomic_t requeue_state; #ifdef CONFIG_PREEMPT_RT; struct rcuwait requeue_wait; #endif; };}hjRsbah}(h]h ]h"]h$]h&]jTjUuh1jDhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjRubh)}(h **Members**h]j)}(hjSh]hMembers}(hjShhhNhNubah}(h]h ]h"]h$]h&]uh1jhjRubah}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjRubj*)}(hhh](j*)}(h=``list`` priority-sorted list of tasks waiting on this futex h](j *)}(h``list``h]jZ)}(hjSh]hlist}(hj!ShhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjSubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjSubj&*)}(hhh]h)}(h3priority-sorted list of tasks waiting on this futexh]h3priority-sorted list of tasks waiting on this futex}(hj8ShhhNhNubah}(h]h ]h"]h$]h&]uh1hhj4ShKhj5Subah}(h]h ]h"]h$]h&]uh1j%*hjSubeh}(h]h ]h"]h$]h&]uh1j*hj4ShKhjSubj*)}(h'``task`` the task waiting on the futex h](j *)}(h``task``h]jZ)}(hjXSh]htask}(hjZShhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjVSubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjRSubj&*)}(hhh]h)}(hthe task waiting on the futexh]hthe task waiting on the futex}(hjqShhhNhNubah}(h]h ]h"]h$]h&]uh1hhjmShKhjnSubah}(h]h ]h"]h$]h&]uh1j%*hjRSubeh}(h]h ]h"]h$]h&]uh1j*hjmShKhjSubj*)}(h"``lock_ptr`` the hash bucket lock h](j *)}(h ``lock_ptr``h]jZ)}(hjSh]hlock_ptr}(hjShhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjSubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjSubj&*)}(hhh]h)}(hthe hash bucket lockh]hthe hash bucket lock}(hjShhhNhNubah}(h]h ]h"]h$]h&]uh1hhjShKhjSubah}(h]h ]h"]h$]h&]uh1j%*hjSubeh}(h]h ]h"]h$]h&]uh1j*hjShKhjSubj*)}(h)``wake`` the wake handler for this queue h](j *)}(h``wake``h]jZ)}(hjSh]hwake}(hjShhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjSubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjSubj&*)}(hhh]h)}(hthe wake handler for this queueh]hthe wake handler for this queue}(hjShhhNhNubah}(h]h ]h"]h$]h&]uh1hhjShKhjSubah}(h]h ]h"]h$]h&]uh1j%*hjSubeh}(h]h ]h"]h$]h&]uh1j*hjShKhjSubj*)}(h4``wake_data`` data associated with the wake handler h](j *)}(h ``wake_data``h]jZ)}(hjTh]h wake_data}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjTubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjSubj&*)}(hhh]h)}(h%data associated with the wake handlerh]h%data associated with the wake handler}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1hhjThKhjTubah}(h]h ]h"]h$]h&]uh1j%*hjSubeh}(h]h ]h"]h$]h&]uh1j*hjThKhjSubj*)}(h'``key`` the key the futex is hashed on h](j *)}(h``key``h]jZ)}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj:Tubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhj6Tubj&*)}(hhh]h)}(hthe key the futex is hashed onh]hthe key the futex is hashed on}(hjUThhhNhNubah}(h]h ]h"]h$]h&]uh1hhjQThKhjRTubah}(h]h ]h"]h$]h&]uh1j%*hj6Tubeh}(h]h ]h"]h$]h&]uh1j*hjQThKhjSubj*)}(h1``pi_state`` optional priority inheritance state h](j *)}(h ``pi_state``h]jZ)}(hjuTh]hpi_state}(hjwThhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjsTubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjoTubj&*)}(hhh]h)}(h#optional priority inheritance stateh]h#optional priority inheritance state}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1hhjThKhjTubah}(h]h ]h"]h$]h&]uh1j%*hjoTubeh}(h]h ]h"]h$]h&]uh1j*hjThKhjSubj*)}(h8``rt_waiter`` rt_waiter storage for use with requeue_pi h](j *)}(h ``rt_waiter``h]jZ)}(hjTh]h rt_waiter}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjTubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjTubj&*)}(hhh]h)}(h)rt_waiter storage for use with requeue_pih]h)rt_waiter storage for use with requeue_pi}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1hhjThKhjTubah}(h]h ]h"]h$]h&]uh1j%*hjTubeh}(h]h ]h"]h$]h&]uh1j*hjThKhjSubj*)}(h3``requeue_pi_key`` the requeue_pi target futex key h](j *)}(h``requeue_pi_key``h]jZ)}(hjTh]hrequeue_pi_key}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjTubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjTubj&*)}(hhh]h)}(hthe requeue_pi target futex keyh]hthe requeue_pi target futex key}(hjUhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjThKhjTubah}(h]h ]h"]h$]h&]uh1j%*hjTubeh}(h]h ]h"]h$]h&]uh1j*hjThKhjSubj*)}(h4``bitset`` bitset for the optional bitmasked wakeup h](j *)}(h ``bitset``h]jZ)}(hj Uh]hbitset}(hj"UhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjUubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjUubj&*)}(hhh]h)}(h(bitset for the optional bitmasked wakeuph]h(bitset for the optional bitmasked wakeup}(hj9UhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj5UhKhj6Uubah}(h]h ]h"]h$]h&]uh1j%*hjUubeh}(h]h ]h"]h$]h&]uh1j*hj5UhKhjSubj*)}(h5``requeue_state`` State field for futex_requeue_pi() h](j *)}(h``requeue_state``h]jZ)}(hjYUh]h requeue_state}(hj[UhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjWUubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjSUubj&*)}(hhh]h)}(h"State field for futex_requeue_pi()h]h"State field for futex_requeue_pi()}(hjrUhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjnUhKhjoUubah}(h]h ]h"]h$]h&]uh1j%*hjSUubeh}(h]h ]h"]h$]h&]uh1j*hjnUhKhjSubj*)}(h:``requeue_wait`` RCU wait for futex_requeue_pi() (RT only)h](j *)}(h``requeue_wait``h]jZ)}(hjUh]h requeue_wait}(hjUhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjUubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjUubj&*)}(hhh]h)}(h)RCU wait for futex_requeue_pi() (RT only)h]h)RCU wait for futex_requeue_pi() (RT only)}(hjUhhhNhNubah}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjUubah}(h]h ]h"]h$]h&]uh1j%*hjUubeh}(h]h ]h"]h$]h&]uh1j*hjUhKhjSubeh}(h]h ]h"]h$]h&]uh1j*hjRubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhjdRhNubh)}(h**Description**h]j)}(hjUh]h Description}(hjUhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjUubah}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhj=hhubh)}(hWe use this hashed waitqueue, instead of a normal wait_queue_entry_t, so we can wake only the relevant ones (hashed queues may be shared).h]hWe use this hashed waitqueue, instead of a normal wait_queue_entry_t, so we can wake only the relevant ones (hashed queues may be shared).}(hjUhhhNhNubah}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhj=hhubh)}(hA futex_q has a woken state, just like tasks have TASK_RUNNING. It is considered woken when plist_node_empty(:c:type:`q->list `) || q->lock_ptr == 0. The order of wakeup is always to make the first condition true, then the second.h](hmA futex_q has a woken state, just like tasks have TASK_RUNNING. It is considered woken when plist_node_empty(}(hjUhhhNhNubh)}(h:c:type:`q->list `h]jZ)}(hjVh]hq->list}(hjVhhhNhNubah}(h]h ](hjc-typeeh"]h$]h&]uh1jYhjVubah}(h]h ]h"]h$]h&]refdochΌ refdomainjreftypetype refexplicitrefwarnjjhj Nuh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjUubhg) || q->lock_ptr == 0. The order of wakeup is always to make the first condition true, then the second.}(hjUhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhj VhKhj=hhubh)}(hxPI futexes are typically woken before they are removed from the hash list via the rt_mutex code. See futex_unqueue_pi().h]hxPI futexes are typically woken before they are removed from the hash list via the rt_mutex code. See futex_unqueue_pi().}(hj+VhhhNhNubah}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhj=hhubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)it_IT.futex_match (C function)c.it_IT.futex_matchhNtauh1jB)hj=hhhjdRhNubjT))}(hhh](jY))}(h>int futex_match (union futex_key *key1, union futex_key *key2)h]j_))}(h=int futex_match(union futex_key *key1, union futex_key *key2)h](j+)}(hinth]hint}(hjSVhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjOVhhhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKubj,)}(h h]h }(hjbVhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjOVhhhjaVhKubje))}(h futex_matchh]jk))}(h futex_matchh]h futex_match}(hjtVhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjpVubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjOVhhhjaVhKubj.,)}(h.(union futex_key *key1, union futex_key *key2)h](j4,)}(hunion futex_key *key1h](j:,)}(hj>h]hunion}(hjVhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjVubj,)}(h h]h }(hjVhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjVubh)}(hhh]jk))}(h futex_keyh]h futex_key}(hjVhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjVubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjVmodnameN classnameNjj)}j](jNj)}jjvVsbc.it_IT.futex_matchesbuh1hhjVubj,)}(h h]h }(hjVhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjVubj,)}(hj,h]h*}(hjVhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjVubjk))}(hkey1h]hkey1}(hjVhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjVubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjVubj4,)}(hunion futex_key *key2h](j:,)}(hj>h]hunion}(hjWhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjVubj,)}(h h]h }(hjWhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjVubh)}(hhh]jk))}(h futex_keyh]h futex_key}(hj!WhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjWubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj#WmodnameN classnameNjj)}j](jNjVc.it_IT.futex_matchesbuh1hhjVubj,)}(h h]h }(hj@WhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjVubj,)}(hj,h]h*}(hjNWhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjVubjk))}(hkey2h]hkey2}(hj[WhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjVubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjVubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hjOVhhhjaVhKubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjKVhhhjaVhKubah}(h]jFVah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjaVhKhjHVhhubj))}(hhh]h)}(h&Check whether two futex keys are equalh]h&Check whether two futex keys are equal}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjWhhubah}(h]h ]h"]h$]h&]uh1j)hjHVhhhjaVhKubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jWj)jWj)j)j)uh1jS)hhhj=hjdRhNubj))}(h**Parameters** ``union futex_key *key1`` Pointer to key1 ``union futex_key *key2`` Pointer to key2 **Description** Return 1 if two futex_keys are equal, 0 otherwise.h](h)}(h**Parameters**h]j)}(hjWh]h Parameters}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjWubah}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjWubj*)}(hhh](j*)}(h*``union futex_key *key1`` Pointer to key1 h](j *)}(h``union futex_key *key1``h]jZ)}(hjWh]hunion futex_key *key1}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjWubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjWubj&*)}(hhh]h)}(hPointer to key1h]hPointer to key1}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjWhKhjWubah}(h]h ]h"]h$]h&]uh1j%*hjWubeh}(h]h ]h"]h$]h&]uh1j*hjWhKhjWubj*)}(h*``union futex_key *key2`` Pointer to key2 h](j *)}(h``union futex_key *key2``h]jZ)}(hjWh]hunion futex_key *key2}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjWubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjWubj&*)}(hhh]h)}(hPointer to key2h]hPointer to key2}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjXhKhjXubah}(h]h ]h"]h$]h&]uh1j%*hjWubeh}(h]h ]h"]h$]h&]uh1j*hjXhKhjWubeh}(h]h ]h"]h$]h&]uh1j*hjWubh)}(h**Description**h]j)}(hj:Xh]h Description}(hjlock must be held by the caller, and is released here. A call to futex_queue() is typically paired with exactly one call to futex_unqueue(). The exceptions involve the PI related operations, which may use futex_unqueue_pi() or nothing if the unqueue is done as part of the wake process and the unqueue state is implicit in the state of woken task (see futex_wait_requeue_pi() for an example). Note that **task** may be NULL, for async usage of futexes.h](h)}(h**Parameters**h]j)}(hjCZh]h Parameters}(hjEZhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjAZubah}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhM)hj=Zubj*)}(hhh](j*)}(h-``struct futex_q *q`` The futex_q to enqueue h](j *)}(h``struct futex_q *q``h]jZ)}(hjbZh]hstruct futex_q *q}(hjdZhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj`Zubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhM&hj\Zubj&*)}(hhh]h)}(hThe futex_q to enqueueh]hThe futex_q to enqueue}(hj{ZhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjwZhM&hjxZubah}(h]h ]h"]h$]h&]uh1j%*hj\Zubeh}(h]h ]h"]h$]h&]uh1j*hjwZhM&hjYZubj*)}(h=``struct futex_hash_bucket *hb`` The destination hash bucket h](j *)}(h ``struct futex_hash_bucket *hb``h]jZ)}(hjZh]hstruct futex_hash_bucket *hb}(hjZhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjZubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhM'hjZubj&*)}(hhh]h)}(hThe destination hash bucketh]hThe destination hash bucket}(hjZhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjZhM'hjZubah}(h]h ]h"]h$]h&]uh1j%*hjZubeh}(h]h ]h"]h$]h&]uh1j*hjZhM'hjYZubj*)}(h6``struct task_struct *task`` Task queueing this futex h](j *)}(h``struct task_struct *task``h]jZ)}(hjZh]hstruct task_struct *task}(hjZhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjZubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhM(hjZubj&*)}(hhh]h)}(hTask queueing this futexh]hTask queueing this futex}(hjZhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjZhM(hjZubah}(h]h ]h"]h$]h&]uh1j%*hjZubeh}(h]h ]h"]h$]h&]uh1j*hjZhM(hjYZubeh}(h]h ]h"]h$]h&]uh1j*hj=Zubh)}(h**Description**h]j)}(hj[h]h Description}(hj[hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj [ubah}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhM*hj=Zubh)}(hXThe hb->lock must be held by the caller, and is released here. A call to futex_queue() is typically paired with exactly one call to futex_unqueue(). The exceptions involve the PI related operations, which may use futex_unqueue_pi() or nothing if the unqueue is done as part of the wake process and the unqueue state is implicit in the state of woken task (see futex_wait_requeue_pi() for an example).h]hXThe hb->lock must be held by the caller, and is released here. A call to futex_queue() is typically paired with exactly one call to futex_unqueue(). The exceptions involve the PI related operations, which may use futex_unqueue_pi() or nothing if the unqueue is done as part of the wake process and the unqueue state is implicit in the state of woken task (see futex_wait_requeue_pi() for an example).}(hj%[hhhNhNubah}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhM*hj=Zubh)}(h;Note that **task** may be NULL, for async usage of futexes.h](h Note that }(hj4[hhhNhNubj)}(h**task**h]htask}(hj<[hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj4[ubh) may be NULL, for async usage of futexes.}(hj4[hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhM1hj=Zubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhjdRhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)it_IT.futex_vector (C struct)c.it_IT.futex_vectorhNtauh1jB)hj=hhhjdRhNubjT))}(hhh](jY))}(h futex_vectorh]j_))}(hstruct futex_vectorh](j:,)}(hj=,h]hstruct}(hju[hhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjq[hhhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhM6ubj,)}(h h]h }(hj[hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjq[hhhj[hM6ubje))}(h futex_vectorh]jk))}(hjo[h]h futex_vector}(hj[hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj[ubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjq[hhhj[hM6ubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjm[hhhj[hM6ubah}(h]jh[ah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hj[hM6hjj[hhubj))}(hhh]h)}(h"Auxiliary struct for futex_waitv()h]h"Auxiliary struct for futex_waitv()}(hj[hhhNhNubah}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhMhj[hhubah}(h]h ]h"]h$]h&]uh1j)hjj[hhhj[hM6ubeh}(h]h ](jstructeh"]h$]h&]j)jj)j[j)j[j)j)j)uh1jS)hhhj=hjdRhNubj))}(h**Definition**:: struct futex_vector { struct futex_waitv w; struct futex_q q; }; **Members** ``w`` Userspace provided data ``q`` Kernel side datah](h)}(h**Definition**::h](j)}(h**Definition**h]h Definition}(hj[hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj[ubh:}(hj[hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhMhj[ubjE)}(hHstruct futex_vector { struct futex_waitv w; struct futex_q q; };h]hHstruct futex_vector { struct futex_waitv w; struct futex_q q; };}hj[sbah}(h]h ]h"]h$]h&]jTjUuh1jDhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhMhj[ubh)}(h **Members**h]j)}(hj\h]hMembers}(hj\hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj\ubah}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhMhj[ubj*)}(hhh](j*)}(h``w`` Userspace provided data h](j *)}(h``w``h]jZ)}(hj$\h]hw}(hj&\hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj"\ubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhMhj\ubj&*)}(hhh]h)}(hUserspace provided datah]hUserspace provided data}(hj=\hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj9\hMhj:\ubah}(h]h ]h"]h$]h&]uh1j%*hj\ubeh}(h]h ]h"]h$]h&]uh1j*hj9\hMhj\ubj*)}(h``q`` Kernel side datah](j *)}(h``q``h]jZ)}(hj]\h]hq}(hj_\hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj[\ubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhMhjW\ubj&*)}(hhh]h)}(hKernel side datah]hKernel side data}(hjv\hhhNhNubah}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhMhjs\ubah}(h]h ]h"]h$]h&]uh1j%*hjW\ubeh}(h]h ]h"]h$]h&]uh1j*hjr\hMhj\ubeh}(h]h ]h"]h$]h&]uh1j*hj[ubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhjdRhNubh)}(h**Description**h]j)}(hj\h]h Description}(hj\hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj\ubah}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhMhj=hhubh)}(hBStruct used to build an array with all data need for futex_waitv()h]hBStruct used to build an array with all data need for futex_waitv()}(hj\hhhNhNubah}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhMhj=hhubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)'it_IT.futex_lock_pi_atomic (C function)c.it_IT.futex_lock_pi_atomichNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(hint futex_lock_pi_atomic (u32 __user *uaddr, struct futex_hash_bucket *hb, union futex_key *key, struct futex_pi_state **ps, struct task_struct *task, struct task_struct **exiting, int set_waiters)h]j_))}(hint futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb, union futex_key *key, struct futex_pi_state **ps, struct task_struct *task, struct task_struct **exiting, int set_waiters)h](j+)}(hinth]hint}(hj\hhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hj\hhhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMubj,)}(h h]h }(hj\hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj\hhhj\hMubje))}(hfutex_lock_pi_atomich]jk))}(hfutex_lock_pi_atomich]hfutex_lock_pi_atomic}(hj\hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj\ubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hj\hhhj\hMubj.,)}(h(u32 __user *uaddr, struct futex_hash_bucket *hb, union futex_key *key, struct futex_pi_state **ps, struct task_struct *task, struct task_struct **exiting, int set_waiters)h](j4,)}(hu32 __user *uaddrh](h)}(hhh]jk))}(hu32h]hu32}(hj]hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj]ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj ]modnameN classnameNjj)}j](jNj)}jj]sbc.it_IT.futex_lock_pi_atomicesbuh1hhj]ubj,)}(h h]h }(hj?]hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj]ubh__user}(hj]hhhNhNubj,)}(h h]h }(hjQ]hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj]ubj,)}(hj,h]h*}(hj_]hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj]ubjk))}(huaddrh]huaddr}(hjl]hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj]ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj]ubj4,)}(hstruct futex_hash_bucket *hbh](j:,)}(hj=,h]hstruct}(hj]hhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hj]ubj,)}(h h]h }(hj]hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj]ubh)}(hhh]jk))}(hfutex_hash_bucketh]hfutex_hash_bucket}(hj]hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj]ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj]modnameN classnameNjj)}j](jNj;]c.it_IT.futex_lock_pi_atomicesbuh1hhj]ubj,)}(h h]h }(hj]hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj]ubj,)}(hj,h]h*}(hj]hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj]ubjk))}(hhbh]hhb}(hj]hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj]ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj]ubj4,)}(hunion futex_key *keyh](j:,)}(hj>h]hunion}(hj]hhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hj]ubj,)}(h h]h }(hj^hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj]ubh)}(hhh]jk))}(h futex_keyh]h futex_key}(hj^hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj^ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj^modnameN classnameNjj)}j](jNj;]c.it_IT.futex_lock_pi_atomicesbuh1hhj]ubj,)}(h h]h }(hj3^hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj]ubj,)}(hj,h]h*}(hjA^hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj]ubjk))}(hkeyh]hkey}(hjN^hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj]ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj]ubj4,)}(hstruct futex_pi_state **psh](j:,)}(hj=,h]hstruct}(hjg^hhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjc^ubj,)}(h h]h }(hjt^hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjc^ubh)}(hhh]jk))}(hfutex_pi_stateh]hfutex_pi_state}(hj^hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj^ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj^modnameN classnameNjj)}j](jNj;]c.it_IT.futex_lock_pi_atomicesbuh1hhjc^ubj,)}(h h]h }(hj^hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjc^ubj,)}(hj,h]h*}(hj^hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjc^ubj,)}(hj,h]h*}(hj^hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjc^ubjk))}(hpsh]hps}(hj^hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjc^ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj]ubj4,)}(hstruct task_struct *taskh](j:,)}(hj=,h]hstruct}(hj^hhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hj^ubj,)}(h h]h }(hj^hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj^ubh)}(hhh]jk))}(h task_structh]h task_struct}(hj_hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj_ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj_modnameN classnameNjj)}j](jNj;]c.it_IT.futex_lock_pi_atomicesbuh1hhj^ubj,)}(h h]h }(hj"_hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj^ubj,)}(hj,h]h*}(hj0_hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj^ubjk))}(htaskh]htask}(hj=_hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj^ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj]ubj4,)}(hstruct task_struct **exitingh](j:,)}(hj=,h]hstruct}(hjV_hhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjR_ubj,)}(h h]h }(hjc_hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjR_ubh)}(hhh]jk))}(h task_structh]h task_struct}(hjt_hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjq_ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjv_modnameN classnameNjj)}j](jNj;]c.it_IT.futex_lock_pi_atomicesbuh1hhjR_ubj,)}(h h]h }(hj_hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjR_ubj,)}(hj,h]h*}(hj_hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjR_ubj,)}(hj,h]h*}(hj_hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjR_ubjk))}(hexitingh]hexiting}(hj_hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjR_ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj]ubj4,)}(hint set_waitersh](j+)}(hinth]hint}(hj_hhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hj_ubj,)}(h h]h }(hj_hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj_ubjk))}(h set_waitersh]h set_waiters}(hj_hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj_ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj]ubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hj\hhhj\hMubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj\hhhj\hMubah}(h]j\ah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hj\hMhj\hhubj))}(hhh]h)}(h0Atomic work required to acquire a pi aware futexh]h0Atomic work required to acquire a pi aware futex}(hj`hhhNhNubah}(h]h ]h"]h$]h&]uh1hhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhj`hhubah}(h]h ]h"]h$]h&]uh1j)hj\hhhj\hMubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)j2`j)j2`j)j)j)uh1jS)hhhj=hNhNubj))}(hX**Parameters** ``u32 __user *uaddr`` the pi futex user address ``struct futex_hash_bucket *hb`` the pi futex hash bucket ``union futex_key *key`` the futex key associated with uaddr and hb ``struct futex_pi_state **ps`` the pi_state pointer where we store the result of the lookup ``struct task_struct *task`` the task to perform the atomic lock work for. This will be "current" except in the case of requeue pi. ``struct task_struct **exiting`` Pointer to store the task pointer of the owner task which is in the middle of exiting ``int set_waiters`` force setting the FUTEX_WAITERS bit (1) or not (0) **Return** - 0 - ready to wait; - 1 - acquired the lock; - <0 - error **Description** The hb->lock must be held by the caller. **exiting** is only set when the return value is -EBUSY. If so, this holds a refcount on the exiting task on return and the caller needs to drop it after waiting for the exit to complete.h](h)}(h**Parameters**h]j)}(hj<`h]h Parameters}(hj>`hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj:`ubah}(h]h ]h"]h$]h&]uh1hhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhj6`ubj*)}(hhh](j*)}(h0``u32 __user *uaddr`` the pi futex user address h](j *)}(h``u32 __user *uaddr``h]jZ)}(hj[`h]hu32 __user *uaddr}(hj]`hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjY`ubah}(h]h ]h"]h$]h&]uh1j *hm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhjU`ubj&*)}(hhh]h)}(hthe pi futex user addressh]hthe pi futex user address}(hjt`hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjp`hMhjq`ubah}(h]h ]h"]h$]h&]uh1j%*hjU`ubeh}(h]h ]h"]h$]h&]uh1j*hjp`hMhjR`ubj*)}(h:``struct futex_hash_bucket *hb`` the pi futex hash bucket h](j *)}(h ``struct futex_hash_bucket *hb``h]jZ)}(hj`h]hstruct futex_hash_bucket *hb}(hj`hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj`ubah}(h]h ]h"]h$]h&]uh1j *hm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhj`ubj&*)}(hhh]h)}(hthe pi futex hash bucketh]hthe pi futex hash bucket}(hj`hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj`hMhj`ubah}(h]h ]h"]h$]h&]uh1j%*hj`ubeh}(h]h ]h"]h$]h&]uh1j*hj`hMhjR`ubj*)}(hD``union futex_key *key`` the futex key associated with uaddr and hb h](j *)}(h``union futex_key *key``h]jZ)}(hj`h]hunion futex_key *key}(hj`hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj`ubah}(h]h ]h"]h$]h&]uh1j *hm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhj`ubj&*)}(hhh]h)}(h*the futex key associated with uaddr and hbh]h*the futex key associated with uaddr and hb}(hj`hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj`hMhj`ubah}(h]h ]h"]h$]h&]uh1j%*hj`ubeh}(h]h ]h"]h$]h&]uh1j*hj`hMhjR`ubj*)}(h\``struct futex_pi_state **ps`` the pi_state pointer where we store the result of the lookup h](j *)}(h``struct futex_pi_state **ps``h]jZ)}(hjah]hstruct futex_pi_state **ps}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjaubah}(h]h ]h"]h$]h&]uh1j *hm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhjaubj&*)}(hhh]h)}(haubah}(h]h ]h"]h$]h&]uh1j *hm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhj:aubj&*)}(hhh]h)}(hgthe task to perform the atomic lock work for. This will be "current" except in the case of requeue pi.h]hkthe task to perform the atomic lock work for. This will be “current” except in the case of requeue pi.}(hjYahhhNhNubah}(h]h ]h"]h$]h&]uh1hhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhjVaubah}(h]h ]h"]h$]h&]uh1j%*hj:aubeh}(h]h ]h"]h$]h&]uh1j*hjUahMhjR`ubj*)}(hw``struct task_struct **exiting`` Pointer to store the task pointer of the owner task which is in the middle of exiting h](j *)}(h ``struct task_struct **exiting``h]jZ)}(hjzah]hstruct task_struct **exiting}(hj|ahhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjxaubah}(h]h ]h"]h$]h&]uh1j *hm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhjtaubj&*)}(hhh]h)}(hUPointer to store the task pointer of the owner task which is in the middle of exitingh]hUPointer to store the task pointer of the owner task which is in the middle of exiting}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1hhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhjaubah}(h]h ]h"]h$]h&]uh1j%*hjtaubeh}(h]h ]h"]h$]h&]uh1j*hjahMhjR`ubj*)}(hG``int set_waiters`` force setting the FUTEX_WAITERS bit (1) or not (0) h](j *)}(h``int set_waiters``h]jZ)}(hjah]hint set_waiters}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjaubah}(h]h ]h"]h$]h&]uh1j *hm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhjaubj&*)}(hhh]h)}(h2force setting the FUTEX_WAITERS bit (1) or not (0)h]h2force setting the FUTEX_WAITERS bit (1) or not (0)}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1hhjahMhjaubah}(h]h ]h"]h$]h&]uh1j%*hjaubeh}(h]h ]h"]h$]h&]uh1j*hjahMhjR`ubeh}(h]h ]h"]h$]h&]uh1j*hj6`ubh)}(h **Return**h]j)}(hjah]hReturn}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1jhjaubah}(h]h ]h"]h$]h&]uh1hhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhj6`ubj))}(h=- 0 - ready to wait; - 1 - acquired the lock; - <0 - error h]jV )}(hhh](j[ )}(h0 - ready to wait;h]h)}(hjbh]h0 - ready to wait;}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1hhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhj bubah}(h]h ]h"]h$]h&]uh1jZ hj bubj[ )}(h1 - acquired the lock;h]h)}(hj&bh]h1 - acquired the lock;}(hj(bhhhNhNubah}(h]h ]h"]h$]h&]uh1hhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhj$bubah}(h]h ]h"]h$]h&]uh1jZ hj bubj[ )}(h <0 - error h]h)}(h <0 - errorh]h <0 - error}(hj@bhhhNhNubah}(h]h ]h"]h$]h&]uh1hhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhjlock must be held by the caller.h]h(The hb->lock must be held by the caller.}(hjybhhhNhNubah}(h]h ]h"]h$]h&]uh1hhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhj6`ubh)}(h**exiting** is only set when the return value is -EBUSY. If so, this holds a refcount on the exiting task on return and the caller needs to drop it after waiting for the exit to complete.h](j)}(h **exiting**h]hexiting}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjbubh is only set when the return value is -EBUSY. If so, this holds a refcount on the exiting task on return and the caller needs to drop it after waiting for the exit to complete.}(hjbhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhj6`ubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)!it_IT.fixup_pi_owner (C function)c.it_IT.fixup_pi_ownerhNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(hEint fixup_pi_owner (u32 __user *uaddr, struct futex_q *q, int locked)h]j_))}(hDint fixup_pi_owner(u32 __user *uaddr, struct futex_q *q, int locked)h](j+)}(hinth]hint}(hjbhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjbhhhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhubj,)}(h h]h }(hjbhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjbhhhjbhMhubje))}(hfixup_pi_ownerh]jk))}(hfixup_pi_ownerh]hfixup_pi_owner}(hjbhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjbubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjbhhhjbhMhubj.,)}(h2(u32 __user *uaddr, struct futex_q *q, int locked)h](j4,)}(hu32 __user *uaddrh](h)}(hhh]jk))}(hu32h]hu32}(hjchhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjcubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjcmodnameN classnameNjj)}j](jNj)}jjbsbc.it_IT.fixup_pi_owneresbuh1hhjbubj,)}(h h]h }(hj&chhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjbubh__user}(hjbhhhNhNubj,)}(h h]h }(hj8chhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjbubj,)}(hj,h]h*}(hjFchhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjbubjk))}(huaddrh]huaddr}(hjSchhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjbubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjbubj4,)}(hstruct futex_q *qh](j:,)}(hj=,h]hstruct}(hjlchhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjhcubj,)}(h h]h }(hjychhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjhcubh)}(hhh]jk))}(hfutex_qh]hfutex_q}(hjchhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjcubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjcmodnameN classnameNjj)}j](jNj"cc.it_IT.fixup_pi_owneresbuh1hhjhcubj,)}(h h]h }(hjchhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjhcubj,)}(hj,h]h*}(hjchhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjhcubjk))}(hj Nh]hq}(hjchhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjhcubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjbubj4,)}(h int lockedh](j+)}(hinth]hint}(hjchhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjcubj,)}(h h]h }(hjchhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjcubjk))}(hlockedh]hlocked}(hjchhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjcubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjbubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hjbhhhjbhMhubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjbhhhjbhMhubah}(h]jbah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjbhMhhjbhhubj))}(hhh]h)}(h-Post lock pi_state and corner case managementh]h-Post lock pi_state and corner case management}(hj"dhhhNhNubah}(h]h ]h"]h$]h&]uh1hhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMZhjdhhubah}(h]h ]h"]h$]h&]uh1j)hjbhhhjbhMhubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)j:dj)j:dj)j)j)uh1jS)hhhj=hNhNubj))}(hX#**Parameters** ``u32 __user *uaddr`` user address of the futex ``struct futex_q *q`` futex_q (contains pi_state and access to the rt_mutex) ``int locked`` if the attempt to take the rt_mutex succeeded (1) or not (0) **Description** After attempting to lock an rt_mutex, this function is called to cleanup the pi_state owner as well as handle race conditions that may allow us to acquire the lock. Must be called with the hb lock held. **Return** - 1 - success, lock taken; - 0 - success, lock not taken; - <0 - on error (-EFAULT)h](h)}(h**Parameters**h]j)}(hjDdh]h Parameters}(hjFdhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjBdubah}(h]h ]h"]h$]h&]uh1hhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chM^hj>dubj*)}(hhh](j*)}(h0``u32 __user *uaddr`` user address of the futex h](j *)}(h``u32 __user *uaddr``h]jZ)}(hjcdh]hu32 __user *uaddr}(hjedhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjadubah}(h]h ]h"]h$]h&]uh1j *hm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chM[hj]dubj&*)}(hhh]h)}(huser address of the futexh]huser address of the futex}(hj|dhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjxdhM[hjydubah}(h]h ]h"]h$]h&]uh1j%*hj]dubeh}(h]h ]h"]h$]h&]uh1j*hjxdhM[hjZdubj*)}(hM``struct futex_q *q`` futex_q (contains pi_state and access to the rt_mutex) h](j *)}(h``struct futex_q *q``h]jZ)}(hjdh]hstruct futex_q *q}(hjdhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjdubah}(h]h ]h"]h$]h&]uh1j *hm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chM\hjdubj&*)}(hhh]h)}(h6futex_q (contains pi_state and access to the rt_mutex)h]h6futex_q (contains pi_state and access to the rt_mutex)}(hjdhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjdhM\hjdubah}(h]h ]h"]h$]h&]uh1j%*hjdubeh}(h]h ]h"]h$]h&]uh1j*hjdhM\hjZdubj*)}(hL``int locked`` if the attempt to take the rt_mutex succeeded (1) or not (0) h](j *)}(h``int locked``h]jZ)}(hjdh]h int locked}(hjdhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjdubah}(h]h ]h"]h$]h&]uh1j *hm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chM]hjdubj&*)}(hhh]h)}(hdubh)}(h**Description**h]j)}(hjeh]h Description}(hjehhhNhNubah}(h]h ]h"]h$]h&]uh1jhjeubah}(h]h ]h"]h$]h&]uh1hhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chM_hj>dubh)}(hAfter attempting to lock an rt_mutex, this function is called to cleanup the pi_state owner as well as handle race conditions that may allow us to acquire the lock. Must be called with the hb lock held.h]hAfter attempting to lock an rt_mutex, this function is called to cleanup the pi_state owner as well as handle race conditions that may allow us to acquire the lock. Must be called with the hb lock held.}(hj&ehhhNhNubah}(h]h ]h"]h$]h&]uh1hhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chM_hj>dubh)}(h **Return**h]j)}(hj7eh]hReturn}(hj9ehhhNhNubah}(h]h ]h"]h$]h&]uh1jhj5eubah}(h]h ]h"]h$]h&]uh1hhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMchj>dubj))}(hU- 1 - success, lock taken; - 0 - success, lock not taken; - <0 - on error (-EFAULT)h]jV )}(hhh](j[ )}(h1 - success, lock taken;h]h)}(hjVeh]h1 - success, lock taken;}(hjXehhhNhNubah}(h]h ]h"]h$]h&]uh1hhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMchjTeubah}(h]h ]h"]h$]h&]uh1jZ hjQeubj[ )}(h0 - success, lock not taken;h]h)}(hjneh]h0 - success, lock not taken;}(hjpehhhNhNubah}(h]h ]h"]h$]h&]uh1hhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMdhjleubah}(h]h ]h"]h$]h&]uh1jZ hjQeubj[ )}(h<0 - on error (-EFAULT)h]h)}(hjeh]h<0 - on error (-EFAULT)}(hjehhhNhNubah}(h]h ]h"]h$]h&]uh1hhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMehjeubah}(h]h ]h"]h$]h&]uh1jZ hjQeubeh}(h]h ]h"]h$]h&]j j uh1jU hjeehMchjMeubah}(h]h ]h"]h$]h&]uh1j)hjeehMchj>dubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO) it_IT.requeue_futex (C function)c.it_IT.requeue_futexhNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(h{void requeue_futex (struct futex_q *q, struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2, union futex_key *key2)h]j_))}(hzvoid requeue_futex(struct futex_q *q, struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2, union futex_key *key2)h](j+)}(hvoidh]hvoid}(hjehhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjehhhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKKubj,)}(h h]h }(hjehhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjehhhjehKKubje))}(h requeue_futexh]jk))}(h requeue_futexh]h requeue_futex}(hjehhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjeubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjehhhjehKKubj.,)}(hh(struct futex_q *q, struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2, union futex_key *key2)h](j4,)}(hstruct futex_q *qh](j:,)}(hj=,h]hstruct}(hjfhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjfubj,)}(h h]h }(hjfhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjfubh)}(hhh]jk))}(hfutex_qh]hfutex_q}(hj#fhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj fubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj%fmodnameN classnameNjj)}j](jNj)}jjesbc.it_IT.requeue_futexesbuh1hhjfubj,)}(h h]h }(hjDfhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjfubj,)}(hj,h]h*}(hjRfhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjfubjk))}(hj Nh]hq}(hj_fhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjfubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjeubj4,)}(hstruct futex_hash_bucket *hb1h](j:,)}(hj=,h]hstruct}(hjwfhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjsfubj,)}(h h]h }(hjfhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjsfubh)}(hhh]jk))}(hfutex_hash_bucketh]hfutex_hash_bucket}(hjfhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjfubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjfmodnameN classnameNjj)}j](jNj@fc.it_IT.requeue_futexesbuh1hhjsfubj,)}(h h]h }(hjfhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjsfubj,)}(hj,h]h*}(hjfhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjsfubjk))}(hhb1h]hhb1}(hjfhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjsfubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjeubj4,)}(hstruct futex_hash_bucket *hb2h](j:,)}(hj=,h]hstruct}(hjfhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjfubj,)}(h h]h }(hjfhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjfubh)}(hhh]jk))}(hfutex_hash_bucketh]hfutex_hash_bucket}(hjghhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjgubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjgmodnameN classnameNjj)}j](jNj@fc.it_IT.requeue_futexesbuh1hhjfubj,)}(h h]h }(hj%ghhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjfubj,)}(hj,h]h*}(hj3ghhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjfubjk))}(hhb2h]hhb2}(hj@ghhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjfubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjeubj4,)}(hunion futex_key *key2h](j:,)}(hj>h]hunion}(hjYghhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjUgubj,)}(h h]h }(hjfghhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjUgubh)}(hhh]jk))}(h futex_keyh]h futex_key}(hjwghhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjtgubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjygmodnameN classnameNjj)}j](jNj@fc.it_IT.requeue_futexesbuh1hhjUgubj,)}(h h]h }(hjghhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjUgubj,)}(hj,h]h*}(hjghhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjUgubjk))}(hkey2h]hkey2}(hjghhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjUgubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjeubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hjehhhjehKKubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjehhhjehKKubah}(h]jeah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjehKKhjehhubj))}(hhh]h)}(h(Requeue a futex_q from one hb to anotherh]h(Requeue a futex_q from one hb to another}(hjghhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKEhjghhubah}(h]h ]h"]h$]h&]uh1j)hjehhhjehKKubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jgj)jgj)j)j)uh1jS)hhhj=hNhNubj))}(h**Parameters** ``struct futex_q *q`` the futex_q to requeue ``struct futex_hash_bucket *hb1`` the source hash_bucket ``struct futex_hash_bucket *hb2`` the target hash_bucket ``union futex_key *key2`` the new key for the requeued futex_qh](h)}(h**Parameters**h]j)}(hjgh]h Parameters}(hjghhhNhNubah}(h]h ]h"]h$]h&]uh1jhjgubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKIhjgubj*)}(hhh](j*)}(h-``struct futex_q *q`` the futex_q to requeue h](j *)}(h``struct futex_q *q``h]jZ)}(hjhh]hstruct futex_q *q}(hjhhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjhubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKFhjhubj&*)}(hhh]h)}(hthe futex_q to requeueh]hthe futex_q to requeue}(hj5hhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj1hhKFhj2hubah}(h]h ]h"]h$]h&]uh1j%*hjhubeh}(h]h ]h"]h$]h&]uh1j*hj1hhKFhjhubj*)}(h9``struct futex_hash_bucket *hb1`` the source hash_bucket h](j *)}(h!``struct futex_hash_bucket *hb1``h]jZ)}(hjUhh]hstruct futex_hash_bucket *hb1}(hjWhhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjShubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKGhjOhubj&*)}(hhh]h)}(hthe source hash_bucketh]hthe source hash_bucket}(hjnhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjjhhKGhjkhubah}(h]h ]h"]h$]h&]uh1j%*hjOhubeh}(h]h ]h"]h$]h&]uh1j*hjjhhKGhjhubj*)}(h9``struct futex_hash_bucket *hb2`` the target hash_bucket h](j *)}(h!``struct futex_hash_bucket *hb2``h]jZ)}(hjhh]hstruct futex_hash_bucket *hb2}(hjhhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjhubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKHhjhubj&*)}(hhh]h)}(hthe target hash_bucketh]hthe target hash_bucket}(hjhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhKHhjhubah}(h]h ]h"]h$]h&]uh1j%*hjhubeh}(h]h ]h"]h$]h&]uh1j*hjhhKHhjhubj*)}(h>``union futex_key *key2`` the new key for the requeued futex_qh](j *)}(h``union futex_key *key2``h]jZ)}(hjhh]hunion futex_key *key2}(hjhhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjhubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKJhjhubj&*)}(hhh]h)}(h$the new key for the requeued futex_qh]h$the new key for the requeued futex_q}(hjhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKIhjhubah}(h]h ]h"]h$]h&]uh1j%*hjhubeh}(h]h ]h"]h$]h&]uh1j*hjhhKJhjhubeh}(h]h ]h"]h$]h&]uh1j*hjgubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)(it_IT.requeue_pi_wake_futex (C function)c.it_IT.requeue_pi_wake_futexhNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(hbvoid requeue_pi_wake_futex (struct futex_q *q, union futex_key *key, struct futex_hash_bucket *hb)h]j_))}(havoid requeue_pi_wake_futex(struct futex_q *q, union futex_key *key, struct futex_hash_bucket *hb)h](j+)}(hvoidh]hvoid}(hj!ihhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjihhhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKubj,)}(h h]h }(hj0ihhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjihhhj/ihKubje))}(hrequeue_pi_wake_futexh]jk))}(hrequeue_pi_wake_futexh]hrequeue_pi_wake_futex}(hjBihhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj>iubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjihhhj/ihKubj.,)}(hG(struct futex_q *q, union futex_key *key, struct futex_hash_bucket *hb)h](j4,)}(hstruct futex_q *qh](j:,)}(hj=,h]hstruct}(hj^ihhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjZiubj,)}(h h]h }(hjkihhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjZiubh)}(hhh]jk))}(hfutex_qh]hfutex_q}(hj|ihhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjyiubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj~imodnameN classnameNjj)}j](jNj)}jjDisbc.it_IT.requeue_pi_wake_futexesbuh1hhjZiubj,)}(h h]h }(hjihhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjZiubj,)}(hj,h]h*}(hjihhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjZiubjk))}(hj Nh]hq}(hjihhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjZiubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjViubj4,)}(hunion futex_key *keyh](j:,)}(hj>h]hunion}(hjihhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjiubj,)}(h h]h }(hjihhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjiubh)}(hhh]jk))}(h futex_keyh]h futex_key}(hjihhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjiubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjimodnameN classnameNjj)}j](jNjic.it_IT.requeue_pi_wake_futexesbuh1hhjiubj,)}(h h]h }(hj jhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjiubj,)}(hj,h]h*}(hjjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjiubjk))}(hkeyh]hkey}(hj(jhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjiubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjViubj4,)}(hstruct futex_hash_bucket *hbh](j:,)}(hj=,h]hstruct}(hjAjhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hj=jubj,)}(h h]h }(hjNjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj=jubh)}(hhh]jk))}(hfutex_hash_bucketh]hfutex_hash_bucket}(hj_jhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj\jubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjajmodnameN classnameNjj)}j](jNjic.it_IT.requeue_pi_wake_futexesbuh1hhj=jubj,)}(h h]h }(hj~jhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj=jubj,)}(hj,h]h*}(hjjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj=jubjk))}(hhbh]hhb}(hjjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj=jubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjViubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hjihhhj/ihKubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjihhhj/ihKubah}(h]jiah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hj/ihKhjihhubj))}(hhh]h)}(h1Wake a task that acquired the lock during requeueh]h1Wake a task that acquired the lock during requeue}(hjjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjjhhubah}(h]h ]h"]h$]h&]uh1j)hjihhhj/ihKubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jjj)jjj)j)j)uh1jS)hhhj=hNhNubj))}(hX**Parameters** ``struct futex_q *q`` the futex_q ``union futex_key *key`` the key of the requeue target futex ``struct futex_hash_bucket *hb`` the hash_bucket of the requeue target futex **Description** During futex_requeue, with requeue_pi=1, it is possible to acquire the target futex if it is uncontended or via a lock steal. 1) Set **q**::key to the requeue target futex key so the waiter can detect the wakeup on the right futex. 2) Dequeue **q** from the hash bucket. 3) Set **q**::rt_waiter to NULL so the woken up task can detect atomic lock acquisition. 4) Set the q->lock_ptr to the requeue target hb->lock for the case that the waiter has to fixup the pi state. 5) Complete the requeue state so the waiter can make progress. After this point the waiter task can return from the syscall immediately in case that the pi state does not have to be fixed up. 6) Wake the waiter task. Must be called with both q->lock_ptr and hb->lock held.h](h)}(h**Parameters**h]j)}(hjjh]h Parameters}(hjjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjjubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjjubj*)}(hhh](j*)}(h"``struct futex_q *q`` the futex_q h](j *)}(h``struct futex_q *q``h]jZ)}(hjkh]hstruct futex_q *q}(hjkhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjkubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjjubj&*)}(hhh]h)}(h the futex_qh]h the futex_q}(hjkhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjkhKhjkubah}(h]h ]h"]h$]h&]uh1j%*hjjubeh}(h]h ]h"]h$]h&]uh1j*hjkhKhjjubj*)}(h=``union futex_key *key`` the key of the requeue target futex h](j *)}(h``union futex_key *key``h]jZ)}(hj=kh]hunion futex_key *key}(hj?khhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj;kubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhj7kubj&*)}(hhh]h)}(h#the key of the requeue target futexh]h#the key of the requeue target futex}(hjVkhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjRkhKhjSkubah}(h]h ]h"]h$]h&]uh1j%*hj7kubeh}(h]h ]h"]h$]h&]uh1j*hjRkhKhjjubj*)}(hM``struct futex_hash_bucket *hb`` the hash_bucket of the requeue target futex h](j *)}(h ``struct futex_hash_bucket *hb``h]jZ)}(hjvkh]hstruct futex_hash_bucket *hb}(hjxkhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjtkubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjpkubj&*)}(hhh]h)}(h+the hash_bucket of the requeue target futexh]h+the hash_bucket of the requeue target futex}(hjkhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjkhKhjkubah}(h]h ]h"]h$]h&]uh1j%*hjpkubeh}(h]h ]h"]h$]h&]uh1j*hjkhKhjjubeh}(h]h ]h"]h$]h&]uh1j*hjjubh)}(h**Description**h]j)}(hjkh]h Description}(hjkhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjkubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjjubh)}(h}During futex_requeue, with requeue_pi=1, it is possible to acquire the target futex if it is uncontended or via a lock steal.h]h}During futex_requeue, with requeue_pi=1, it is possible to acquire the target futex if it is uncontended or via a lock steal.}(hjkhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjjubhenumerated_list)}(hhh](j[ )}(hgSet **q**::key to the requeue target futex key so the waiter can detect the wakeup on the right futex. h]h)}(hfSet **q**::key to the requeue target futex key so the waiter can detect the wakeup on the right futex.h](hSet }(hjkhhhNhNubj)}(h**q**h]hq}(hjkhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjkubh]::key to the requeue target futex key so the waiter can detect the wakeup on the right futex.}(hjkhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjkubah}(h]h ]h"]h$]h&]uh1jZ hjkubj[ )}(h$Dequeue **q** from the hash bucket. h]h)}(h#Dequeue **q** from the hash bucket.h](hDequeue }(hj lhhhNhNubj)}(h**q**h]hq}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj lubh from the hash bucket.}(hj lhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjlubah}(h]h ]h"]h$]h&]uh1jZ hjkubj[ )}(hVSet **q**::rt_waiter to NULL so the woken up task can detect atomic lock acquisition. h]h)}(hUSet **q**::rt_waiter to NULL so the woken up task can detect atomic lock acquisition.h](hSet }(hj5lhhhNhNubj)}(h**q**h]hq}(hj=lhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj5lubhL::rt_waiter to NULL so the woken up task can detect atomic lock acquisition.}(hj5lhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhj1lubah}(h]h ]h"]h$]h&]uh1jZ hjkubj[ )}(hkSet the q->lock_ptr to the requeue target hb->lock for the case that the waiter has to fixup the pi state. h]h)}(hjSet the q->lock_ptr to the requeue target hb->lock for the case that the waiter has to fixup the pi state.h]hjSet the q->lock_ptr to the requeue target hb->lock for the case that the waiter has to fixup the pi state.}(hj`lhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhj\lubah}(h]h ]h"]h$]h&]uh1jZ hjkubj[ )}(hComplete the requeue state so the waiter can make progress. After this point the waiter task can return from the syscall immediately in case that the pi state does not have to be fixed up. h]h)}(hComplete the requeue state so the waiter can make progress. After this point the waiter task can return from the syscall immediately in case that the pi state does not have to be fixed up.h]hComplete the requeue state so the waiter can make progress. After this point the waiter task can return from the syscall immediately in case that the pi state does not have to be fixed up.}(hjylhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjulubah}(h]h ]h"]h$]h&]uh1jZ hjkubj[ )}(hWake the waiter task. h]h)}(hWake the waiter task.h]hWake the waiter task.}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjlubah}(h]h ]h"]h$]h&]uh1jZ hjkubeh}(h]h ]h"]h$]h&]enumtypearabicprefixhsuffix)uh1jkhjjubh)}(h7Must be called with both q->lock_ptr and hb->lock held.h]h7Must be called with both q->lock_ptr and hb->lock held.}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjjubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)-it_IT.futex_proxy_trylock_atomic (C function)"c.it_IT.futex_proxy_trylock_atomichNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(hint futex_proxy_trylock_atomic (u32 __user *pifutex, struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2, union futex_key *key1, union futex_key *key2, struct futex_pi_state **ps, struct task_struct **exiting, int set_waiters)h]j_))}(hint futex_proxy_trylock_atomic(u32 __user *pifutex, struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2, union futex_key *key1, union futex_key *key2, struct futex_pi_state **ps, struct task_struct **exiting, int set_waiters)h](j+)}(hinth]hint}(hjlhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjlhhhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chM ubj,)}(h h]h }(hjlhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjlhhhjlhM ubje))}(hfutex_proxy_trylock_atomich]jk))}(hfutex_proxy_trylock_atomich]hfutex_proxy_trylock_atomic}(hjmhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjlubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjlhhhjlhM ubj.,)}(h(u32 __user *pifutex, struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2, union futex_key *key1, union futex_key *key2, struct futex_pi_state **ps, struct task_struct **exiting, int set_waiters)h](j4,)}(hu32 __user *pifutexh](h)}(hhh]jk))}(hu32h]hu32}(hj!mhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjmubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj#mmodnameN classnameNjj)}j](jNj)}jjmsb"c.it_IT.futex_proxy_trylock_atomicesbuh1hhjmubj,)}(h h]h }(hjBmhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjmubh__user}(hjmhhhNhNubj,)}(h h]h }(hjTmhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjmubj,)}(hj,h]h*}(hjbmhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjmubjk))}(hpifutexh]hpifutex}(hjomhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjmubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjmubj4,)}(hstruct futex_hash_bucket *hb1h](j:,)}(hj=,h]hstruct}(hjmhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjmubj,)}(h h]h }(hjmhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjmubh)}(hhh]jk))}(hfutex_hash_bucketh]hfutex_hash_bucket}(hjmhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjmubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmmodnameN classnameNjj)}j](jNj>m"c.it_IT.futex_proxy_trylock_atomicesbuh1hhjmubj,)}(h h]h }(hjmhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjmubj,)}(hj,h]h*}(hjmhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjmubjk))}(hhb1h]hhb1}(hjmhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjmubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjmubj4,)}(hstruct futex_hash_bucket *hb2h](j:,)}(hj=,h]hstruct}(hjmhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjmubj,)}(h h]h }(hjnhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjmubh)}(hhh]jk))}(hfutex_hash_bucketh]hfutex_hash_bucket}(hjnhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjnubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjnmodnameN classnameNjj)}j](jNj>m"c.it_IT.futex_proxy_trylock_atomicesbuh1hhjmubj,)}(h h]h }(hj6nhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjmubj,)}(hj,h]h*}(hjDnhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjmubjk))}(hhb2h]hhb2}(hjQnhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjmubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjmubj4,)}(hunion futex_key *key1h](j:,)}(hj>h]hunion}(hjjnhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjfnubj,)}(h h]h }(hjwnhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjfnubh)}(hhh]jk))}(h futex_keyh]h futex_key}(hjnhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjnubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjnmodnameN classnameNjj)}j](jNj>m"c.it_IT.futex_proxy_trylock_atomicesbuh1hhjfnubj,)}(h h]h }(hjnhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjfnubj,)}(hj,h]h*}(hjnhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjfnubjk))}(hkey1h]hkey1}(hjnhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjfnubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjmubj4,)}(hunion futex_key *key2h](j:,)}(hj>h]hunion}(hjnhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjnubj,)}(h h]h }(hjnhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjnubh)}(hhh]jk))}(h futex_keyh]h futex_key}(hjnhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjnubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjnmodnameN classnameNjj)}j](jNj>m"c.it_IT.futex_proxy_trylock_atomicesbuh1hhjnubj,)}(h h]h }(hjohhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjnubj,)}(hj,h]h*}(hj&ohhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjnubjk))}(hkey2h]hkey2}(hj3ohhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjnubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjmubj4,)}(hstruct futex_pi_state **psh](j:,)}(hj=,h]hstruct}(hjLohhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjHoubj,)}(h h]h }(hjYohhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjHoubh)}(hhh]jk))}(hfutex_pi_stateh]hfutex_pi_state}(hjjohhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjgoubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjlomodnameN classnameNjj)}j](jNj>m"c.it_IT.futex_proxy_trylock_atomicesbuh1hhjHoubj,)}(h h]h }(hjohhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjHoubj,)}(hj,h]h*}(hjohhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjHoubj,)}(hj,h]h*}(hjohhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjHoubjk))}(hpsh]hps}(hjohhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjHoubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjmubj4,)}(hstruct task_struct **exitingh](j:,)}(hj=,h]hstruct}(hjohhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjoubj,)}(h h]h }(hjohhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjoubh)}(hhh]jk))}(h task_structh]h task_struct}(hjohhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjoubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjomodnameN classnameNjj)}j](jNj>m"c.it_IT.futex_proxy_trylock_atomicesbuh1hhjoubj,)}(h h]h }(hjphhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjoubj,)}(hj,h]h*}(hjphhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjoubj,)}(hj,h]h*}(hj"phhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjoubjk))}(hexitingh]hexiting}(hj/phhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjoubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjmubj4,)}(hint set_waitersh](j+)}(hinth]hint}(hjHphhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjDpubj,)}(h h]h }(hjVphhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjDpubjk))}(h set_waitersh]h set_waiters}(hjdphhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjDpubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjmubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hjlhhhjlhM ubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjlhhhjlhM ubah}(h]jlah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjlhM hjlhhubj))}(hhh]h)}(h)Attempt an atomic lock for the top waiterh]h)Attempt an atomic lock for the top waiter}(hjphhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjphhubah}(h]h ]h"]h$]h&]uh1j)hjlhhhjlhM ubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jpj)jpj)j)j)uh1jS)hhhj=hNhNubj))}(hX**Parameters** ``u32 __user *pifutex`` the user address of the to futex ``struct futex_hash_bucket *hb1`` the from futex hash bucket, must be locked by the caller ``struct futex_hash_bucket *hb2`` the to futex hash bucket, must be locked by the caller ``union futex_key *key1`` the from futex key ``union futex_key *key2`` the to futex key ``struct futex_pi_state **ps`` address to store the pi_state pointer ``struct task_struct **exiting`` Pointer to store the task pointer of the owner task which is in the middle of exiting ``int set_waiters`` force setting the FUTEX_WAITERS bit (1) or not (0) **Description** Try and get the lock on behalf of the top waiter if we can do it atomically. Wake the top waiter if we succeed. If the caller specified set_waiters, then direct futex_lock_pi_atomic() to force setting the FUTEX_WAITERS bit. hb1 and hb2 must be held by the caller. **exiting** is only set when the return value is -EBUSY. If so, this holds a refcount on the exiting task on return and the caller needs to drop it after waiting for the exit to complete. **Return** - 0 - failed to acquire the lock atomically; - >0 - acquired the lock, return value is vpid of the top_waiter - <0 - errorh](h)}(h**Parameters**h]j)}(hjph]h Parameters}(hjphhhNhNubah}(h]h ]h"]h$]h&]uh1jhjpubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjpubj*)}(hhh](j*)}(h9``u32 __user *pifutex`` the user address of the to futex h](j *)}(h``u32 __user *pifutex``h]jZ)}(hjph]hu32 __user *pifutex}(hjphhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjpubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjpubj&*)}(hhh]h)}(h the user address of the to futexh]h the user address of the to futex}(hjphhhNhNubah}(h]h ]h"]h$]h&]uh1hhjphKhjpubah}(h]h ]h"]h$]h&]uh1j%*hjpubeh}(h]h ]h"]h$]h&]uh1j*hjphKhjpubj*)}(h[``struct futex_hash_bucket *hb1`` the from futex hash bucket, must be locked by the caller h](j *)}(h!``struct futex_hash_bucket *hb1``h]jZ)}(hjqh]hstruct futex_hash_bucket *hb1}(hj qhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjqubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjqubj&*)}(hhh]h)}(h8the from futex hash bucket, must be locked by the callerh]h8the from futex hash bucket, must be locked by the caller}(hj!qhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjqhKhjqubah}(h]h ]h"]h$]h&]uh1j%*hjqubeh}(h]h ]h"]h$]h&]uh1j*hjqhKhjpubj*)}(hY``struct futex_hash_bucket *hb2`` the to futex hash bucket, must be locked by the caller h](j *)}(h!``struct futex_hash_bucket *hb2``h]jZ)}(hjAqh]hstruct futex_hash_bucket *hb2}(hjCqhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj?qubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhj;qubj&*)}(hhh]h)}(h6the to futex hash bucket, must be locked by the callerh]h6the to futex hash bucket, must be locked by the caller}(hjZqhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjVqhKhjWqubah}(h]h ]h"]h$]h&]uh1j%*hj;qubeh}(h]h ]h"]h$]h&]uh1j*hjVqhKhjpubj*)}(h-``union futex_key *key1`` the from futex key h](j *)}(h``union futex_key *key1``h]jZ)}(hjzqh]hunion futex_key *key1}(hj|qhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjxqubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjtqubj&*)}(hhh]h)}(hthe from futex keyh]hthe from futex key}(hjqhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjqhKhjqubah}(h]h ]h"]h$]h&]uh1j%*hjtqubeh}(h]h ]h"]h$]h&]uh1j*hjqhKhjpubj*)}(h+``union futex_key *key2`` the to futex key h](j *)}(h``union futex_key *key2``h]jZ)}(hjqh]hunion futex_key *key2}(hjqhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjqubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjqubj&*)}(hhh]h)}(hthe to futex keyh]hthe to futex key}(hjqhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjqhKhjqubah}(h]h ]h"]h$]h&]uh1j%*hjqubeh}(h]h ]h"]h$]h&]uh1j*hjqhKhjpubj*)}(hE``struct futex_pi_state **ps`` address to store the pi_state pointer h](j *)}(h``struct futex_pi_state **ps``h]jZ)}(hjqh]hstruct futex_pi_state **ps}(hjqhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjqubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjqubj&*)}(hhh]h)}(h%address to store the pi_state pointerh]h%address to store the pi_state pointer}(hjrhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjrhKhjrubah}(h]h ]h"]h$]h&]uh1j%*hjqubeh}(h]h ]h"]h$]h&]uh1j*hjrhKhjpubj*)}(hw``struct task_struct **exiting`` Pointer to store the task pointer of the owner task which is in the middle of exiting h](j *)}(h ``struct task_struct **exiting``h]jZ)}(hj%rh]hstruct task_struct **exiting}(hj'rhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj#rubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjrubj&*)}(hhh]h)}(hUPointer to store the task pointer of the owner task which is in the middle of exitingh]hUPointer to store the task pointer of the owner task which is in the middle of exiting}(hj>rhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhj;rubah}(h]h ]h"]h$]h&]uh1j%*hjrubeh}(h]h ]h"]h$]h&]uh1j*hj:rhKhjpubj*)}(hG``int set_waiters`` force setting the FUTEX_WAITERS bit (1) or not (0) h](j *)}(h``int set_waiters``h]jZ)}(hj_rh]hint set_waiters}(hjarhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj]rubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjYrubj&*)}(hhh]h)}(h2force setting the FUTEX_WAITERS bit (1) or not (0)h]h2force setting the FUTEX_WAITERS bit (1) or not (0)}(hjxrhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjtrhKhjurubah}(h]h ]h"]h$]h&]uh1j%*hjYrubeh}(h]h ]h"]h$]h&]uh1j*hjtrhKhjpubeh}(h]h ]h"]h$]h&]uh1j*hjpubh)}(h**Description**h]j)}(hjrh]h Description}(hjrhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjrubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjpubh)}(hXTry and get the lock on behalf of the top waiter if we can do it atomically. Wake the top waiter if we succeed. If the caller specified set_waiters, then direct futex_lock_pi_atomic() to force setting the FUTEX_WAITERS bit. hb1 and hb2 must be held by the caller.h]hXTry and get the lock on behalf of the top waiter if we can do it atomically. Wake the top waiter if we succeed. If the caller specified set_waiters, then direct futex_lock_pi_atomic() to force setting the FUTEX_WAITERS bit. hb1 and hb2 must be held by the caller.}(hjrhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjpubh)}(h**exiting** is only set when the return value is -EBUSY. If so, this holds a refcount on the exiting task on return and the caller needs to drop it after waiting for the exit to complete.h](j)}(h **exiting**h]hexiting}(hjrhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjrubh is only set when the return value is -EBUSY. If so, this holds a refcount on the exiting task on return and the caller needs to drop it after waiting for the exit to complete.}(hjrhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjpubh)}(h **Return**h]j)}(hjrh]hReturn}(hjrhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjrubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjpubj))}(h{- 0 - failed to acquire the lock atomically; - >0 - acquired the lock, return value is vpid of the top_waiter - <0 - errorh]jV )}(hhh](j[ )}(h*0 - failed to acquire the lock atomically;h]h)}(hjrh]h*0 - failed to acquire the lock atomically;}(hjrhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjrubah}(h]h ]h"]h$]h&]uh1jZ hjrubj[ )}(h>>0 - acquired the lock, return value is vpid of the top_waiterh]h)}(hjsh]h>>0 - acquired the lock, return value is vpid of the top_waiter}(hjshhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjsubah}(h]h ]h"]h$]h&]uh1jZ hjrubj[ )}(h <0 - errorh]h)}(hj-sh]h <0 - error}(hj/shhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chM hj+subah}(h]h ]h"]h$]h&]uh1jZ hjrubeh}(h]h ]h"]h$]h&]j j uh1jU hj shMhjrubah}(h]h ]h"]h$]h&]uh1j)hj shMhjpubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO) it_IT.futex_requeue (C function)c.it_IT.futex_requeuehNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(hint futex_requeue (u32 __user *uaddr1, unsigned int flags1, u32 __user *uaddr2, unsigned int flags2, int nr_wake, int nr_requeue, u32 *cmpval, int requeue_pi)h]j_))}(hint futex_requeue(u32 __user *uaddr1, unsigned int flags1, u32 __user *uaddr2, unsigned int flags2, int nr_wake, int nr_requeue, u32 *cmpval, int requeue_pi)h](j+)}(hinth]hint}(hjoshhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjkshhhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMoubj,)}(h h]h }(hj~shhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjkshhhj}shMoubje))}(h futex_requeueh]jk))}(h futex_requeueh]h futex_requeue}(hjshhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjsubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjkshhhj}shMoubj.,)}(h(u32 __user *uaddr1, unsigned int flags1, u32 __user *uaddr2, unsigned int flags2, int nr_wake, int nr_requeue, u32 *cmpval, int requeue_pi)h](j4,)}(hu32 __user *uaddr1h](h)}(hhh]jk))}(hu32h]hu32}(hjshhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjsubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjsmodnameN classnameNjj)}j](jNj)}jjssbc.it_IT.futex_requeueesbuh1hhjsubj,)}(h h]h }(hjshhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjsubh__user}(hjshhhNhNubj,)}(h h]h }(hjshhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjsubj,)}(hj,h]h*}(hjshhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjsubjk))}(huaddr1h]huaddr1}(hjshhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjsubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjsubj4,)}(hunsigned int flags1h](j+)}(hunsignedh]hunsigned}(hjthhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjtubj,)}(h h]h }(hj$thhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjtubj+)}(hinth]hint}(hj2thhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjtubj,)}(h h]h }(hj@thhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjtubjk))}(hflags1h]hflags1}(hjNthhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjtubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjsubj4,)}(hu32 __user *uaddr2h](h)}(hhh]jk))}(hu32h]hu32}(hjjthhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjgtubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjltmodnameN classnameNjj)}j](jNjsc.it_IT.futex_requeueesbuh1hhjctubj,)}(h h]h }(hjthhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjctubh__user}(hjcthhhNhNubj,)}(h h]h }(hjthhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjctubj,)}(hj,h]h*}(hjthhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjctubjk))}(huaddr2h]huaddr2}(hjthhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjctubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjsubj4,)}(hunsigned int flags2h](j+)}(hunsignedh]hunsigned}(hjthhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjtubj,)}(h h]h }(hjthhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjtubj+)}(hinth]hint}(hjthhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjtubj,)}(h h]h }(hjthhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjtubjk))}(hflags2h]hflags2}(hjuhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjtubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjsubj4,)}(h int nr_wakeh](j+)}(hinth]hint}(hj uhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjuubj,)}(h h]h }(hj.uhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjuubjk))}(hnr_wakeh]hnr_wake}(hjvj)j>vj)j)j)uh1jS)hhhj=hNhNubj))}(hX**Parameters** ``u32 __user *uaddr1`` source futex user address ``unsigned int flags1`` futex flags (FLAGS_SHARED, etc.) ``u32 __user *uaddr2`` target futex user address ``unsigned int flags2`` futex flags (FLAGS_SHARED, etc.) ``int nr_wake`` number of waiters to wake (must be 1 for requeue_pi) ``int nr_requeue`` number of waiters to requeue (0-INT_MAX) ``u32 *cmpval`` **uaddr1** expected value (or ``NULL``) ``int requeue_pi`` if we are attempting to requeue from a non-pi futex to a pi futex (pi to pi requeue is not supported) **Description** Requeue waiters on uaddr1 to uaddr2. In the requeue_pi case, try to acquire uaddr2 atomically on behalf of the top waiter. **Return** - >=0 - on success, the number of tasks requeued or woken; - <0 - on errorh](h)}(h**Parameters**h]j)}(hjHvh]h Parameters}(hjJvhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjFvubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMahjBvubj*)}(hhh](j*)}(h1``u32 __user *uaddr1`` source futex user address h](j *)}(h``u32 __user *uaddr1``h]jZ)}(hjgvh]hu32 __user *uaddr1}(hjivhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjevubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chM^hjavubj&*)}(hhh]h)}(hsource futex user addressh]hsource futex user address}(hjvhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj|vhM^hj}vubah}(h]h ]h"]h$]h&]uh1j%*hjavubeh}(h]h ]h"]h$]h&]uh1j*hj|vhM^hj^vubj*)}(h9``unsigned int flags1`` futex flags (FLAGS_SHARED, etc.) h](j *)}(h``unsigned int flags1``h]jZ)}(hjvh]hunsigned int flags1}(hjvhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjvubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chM_hjvubj&*)}(hhh]h)}(h futex flags (FLAGS_SHARED, etc.)h]h futex flags (FLAGS_SHARED, etc.)}(hjvhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjvhM_hjvubah}(h]h ]h"]h$]h&]uh1j%*hjvubeh}(h]h ]h"]h$]h&]uh1j*hjvhM_hj^vubj*)}(h1``u32 __user *uaddr2`` target futex user address h](j *)}(h``u32 __user *uaddr2``h]jZ)}(hjvh]hu32 __user *uaddr2}(hjvhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjvubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chM`hjvubj&*)}(hhh]h)}(htarget futex user addressh]htarget futex user address}(hjvhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjvhM`hjvubah}(h]h ]h"]h$]h&]uh1j%*hjvubeh}(h]h ]h"]h$]h&]uh1j*hjvhM`hj^vubj*)}(h9``unsigned int flags2`` futex flags (FLAGS_SHARED, etc.) h](j *)}(h``unsigned int flags2``h]jZ)}(hjwh]hunsigned int flags2}(hjwhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjwubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMahj wubj&*)}(hhh]h)}(h futex flags (FLAGS_SHARED, etc.)h]h futex flags (FLAGS_SHARED, etc.)}(hj+whhhNhNubah}(h]h ]h"]h$]h&]uh1hhj'whMahj(wubah}(h]h ]h"]h$]h&]uh1j%*hj wubeh}(h]h ]h"]h$]h&]uh1j*hj'whMahj^vubj*)}(hE``int nr_wake`` number of waiters to wake (must be 1 for requeue_pi) h](j *)}(h``int nr_wake``h]jZ)}(hjKwh]h int nr_wake}(hjMwhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjIwubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMbhjEwubj&*)}(hhh]h)}(h4number of waiters to wake (must be 1 for requeue_pi)h]h4number of waiters to wake (must be 1 for requeue_pi)}(hjdwhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj`whMbhjawubah}(h]h ]h"]h$]h&]uh1j%*hjEwubeh}(h]h ]h"]h$]h&]uh1j*hj`whMbhj^vubj*)}(h<``int nr_requeue`` number of waiters to requeue (0-INT_MAX) h](j *)}(h``int nr_requeue``h]jZ)}(hjwh]hint nr_requeue}(hjwhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjwubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMchj~wubj&*)}(hhh]h)}(h(number of waiters to requeue (0-INT_MAX)h]h(number of waiters to requeue (0-INT_MAX)}(hjwhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjwhMchjwubah}(h]h ]h"]h$]h&]uh1j%*hj~wubeh}(h]h ]h"]h$]h&]uh1j*hjwhMchj^vubj*)}(h8``u32 *cmpval`` **uaddr1** expected value (or ``NULL``) h](j *)}(h``u32 *cmpval``h]jZ)}(hjwh]h u32 *cmpval}(hjwhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjwubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMdhjwubj&*)}(hhh]h)}(h'**uaddr1** expected value (or ``NULL``)h](j)}(h **uaddr1**h]huaddr1}(hjwhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjwubh expected value (or }(hjwhhhNhNubjZ)}(h``NULL``h]hNULL}(hjwhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjwubh)}(hjwhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjwhMdhjwubah}(h]h ]h"]h$]h&]uh1j%*hjwubeh}(h]h ]h"]h$]h&]uh1j*hjwhMdhj^vubj*)}(hy``int requeue_pi`` if we are attempting to requeue from a non-pi futex to a pi futex (pi to pi requeue is not supported) h](j *)}(h``int requeue_pi``h]jZ)}(hjxh]hint requeue_pi}(hjxhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjxubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMfhjxubj&*)}(hhh]h)}(heif we are attempting to requeue from a non-pi futex to a pi futex (pi to pi requeue is not supported)h]heif we are attempting to requeue from a non-pi futex to a pi futex (pi to pi requeue is not supported)}(hj/xhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMehj,xubah}(h]h ]h"]h$]h&]uh1j%*hjxubeh}(h]h ]h"]h$]h&]uh1j*hj+xhMfhj^vubeh}(h]h ]h"]h$]h&]uh1j*hjBvubh)}(h**Description**h]j)}(hjRxh]h Description}(hjTxhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjPxubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhhjBvubh)}(hzRequeue waiters on uaddr1 to uaddr2. In the requeue_pi case, try to acquire uaddr2 atomically on behalf of the top waiter.h]hzRequeue waiters on uaddr1 to uaddr2. In the requeue_pi case, try to acquire uaddr2 atomically on behalf of the top waiter.}(hjhxhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhhjBvubh)}(h **Return**h]j)}(hjyxh]hReturn}(hj{xhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjwxubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMkhjBvubj))}(hK- >=0 - on success, the number of tasks requeued or woken; - <0 - on errorh]jV )}(hhh](j[ )}(h8>=0 - on success, the number of tasks requeued or woken;h]h)}(hjxh]h8>=0 - on success, the number of tasks requeued or woken;}(hjxhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMkhjxubah}(h]h ]h"]h$]h&]uh1jZ hjxubj[ )}(h <0 - on errorh]h)}(hjxh]h <0 - on error}(hjxhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMlhjxubah}(h]h ]h"]h$]h&]uh1jZ hjxubeh}(h]h ]h"]h$]h&]j j uh1jU hjxhMkhjxubah}(h]h ]h"]h$]h&]uh1j)hjxhMkhjBvubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)1it_IT.handle_early_requeue_pi_wakeup (C function)&c.it_IT.handle_early_requeue_pi_wakeuphNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(huint handle_early_requeue_pi_wakeup (struct futex_hash_bucket *hb, struct futex_q *q, struct hrtimer_sleeper *timeout)h]j_))}(htint handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb, struct futex_q *q, struct hrtimer_sleeper *timeout)h](j+)}(hinth]hint}(hjxhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjxhhhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMubj,)}(h h]h }(hjyhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjxhhhjyhMubje))}(hhandle_early_requeue_pi_wakeuph]jk))}(hhandle_early_requeue_pi_wakeuph]hhandle_early_requeue_pi_wakeup}(hjyhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjyubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjxhhhjyhMubj.,)}(hR(struct futex_hash_bucket *hb, struct futex_q *q, struct hrtimer_sleeper *timeout)h](j4,)}(hstruct futex_hash_bucket *hbh](j:,)}(hj=,h]hstruct}(hj/yhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hj+yubj,)}(h h]h }(hj``u32 __user *uaddr`` the futex we initially wait on (non-pi) h](j *)}(h``u32 __user *uaddr``h]jZ)}(hj~h]hu32 __user *uaddr}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj~ubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhj~ubj&*)}(hhh]h)}(h'the futex we initially wait on (non-pi)h]h'the futex we initially wait on (non-pi)}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj~hMhj~ubah}(h]h ]h"]h$]h&]uh1j%*hj~ubeh}(h]h ]h"]h$]h&]uh1j*hj~hMhj~ubj*)}(h``unsigned int flags`` futex flags (FLAGS_SHARED, FLAGS_CLOCKRT, etc.), they must be the same type, no requeueing from private to shared, etc. h](j *)}(h``unsigned int flags``h]jZ)}(hj~h]hunsigned int flags}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj~ubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhj~ubj&*)}(hhh]h)}(hwfutex flags (FLAGS_SHARED, FLAGS_CLOCKRT, etc.), they must be the same type, no requeueing from private to shared, etc.h]hwfutex flags (FLAGS_SHARED, FLAGS_CLOCKRT, etc.), they must be the same type, no requeueing from private to shared, etc.}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhj~ubah}(h]h ]h"]h$]h&]uh1j%*hj~ubeh}(h]h ]h"]h$]h&]uh1j*hj~hMhj~ubj*)}(h(``u32 val`` the expected value of uaddr h](j *)}(h ``u32 val``h]jZ)}(hjh]hu32 val}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhj~ubj&*)}(hhh]h)}(hthe expected value of uaddrh]hthe expected value of uaddr}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1j%*hj~ubeh}(h]h ]h"]h$]h&]uh1j*hjhMhj~ubj*)}(h'``ktime_t *abs_time`` absolute timeout h](j *)}(h``ktime_t *abs_time``h]jZ)}(hj=h]hktime_t *abs_time}(hj?hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj;ubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhj7ubj&*)}(hhh]h)}(habsolute timeouth]habsolute timeout}(hjVhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjRhMhjSubah}(h]h ]h"]h$]h&]uh1j%*hj7ubeh}(h]h ]h"]h$]h&]uh1j*hjRhMhj~ubj*)}(hF``u32 bitset`` 32 bit wakeup bitset set by userspace, defaults to all h](j *)}(h``u32 bitset``h]jZ)}(hjvh]h u32 bitset}(hjxhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjtubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjpubj&*)}(hhh]h)}(h632 bit wakeup bitset set by userspace, defaults to allh]h632 bit wakeup bitset set by userspace, defaults to all}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1j%*hjpubeh}(h]h ]h"]h$]h&]uh1j*hjhMhj~ubj*)}(hR``u32 __user *uaddr2`` the pi futex we will take prior to returning to user-space h](j *)}(h``u32 __user *uaddr2``h]jZ)}(hjh]hu32 __user *uaddr2}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjubj&*)}(hhh]h)}(h:the pi futex we will take prior to returning to user-spaceh]h:the pi futex we will take prior to returning to user-space}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjhMhj~ubeh}(h]h ]h"]h$]h&]uh1j*hjl~ubh)}(h**Description**h]j)}(hjh]h Description}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjl~ubh)}(hXThe caller will wait on uaddr and will be requeued by futex_requeue() to uaddr2 which must be PI aware and unique from uaddr. Normal wakeup will wake on uaddr2 and complete the acquisition of the rt_mutex prior to returning to userspace. This ensures the rt_mutex maintains an owner when it has waiters; without one, the pi logic would not know which task to boost/deboost, if there was a need to.h]hXThe caller will wait on uaddr and will be requeued by futex_requeue() to uaddr2 which must be PI aware and unique from uaddr. Normal wakeup will wake on uaddr2 and complete the acquisition of the rt_mutex prior to returning to userspace. This ensures the rt_mutex maintains an owner when it has waiters; without one, the pi logic would not know which task to boost/deboost, if there was a need to.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjl~ubh)}(hWe call schedule in futex_wait_queue() when we enqueue and return there via the following-- 1) wakeup on uaddr2 after an atomic lock acquisition by futex_requeue() 2) wakeup on uaddr2 after a requeue 3) signal 4) timeouth]hWe call schedule in futex_wait_queue() when we enqueue and return there via the following-- 1) wakeup on uaddr2 after an atomic lock acquisition by futex_requeue() 2) wakeup on uaddr2 after a requeue 3) signal 4) timeout}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjl~ubh)}(h)If 3, cleanup and return -ERESTARTNOINTR.h]h)If 3, cleanup and return -ERESTARTNOINTR.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjl~ubh)}(hIf 2, we may then block on trying to take the rt_mutex and return via: 5) successful lock 6) signal 7) timeout 8) other lock acquisition failureh]hIf 2, we may then block on trying to take the rt_mutex and return via: 5) successful lock 6) signal 7) timeout 8) other lock acquisition failure}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjl~ubh)}(hEIf 6, return -EWOULDBLOCK (restarting the syscall would do the same).h]hEIf 6, return -EWOULDBLOCK (restarting the syscall would do the same).}(hj<hhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjl~ubh)}(h1If 4 or 7, we cleanup and return with -ETIMEDOUT.h]h1If 4 or 7, we cleanup and return with -ETIMEDOUT.}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjl~ubh)}(h **Return**h]j)}(hj\h]hReturn}(hj^hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjZubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjl~ubj))}(h"- 0 - On success; - <0 - On errorh]jV )}(hhh](j[ )}(h0 - On success;h]h)}(hj{h]h0 - On success;}(hj}hhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjyubah}(h]h ]h"]h$]h&]uh1jZ hjvubj[ )}(h <0 - On errorh]h)}(hjh]h <0 - On error}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjubah}(h]h ]h"]h$]h&]uh1jZ hjvubeh}(h]h ]h"]h$]h&]j j uh1jU hjhMhjrubah}(h]h ]h"]h$]h&]uh1j)hjhMhjl~ubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)#it_IT.futex_wait_queue (C function)c.it_IT.futex_wait_queuehNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(hhvoid futex_wait_queue (struct futex_hash_bucket *hb, struct futex_q *q, struct hrtimer_sleeper *timeout)h]j_))}(hgvoid futex_wait_queue(struct futex_hash_bucket *hb, struct futex_q *q, struct hrtimer_sleeper *timeout)h](j+)}(hvoidh]hvoid}(hjՀhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjрhhhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMVubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjрhhhjhMVubje))}(hfutex_wait_queueh]jk))}(hfutex_wait_queueh]hfutex_wait_queue}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjрhhhjhMVubj.,)}(hR(struct futex_hash_bucket *hb, struct futex_q *q, struct hrtimer_sleeper *timeout)h](j4,)}(hstruct futex_hash_bucket *hbh](j:,)}(hj=,h]hstruct}(hjhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubh)}(hhh]jk))}(hfutex_hash_bucketh]hfutex_hash_bucket}(hj0hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj-ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj2modnameN classnameNjj)}j](jNj)}jjsbc.it_IT.futex_wait_queueesbuh1hhjubj,)}(h h]h }(hjQhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubj,)}(hj,h]h*}(hj_hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubjk))}(hhbh]hhb}(hjlhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj ubj4,)}(hstruct futex_q *qh](j:,)}(hj=,h]hstruct}(hjhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubh)}(hhh]jk))}(hfutex_qh]hfutex_q}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j](jNjMc.it_IT.futex_wait_queueesbuh1hhjubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubj,)}(hj,h]h*}(hjЁhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubjk))}(hj Nh]hq}(hj݁hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj ubj4,)}(hstruct hrtimer_sleeper *timeouth](j:,)}(hj=,h]hstruct}(hjhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubh)}(hhh]jk))}(hhrtimer_sleeperh]hhrtimer_sleeper}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j](jNjMc.it_IT.futex_wait_queueesbuh1hhjubj,)}(h h]h }(hj2hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubj,)}(hj,h]h*}(hj@hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubjk))}(htimeouth]htimeout}(hjMhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj ubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hjрhhhjhMVubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj̀hhhjhMVubah}(h]jȀah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjhMVhjʀhhubj))}(hhh]h)}(h5futex_queue() and wait for wakeup, timeout, or signalh]h5futex_queue() and wait for wakeup, timeout, or signal}(hjwhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMQhjthhubah}(h]h ]h"]h$]h&]uh1j)hjʀhhhjhMVubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jj)jj)j)j)uh1jS)hhhj=hNhNubj))}(h**Parameters** ``struct futex_hash_bucket *hb`` the futex hash bucket, must be locked by the caller ``struct futex_q *q`` the futex_q to queue up on ``struct hrtimer_sleeper *timeout`` the prepared hrtimer_sleeper, or null for no timeouth](h)}(h**Parameters**h]j)}(hjh]h Parameters}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMUhjubj*)}(hhh](j*)}(hU``struct futex_hash_bucket *hb`` the futex hash bucket, must be locked by the caller h](j *)}(h ``struct futex_hash_bucket *hb``h]jZ)}(hjh]hstruct futex_hash_bucket *hb}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubah}(h]h ]h"]h$]h&]uh1j *hs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMRhjubj&*)}(hhh]h)}(h3the futex hash bucket, must be locked by the callerh]h3the futex hash bucket, must be locked by the caller}(hjтhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj͂hMRhj΂ubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hj͂hMRhjubj*)}(h1``struct futex_q *q`` the futex_q to queue up on h](j *)}(h``struct futex_q *q``h]jZ)}(hjh]hstruct futex_q *q}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubah}(h]h ]h"]h$]h&]uh1j *hs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMShjubj&*)}(hhh]h)}(hthe futex_q to queue up onh]hthe futex_q to queue up on}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMShjubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjhMShjubj*)}(hX``struct hrtimer_sleeper *timeout`` the prepared hrtimer_sleeper, or null for no timeouth](j *)}(h#``struct hrtimer_sleeper *timeout``h]jZ)}(hj*h]hstruct hrtimer_sleeper *timeout}(hj,hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj(ubah}(h]h ]h"]h$]h&]uh1j *hs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMUhj$ubj&*)}(hhh]h)}(h4the prepared hrtimer_sleeper, or null for no timeouth]h4the prepared hrtimer_sleeper, or null for no timeout}(hjChhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMThj@ubah}(h]h ]h"]h$]h&]uh1j%*hj$ubeh}(h]h ]h"]h$]h&]uh1j*hj?hMUhjubeh}(h]h ]h"]h$]h&]uh1j*hjubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO))it_IT.futex_unqueue_multiple (C function)c.it_IT.futex_unqueue_multiplehNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(h>int futex_unqueue_multiple (struct futex_vector *v, int count)h]j_))}(h=int futex_unqueue_multiple(struct futex_vector *v, int count)h](j+)}(hinth]hint}(hjhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjhhhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjhhhjhMubje))}(hfutex_unqueue_multipleh]jk))}(hfutex_unqueue_multipleh]hfutex_unqueue_multiple}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjhhhjhMubj.,)}(h#(struct futex_vector *v, int count)h](j4,)}(hstruct futex_vector *vh](j:,)}(hj=,h]hstruct}(hjhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjubj,)}(h h]h }(hj΃hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubh)}(hhh]jk))}(h futex_vectorh]h futex_vector}(hj߃hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj܃ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j](jNj)}jjsbc.it_IT.futex_unqueue_multipleesbuh1hhjubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubj,)}(hj,h]h*}(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubjk))}(hvh]hv}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjubj4,)}(h int counth](j+)}(hinth]hint}(hj4hhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hj0ubj,)}(h h]h }(hjBhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj0ubjk))}(hcounth]hcount}(hjPhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj0ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hjhhhjhMubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj|hhhjhMubah}(h]jwah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjhMhjyhhubj))}(hhh]h)}(h-Remove various futexes from their hash bucketh]h-Remove various futexes from their hash bucket}(hjzhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMwhjwhhubah}(h]h ]h"]h$]h&]uh1j)hjyhhhjhMubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jj)jj)j)j)uh1jS)hhhj=hNhNubj))}(hX**Parameters** ``struct futex_vector *v`` The list of futexes to unqueue ``int count`` Number of futexes in the list **Description** Helper to unqueue a list of futexes. This can't fail. **Return** - >=0 - Index of the last futex that was awoken; - -1 - No futex was awokenh](h)}(h**Parameters**h]j)}(hjh]h Parameters}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chM{hjubj*)}(hhh](j*)}(h:``struct futex_vector *v`` The list of futexes to unqueue h](j *)}(h``struct futex_vector *v``h]jZ)}(hjh]hstruct futex_vector *v}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubah}(h]h ]h"]h$]h&]uh1j *hs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMxhjubj&*)}(hhh]h)}(hThe list of futexes to unqueueh]hThe list of futexes to unqueue}(hjԄhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjЄhMxhjфubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjЄhMxhjubj*)}(h,``int count`` Number of futexes in the list h](j *)}(h ``int count``h]jZ)}(hjh]h int count}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubah}(h]h ]h"]h$]h&]uh1j *hs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMyhjubj&*)}(hhh]h)}(hNumber of futexes in the listh]hNumber of futexes in the list}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hMyhj ubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hj hMyhjubeh}(h]h ]h"]h$]h&]uh1j*hjubh)}(h**Description**h]j)}(hj/h]h Description}(hj1hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj-ubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chM{hjubh)}(h5Helper to unqueue a list of futexes. This can't fail.h]h7Helper to unqueue a list of futexes. This can’t fail.}(hjEhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chM{hjubh)}(h **Return**h]j)}(hjVh]hReturn}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjTubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chM}hjubj))}(hL- >=0 - Index of the last futex that was awoken; - -1 - No futex was awokenh]jV )}(hhh](j[ )}(h.>=0 - Index of the last futex that was awoken;h]h)}(hjuh]h.>=0 - Index of the last futex that was awoken;}(hjwhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chM}hjsubah}(h]h ]h"]h$]h&]uh1jZ hjpubj[ )}(h-1 - No futex was awokenh]h option_list)}(hhh]hoption_list_item)}(hhh](h option_group)}(hhh]hoption)}(h-1h]h option_string)}(hjh]h-1}hjsbah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1jhjubh description)}(h- No futex was awokenh]jV )}(hhh]j[ )}(hNo futex was awokenh]h)}(hjʅh]hNo futex was awoken}(hj̅hhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chM~hjȅubah}(h]h ]h"]h$]h&]uh1jZ hjŅubah}(h]h ]h"]h$]h&]j j uh1jU hjمhM~hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1jhjمhM~hjubah}(h]h ]h"]h$]h&]uh1jZ hjpubeh}(h]h ]h"]h$]h&]j j uh1jU hjhM}hjlubah}(h]h ]h"]h$]h&]uh1j)hjhM}hjubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO),it_IT.futex_wait_multiple_setup (C function)!c.it_IT.futex_wait_multiple_setuphNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(hNint futex_wait_multiple_setup (struct futex_vector *vs, int count, int *woken)h]j_))}(hMint futex_wait_multiple_setup(struct futex_vector *vs, int count, int *woken)h](j+)}(hinth]hint}(hj*hhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hj&hhhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMubj,)}(h h]h }(hj9hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj&hhhj8hMubje))}(hfutex_wait_multiple_setuph]jk))}(hfutex_wait_multiple_setuph]hfutex_wait_multiple_setup}(hjKhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjGubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hj&hhhj8hMubj.,)}(h0(struct futex_vector *vs, int count, int *woken)h](j4,)}(hstruct futex_vector *vsh](j:,)}(hj=,h]hstruct}(hjghhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjcubj,)}(h h]h }(hjthhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjcubh)}(hhh]jk))}(h futex_vectorh]h futex_vector}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j](jNj)}jjMsb!c.it_IT.futex_wait_multiple_setupesbuh1hhjcubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjcubj,)}(hj,h]h*}(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjcubjk))}(hvsh]hvs}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjcubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj_ubj4,)}(h int counth](j+)}(hinth]hint}(hjچhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjֆubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjֆubjk))}(hcounth]hcount}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjֆubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj_ubj4,)}(h int *wokenh](j+)}(hinth]hint}(hjhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hj ubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj ubj,)}(hj,h]h*}(hj+hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj ubjk))}(hwokenh]hwoken}(hj8hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj_ubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hj&hhhj8hMubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj"hhhj8hMubah}(h]jah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hj8hMhjhhubj))}(hhh]h)}(h,Prepare to wait and enqueue multiple futexesh]h,Prepare to wait and enqueue multiple futexes}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhj_hhubah}(h]h ]h"]h$]h&]uh1j)hjhhhj8hMubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jzj)jzj)j)j)uh1jS)hhhj=hNhNubj))}(hXO**Parameters** ``struct futex_vector *vs`` The futex list to wait on ``int count`` The size of the list ``int *woken`` Index of the last woken futex, if any. Used to notify the caller that it can return this index to userspace (return parameter) **Description** Prepare multiple futexes in a single step and enqueue them. This may fail if the futex list is invalid or if any futex was already awoken. On success the task is ready to interruptible sleep. **Return** - 1 - One of the futexes was woken by another thread - 0 - Success - <0 - -EFAULT, -EWOULDBLOCK or -EINVALh](h)}(h**Parameters**h]j)}(hjh]h Parameters}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhj~ubj*)}(hhh](j*)}(h6``struct futex_vector *vs`` The futex list to wait on h](j *)}(h``struct futex_vector *vs``h]jZ)}(hjh]hstruct futex_vector *vs}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubah}(h]h ]h"]h$]h&]uh1j *hs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhjubj&*)}(hhh]h)}(hThe futex list to wait onh]hThe futex list to wait on}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjubj*)}(h#``int count`` The size of the list h](j *)}(h ``int count``h]jZ)}(hj܇h]h int count}(hjއhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjڇubah}(h]h ]h"]h$]h&]uh1j *hs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhjևubj&*)}(hhh]h)}(hThe size of the listh]hThe size of the list}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1j%*hjևubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjubj*)}(h``int *woken`` Index of the last woken futex, if any. Used to notify the caller that it can return this index to userspace (return parameter) h](j *)}(h``int *woken``h]jZ)}(hjh]h int *woken}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubah}(h]h ]h"]h$]h&]uh1j *hs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhjubj&*)}(hhh]h)}(h~Index of the last woken futex, if any. Used to notify the caller that it can return this index to userspace (return parameter)h]h~Index of the last woken futex, if any. Used to notify the caller that it can return this index to userspace (return parameter)}(hj.hhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhj+ubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hj*hMhjubeh}(h]h ]h"]h$]h&]uh1j*hj~ubh)}(h**Description**h]j)}(hjQh]h Description}(hjShhhNhNubah}(h]h ]h"]h$]h&]uh1jhjOubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhj~ubh)}(hPrepare multiple futexes in a single step and enqueue them. This may fail if the futex list is invalid or if any futex was already awoken. On success the task is ready to interruptible sleep.h]hPrepare multiple futexes in a single step and enqueue them. This may fail if the futex list is invalid or if any futex was already awoken. On success the task is ready to interruptible sleep.}(hjghhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhj~ubh)}(h **Return**h]j)}(hjxh]hReturn}(hjzhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjvubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhj~ubj))}(hl- 1 - One of the futexes was woken by another thread - 0 - Success - <0 - -EFAULT, -EWOULDBLOCK or -EINVALh]jV )}(hhh](j[ )}(h21 - One of the futexes was woken by another threadh]h)}(hjh]h21 - One of the futexes was woken by another thread}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhjubah}(h]h ]h"]h$]h&]uh1jZ hjubj[ )}(h 0 - Successh]h)}(hjh]h 0 - Success}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhjubah}(h]h ]h"]h$]h&]uh1jZ hjubj[ )}(h%<0 - -EFAULT, -EWOULDBLOCK or -EINVALh]h)}(hjLjh]h%<0 - -EFAULT, -EWOULDBLOCK or -EINVAL}(hjɈhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhjňubah}(h]h ]h"]h$]h&]uh1jZ hjubeh}(h]h ]h"]h$]h&]j j uh1jU hjhMhjubah}(h]h ]h"]h$]h&]uh1j)hjhMhj~ubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)'it_IT.futex_sleep_multiple (C function)c.it_IT.futex_sleep_multiplehNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(hcvoid futex_sleep_multiple (struct futex_vector *vs, unsigned int count, struct hrtimer_sleeper *to)h]j_))}(hbvoid futex_sleep_multiple(struct futex_vector *vs, unsigned int count, struct hrtimer_sleeper *to)h](j+)}(hvoidh]hvoid}(hj hhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjhhhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjhhhjhMubje))}(hfutex_sleep_multipleh]jk))}(hfutex_sleep_multipleh]hfutex_sleep_multiple}(hj*hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj&ubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjhhhjhMubj.,)}(hI(struct futex_vector *vs, unsigned int count, struct hrtimer_sleeper *to)h](j4,)}(hstruct futex_vector *vsh](j:,)}(hj=,h]hstruct}(hjFhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjBubj,)}(h h]h }(hjShhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjBubh)}(hhh]jk))}(h futex_vectorh]h futex_vector}(hjdhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjaubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjfmodnameN classnameNjj)}j](jNj)}jj,sbc.it_IT.futex_sleep_multipleesbuh1hhjBubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjBubj,)}(hj,h]h*}(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjBubjk))}(hvsh]hvs}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjBubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj>ubj4,)}(hunsigned int counth](j+)}(hunsignedh]hunsigned}(hjhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjubj,)}(h h]h }(hjljhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubj+)}(hinth]hint}(hjՉhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubjk))}(hcounth]hcount}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj>ubj4,)}(hstruct hrtimer_sleeper *toh](j:,)}(hj=,h]hstruct}(hj hhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubh)}(hhh]jk))}(hhrtimer_sleeperh]hhrtimer_sleeper}(hj(hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj%ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj*modnameN classnameNjj)}j](jNjc.it_IT.futex_sleep_multipleesbuh1hhjubj,)}(h h]h }(hjGhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubj,)}(hj,h]h*}(hjUhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubjk))}(htoh]hto}(hjbhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj>ubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hjhhhjhMubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjhhhjhMubah}(h]jah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjhMhjhhubj))}(hhh]h)}(h#Check sleeping conditions and sleeph]h#Check sleeping conditions and sleep}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhjhhubah}(h]h ]h"]h$]h&]uh1j)hjhhhjhMubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jj)jj)j)j)uh1jS)hhhj=hNhNubj))}(hX**Parameters** ``struct futex_vector *vs`` List of futexes to wait for ``unsigned int count`` Length of vs ``struct hrtimer_sleeper *to`` Timeout **Description** Sleep if and only if the timeout hasn't expired and no futex on the list has been woken up.h](h)}(h**Parameters**h]j)}(hjh]h Parameters}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhjubj*)}(hhh](j*)}(h8``struct futex_vector *vs`` List of futexes to wait for h](j *)}(h``struct futex_vector *vs``h]jZ)}(hj͊h]hstruct futex_vector *vs}(hjϊhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjˊubah}(h]h ]h"]h$]h&]uh1j *hs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhjNJubj&*)}(hhh]h)}(hList of futexes to wait forh]hList of futexes to wait for}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1j%*hjNJubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjĊubj*)}(h$``unsigned int count`` Length of vs h](j *)}(h``unsigned int count``h]jZ)}(hjh]hunsigned int count}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubah}(h]h ]h"]h$]h&]uh1j *hs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhjubj&*)}(hhh]h)}(h Length of vsh]h Length of vs}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjĊubj*)}(h'``struct hrtimer_sleeper *to`` Timeout h](j *)}(h``struct hrtimer_sleeper *to``h]jZ)}(hj?h]hstruct hrtimer_sleeper *to}(hjAhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj=ubah}(h]h ]h"]h$]h&]uh1j *hs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhj9ubj&*)}(hhh]h)}(hTimeouth]hTimeout}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjThMhjUubah}(h]h ]h"]h$]h&]uh1j%*hj9ubeh}(h]h ]h"]h$]h&]uh1j*hjThMhjĊubeh}(h]h ]h"]h$]h&]uh1j*hjubh)}(h**Description**h]j)}(hjzh]h Description}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjxubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhjubh)}(h[Sleep if and only if the timeout hasn't expired and no futex on the list has been woken up.h]h]Sleep if and only if the timeout hasn’t expired and no futex on the list has been woken up.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhjubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)&it_IT.futex_wait_multiple (C function)c.it_IT.futex_wait_multiplehNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(haint futex_wait_multiple (struct futex_vector *vs, unsigned int count, struct hrtimer_sleeper *to)h]j_))}(h`int futex_wait_multiple(struct futex_vector *vs, unsigned int count, struct hrtimer_sleeper *to)h](j+)}(hinth]hint}(hjhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjhhhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMubj,)}(h h]h }(hj΋hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjhhhj͋hMubje))}(hfutex_wait_multipleh]jk))}(hfutex_wait_multipleh]hfutex_wait_multiple}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj܋ubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjhhhj͋hMubj.,)}(hI(struct futex_vector *vs, unsigned int count, struct hrtimer_sleeper *to)h](j4,)}(hstruct futex_vector *vsh](j:,)}(hj=,h]hstruct}(hjhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjubj,)}(h h]h }(hj hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubh)}(hhh]jk))}(h futex_vectorh]h futex_vector}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j](jNj)}jjsbc.it_IT.futex_wait_multipleesbuh1hhjubj,)}(h h]h }(hj;hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubj,)}(hj,h]h*}(hjIhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubjk))}(hvsh]hvs}(hjVhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjubj4,)}(hunsigned int counth](j+)}(hunsignedh]hunsigned}(hjohhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjkubj,)}(h h]h }(hj}hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjkubj+)}(hinth]hint}(hjhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjkubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjkubjk))}(hcounth]hcount}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjkubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjubj4,)}(hstruct hrtimer_sleeper *toh](j:,)}(hj=,h]hstruct}(hjhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjubj,)}(h h]h }(hj͌hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubh)}(hhh]jk))}(hhrtimer_sleeperh]hhrtimer_sleeper}(hjތhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjیubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j](jNj7c.it_IT.futex_wait_multipleesbuh1hhjubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubj,)}(hj,h]h*}(hj hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubjk))}(htoh]hto}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hjhhhj͋hMubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjhhhj͋hMubah}(h]jah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hj͋hMhjhhubj))}(hhh]h)}(h.Prepare to wait on and enqueue several futexesh]h.Prepare to wait on and enqueue several futexes}(hjBhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chM hj?hhubah}(h]h ]h"]h$]h&]uh1j)hjhhhj͋hMubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jZj)jZj)j)j)uh1jS)hhhj=hNhNubj))}(hX**Parameters** ``struct futex_vector *vs`` The list of futexes to wait on ``unsigned int count`` The number of objects ``struct hrtimer_sleeper *to`` Timeout before giving up and returning to userspace **Description** Entry point for the FUTEX_WAIT_MULTIPLE futex operation, this function sleeps on a group of futexes and returns on the first futex that is wake, or after the timeout has elapsed. **Return** - >=0 - Hint to the futex that was awoken - <0 - On errorh](h)}(h**Parameters**h]j)}(hjdh]h Parameters}(hjfhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjbubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhj^ubj*)}(hhh](j*)}(h;``struct futex_vector *vs`` The list of futexes to wait on h](j *)}(h``struct futex_vector *vs``h]jZ)}(hjh]hstruct futex_vector *vs}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubah}(h]h ]h"]h$]h&]uh1j *hs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhj}ubj&*)}(hhh]h)}(hThe list of futexes to wait onh]hThe list of futexes to wait on}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1j%*hj}ubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjzubj*)}(h-``unsigned int count`` The number of objects h](j *)}(h``unsigned int count``h]jZ)}(hjh]hunsigned int count}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubah}(h]h ]h"]h$]h&]uh1j *hs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhjubj&*)}(hhh]h)}(hThe number of objectsh]hThe number of objects}(hjՍhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjэhMhjҍubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjэhMhjzubj*)}(hS``struct hrtimer_sleeper *to`` Timeout before giving up and returning to userspace h](j *)}(h``struct hrtimer_sleeper *to``h]jZ)}(hjh]hstruct hrtimer_sleeper *to}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubah}(h]h ]h"]h$]h&]uh1j *hs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhjubj&*)}(hhh]h)}(h3Timeout before giving up and returning to userspaceh]h3Timeout before giving up and returning to userspace}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hMhj ubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hj hMhjzubeh}(h]h ]h"]h$]h&]uh1j*hj^ubh)}(h**Description**h]j)}(hj0h]h Description}(hj2hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj.ubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhj^ubh)}(hEntry point for the FUTEX_WAIT_MULTIPLE futex operation, this function sleeps on a group of futexes and returns on the first futex that is wake, or after the timeout has elapsed.h]hEntry point for the FUTEX_WAIT_MULTIPLE futex operation, this function sleeps on a group of futexes and returns on the first futex that is wake, or after the timeout has elapsed.}(hjFhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhj^ubh)}(h **Return**h]j)}(hjWh]hReturn}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjUubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhj^ubj))}(h:- >=0 - Hint to the futex that was awoken - <0 - On errorh]jV )}(hhh](j[ )}(h'>=0 - Hint to the futex that was awokenh]h)}(hjvh]h'>=0 - Hint to the futex that was awoken}(hjxhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhjtubah}(h]h ]h"]h$]h&]uh1jZ hjqubj[ )}(h<0 - On errorh]h)}(hjh]h<0 - On error}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhjubah}(h]h ]h"]h$]h&]uh1jZ hjqubeh}(h]h ]h"]h$]h&]j j uh1jU hjhMhjmubah}(h]h ]h"]h$]h&]uh1j)hjhMhj^ubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)#it_IT.futex_wait_setup (C function)c.it_IT.futex_wait_setuphNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(hwint futex_wait_setup (u32 __user *uaddr, u32 val, unsigned int flags, struct futex_q *q, struct futex_hash_bucket **hb)h]j_))}(hvint futex_wait_setup(u32 __user *uaddr, u32 val, unsigned int flags, struct futex_q *q, struct futex_hash_bucket **hb)h](j+)}(hinth]hint}(hjЎhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hj̎hhhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMOubj,)}(h h]h }(hjߎhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj̎hhhjގhMOubje))}(hfutex_wait_setuph]jk))}(hfutex_wait_setuph]hfutex_wait_setup}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hj̎hhhjގhMOubj.,)}(hb(u32 __user *uaddr, u32 val, unsigned int flags, struct futex_q *q, struct futex_hash_bucket **hb)h](j4,)}(hu32 __user *uaddrh](h)}(hhh]jk))}(hu32h]hu32}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j](jNj)}jjsbc.it_IT.futex_wait_setupesbuh1hhj ubj,)}(h h]h }(hj1hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj ubh__user}(hj hhhNhNubj,)}(h h]h }(hjChhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj ubj,)}(hj,h]h*}(hjQhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj ubjk))}(huaddrh]huaddr}(hj^hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjubj4,)}(hu32 valh](h)}(hhh]jk))}(hu32h]hu32}(hjzhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjwubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj|modnameN classnameNjj)}j](jNj-c.it_IT.futex_wait_setupesbuh1hhjsubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjsubjk))}(hvalh]hval}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjsubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjubj4,)}(hunsigned int flagsh](j+)}(hunsignedh]hunsigned}(hjhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjubj,)}(h h]h }(hjΏhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubj+)}(hinth]hint}(hj܏hhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubjk))}(hflagsh]hflags}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjubj4,)}(hstruct futex_q *qh](j:,)}(hj=,h]hstruct}(hjhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hj ubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj ubh)}(hhh]jk))}(hfutex_qh]hfutex_q}(hj/hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj,ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj1modnameN classnameNjj)}j](jNj-c.it_IT.futex_wait_setupesbuh1hhj ubj,)}(h h]h }(hjNhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj ubj,)}(hj,h]h*}(hj\hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj ubjk))}(hj Nh]hq}(hjihhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjubj4,)}(hstruct futex_hash_bucket **hbh](j:,)}(hj=,h]hstruct}(hjhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hj}ubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj}ubh)}(hhh]jk))}(hfutex_hash_bucketh]hfutex_hash_bucket}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j](jNj-c.it_IT.futex_wait_setupesbuh1hhj}ubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj}ubj,)}(hj,h]h*}(hj̐hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj}ubj,)}(hj,h]h*}(hjِhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj}ubjk))}(hhbh]hhb}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj}ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hj̎hhhjގhMOubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjȎhhhjގhMOubah}(h]jÎah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjގhMOhjŎhhubj))}(hhh]h)}(hPrepare to wait on a futexh]hPrepare to wait on a futex}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chM@hj hhubah}(h]h ]h"]h$]h&]uh1j)hjŎhhhjގhMOubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)j(j)j(j)j)j)uh1jS)hhhj=hNhNubj))}(hX**Parameters** ``u32 __user *uaddr`` the futex userspace address ``u32 val`` the expected value ``unsigned int flags`` futex flags (FLAGS_SHARED, etc.) ``struct futex_q *q`` the associated futex_q ``struct futex_hash_bucket **hb`` storage for hash_bucket pointer to be returned to caller **Description** Setup the futex_q and locate the hash_bucket. Get the futex value and compare it with the expected value. Handle atomic faults internally. Return with the hb lock held on success, and unlocked on failure. **Return** - 0 - uaddr contains val and hb has been locked; - <1 - -EFAULT or -EWOULDBLOCK (uaddr does not contain val) and hb is unlockedh](h)}(h**Parameters**h]j)}(hj2h]h Parameters}(hj4hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj0ubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMDhj,ubj*)}(hhh](j*)}(h2``u32 __user *uaddr`` the futex userspace address h](j *)}(h``u32 __user *uaddr``h]jZ)}(hjQh]hu32 __user *uaddr}(hjShhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjOubah}(h]h ]h"]h$]h&]uh1j *hs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMAhjKubj&*)}(hhh]h)}(hthe futex userspace addressh]hthe futex userspace address}(hjjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjfhMAhjgubah}(h]h ]h"]h$]h&]uh1j%*hjKubeh}(h]h ]h"]h$]h&]uh1j*hjfhMAhjHubj*)}(h``u32 val`` the expected value h](j *)}(h ``u32 val``h]jZ)}(hjh]hu32 val}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubah}(h]h ]h"]h$]h&]uh1j *hs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMBhjubj&*)}(hhh]h)}(hthe expected valueh]hthe expected value}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMBhjubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjhMBhjHubj*)}(h8``unsigned int flags`` futex flags (FLAGS_SHARED, etc.) h](j *)}(h``unsigned int flags``h]jZ)}(hjÑh]hunsigned int flags}(hjőhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubah}(h]h ]h"]h$]h&]uh1j *hs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMChjubj&*)}(hhh]h)}(h futex flags (FLAGS_SHARED, etc.)h]h futex flags (FLAGS_SHARED, etc.)}(hjܑhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjؑhMChjّubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjؑhMChjHubj*)}(h-``struct futex_q *q`` the associated futex_q h](j *)}(h``struct futex_q *q``h]jZ)}(hjh]hstruct futex_q *q}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubah}(h]h ]h"]h$]h&]uh1j *hs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMDhjubj&*)}(hhh]h)}(hthe associated futex_qh]hthe associated futex_q}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMDhjubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjhMDhjHubj*)}(h[``struct futex_hash_bucket **hb`` storage for hash_bucket pointer to be returned to caller h](j *)}(h!``struct futex_hash_bucket **hb``h]jZ)}(hj5h]hstruct futex_hash_bucket **hb}(hj7hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj3ubah}(h]h ]h"]h$]h&]uh1j *hs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMEhj/ubj&*)}(hhh]h)}(h8storage for hash_bucket pointer to be returned to callerh]h8storage for hash_bucket pointer to be returned to caller}(hjNhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjJhMEhjKubah}(h]h ]h"]h$]h&]uh1j%*hj/ubeh}(h]h ]h"]h$]h&]uh1j*hjJhMEhjHubeh}(h]h ]h"]h$]h&]uh1j*hj,ubh)}(h**Description**h]j)}(hjph]h Description}(hjrhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjnubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMGhj,ubh)}(hSetup the futex_q and locate the hash_bucket. Get the futex value and compare it with the expected value. Handle atomic faults internally. Return with the hb lock held on success, and unlocked on failure.h]hSetup the futex_q and locate the hash_bucket. Get the futex value and compare it with the expected value. Handle atomic faults internally. Return with the hb lock held on success, and unlocked on failure.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMGhj,ubh)}(h **Return**h]j)}(hjh]hReturn}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMKhj,ubj))}(h- 0 - uaddr contains val and hb has been locked; - <1 - -EFAULT or -EWOULDBLOCK (uaddr does not contain val) and hb is unlockedh]jV )}(hhh](j[ )}(h.0 - uaddr contains val and hb has been locked;h]h)}(hjh]h.0 - uaddr contains val and hb has been locked;}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMKhjubah}(h]h ]h"]h$]h&]uh1jZ hjubj[ )}(hL<1 - -EFAULT or -EWOULDBLOCK (uaddr does not contain val) and hb is unlockedh]h)}(hjΒh]hL<1 - -EFAULT or -EWOULDBLOCK (uaddr does not contain val) and hb is unlocked}(hjВhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMLhj̒ubah}(h]h ]h"]h$]h&]uh1jZ hjubeh}(h]h ]h"]h$]h&]j j uh1jU hjŒhMKhjubah}(h]h ]h"]h$]h&]uh1j)hjŒhMKhj,ubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhNhNubeh}(h]riferimento-per-l-api-dei-futexah ]h"]riferimento per l'api dei futexah$]h&]uh1jhjhhhjhMpubj)}(hhh](j)}(hApprofondimentih]hApprofondimenti}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhMubjV )}(hhh](j[ )}(h^``Documentation/locking/spinlocks.rst``: la guida di Linus Torvalds agli spinlock del kernel. h]h)}(h]``Documentation/locking/spinlocks.rst``: la guida di Linus Torvalds agli spinlock del kernel.h](jZ)}(h'``Documentation/locking/spinlocks.rst``h]h#Documentation/locking/spinlocks.rst}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubh6: la guida di Linus Torvalds agli spinlock del kernel.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1jZ hjhhhjhNubj[ )}(hXUnix Systems for Modern Architectures: Symmetric Multiprocessing and Caching for Kernel Programmers. L'introduzione alla sincronizzazione a livello di kernel di Curt Schimmel è davvero ottima (non è scritta per Linux, ma approssimativamente si adatta a tutte le situazioni). Il libro è costoso, ma vale ogni singolo spicciolo per capire la sincronizzazione nei sistemi multi-processore. [ISBN: 0201633388] h](h)}(hdUnix Systems for Modern Architectures: Symmetric Multiprocessing and Caching for Kernel Programmers.h]hdUnix Systems for Modern Architectures: Symmetric Multiprocessing and Caching for Kernel Programmers.}(hj=hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj9ubh)}(hX3L'introduzione alla sincronizzazione a livello di kernel di Curt Schimmel è davvero ottima (non è scritta per Linux, ma approssimativamente si adatta a tutte le situazioni). Il libro è costoso, ma vale ogni singolo spicciolo per capire la sincronizzazione nei sistemi multi-processore. [ISBN: 0201633388]h]hX5L’introduzione alla sincronizzazione a livello di kernel di Curt Schimmel è davvero ottima (non è scritta per Linux, ma approssimativamente si adatta a tutte le situazioni). Il libro è costoso, ma vale ogni singolo spicciolo per capire la sincronizzazione nei sistemi multi-processore. [ISBN: 0201633388]}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj9ubeh}(h]h ]h"]h$]h&]uh1jZ hjhhhjhNubeh}(h]h ]h"]h$]h&]j j uh1jU hjhMhjhhubeh}(h]approfondimentiah ]h"]approfondimentiah$]h&]uh1jhjhhhjhMubj)}(hhh](j)}(hRingraziamentih]hRingraziamenti}(hjphhhNhNubah}(h]h ]h"]h$]h&]uh1jhjmhhhjhMubh)}(hlGrazie a Telsa Gwynne per aver formattato questa guida in DocBook, averla pulita e aggiunto un po' di stile.h]hnGrazie a Telsa Gwynne per aver formattato questa guida in DocBook, averla pulita e aggiunto un po’ di stile.}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjmhhubh)}(hGrazie a Martin Pool, Philipp Rumpf, Stephen Rothwell, Paul Mackerras, Ruedi Aschwanden, Alan Cox, Manfred Spraul, Tim Waugh, Pete Zaitcev, James Morris, Robert Love, Paul McKenney, John Ashby per aver revisionato, corretto, maledetto e commentato.h]hGrazie a Martin Pool, Philipp Rumpf, Stephen Rothwell, Paul Mackerras, Ruedi Aschwanden, Alan Cox, Manfred Spraul, Tim Waugh, Pete Zaitcev, James Morris, Robert Love, Paul McKenney, John Ashby per aver revisionato, corretto, maledetto e commentato.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjmhhubh)}(hMGrazie alla congrega per non aver avuto alcuna influenza su questo documento.h]hMGrazie alla congrega per non aver avuto alcuna influenza su questo documento.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjmhhubeh}(h]ringraziamentiah ]h"]vFringraziamentiah$]h&]uh1jhjhhhjhMubj)}(hhh](j)}(h Glossarioh]h Glossario}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhMubj*)}(hhh](j*)}(hXprelazione Prima del kernel 2.5, o quando ``CONFIG_PREEMPT`` non è impostato, i processi in contesto utente non si avvicendano nell'esecuzione (in pratica, il processo userà il processore fino al proprio termine, a meno che non ci siano delle interruzioni). Con l'aggiunta di ``CONFIG_PREEMPT`` nella versione 2.5.4 questo è cambiato: quando si è in contesto utente, processi con una priorità maggiore possono subentrare nell'esecuzione: gli spinlock furono cambiati per disabilitare la prelazioni, anche su sistemi monoprocessore. h](j *)}(h prelazioneh]h prelazione}(hjȓhhhNhNubah}(h]h ]h"]h$]h&]uh1j *hjhMhjēubj&*)}(hhh]h)}(hX Prima del kernel 2.5, o quando ``CONFIG_PREEMPT`` non è impostato, i processi in contesto utente non si avvicendano nell'esecuzione (in pratica, il processo userà il processore fino al proprio termine, a meno che non ci siano delle interruzioni). Con l'aggiunta di ``CONFIG_PREEMPT`` nella versione 2.5.4 questo è cambiato: quando si è in contesto utente, processi con una priorità maggiore possono subentrare nell'esecuzione: gli spinlock furono cambiati per disabilitare la prelazioni, anche su sistemi monoprocessore.h](hPrima del kernel 2.5, o quando }(hjٓhhhNhNubjZ)}(h``CONFIG_PREEMPT``h]hCONFIG_PREEMPT}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjٓubh non è impostato, i processi in contesto utente non si avvicendano nell’esecuzione (in pratica, il processo userà il processore fino al proprio termine, a meno che non ci siano delle interruzioni). Con l’aggiunta di }(hjٓhhhNhNubjZ)}(h``CONFIG_PREEMPT``h]hCONFIG_PREEMPT}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjٓubh nella versione 2.5.4 questo è cambiato: quando si è in contesto utente, processi con una priorità maggiore possono subentrare nell’esecuzione: gli spinlock furono cambiati per disabilitare la prelazioni, anche su sistemi monoprocessore.}(hjٓhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj֓ubah}(h]h ]h"]h$]h&]uh1j%*hjēubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjubj*)}(hXbh Bottom Half: per ragioni storiche, le funzioni che contengono '_bh' nel loro nome ora si riferiscono a qualsiasi interruzione software; per esempio, spin_lock_bh() blocca qualsiasi interuzione software sul processore corrente. I *Bottom Halves* sono deprecati, e probabilmente verranno sostituiti dai tasklet. In un dato momento potrà esserci solo un *bottom half* in esecuzione. h](j *)}(hbhh]hbh}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j *hjhMhjubj&*)}(hhh]h)}(hX|Bottom Half: per ragioni storiche, le funzioni che contengono '_bh' nel loro nome ora si riferiscono a qualsiasi interruzione software; per esempio, spin_lock_bh() blocca qualsiasi interuzione software sul processore corrente. I *Bottom Halves* sono deprecati, e probabilmente verranno sostituiti dai tasklet. In un dato momento potrà esserci solo un *bottom half* in esecuzione.h](hBottom Half: per ragioni storiche, le funzioni che contengono ‘_bh’ nel loro nome ora si riferiscono a qualsiasi interruzione software; per esempio, spin_lock_bh() blocca qualsiasi interuzione software sul processore corrente. I }(hj,hhhNhNubj)}(h*Bottom Halves*h]h Bottom Halves}(hj4hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj,ubhl sono deprecati, e probabilmente verranno sostituiti dai tasklet. In un dato momento potrà esserci solo un }(hj,hhhNhNubj)}(h *bottom half*h]h bottom half}(hjFhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj,ubh in esecuzione.}(hj,hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj)ubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjhhubj*)}(hcontesto d'interruzione Non è il contesto utente: qui si processano le interruzioni hardware e software. La macro in_interrupt() ritorna vero. h](j *)}(hcontesto d'interruzioneh]hcontesto d’interruzione}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1j *hjhMhjjubj&*)}(hhh]h)}(hwNon è il contesto utente: qui si processano le interruzioni hardware e software. La macro in_interrupt() ritorna vero.h]hwNon è il contesto utente: qui si processano le interruzioni hardware e software. La macro in_interrupt() ritorna vero.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj|ubah}(h]h ]h"]h$]h&]uh1j%*hjjubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjhhubj*)}(hX8contesto utente Il kernel che esegue qualcosa per conto di un particolare processo (per esempio una chiamata di sistema) o di un thread del kernel. Potete identificare il processo con la macro ``current``. Da non confondere con lo spazio utente. Può essere interrotto sia da interruzioni software che hardware. h](j *)}(hcontesto utenteh]hcontesto utente}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j *hjhMhjubj&*)}(hhh]h)}(hX'Il kernel che esegue qualcosa per conto di un particolare processo (per esempio una chiamata di sistema) o di un thread del kernel. Potete identificare il processo con la macro ``current``. Da non confondere con lo spazio utente. Può essere interrotto sia da interruzioni software che hardware.h](hIl kernel che esegue qualcosa per conto di un particolare processo (per esempio una chiamata di sistema) o di un thread del kernel. Potete identificare il processo con la macro }(hjhhhNhNubjZ)}(h ``current``h]hcurrent}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubhk. Da non confondere con lo spazio utente. Può essere interrotto sia da interruzioni software che hardware.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjhhubj*)}(h{interruzione hardware Richiesta di interruzione hardware. in_hardirq() ritorna vero in un gestore d'interruzioni hardware. h](j *)}(hinterruzione hardwareh]hinterruzione hardware}(hjޔhhhNhNubah}(h]h ]h"]h$]h&]uh1j *hjhMhjڔubj&*)}(hhh]h)}(hdRichiesta di interruzione hardware. in_hardirq() ritorna vero in un gestore d'interruzioni hardware.h]hfRichiesta di interruzione hardware. in_hardirq() ritorna vero in un gestore d’interruzioni hardware.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1j%*hjڔubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjhhubj*)}(hXinterruzione software / softirq Gestore di interruzioni software: in_hardirq() ritorna falso; in_softirq() ritorna vero. I tasklet e le softirq sono entrambi considerati 'interruzioni software'. In soldoni, un softirq è uno delle 32 interruzioni software che possono essere eseguite su più processori in contemporanea. A volte si usa per riferirsi anche ai tasklet (in pratica tutte le interruzioni software). h](j *)}(hinterruzione software / softirqh]hinterruzione software / softirq}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j *hjhMhj ubj&*)}(hhh](h)}(hGestore di interruzioni software: in_hardirq() ritorna falso; in_softirq() ritorna vero. I tasklet e le softirq sono entrambi considerati 'interruzioni software'.h]hGestore di interruzioni software: in_hardirq() ritorna falso; in_softirq() ritorna vero. I tasklet e le softirq sono entrambi considerati ‘interruzioni software’.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjubh)}(hIn soldoni, un softirq è uno delle 32 interruzioni software che possono essere eseguite su più processori in contemporanea. A volte si usa per riferirsi anche ai tasklet (in pratica tutte le interruzioni software).h]hIn soldoni, un softirq è uno delle 32 interruzioni software che possono essere eseguite su più processori in contemporanea. A volte si usa per riferirsi anche ai tasklet (in pratica tutte le interruzioni software).}(hj,hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjubeh}(h]h ]h"]h$]h&]uh1j%*hj ubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjhhubj*)}(h_monoprocessore / UP (Uni-Processor) un solo processore, ovvero non è SMP. (``CONFIG_SMP=n``). h](j *)}(hmonoprocessore / UPh]hmonoprocessore / UP}(hjJhhhNhNubah}(h]h ]h"]h$]h&]uh1j *hjhMhjFubj&*)}(hhh]h)}(hJ(Uni-Processor) un solo processore, ovvero non è SMP. (``CONFIG_SMP=n``).h](h8(Uni-Processor) un solo processore, ovvero non è SMP. (}(hj[hhhNhNubjZ)}(h``CONFIG_SMP=n``h]h CONFIG_SMP=n}(hjchhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj[ubh).}(hj[hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjXubah}(h]h ]h"]h$]h&]uh1j%*hjFubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjhhubj*)}(humulti-processore / SMP (Symmetric Multi-Processor) kernel compilati per sistemi multi-processore (``CONFIG_SMP=y``). h](j *)}(hmulti-processore / SMPh]hmulti-processore / SMP}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j *hjhMhjubj&*)}(hhh]h)}(h](Symmetric Multi-Processor) kernel compilati per sistemi multi-processore (``CONFIG_SMP=y``).h](hK(Symmetric Multi-Processor) kernel compilati per sistemi multi-processore (}(hjhhhNhNubjZ)}(h``CONFIG_SMP=y``h]h CONFIG_SMP=y}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjubh).}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjhhubj*)}(hIspazio utente Un processo che esegue il proprio codice fuori dal kernel. h](j *)}(h spazio utenteh]h spazio utente}(hj̕hhhNhNubah}(h]h ]h"]h$]h&]uh1j *hjhMhjȕubj&*)}(hhh]h)}(h:Un processo che esegue il proprio codice fuori dal kernel.h]h:Un processo che esegue il proprio codice fuori dal kernel.}(hjݕhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjڕubah}(h]h ]h"]h$]h&]uh1j%*hjȕubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjhhubj*)}(htasklet Un'interruzione software registrabile dinamicamente che ha la garanzia d'essere eseguita solo su un processore alla volta. h](j *)}(htaskleth]htasklet}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j *hjhMhjubj&*)}(hhh]h)}(hzUn'interruzione software registrabile dinamicamente che ha la garanzia d'essere eseguita solo su un processore alla volta.h]h~Un’interruzione software registrabile dinamicamente che ha la garanzia d’essere eseguita solo su un processore alla volta.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj ubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjhhubj*)}(htimer Un'interruzione software registrabile dinamicamente che viene eseguita (circa) in un determinato momento. Quando è in esecuzione è come un tasklet (infatti, sono chiamati da ``TIMER_SOFTIRQ``).h](j *)}(htimerh]htimer}(hj*hhhNhNubah}(h]h ]h"]h$]h&]uh1j *hjhMhj&ubj&*)}(hhh]h)}(hUn'interruzione software registrabile dinamicamente che viene eseguita (circa) in un determinato momento. Quando è in esecuzione è come un tasklet (infatti, sono chiamati da ``TIMER_SOFTIRQ``).h](hUn’interruzione software registrabile dinamicamente che viene eseguita (circa) in un determinato momento. Quando è in esecuzione è come un tasklet (infatti, sono chiamati da }(hj;hhhNhNubjZ)}(h``TIMER_SOFTIRQ``h]h TIMER_SOFTIRQ}(hjChhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj;ubh).}(hj;hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj8ubah}(h]h ]h"]h$]h&]uh1j%*hj&ubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjhhubeh}(h]h ]h"]h$]h&]uh1j*hjhhhjhNubeh}(h] glossarioah ]h"] glossarioah$]h&]uh1jhjhhhjhMubeh}(h](*l-inaffidabile-guida-alla-sincronizzazionejeh ]h"](*l'inaffidabile guida alla sincronizzazioneit_kernel_hacking_lockeh$]h&]uh1jhhhhhjhK j1 }j{jsj3 }jjsubeh}(h]h ]h"]h$]h&]sourcejuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(jN generatorN datestampN source_linkN source_urlN toc_backlinksjfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerjerror_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourcej _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}(Iquali funzioni possono essere chiamate in modo sicuro dalle interruzioni?]jastallo: semplice ed avanzato]ja!contesto di interruzione hardware]jadati per processore]j aurefids}(j]jaj5 ]j+ aunameids}(j{jjzjwjjjjjjjK jH jjjjjOjLjjj j j+ j( j j jq jn j j jC j@ j j j; j8 j. j5 j- jj j j& j# jjjjjjjjj+j(jjj=j:j5j2jjjA!j>!j8jj j j j j9!j6!j'j'j#j#jz&jw&j'j j'j'j.)jj(j(j')j$)j=j=jjjjjgjjjrjou nametypes}(j{jzjjjjK jjjOjj j+ j jq j jC j j; j. j- j j& jjjjj+jj=j5jjA!j8j j j9!j'j#jz&j'j'j.)j(j')j=jjjjjruh}(jjjwjjjjjjjjjH jjjjjjLjjjRj jj( j j j. jn jM j jt j@ j j j j8 j j5 jN jjN j jm j# j jj6 jj jjjjj(jjj.j:jj2jjj@j>!jjjj j;j j* j6!j j'jD!j#j#jw&j#j j}&j'j'jj'j(j'j$)j(j=j1)jQ)jZ)j*j*j+j+jy-j~-j(/j-/j0j0jh2jm2j4j4j6j6j8j8j1:j6:j;j;jj=j>j>j?j?j:Cj?Cj`GjeGjHjHjbKjgKjdMjiMjNjNjPjPjbRjhRjFVjKVjrXjwXjh[jm[j\j\jbjbjejejijijljljbsjgsjxjxj{j{jȀj̀jwj|jj"jjjjjÎjȎjgjjjmjojjjfjeju footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}jKsRparse_messages]hsystem_message)}(hhh]h)}(heUnexpected possible title overline or transition. Treating it as ordinary text because it's so short.h]hgUnexpected possible title overline or transition. Treating it as ordinary text because it’s so short.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]levelKtypeINFOlineMSsourcejuh1jhj ubatransform_messages](j)}(hhh]h)}(hhh]h