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.Mh]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.hhK5ubah}(h]h ]h"]h$]h&]jTjU add_permalinkuh1j^)sphinx_line_type declaratorhjZ)hhhj)hK5ubah}(h]jQ)ah ](sig sig-objecteh"]h$]h&] is_multiline _toc_parts) _toc_namehuh1jX)hj)hK5hjU)hhubh desc_content)}(hhh]h}(h]h ]h"]h$]h&]uh1j)hjU)hhhj)hK5ubeh}(h]h ](jmacroeh"]h$]h&]domainjobjtypej)desctypej)noindex noindexentrynocontentsentryuh1jS)hhhj1)hNhNubh)}(h``mutex_init (mutex)``h]jZ)}(hj)h]hmutex_init (mutex)}(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.hhK7hj1)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.hhKDubah}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj*hhhj*hKDubah}(h]j*ah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hj*hKDhj*hhubj))}(hhh]h}(h]h ]h"]h$]h&]uh1j)hj*hhhj*hKDubeh}(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.hhKFhj1)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.hhK]ubhdesc_sig_space)}(h h]h }(hj,hhhNhNubah}(h]h ]wah"]h$]h&]uh1j,hj+hhhj,hK]ubje))}(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,hK]ubhdesc_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,hK]ubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj+hhhj,hK]ubah}(h]j+ah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hj,hK]hj+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,hK]ubeh}(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.chKubj,)}(h h]h }(hj-hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj-hhhj-hKubje))}(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-hKubj.,)}(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-hKubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj~-hhhj-hKubah}(h]jy-ah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hj-hKhj{-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.c0hKhjD.hhubah}(h]h ]h"]h$]h&]uh1j)hj{-hhhj-hKubeh}(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.chMhjc.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.chMhjc.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.chM-ubj,)}(h h]h }(hjM:hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj::hhhjL:hM-ubje))}(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:hM-ubj.,)}(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:hM-ubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj6:hhhjL:hM-ubah}(h]j1:ah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjL:hM-hj3: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:hM-ubeh}(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.chM1hj;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.chM0hj;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.chM0hj;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.chM3hj;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.chM6hj;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.chM3hj;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.chMuubj,)}(h h]h }(hj<hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj;hhhj<hMuubje))}(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<hMuubj.,)}(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<hMuubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj;hhhj<hMuubah}(h]j;ah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hj<hMuhj;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.chMuhj =hhubah}(h]h ]h"]h$]h&]uh1j)hj;hhhj<hMuubeh}(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.chMyhj)=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.chMvhjH=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=hMvhjd=ubah}(h]h ]h"]h$]h&]uh1j%*hjH=ubeh}(h]h ]h"]h$]h&]uh1j*hjc=hMvhjE=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.chMwhj=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=hMwhj=ubah}(h]h ]h"]h$]h&]uh1j%*hj=ubeh}(h]h ]h"]h$]h&]uh1j*hj=hMwhjE=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.chMyhj)=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.chMyhj)=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_get (C function)c.it_IT.futex_hash_gethNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(h2void futex_hash_get (struct futex_hash_bucket *hb)h]j_))}(h1void futex_hash_get(struct futex_hash_bucket *hb)h](j+)}(hvoidh]hvoid}(hj >hhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+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.>hKubje))}(hfutex_hash_geth]jk))}(hfutex_hash_geth]hfutex_hash_get}(hjA>hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj=>ubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hj>hhhj.>hKubj.,)}(h(struct futex_hash_bucket *hb)h]j4,)}(hstruct futex_hash_bucket *hbh](j:,)}(hj=,h]hstruct}(hj]>hhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjY>ubj,)}(h h]h }(hjj>hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjY>ubh)}(hhh]jk))}(hfutex_hash_bucketh]hfutex_hash_bucket}(hj{>hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjx>ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj}>modnameN classnameNjj)}j](jNj)}jjC>sbc.it_IT.futex_hash_getesbuh1hhjY>ubj,)}(h h]h }(hj>hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjY>ubj,)}(hj,h]h*}(hj>hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjY>ubjk))}(hhbh]hhb}(hj>hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjY>ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjU>ubah}(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)}(h/Get an additional reference for the local hash.h]h/Get an additional reference for the local 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.chKhj>hhubah}(h]h ]h"]h$]h&]uh1j)hj>hhhj.>hKubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)j>j)j>j)j)j)uh1jS)hhhj=hNhNubj))}(h**Parameters** ``struct futex_hash_bucket *hb`` ptr to the private local hash. **Description** Obtain an additional reference for the already obtained hash bucket. The caller must already own an reference.h](h)}(h**Parameters**h]j)}(hj?h]h Parameters}(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.chKhj>ubj*)}(hhh]j*)}(h@``struct futex_hash_bucket *hb`` ptr to the private local hash. 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 *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhj?ubj&*)}(hhh]h)}(hptr to the private local hash.h]hptr to the private local hash.}(hj;?hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj7?hKhj8?ubah}(h]h ]h"]h$]h&]uh1j%*hj?ubeh}(h]h ]h"]h$]h&]uh1j*hj7?hKhj?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.chKhj>ubh)}(hnObtain an additional reference for the already obtained hash bucket. The caller must already own an reference.h]hnObtain an additional reference for the already obtained hash bucket. The caller must already own an reference.}(hjs?hhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chKhj>ubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)it_IT.__futex_hash (C function)c.it_IT.__futex_hashhNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(h^struct futex_hash_bucket * __futex_hash (union futex_key *key, struct futex_private_hash *fph)h]j_))}(h\struct futex_hash_bucket *__futex_hash(union futex_key *key, struct futex_private_hash *fph)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.chMubj,)}(h h]h }(hj?hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj?hhhj?hMubh)}(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)}j __futex_hashsbc.it_IT.__futex_hashesbuh1hhj?hhhj?hMubj,)}(h h]h }(hj?hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj?hhhj?hMubj,)}(hj,h]h*}(hj?hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj?hhhj?hMubje))}(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?hMubj.,)}(h6(union futex_key *key, struct futex_private_hash *fph)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)hj9@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*}(hji@hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj@ubjk))}(hkeyh]hkey}(hjv@hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj@ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj@ubj4,)}(hstruct futex_private_hash *fphh](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_private_hashh]hfutex_private_hash}(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))}(hfphh]hfph}(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)}(hReturn the hash bucketh]hReturn the hash bucket}(hjAhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjAhhubah}(h]h ]h"]h$]h&]uh1j)hj?hhhj?hMubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)j)Aj)j)Aj)j)j)uh1jS)hhhj=hNhNubj))}(hX**Parameters** ``union futex_key *key`` Pointer to the futex key for which the hash is calculated ``struct futex_private_hash *fph`` Pointer to private hash if known **Description** We hash on the keys returned from get_futex_key (see below) and return the corresponding hash bucket. If the FUTEX is PROCESS_PRIVATE then a per-process hash bucket (from the private hash) is returned if existing. Otherwise a hash bucket from the global hash is returned.h](h)}(h**Parameters**h]j)}(hj3Ah]h Parameters}(hj5AhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj1Aubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhj-Aubj*)}(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)}(hjRAh]hunion futex_key *key}(hjTAhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjPAubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjLAubj&*)}(hhh]h)}(h9Pointer to the futex key for which the hash is calculatedh]h9Pointer to the futex key for which the hash is calculatedC}(hjkAhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjgAhMhjhAubah}(h]h ]h"]h$]h&]uh1j%*hjLAubeh}(h]h ]h"]h$]h&]uh1j*hjgAhMhjIAubj*)}(hD``struct futex_private_hash *fph`` Pointer to private hash if known h](j *)}(h"``struct futex_private_hash *fph``h]jZ)}(hjAh]hstruct futex_private_hash *fph}(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.chMhjAubj&*)}(hhh]h)}(h Pointer to private hash if knownh]h Pointer to private hash if known}(hjAhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjAhMhjAubah}(h]h ]h"]h$]h&]uh1j%*hjAubeh}(h]h ]h"]h$]h&]uh1j*hjAhMhjIAubeh}(h]h ]h"]h$]h&]uh1j*hj-Aubh)}(h**Description**h]j)}(hjAh]h Description}(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.chMhj-Aubh)}(hXWe hash on the keys returned from get_futex_key (see below) and return the corresponding hash bucket. If the FUTEX is PROCESS_PRIVATE then a per-process hash bucket (from the private hash) is returned if existing. Otherwise a hash bucket from the global hash is returned.h]hXWe hash on the keys returned from get_futex_key (see below) and return the corresponding hash bucket. If the FUTEX is PROCESS_PRIVATE then a per-process hash bucket (from the private hash) is returned if existing. Otherwise a hash bucket from the global hash is returned.}(hjAhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhj-Aubeh}(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 BhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjBhhho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMubj,)}(h h]h }(hjBhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjBhhhjBhMubh)}(hhh]jk))}(hhrtimer_sleeperh]hhrtimer_sleeper}(hj*BhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj'Bubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj,BmodnameN classnameNjj)}j](jNj)}jfutex_setup_timersbc.it_IT.futex_setup_timeresbuh1hhjBhhhjBhMubj,)}(h h]h }(hjLBhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjBhhhjBhMubj,)}(hj,h]h*}(hjZBhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjBhhhjBhMubje))}(hfutex_setup_timerh]jk))}(hjIBh]hfutex_setup_timer}(hjkBhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjgBubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjBhhhjBhMubj.,)}(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}(hjBhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjBubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjBmodnameN classnameNjj)}j](jNjGBc.it_IT.futex_setup_timeresbuh1hhjBubj,)}(h h]h }(hjBhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjBubj,)}(hj,h]h*}(hjBhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjBubjk))}(htimeh]htime}(hjBhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjBubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj~Bubj4,)}(hstruct hrtimer_sleeper *timeouth](j:,)}(hj=,h]hstruct}(hjBhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjBubj,)}(h h]h }(hjBhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjBubh)}(hhh]jk))}(hhrtimer_sleeperh]hhrtimer_sleeper}(hjBhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjBubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjBmodnameN classnameNjj)}j](jNjGBc.it_IT.futex_setup_timeresbuh1hhjBubj,)}(h h]h }(hjChhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjBubj,)}(hj,h]h*}(hj'ChhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjBubjk))}(htimeouth]htimeout}(hj4ChhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjBubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj~Bubj4,)}(h int flagsh](j+)}(hinth]hint}(hjMChhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjICubj,)}(h h]h }(hj[ChhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjICubjk))}(hflagsh]hflags}(hjiChhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjICubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj~Bubj4,)}(h u64 range_nsh](h)}(hhh]jk))}(hu64h]hu64}(hjChhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjCubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjCmodnameN classnameNjj)}j](jNjGBc.it_IT.futex_setup_timeresbuh1hhj~Cubj,)}(h h]h }(hjChhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj~Cubjk))}(hrange_nsh]hrange_ns}(hjChhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj~Cubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj~Bubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hjBhhhjBhMubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjBhhhjBhMubah}(h]jAah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjBhMhjBhhubj))}(hhh]h)}(hset up the sleeping hrtimer.h]hset up the sleeping hrtimer.}(hjChhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjChhubah}(h]h ]h"]h$]h&]uh1j)hjBhhhjBhMubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jCj)jCj)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)}(hjCh]h Parameters}(hjDhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjCubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjCubj*)}(hhh](j*)}(h1``ktime_t *time`` ptr to the given timeout value h](j *)}(h``ktime_t *time``h]jZ)}(hjDh]h ktime_t *time}(hjDhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjDubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjDubj&*)}(hhh]h)}(hptr to the given timeout valueh]hptr to the given timeout value}(hj6DhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj2DhMhj3Dubah}(h]h ]h"]h$]h&]uh1j%*hjDubeh}(h]h ]h"]h$]h&]uh1j*hj2DhMhjDubj*)}(hO``struct hrtimer_sleeper *timeout`` the hrtimer_sleeper structure to be set up h](j *)}(h#``struct hrtimer_sleeper *timeout``h]jZ)}(hjVDh]hstruct hrtimer_sleeper *timeout}(hjXDhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjTDubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjPDubj&*)}(hhh]h)}(h*the hrtimer_sleeper structure to be set uph]h*the hrtimer_sleeper structure to be set up}(hjoDhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjkDhMhjlDubah}(h]h ]h"]h$]h&]uh1j%*hjPDubeh}(h]h ]h"]h$]h&]uh1j*hjkDhMhjDubj*)}(h``int flags`` futex flags h](j *)}(h ``int flags``h]jZ)}(hjDh]h int flags}(hjDhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjDubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjDubj&*)}(hhh]h)}(h futex flagsh]h futex flags}(hjDhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjDhMhjDubah}(h]h ]h"]h$]h&]uh1j%*hjDubeh}(h]h ]h"]h$]h&]uh1j*hjDhMhjDubj*)}(h&``u64 range_ns`` optional range in ns h](j *)}(h``u64 range_ns``h]jZ)}(hjDh]h u64 range_ns}(hjDhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjDubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjDubj&*)}(hhh]h)}(hoptional range in nsh]hoptional range in ns}(hjDhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjDhMhjDubah}(h]h ]h"]h$]h&]uh1j%*hjDubeh}(h]h ]h"]h$]h&]uh1j*hjDhMhjDubeh}(h]h ]h"]h$]h&]uh1j*hjCubh)}(h **Return**h]j)}(hjEh]hReturn}(hjEhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjEubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjCubj*)}(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}(hj EhhhNhNubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjEubj&*)}(hhh]h)}(h value givenh]h value given}(hj2EhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhj/Eubah}(h]h ]h"]h$]h&]uh1j%*hjEubeh}(h]h ]h"]h$]h&]uh1j*hj.EhMhjEubah}(h]h ]h"]h$]h&]uh1j*hjCubeh}(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}(hjsEhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjoEhhho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chM ubj,)}(h h]h }(hjEhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjoEhhhjEhM ubje))}(h get_futex_keyh]jk))}(h get_futex_keyh]h get_futex_key}(hjEhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjEubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjoEhhhjEhM ubj.,)}(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}(hjEhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjEubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjEmodnameN classnameNjj)}j](jNj)}jjEsbc.it_IT.get_futex_keyesbuh1hhjEubj,)}(h h]h }(hjEhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjEubh__user}(hjEhhhNhNubj,)}(h h]h }(hjEhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjEubj,)}(hj,h]h*}(hjEhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjEubjk))}(huaddrh]huaddr}(hjFhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjEubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjEubj4,)}(hunsigned int flagsh](j+)}(hunsignedh]hunsigned}(hjFhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjFubj,)}(h h]h }(hj(FhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjFubj+)}(hinth]hint}(hj6FhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjFubj,)}(h h]h }(hjDFhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjFubjk))}(hflagsh]hflags}(hjRFhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjFubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjEubj4,)}(hunion futex_key *keyh](j:,)}(hj@h]hunion}(hjkFhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjgFubj,)}(h h]h }(hjxFhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjgFubh)}(hhh]jk))}(h futex_keyh]h futex_key}(hjFhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjFubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjFmodnameN classnameNjj)}j](jNjEc.it_IT.get_futex_keyesbuh1hhjgFubj,)}(h h]h }(hjFhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjgFubj,)}(hj,h]h*}(hjFhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjgFubjk))}(hkeyh]hkey}(hjFhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjgFubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjEubj4,)}(henum futex_access rwh](j:,)}(henumh]henum}(hjFhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjFubj,)}(h h]h }(hjFhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjFubh)}(hhh]jk))}(h futex_accessh]h futex_access}(hjFhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjFubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjFmodnameN classnameNjj)}j](jNjEc.it_IT.get_futex_keyesbuh1hhjFubj,)}(h h]h }(hjGhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjFubjk))}(hrwh]hrw}(hj(GhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjFubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjEubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hjoEhhhjEhM ubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjkEhhhjEhM ubah}(h]jfEah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjEhM hjhEhhubj))}(hhh]h)}(h-Get parameters which are the keys for a futexh]h-Get parameters which are the keys for a futex}(hjRGhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chM hjOGhhubah}(h]h ]h"]h$]h&]uh1j)hjhEhhhjEhM ubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jjGj)jjGj)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 offset within mapping, 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)}(hjtGh]h Parameters}(hjvGhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjrGubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chM hjnGubj*)}(hhh](j*)}(h3``u32 __user *uaddr`` virtual address of the futex h](j *)}(h``u32 __user *uaddr``h]jZ)}(hjGh]hu32 __user *uaddr}(hjGhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjGubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chM hjGubj&*)}(hhh]h)}(hvirtual address of the futexh]hvirtual address of the futex}(hjGhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjGhM hjGubah}(h]h ]h"]h$]h&]uh1j%*hjGubeh}(h]h ]h"]h$]h&]uh1j*hjGhM hjGubj*)}(h``unsigned int flags`` FLAGS_* h](j *)}(h``unsigned int flags``h]jZ)}(hjGh]hunsigned int flags}(hjGhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjGubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chM hjGubj&*)}(hhh]h)}(hFLAGS_*h]hFLAGS_*}(hjGhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjGhM hjGubah}(h]h ]h"]h$]h&]uh1j%*hjGubeh}(h]h ]h"]h$]h&]uh1j*hjGhM hjGubj*)}(h9``union futex_key *key`` address where result is stored. h](j *)}(h``union futex_key *key``h]jZ)}(hjHh]hunion futex_key *key}(hjHhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjHubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chM hjGubj&*)}(hhh]h)}(haddress where result is stored.h]haddress where result is stored.}(hjHhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjHhM hjHubah}(h]h ]h"]h$]h&]uh1j%*hjGubeh}(h]h ]h"]h$]h&]uh1j*hjHhM hjGubj*)}(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)}(hj>Hh]henum futex_access rw}(hj@HhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhji_sequence, page offset within mapping, offset_within_page ) h]h)}(hE( inode->i_sequence, page offset within mapping, offset_within_page )h]hE( inode->i_sequence, page offset within mapping, offset_within_page )}(hjHhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjHubah}(h]h ]h"]h$]h&]uh1j)hj IhMhjnGubh)}(h([ also see get_inode_sequence_number() ]h]h([ also see get_inode_sequence_number() ]}(hjIhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjnGubh)}(h8For private mappings (or when **!fshared**), the key is:h](hFor private mappings (or when }(hj!IhhhNhNubj)}(h **!fshared**h]h!fshared}(hj)IhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj!Iubh), the key is:}(hj!IhhhNhNubeh}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjnGubj))}(h( current->mm, address, 0 ) h]h)}(h( current->mm, address, 0 )h]h( current->mm, address, 0 )}(hjFIhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjBIubah}(h]h ]h"]h$]h&]uh1j)hjTIhMhjnGubh)}(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[IhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjnGubh)}(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.}(hjjIhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chM!hjnGubeh}(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}(hjIhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+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,hjIhhhjIhMubje))}(hfault_in_user_writeableh]jk))}(hfault_in_user_writeableh]hfault_in_user_writeable}(hjIhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjIubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjIhhhjIhMubj.,)}(h(u32 __user *uaddr)h]j4,)}(hu32 __user *uaddrh](h)}(hhh]jk))}(hu32h]hu32}(hjIhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjIubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjImodnameN classnameNjj)}j](jNj)}jjIsbc.it_IT.fault_in_user_writeableesbuh1hhjIubj,)}(h h]h }(hjIhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjIubh__user}(hjIhhhNhNubj,)}(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))}(huaddrh]huaddr}(hj'JhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjIubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjIubah}(h]h ]h"]h$]h&]jTjUuh1j-,hjIhhhjIhMubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjIhhhjIhMubah}(h]jIah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjIhMhjIhhubj))}(hhh]h)}(h*Fault in user address and verify RW accessh]h*Fault in user address and verify RW access}(hjQJhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjNJhhubah}(h]h ]h"]h$]h&]uh1j)hjIhhhjIhMubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jiJj)jiJj)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)}(hjsJh]h Parameters}(hjuJhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjqJubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjmJubj*)}(hhh]j*)}(h=``u32 __user *uaddr`` pointer to faulting user space address h](j *)}(h``u32 __user *uaddr``h]jZ)}(hjJh]hu32 __user *uaddr}(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&pointer to faulting user space addressh]h&pointer to faulting user space address}(hjJhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjJhMhjJubah}(h]h ]h"]h$]h&]uh1j%*hjJubeh}(h]h ]h"]h$]h&]uh1j*hjJhMhjJubah}(h]h ]h"]h$]h&]uh1j*hjmJubh)}(h**Description**h]j)}(hjJh]h Description}(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.chMhjmJubh)}(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 }(hjJhhhNhNubj)}(h **uaddr**h]huaddr}(hjJhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjJubh.}(hjJhhhNhNubeh}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjmJubh)}(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.}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chM hjmJubeh}(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}(hj3KhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hj/Khhho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMubj,)}(h h]h }(hjAKhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj/Khhhj@KhMubh)}(hhh]jk))}(hfutex_qh]hfutex_q}(hjRKhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjOKubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjTKmodnameN classnameNjj)}j](jNj)}jfutex_top_waitersbc.it_IT.futex_top_waiteresbuh1hhj/Khhhj@KhMubj,)}(h h]h }(hjtKhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj/Khhhj@KhMubj,)}(hj,h]h*}(hjKhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj/Khhhj@KhMubje))}(hfutex_top_waiterh]jk))}(hjqKh]hfutex_top_waiter}(hjKhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjKubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hj/Khhhj@KhMubj.,)}(h4(struct futex_hash_bucket *hb, union futex_key *key)h](j4,)}(hstruct futex_hash_bucket *hbh](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))}(hfutex_hash_bucketh]hfutex_hash_bucket}(hjKhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjKubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjKmodnameN classnameNjj)}j](jNjoKc.it_IT.futex_top_waiteresbuh1hhjKubj,)}(h h]h }(hjKhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjKubj,)}(hj,h]h*}(hjKhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjKubjk))}(hhbh]hhb}(hjLhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjKubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjKubj4,)}(hunion futex_key *keyh](j:,)}(hj@h]hunion}(hjLhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjLubj,)}(h h]h }(hj,LhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjLubh)}(hhh]jk))}(h futex_keyh]h futex_key}(hj=LhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj:Lubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj?LmodnameN classnameNjj)}j](jNjoKc.it_IT.futex_top_waiteresbuh1hhjLubj,)}(h h]h }(hj\LhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjLubj,)}(hj,h]h*}(hjjLhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjLubjk))}(hkeyh]hkey}(hjwLhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjLubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjKubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hj/Khhhj@KhMubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj+Khhhj@KhMubah}(h]j&Kah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hj@KhMhj(Khhubj))}(hhh]h)}(h-Return the highest priority waiter on a futexh]h-Return the highest priority waiter on a futex}(hjLhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjLhhubah}(h]h ]h"]h$]h&]uh1j)hj(Khhhj@KhMubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jLj)jLj)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)}(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.chM!hjLubj*)}(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)}(hjLh]hstruct futex_hash_bucket *hb}(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'the hash bucket the futex_q's reside inh]h)the hash bucket the futex_q’s reside in}(hjLhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjLhMhjLubah}(h]h ]h"]h$]h&]uh1j%*hjLubeh}(h]h ]h"]h$]h&]uh1j*hjLhMhjLubj*)}(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)}(hjMh]hunion futex_key *key}(hjMhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjMubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjMubj&*)}(hhh]h)}(hthe futex key (to distinguish it from other futex futex_q’s)}(hj4MhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj0MhMhj1Mubah}(h]h ]h"]h$]h&]uh1j%*hjMubeh}(h]h ]h"]h$]h&]uh1j*hj0MhMhjLubeh}(h]h ]h"]h$]h&]uh1j*hjLubh)}(h**Description**h]j)}(hjVMh]h Description}(hjXMhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjTMubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chM!hjLubh)}(h%Must be called with the hb lock held.h]h%Must be called with the hb lock held.}(hjlMhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chM!hjLubeh}(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}(hjMhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjMhhho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chM/ubj,)}(h h]h }(hjMhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjMhhhjMhM/ubje))}(hwait_for_owner_exitingh]jk))}(hwait_for_owner_exitingh]hwait_for_owner_exiting}(hjMhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjMubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjMhhhjMhM/ubj.,)}(h&(int ret, struct task_struct *exiting)h](j4,)}(hint reth](j+)}(hinth]hint}(hjMhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjMubj,)}(h h]h }(hjMhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjMubjk))}(hreth]hret}(hjMhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjMubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjMubj4,)}(hstruct task_struct *exitingh](j:,)}(hj=,h]hstruct}(hj NhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hj Nubj,)}(h h]h }(hjNhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj Nubh)}(hhh]jk))}(h task_structh]h task_struct}(hj+NhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj(Nubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj-NmodnameN classnameNjj)}j](jNj)}jjMsbc.it_IT.wait_for_owner_exitingesbuh1hhj Nubj,)}(h h]h }(hjLNhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj Nubj,)}(hj,h]h*}(hjZNhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj Nubjk))}(hexitingh]hexiting}(hjgNhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj Nubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjMubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hjMhhhjMhM/ubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjMhhhjMhM/ubah}(h]jMah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjMhM/hjMhhubj))}(hhh]h)}(h Block until the owner has exitedh]h Block until the owner has exited}(hjNhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chM/hjNhhubah}(h]h ]h"]h$]h&]uh1j)hjMhhhjMhM/ubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jNj)jNj)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)}(hjNh]h Parameters}(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.chM3hjNubj*)}(hhh](j*)}(h.``int ret`` owner's current futex lock status h](j *)}(h ``int ret``h]jZ)}(hjNh]hint ret}(hjNhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjNubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chM0hjNubj&*)}(hhh]h)}(h!owner's current futex lock statush]h#owner’s current futex lock status}(hjNhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjNhM0hjNubah}(h]h ]h"]h$]h&]uh1j%*hjNubeh}(h]h ]h"]h$]h&]uh1j*hjNhM0hjNubj*)}(h<``struct task_struct *exiting`` Pointer to the exiting task h](j *)}(h``struct task_struct *exiting``h]jZ)}(hj Oh]hstruct task_struct *exiting}(hj OhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj Oubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chM1hjOubj&*)}(hhh]h)}(hPointer to the exiting taskh]hPointer to the exiting task}(hj$OhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj OhM1hj!Oubah}(h]h ]h"]h$]h&]uh1j%*hjOubeh}(h]h ]h"]h$]h&]uh1j*hj OhM1hjNubeh}(h]h ]h"]h$]h&]uh1j*hjNubh)}(h**Description**h]j)}(hjFOh]h Description}(hjHOhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjDOubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chM3hjNubh)}(h+Caller must hold a refcount on **exiting**.h](hCaller must hold a refcount on }(hj\OhhhNhNubj)}(h **exiting**h]hexiting}(hjdOhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj\Oubh.}(hj\OhhhNhNubeh}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chM3hjNubeh}(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}(hjOhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjOhhho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMNubj,)}(h h]h }(hjOhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjOhhhjOhMNubje))}(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)hjOhhhjOhMNubj.,)}(h(struct futex_q *q)h]j4,)}(hstruct futex_q *qh](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))}(hfutex_qh]hfutex_q}(hjOhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjOubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjOmodnameN classnameNjj)}j](jNj)}jjOsbc.it_IT.__futex_unqueueesbuh1hhjOubj,)}(h h]h }(hjPhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjOubj,)}(hj,h]h*}(hj'PhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjOubjk))}(hqh]hq}(hj4PhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjOubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjOubah}(h]h ]h"]h$]h&]jTjUuh1j-,hjOhhhjOhMNubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjOhhhjOhMNubah}(h]jOah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjOhMNhjOhhubj))}(hhh]h)}(h-Remove the futex_q from its futex_hash_bucketh]h-Remove the futex_q from its futex_hash_bucket}(hj^PhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMNhj[Phhubah}(h]h ]h"]h$]h&]uh1j)hjOhhhjOhMNubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jvPj)jvPj)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)}(hjPh]h Parameters}(hjPhhhNhNubah}(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.chMRhjzPubj*)}(hhh]j*)}(h-``struct futex_q *q`` The futex_q to unqueue h](j *)}(h``struct futex_q *q``h]jZ)}(hjPh]hstruct futex_q *q}(hjPhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjPubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMOhjPubj&*)}(hhh]h)}(hThe futex_q to unqueueh]hThe futex_q to unqueue}(hjPhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjPhMOhjPubah}(h]h ]h"]h$]h&]uh1j%*hjPubeh}(h]h ]h"]h$]h&]uh1j*hjPhMOhjPubah}(h]h ]h"]h$]h&]uh1j*hjzPubh)}(h**Description**h]j)}(hjPh]h Description}(hjPhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjPubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMQhjzPubh)}(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.}(hjPhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMQhjzPubeh}(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}(hjQhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjQhhho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMubj,)}(h h]h }(hj.QhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjQhhhj-QhMubje))}(h futex_unqueueh]jk))}(h futex_unqueueh]h futex_unqueue}(hj@QhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjlock_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)}(hjRh]h Parameters}(hjRhhhNhNubah}(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*)}(h-``struct futex_q *q`` The futex_q to unqueue h](j *)}(h``struct futex_q *q``h]jZ)}(hj Rh]hstruct futex_q *q}(hj"RhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjRubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjRubj&*)}(hhh]h)}(hThe futex_q to unqueueh]hThe futex_q to unqueue}(hj9RhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj5RhMhj6Rubah}(h]h ]h"]h$]h&]uh1j%*hjRubeh}(h]h ]h"]h$]h&]uh1j*hj5RhMhjRubah}(h]h ]h"]h$]h&]uh1j*hjQubh)}(h**Description**h]j)}(hj[Rh]h Description}(hj]RhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjYRubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjQubh)}(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().}(hjqRhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjQubh)}(h **Return**h]j)}(hjRh]hReturn}(hjRhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjRubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjQubj))}(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)}(hjRh]hA1 - if the futex_q was still queued (and we removed unqueued it);}(hjRhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjRubah}(h]h ]h"]h$]h&]uh1jZ hjRubj[ )}(h;0 - if the futex_q was already removed by the waking threadh]h)}(hjRh]h;0 - if the futex_q was already removed by the waking thread}(hjRhhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjRubah}(h]h ]h"]h$]h&]uh1jZ hjRubeh}(h]h ]h"]h$]h&]j j uh1jU hjRhMhjRubah}(h]h ]h"]h$]h&]uh1j)hjRhMhjQubeh}(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}(hjRhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjRhhho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMubj,)}(h h]h }(hj ShhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjRhhhj ShMubje))}(hfutex_exit_recursiveh]jk))}(hfutex_exit_recursiveh]hfutex_exit_recursive}(hjShhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjSubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjRhhhj ShMubj.,)}(h(struct task_struct *tsk)h]j4,)}(hstruct task_struct *tskh](j:,)}(hj=,h]hstruct}(hj8ShhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hj4Subj,)}(h h]h }(hjEShhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj4Subh)}(hhh]jk))}(h task_structh]h task_struct}(hjVShhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjSSubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjXSmodnameN classnameNjj)}j](jNj)}jjSsbc.it_IT.futex_exit_recursiveesbuh1hhj4Subj,)}(h h]h }(hjwShhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj4Subj,)}(hj,h]h*}(hjShhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj4Subjk))}(htskh]htsk}(hjShhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj4Subeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj0Subah}(h]h ]h"]h$]h&]jTjUuh1j-,hjRhhhj ShMubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjRhhhj ShMubah}(h]jRah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hj ShMhjRhhubj))}(hhh]h)}(h-Set the tasks futex state to FUTEX_STATE_DEADh]h-Set the tasks futex state to FUTEX_STATE_DEAD}(hjShhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjShhubah}(h]h ]h"]h$]h&]uh1j)hjRhhhj ShMubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jSj)jSj)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)}(hjSh]h Parameters}(hjShhhNhNubah}(h]h ]h"]h$]h&]uh1jhjSubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjSubj*)}(hhh]j*)}(h5``struct task_struct *tsk`` task to set the state on h](j *)}(h``struct task_struct *tsk``h]jZ)}(hjSh]hstruct task_struct *tsk}(hjShhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjSubah}(h]h ]h"]h$]h&]uh1j *ho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjSubj&*)}(hhh]h)}(htask to set the state onh]htask to set the state on}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1hhjThMhjTubah}(h]h ]h"]h$]h&]uh1j%*hjSubeh}(h]h ]h"]h$]h&]uh1j*hjThMhjSubah}(h]h ]h"]h$]h&]uh1j*hjSubh)}(h**Description**h]j)}(hj8Th]h Description}(hj:ThhhNhNubah}(h]h ]h"]h$]h&]uh1jhj6Tubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjSubh)}(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.}(hjNThhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjSubh)}(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().}(hj]ThhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjSubh)}(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.}(hjlThhhNhNubah}(h]h ]h"]h$]h&]uh1hho/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1404: ./kernel/futex/core.chMhjSubeh}(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}(hjThhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjThhhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKubj,)}(h h]h }(hjThhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjThhhjThKubje))}(hfutex_qh]jk))}(hjTh]hfutex_q}(hjThhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjTubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjThhhjThKubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjThhhjThKubah}(h]jTah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjThKhjThhubj))}(hhh]h)}(h2The hashed futex queue entry, one per waiting taskh]h2The hashed futex queue entry, one per waiting task}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjThhubah}(h]h ]h"]h$]h&]uh1j)hjThhhjThKubeh}(h]h ](jstructeh"]h$]h&]j)jj)jTj)jTj)j)j)uh1jS)hhhj=hjThNubj))}(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; bool drop_hb_ref; #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() ``drop_hb_ref`` Waiter should drop the extra hash bucket reference if true ``requeue_wait`` RCU wait for futex_requeue_pi() (RT only)h](h)}(h**Definition**::h](j)}(h**Definition**h]h Definition}(hjUhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjTubh:}(hjThhhNhNubeh}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjTubjE)}(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; bool drop_hb_ref; #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; bool drop_hb_ref; #ifdef CONFIG_PREEMPT_RT; struct rcuwait requeue_wait; #endif; };}hjUsbah}(h]h ]h"]h$]h&]jTjUuh1jDhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjTubh)}(h **Members**h]j)}(hj,Uh]hMembers}(hj.UhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj*Uubah}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjTubj*)}(hhh](j*)}(h=``list`` priority-sorted list of tasks waiting on this futex h](j *)}(h``list``h]jZ)}(hjKUh]hlist}(hjMUhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjIUubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjEUubj&*)}(hhh]h)}(h3priority-sorted list of tasks waiting on this futexh]h3priority-sorted list of tasks waiting on this futex}(hjdUhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj`UhKhjaUubah}(h]h ]h"]h$]h&]uh1j%*hjEUubeh}(h]h ]h"]h$]h&]uh1j*hj`UhKhjBUubj*)}(h'``task`` the task waiting on the futex h](j *)}(h``task``h]jZ)}(hjUh]htask}(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.hhKhj~Uubj&*)}(hhh]h)}(hthe task waiting on the futexh]hthe task waiting on the futex}(hjUhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjUhKhjUubah}(h]h ]h"]h$]h&]uh1j%*hj~Uubeh}(h]h ]h"]h$]h&]uh1j*hjUhKhjBUubj*)}(h"``lock_ptr`` the hash bucket lock h](j *)}(h ``lock_ptr``h]jZ)}(hjUh]hlock_ptr}(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)}(hthe hash bucket lockh]hthe hash bucket lock}(hjUhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjUhKhjUubah}(h]h ]h"]h$]h&]uh1j%*hjUubeh}(h]h ]h"]h$]h&]uh1j*hjUhKhjBUubj*)}(h)``wake`` the wake handler for this queue h](j *)}(h``wake``h]jZ)}(hjUh]hwake}(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)}(hthe wake handler for this queueh]hthe wake handler for this queue}(hjVhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj VhKhj Vubah}(h]h ]h"]h$]h&]uh1j%*hjUubeh}(h]h ]h"]h$]h&]uh1j*hj VhKhjBUubj*)}(h4``wake_data`` data associated with the wake handler h](j *)}(h ``wake_data``h]jZ)}(hj/Vh]h wake_data}(hj1VhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj-Vubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhj)Vubj&*)}(hhh]h)}(h%data associated with the wake handlerh]h%data associated with the wake handler}(hjHVhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjDVhKhjEVubah}(h]h ]h"]h$]h&]uh1j%*hj)Vubeh}(h]h ]h"]h$]h&]uh1j*hjDVhKhjBUubj*)}(h'``key`` the key the futex is hashed on h](j *)}(h``key``h]jZ)}(hjhVh]hkey}(hjjVhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjfVubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjbVubj&*)}(hhh]h)}(hthe key the futex is hashed onh]hthe key the futex is hashed on}(hjVhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj}VhKhj~Vubah}(h]h ]h"]h$]h&]uh1j%*hjbVubeh}(h]h ]h"]h$]h&]uh1j*hj}VhKhjBUubj*)}(h1``pi_state`` optional priority inheritance state h](j *)}(h ``pi_state``h]jZ)}(hjVh]hpi_state}(hjVhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjVubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjVubj&*)}(hhh]h)}(h#optional priority inheritance stateh]h#optional priority inheritance state}(hjVhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjVhKhjVubah}(h]h ]h"]h$]h&]uh1j%*hjVubeh}(h]h ]h"]h$]h&]uh1j*hjVhKhjBUubj*)}(h8``rt_waiter`` rt_waiter storage for use with requeue_pi h](j *)}(h ``rt_waiter``h]jZ)}(hjVh]h rt_waiter}(hjVhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjVubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjVubj&*)}(hhh]h)}(h)rt_waiter storage for use with requeue_pih]h)rt_waiter storage for use with requeue_pi}(hjVhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjVhKhjVubah}(h]h ]h"]h$]h&]uh1j%*hjVubeh}(h]h ]h"]h$]h&]uh1j*hjVhKhjBUubj*)}(h3``requeue_pi_key`` the requeue_pi target futex key h](j *)}(h``requeue_pi_key``h]jZ)}(hjWh]hrequeue_pi_key}(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.hhKhj Wubj&*)}(hhh]h)}(hthe requeue_pi target futex keyh]hthe requeue_pi target futex key}(hj,WhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj(WhKhj)Wubah}(h]h ]h"]h$]h&]uh1j%*hj Wubeh}(h]h ]h"]h$]h&]uh1j*hj(WhKhjBUubj*)}(h4``bitset`` bitset for the optional bitmasked wakeup h](j *)}(h ``bitset``h]jZ)}(hjLWh]hbitset}(hjNWhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjJWubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjFWubj&*)}(hhh]h)}(h(bitset for the optional bitmasked wakeuph]h(bitset for the optional bitmasked wakeup}(hjeWhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjaWhKhjbWubah}(h]h ]h"]h$]h&]uh1j%*hjFWubeh}(h]h ]h"]h$]h&]uh1j*hjaWhKhjBUubj*)}(h5``requeue_state`` State field for futex_requeue_pi() h](j *)}(h``requeue_state``h]jZ)}(hjWh]h requeue_state}(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)}(h"State field for futex_requeue_pi()h]h"State field for futex_requeue_pi()}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjWhKhjWubah}(h]h ]h"]h$]h&]uh1j%*hjWubeh}(h]h ]h"]h$]h&]uh1j*hjWhKhjBUubj*)}(hK``drop_hb_ref`` Waiter should drop the extra hash bucket reference if true h](j *)}(h``drop_hb_ref``h]jZ)}(hjWh]h drop_hb_ref}(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)}(h:Waiter should drop the extra hash bucket reference if trueh]h:Waiter should drop the extra hash bucket reference if true}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjWhKhjWubah}(h]h ]h"]h$]h&]uh1j%*hjWubeh}(h]h ]h"]h$]h&]uh1j*hjWhKhjBUubj*)}(h:``requeue_wait`` RCU wait for futex_requeue_pi() (RT only)h](j *)}(h``requeue_wait``h]jZ)}(hjWh]h requeue_wait}(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)}(h)RCU wait for futex_requeue_pi() (RT only)h]h)RCU wait for futex_requeue_pi() (RT only)}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhj Xubah}(h]h ]h"]h$]h&]uh1j%*hjWubeh}(h]h ]h"]h$]h&]uh1j*hj XhKhjBUubeh}(h]h ]h"]h$]h&]uh1j*hjTubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhjThNubh)}(h**Description**h]j)}(hj:Xh]h Description}(hjlist `) || 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(}(hj_XhhhNhNubh)}(h:c:type:`q->list `h]jZ)}(hjiXh]hq->list}(hjkXhhhNhNubah}(h]h ](hjc-typeeh"]h$]h&]uh1jYhjgXubah}(h]h ]h"]h$]h&]refdochΌ refdomainjreftypetype refexplicitrefwarnjjhj6Puh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhj_Xubhg) || q->lock_ptr == 0. The order of wakeup is always to make the first condition true, then the second.}(hj_XhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjXhKhj=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().}(hjXhhhNhNubah}(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=hhhjThNubjT))}(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}(hjXhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjXhhhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKubj,)}(h h]h }(hjXhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjXhhhjXhKubje))}(h futex_matchh]jk))}(h futex_matchh]h futex_match}(hjXhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjXubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjXhhhjXhKubj.,)}(h.(union futex_key *key1, union futex_key *key2)h](j4,)}(hunion futex_key *key1h](j:,)}(hj@h]hunion}(hjXhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjXubj,)}(h h]h }(hjYhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjXubh)}(hhh]jk))}(h futex_keyh]h futex_key}(hjYhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjYubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjYmodnameN classnameNjj)}j](jNj)}jjXsbc.it_IT.futex_matchesbuh1hhjXubj,)}(h h]h }(hj4YhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjXubj,)}(hj,h]h*}(hjBYhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjXubjk))}(hkey1h]hkey1}(hjOYhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjXubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjXubj4,)}(hunion futex_key *key2h](j:,)}(hj@h]hunion}(hjhYhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjdYubj,)}(h h]h }(hjuYhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjdYubh)}(hhh]jk))}(h futex_keyh]h futex_key}(hjYhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjYubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjYmodnameN classnameNjj)}j](jNj0Yc.it_IT.futex_matchesbuh1hhjdYubj,)}(h h]h }(hjYhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjdYubj,)}(hj,h]h*}(hjYhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjdYubjk))}(hkey2h]hkey2}(hjYhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjdYubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjXubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hjXhhhjXhKubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjXhhhjXhKubah}(h]jXah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjXhKhjXhhubj))}(hhh]h)}(h&Check whether two futex keys are equalh]h&Check whether two futex keys are equal}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjYhhubah}(h]h ]h"]h$]h&]uh1j)hjXhhhjXhKubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jZj)jZj)j)j)uh1jS)hhhj=hjThNubj))}(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)}(hj Zh]h Parameters}(hjZhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj Zubah}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjZubj*)}(hhh](j*)}(h*``union futex_key *key1`` Pointer to key1 h](j *)}(h``union futex_key *key1``h]jZ)}(hj+Zh]hunion futex_key *key1}(hj-ZhhhNhNubah}(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.hhKhj%Zubj&*)}(hhh]h)}(hPointer to key1h]hPointer to key1}(hjDZhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj@ZhKhjAZubah}(h]h ]h"]h$]h&]uh1j%*hj%Zubeh}(h]h ]h"]h$]h&]uh1j*hj@ZhKhj"Zubj*)}(h*``union futex_key *key2`` Pointer to key2 h](j *)}(h``union futex_key *key2``h]jZ)}(hjdZh]hunion futex_key *key2}(hjfZhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjbZubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhj^Zubj&*)}(hhh]h)}(hPointer to key2h]hPointer to key2}(hj}ZhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjyZhKhjzZubah}(h]h ]h"]h$]h&]uh1j%*hj^Zubeh}(h]h ]h"]h$]h&]uh1j*hjyZhKhj"Zubeh}(h]h ]h"]h$]h&]uh1j*hjZubh)}(h**Description**h]j)}(hjZh]h Description}(hjZhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjZubah}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjZubh)}(h2Return 1 if two futex_keys are equal, 0 otherwise.h]h2Return 1 if two futex_keys are equal, 0 otherwise.}(hjZhhhNhNubah}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhKhjZubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhjThNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)it_IT.futex_queue (C function)c.it_IT.futex_queuehNtauh1jB)hj=hhhjThNubjT))}(hhh](jY))}(h\void futex_queue (struct futex_q *q, struct futex_hash_bucket *hb, struct task_struct *task)h]j_))}(h[void futex_queue(struct futex_q *q, struct futex_hash_bucket *hb, struct task_struct *task)h](j+)}(hvoidh]hvoid}(hjZhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjZhhhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhM_ubj,)}(h h]h }(hjZhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjZhhhjZhM_ubje))}(h futex_queueh]jk))}(h futex_queueh]h futex_queue}(hj[hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj[ubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjZhhhjZhM_ubj.,)}(hK(struct futex_q *q, struct futex_hash_bucket *hb, struct task_struct *task)h](j4,)}(hstruct futex_q *qh](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_qh]hfutex_q}(hj?[hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj<[ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjA[modnameN classnameNjj)}j](jNj)}jj[sbc.it_IT.futex_queueesbuh1hhj[ubj,)}(h h]h }(hj`[hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj[ubj,)}(hj,h]h*}(hjn[hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj[ubjk))}(hj6Ph]hq}(hj{[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_queueesbuh1hhj[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,)}(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_queueesbuh1hhj\ubj,)}(h h]h }(hjA\hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj\ubj,)}(hj,h]h*}(hjO\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[ubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hjZhhhjZhM_ubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjZhhhjZhM_ubah}(h]jZah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjZhM_hjZhhubj))}(hhh]h)}(h,Enqueue the futex_q on the futex_hash_bucketh]h,Enqueue the futex_q on the futex_hash_bucket}(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\hhubah}(h]h ]h"]h$]h&]uh1j)hjZhhhjZhM_ubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)j\j)j\j)j)j)uh1jS)hhhj=hjThNubj))}(hX**Parameters** ``struct futex_q *q`` The futex_q to enqueue ``struct futex_hash_bucket *hb`` The destination hash bucket ``struct task_struct *task`` Task queueing this futex **Description** The 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). Note that **task** may be NULL, for async usage of futexes.h](h)}(h**Parameters**h]j)}(hj\h]h Parameters}(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.hhMchj\ubj*)}(hhh](j*)}(h-``struct futex_q *q`` The futex_q to enqueue h](j *)}(h``struct futex_q *q``h]jZ)}(hj\h]hstruct futex_q *q}(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.hhM`hj\ubj&*)}(hhh]h)}(hThe futex_q to enqueueh]hThe futex_q to enqueue}(hj\hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj\hM`hj\ubah}(h]h ]h"]h$]h&]uh1j%*hj\ubeh}(h]h ]h"]h$]h&]uh1j*hj\hM`hj\ubj*)}(h=``struct futex_hash_bucket *hb`` The destination 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 *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhMahj\ubj&*)}(hhh]h)}(hThe destination hash bucketh]hThe destination hash bucket}(hj]hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj]hMahj]ubah}(h]h ]h"]h$]h&]uh1j%*hj\ubeh}(h]h ]h"]h$]h&]uh1j*hj]hMahj\ubj*)}(h6``struct task_struct *task`` Task queueing this futex h](j *)}(h``struct task_struct *task``h]jZ)}(hj9]h]hstruct task_struct *task}(hj;]hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj7]ubah}(h]h ]h"]h$]h&]uh1j *hp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhMbhj3]ubj&*)}(hhh]h)}(hTask queueing this futexh]hTask queueing this futex}(hjR]hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjN]hMbhjO]ubah}(h]h ]h"]h$]h&]uh1j%*hj3]ubeh}(h]h ]h"]h$]h&]uh1j*hjN]hMbhj\ubeh}(h]h ]h"]h$]h&]uh1j*hj\ubh)}(h**Description**h]j)}(hjt]h]h Description}(hjv]hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjr]ubah}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhMdhj\ubh)}(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.hhMdhj\ubh)}(h;Note that **task** may be NULL, for async usage of futexes.h](h Note that }(hj]hhhNhNubj)}(h**task**h]htask}(hj]hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj]ubh) may be NULL, for async usage of futexes.}(hj]hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhMkhj\ubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhjThNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)it_IT.futex_vector (C struct)c.it_IT.futex_vectorhNtauh1jB)hj=hhhjThNubjT))}(hhh](jY))}(h futex_vectorh]j_))}(hstruct futex_vectorh](j:,)}(hj=,h]hstruct}(hj]hhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hj]hhhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhMpubj,)}(h h]h }(hj]hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj]hhhj]hMpubje))}(h futex_vectorh]jk))}(hj]h]h futex_vector}(hj]hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj]ubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hj]hhhj]hMpubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj]hhhj]hMpubah}(h]j]ah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hj]hMphj]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)hj]hhhj]hMpubeh}(h]h ](jstructeh"]h$]h&]j)jj)j4^j)j4^j)j)j)uh1jS)hhhj=hjThNubj))}(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.hhMhj8^ubjE)}(hHstruct futex_vector { struct futex_waitv w; struct futex_q q; };h]hHstruct futex_vector { struct futex_waitv w; struct futex_q q; };}hjY^sbah}(h]h ]h"]h$]h&]jTjUuh1jDhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhMhj8^ubh)}(h **Members**h]j)}(hjj^h]hMembers}(hjl^hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjh^ubah}(h]h ]h"]h$]h&]uh1hhp/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1407: ./kernel/futex/futex.hhMhj8^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&]uh1hhj^hMhj^ubah}(h]h ]h"]h$]h&]uh1j%*hj^ubeh}(h]h ]h"]h$]h&]uh1j*hj^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.hhMhj^ubj&*)}(hhh]h)}(hKernel side datah]hKernel side data}(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^ubah}(h]h ]h"]h$]h&]uh1j%*hj^ubeh}(h]h ]h"]h$]h&]uh1j*hj^hMhj^ubeh}(h]h ]h"]h$]h&]uh1j*hj8^ubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhjThNubh)}(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}(hjC_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 }(hjR_hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj?_hhhjQ_hMubje))}(hfutex_lock_pi_atomich]jk))}(hfutex_lock_pi_atomich]hfutex_lock_pi_atomic}(hjd_hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj`_ubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hj?_hhhjQ_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)}jjf_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 }(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))}(huaddrh]huaddr}(hj_hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj|_ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjx_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*}(hj5`hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj_ubjk))}(hhbh]hhb}(hjB`hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj_ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjx_ubj4,)}(hunion futex_key *keyh](j:,)}(hj@h]hunion}(hj[`hhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjW`ubj,)}(h h]h }(hjh`hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjW`ubh)}(hhh]jk))}(h futex_keyh]h futex_key}(hjy`hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjv`ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj{`modnameN classnameNjj)}j](jNj_c.it_IT.futex_lock_pi_atomicesbuh1hhjW`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))}(hkeyh]hkey}(hj`hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjW`ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjx_ubj4,)}(hstruct futex_pi_state **psh](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_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_atomicesbuh1hhj`ubj,)}(h h]h }(hj ahhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj`ubj,)}(hj,h]h*}(hjahhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj`ubj,)}(hj,h]h*}(hj$ahhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj`ubjk))}(hpsh]hps}(hj1ahhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj`ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjx_ubj4,)}(hstruct task_struct *taskh](j:,)}(hj=,h]hstruct}(hjJahhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjFaubj,)}(h h]h }(hjWahhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjFaubh)}(hhh]jk))}(h task_structh]h task_struct}(hjhahhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjeaubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjjamodnameN classnameNjj)}j](jNj_c.it_IT.futex_lock_pi_atomicesbuh1hhjFaubj,)}(h h]h }(hjahhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjFaubj,)}(hj,h]h*}(hjahhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjFaubjk))}(htaskh]htask}(hjahhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjFaubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjx_ubj4,)}(hstruct task_struct **exitingh](j:,)}(hj=,h]hstruct}(hjahhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjaubj,)}(h h]h }(hjahhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjaubh)}(hhh]jk))}(h task_structh]h task_struct}(hjahhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjaubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjamodnameN classnameNjj)}j](jNj_c.it_IT.futex_lock_pi_atomicesbuh1hhjaubj,)}(h h]h }(hjahhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjaubj,)}(hj,h]h*}(hjbhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjaubj,)}(hj,h]h*}(hjbhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjaubjk))}(hexitingh]hexiting}(hj bhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjaubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjx_ubj4,)}(hint set_waitersh](j+)}(hinth]hint}(hj9bhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hj5bubj,)}(h h]h }(hjGbhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj5bubjk))}(h set_waitersh]h set_waiters}(hjUbhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj5bubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjx_ubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hj?_hhhjQ_hMubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj;_hhhjQ_hMubah}(h]j6_ah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjQ_hMhj8_hhubj))}(hhh]h)}(h0Atomic work required to acquire a pi aware futexh]h0Atomic work required to acquire a pi aware futex}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1hhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhj|bhhubah}(h]h ]h"]h$]h&]uh1j)hj8_hhhjQ_hMubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jbj)jbj)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)}(hjbh]h Parameters}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjbubah}(h]h ]h"]h$]h&]uh1hhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhjbubj*)}(hhh](j*)}(h0``u32 __user *uaddr`` the pi futex user address h](j *)}(h``u32 __user *uaddr``h]jZ)}(hjbh]hu32 __user *uaddr}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjbubah}(h]h ]h"]h$]h&]uh1j *hm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhjbubj&*)}(hhh]h)}(hthe pi futex user addressh]hthe pi futex user address}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjbhMhjbubah}(h]h ]h"]h$]h&]uh1j%*hjbubeh}(h]h ]h"]h$]h&]uh1j*hjbhMhjbubj*)}(h:``struct futex_hash_bucket *hb`` the pi futex hash bucket h](j *)}(h ``struct futex_hash_bucket *hb``h]jZ)}(hjbh]hstruct futex_hash_bucket *hb}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjbubah}(h]h ]h"]h$]h&]uh1j *hm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhjbubj&*)}(hhh]h)}(hthe pi futex hash bucketh]hthe pi futex hash bucket}(hjchhhNhNubah}(h]h ]h"]h$]h&]uh1hhjchMhjcubah}(h]h ]h"]h$]h&]uh1j%*hjbubeh}(h]h ]h"]h$]h&]uh1j*hjchMhjbubj*)}(hD``union futex_key *key`` the futex key associated with uaddr and hb h](j *)}(h``union futex_key *key``h]jZ)}(hj2ch]hunion futex_key *key}(hj4chhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj0cubah}(h]h ]h"]h$]h&]uh1j *hm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhj,cubj&*)}(hhh]h)}(h*the futex key associated with uaddr and hbh]h*the futex key associated with uaddr and hb}(hjKchhhNhNubah}(h]h ]h"]h$]h&]uh1hhjGchMhjHcubah}(h]h ]h"]h$]h&]uh1j%*hj,cubeh}(h]h ]h"]h$]h&]uh1j*hjGchMhjbubj*)}(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)}(hjkch]hstruct futex_pi_state **ps}(hjmchhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjicubah}(h]h ]h"]h$]h&]uh1j *hm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhjecubj&*)}(hhh]h)}(hlock must be held by the caller.h]h(The hb->lock must be held by the caller.}(hjdhhhNhNubah}(h]h ]h"]h$]h&]uh1hhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhjbubh)}(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}(hjdhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjdubh 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.}(hjdhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMhjbubeh}(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}(hj*ehhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hj&ehhhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMZubj,)}(h h]h }(hj9ehhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj&ehhhj8ehMZubje))}(hfixup_pi_ownerh]jk))}(hfixup_pi_ownerh]hfixup_pi_owner}(hjKehhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjGeubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hj&ehhhj8ehMZubj.,)}(h2(u32 __user *uaddr, struct futex_q *q, int locked)h](j4,)}(hu32 __user *uaddrh](h)}(hhh]jk))}(hu32h]hu32}(hjjehhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjgeubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjlemodnameN classnameNjj)}j](jNj)}jjMesbc.it_IT.fixup_pi_owneresbuh1hhjceubj,)}(h h]h }(hjehhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjceubh__user}(hjcehhhNhNubj,)}(h h]h }(hjehhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjceubj,)}(hj,h]h*}(hjehhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjceubjk))}(huaddrh]huaddr}(hjehhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjceubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj_eubj4,)}(hstruct futex_q *qh](j:,)}(hj=,h]hstruct}(hjehhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjeubj,)}(h h]h }(hjehhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjeubh)}(hhh]jk))}(hfutex_qh]hfutex_q}(hjehhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjeubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjemodnameN classnameNjj)}j](jNjec.it_IT.fixup_pi_owneresbuh1hhjeubj,)}(h h]h }(hjfhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjeubj,)}(hj,h]h*}(hjfhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjeubjk))}(hj6Ph]hq}(hj)fhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjeubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj_eubj4,)}(h int lockedh](j+)}(hinth]hint}(hjAfhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hj=fubj,)}(h h]h }(hjOfhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj=fubjk))}(hlockedh]hlocked}(hj]fhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj=fubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj_eubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hj&ehhhj8ehMZubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj"ehhhj8ehMZubah}(h]jeah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hj8ehMZhjehhubj))}(hhh]h)}(h-Post lock pi_state and corner case managementh]h-Post lock pi_state and corner case management}(hjfhhhNhNubah}(h]h ]h"]h$]h&]uh1hhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chMZhjfhhubah}(h]h ]h"]h$]h&]uh1j)hjehhhj8ehMZubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jfj)jfj)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)}(hjfh]h Parameters}(hjfhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjfubah}(h]h ]h"]h$]h&]uh1hhm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chM^hjfubj*)}(hhh](j*)}(h0``u32 __user *uaddr`` user address of the futex h](j *)}(h``u32 __user *uaddr``h]jZ)}(hjfh]hu32 __user *uaddr}(hjfhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjfubah}(h]h ]h"]h$]h&]uh1j *hm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chM[hjfubj&*)}(hhh]h)}(huser address of the futexh]huser address of the futex}(hjfhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjfhM[hjfubah}(h]h ]h"]h$]h&]uh1j%*hjfubeh}(h]h ]h"]h$]h&]uh1j*hjfhM[hjfubj*)}(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)}(hjgh]hstruct futex_q *q}(hjghhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjfubah}(h]h ]h"]h$]h&]uh1j *hm/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1410: ./kernel/futex/pi.chM\hjfubj&*)}(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)}(hjghhhNhNubah}(h]h ]h"]h$]h&]uh1hhjghM\hjgubah}(h]h ]h"]h$]h&]uh1j%*hjfubeh}(h]h ]h"]h$]h&]uh1j*hjghM\hjfubj*)}(hL``int locked`` if the attempt to take the rt_mutex succeeded (1) or not (0) h](j *)}(h``int locked``h]jZ)}(hj:gh]h int locked}(hj``union futex_key *key2`` the new key for the requeued futex_qh](j *)}(h``union futex_key *key2``h]jZ)}(hj,kh]hunion futex_key *key2}(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.chKJhj&kubj&*)}(hhh]h)}(h$the new key for the requeued futex_qh]h$the new key for the requeued futex_q}(hjEkhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKIhjBkubah}(h]h ]h"]h$]h&]uh1j%*hj&kubeh}(h]h ]h"]h$]h&]uh1j*hjAkhKJhjxjubeh}(h]h ]h"]h$]h&]uh1j*hj\jubeh}(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}(hjkhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjkhhhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKubj,)}(h h]h }(hjkhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjkhhhjkhKubje))}(hrequeue_pi_wake_futexh]jk))}(hrequeue_pi_wake_futexh]hrequeue_pi_wake_futex}(hjkhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjkubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjkhhhjkhKubj.,)}(hG(struct futex_q *q, union futex_key *key, struct futex_hash_bucket *hb)h](j4,)}(hstruct futex_q *qh](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))}(hfutex_qh]hfutex_q}(hjkhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjkubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjkmodnameN classnameNjj)}j](jNj)}jjksbc.it_IT.requeue_pi_wake_futexesbuh1hhjkubj,)}(h h]h }(hjlhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjkubj,)}(hj,h]h*}(hjlhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjkubjk))}(hj6Ph]hq}(hjlhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjkubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjkubj4,)}(hunion futex_key *keyh](j:,)}(hj@h]hunion}(hj5lhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hj1lubj,)}(h h]h }(hjBlhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj1lubh)}(hhh]jk))}(h futex_keyh]h futex_key}(hjSlhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjPlubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjUlmodnameN classnameNjj)}j](jNjkc.it_IT.requeue_pi_wake_futexesbuh1hhj1lubj,)}(h h]h }(hjrlhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj1lubj,)}(hj,h]h*}(hjlhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj1lubjk))}(hkeyh]hkey}(hjlhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj1lubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjkubj4,)}(hstruct futex_hash_bucket *hbh](j:,)}(hj=,h]hstruct}(hjlhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjlubj,)}(h h]h }(hjlhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjlubh)}(hhh]jk))}(hfutex_hash_bucketh]hfutex_hash_bucket}(hjlhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjlubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjlmodnameN classnameNjj)}j](jNjkc.it_IT.requeue_pi_wake_futexesbuh1hhjlubj,)}(h h]h }(hjlhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjlubj,)}(hj,h]h*}(hjlhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjlubjk))}(hhbh]hhb}(hjlhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjlubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjkubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hjkhhhjkhKubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj~khhhjkhKubah}(h]jykah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjkhKhj{khhubj))}(hhh]h)}(h1Wake a task that acquired the lock during requeueh]h1Wake a task that acquired the lock during requeue}(hj(mhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhj%mhhubah}(h]h ]h"]h$]h&]uh1j)hj{khhhjkhKubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)j@mj)j@mj)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)}(hjJmh]h Parameters}(hjLmhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHmubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjDmubj*)}(hhh](j*)}(h"``struct futex_q *q`` the futex_q h](j *)}(h``struct futex_q *q``h]jZ)}(hjimh]hstruct futex_q *q}(hjkmhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjgmubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjcmubj&*)}(hhh]h)}(h the futex_qh]h the futex_q}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj~mhKhjmubah}(h]h ]h"]h$]h&]uh1j%*hjcmubeh}(h]h ]h"]h$]h&]uh1j*hj~mhKhj`mubj*)}(h=``union futex_key *key`` the key of the requeue target futex h](j *)}(h``union futex_key *key``h]jZ)}(hjmh]hunion futex_key *key}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjmubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjmubj&*)}(hhh]h)}(h#the key of the requeue target futexh]h#the key of the requeue target futex}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjmhKhjmubah}(h]h ]h"]h$]h&]uh1j%*hjmubeh}(h]h ]h"]h$]h&]uh1j*hjmhKhj`mubj*)}(hM``struct futex_hash_bucket *hb`` the hash_bucket of the requeue target futex h](j *)}(h ``struct futex_hash_bucket *hb``h]jZ)}(hjmh]hstruct futex_hash_bucket *hb}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjmubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjmubj&*)}(hhh]h)}(h+the hash_bucket of the requeue target futexh]h+the hash_bucket of the requeue target futex}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjmhKhjmubah}(h]h ]h"]h$]h&]uh1j%*hjmubeh}(h]h ]h"]h$]h&]uh1j*hjmhKhj`mubeh}(h]h ]h"]h$]h&]uh1j*hjDmubh)}(h**Description**h]j)}(hjnh]h Description}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjnubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjDmubh)}(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.}(hj,nhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjDmubhenumerated_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 }(hjDnhhhNhNubj)}(h**q**h]hq}(hjLnhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjDnubh]::key to the requeue target futex key so the waiter can detect the wakeup on the right futex.}(hjDnhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhj@nubah}(h]h ]h"]h$]h&]uh1jZ hj=nubj[ )}(h$Dequeue **q** from the hash bucket. h]h)}(h#Dequeue **q** from the hash bucket.h](hDequeue }(hjonhhhNhNubj)}(h**q**h]hq}(hjwnhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjonubh from the hash bucket.}(hjonhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjknubah}(h]h ]h"]h$]h&]uh1jZ hj=nubj[ )}(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 }(hjnhhhNhNubj)}(h**q**h]hq}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjnubhL::rt_waiter to NULL so the woken up task can detect atomic lock acquisition.}(hjnhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjnubah}(h]h ]h"]h$]h&]uh1jZ hj=nubj[ )}(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.}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjnubah}(h]h ]h"]h$]h&]uh1jZ hj=nubj[ )}(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.}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjnubah}(h]h ]h"]h$]h&]uh1jZ hj=nubj[ )}(hWake the waiter task. h]h)}(hWake the waiter task.h]hWake the waiter task.}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjnubah}(h]h ]h"]h$]h&]uh1jZ hj=nubeh}(h]h ]h"]h$]h&]enumtypearabicprefixhsuffix)uh1j;nhjDmubh)}(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.}(hjohhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjDmubeh}(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}(hjFohhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjBohhhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKubj,)}(h h]h }(hjUohhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjBohhhjTohKubje))}(hfutex_proxy_trylock_atomich]jk))}(hfutex_proxy_trylock_atomich]hfutex_proxy_trylock_atomic}(hjgohhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjcoubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjBohhhjTohKubj.,)}(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}(hjohhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjoubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjomodnameN classnameNjj)}j](jNj)}jjiosb"c.it_IT.futex_proxy_trylock_atomicesbuh1hhjoubj,)}(h h]h }(hjohhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjoubh__user}(hjohhhNhNubj,)}(h h]h }(hjohhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjoubj,)}(hj,h]h*}(hjohhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjoubjk))}(hpifutexh]hpifutex}(hjohhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjoubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj{oubj4,)}(hstruct futex_hash_bucket *hb1h](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))}(hfutex_hash_bucketh]hfutex_hash_bucket}(hj phhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjpubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj pmodnameN classnameNjj)}j](jNjo"c.it_IT.futex_proxy_trylock_atomicesbuh1hhjoubj,)}(h h]h }(hj*phhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjoubj,)}(hj,h]h*}(hj8phhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjoubjk))}(hhb1h]hhb1}(hjEphhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjoubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj{oubj4,)}(hstruct futex_hash_bucket *hb2h](j:,)}(hj=,h]hstruct}(hj^phhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjZpubj,)}(h h]h }(hjkphhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjZpubh)}(hhh]jk))}(hfutex_hash_bucketh]hfutex_hash_bucket}(hj|phhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjypubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj~pmodnameN classnameNjj)}j](jNjo"c.it_IT.futex_proxy_trylock_atomicesbuh1hhjZpubj,)}(h h]h }(hjphhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjZpubj,)}(hj,h]h*}(hjphhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjZpubjk))}(hhb2h]hhb2}(hjphhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjZpubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj{oubj4,)}(hunion futex_key *key1h](j:,)}(hj@h]hunion}(hjphhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjpubj,)}(h h]h }(hjphhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjpubh)}(hhh]jk))}(h futex_keyh]h futex_key}(hjphhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjpubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjpmodnameN classnameNjj)}j](jNjo"c.it_IT.futex_proxy_trylock_atomicesbuh1hhjpubj,)}(h h]h }(hj qhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjpubj,)}(hj,h]h*}(hjqhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjpubjk))}(hkey1h]hkey1}(hj'qhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjpubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj{oubj4,)}(hunion futex_key *key2h](j:,)}(hj@h]hunion}(hj@qhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjohhhjTohKubah}(h]j9oah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjTohKhj;ohhubj))}(hhh]h)}(h)Attempt an atomic lock for the top waiterh]h)Attempt an atomic lock for the top waiter}(hjrhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjrhhubah}(h]h ]h"]h$]h&]uh1j)hj;ohhhjTohKubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)j sj)j sj)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)}(hjsh]h Parameters}(hjshhhNhNubah}(h]h ]h"]h$]h&]uh1jhjsubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjsubj*)}(hhh](j*)}(h9``u32 __user *pifutex`` the user address of the to futex h](j *)}(h``u32 __user *pifutex``h]jZ)}(hj4sh]hu32 __user *pifutex}(hj6shhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj2subah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhj.subj&*)}(hhh]h)}(h the user address of the to futexh]h the user address of the to futex}(hjMshhhNhNubah}(h]h ]h"]h$]h&]uh1hhjIshKhjJsubah}(h]h ]h"]h$]h&]uh1j%*hj.subeh}(h]h ]h"]h$]h&]uh1j*hjIshKhj+subj*)}(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)}(hjmsh]hstruct futex_hash_bucket *hb1}(hjoshhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjksubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chKhjgsubj&*)}(hhh]h)}(h8the from futex hash bucket, must be locked by the callerh]h8the from futex hash bucket, must be locked by the caller}(hjshhhNhNubah}(h]h ]h"]h$]h&]uh1hhjshKhjsubah}(h]h ]h"]h$]h&]uh1j%*hjgsubeh}(h]h ]h"]h$]h&]uh1j*hjshKhj+subj*)}(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)}(hjsh]hstruct futex_hash_bucket *hb2}(hjshhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjsubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjsubj&*)}(hhh]h)}(h6the to futex hash bucket, must be locked by the callerh]h6the to futex hash bucket, must be locked by the caller}(hjshhhNhNubah}(h]h ]h"]h$]h&]uh1hhjshMhjsubah}(h]h ]h"]h$]h&]uh1j%*hjsubeh}(h]h ]h"]h$]h&]uh1j*hjshMhj+subj*)}(h-``union futex_key *key1`` the from futex key h](j *)}(h``union futex_key *key1``h]jZ)}(hjsh]hunion futex_key *key1}(hjshhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjsubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjsubj&*)}(hhh]h)}(hthe from futex keyh]hthe from futex key}(hjshhhNhNubah}(h]h ]h"]h$]h&]uh1hhjshMhjsubah}(h]h ]h"]h$]h&]uh1j%*hjsubeh}(h]h ]h"]h$]h&]uh1j*hjshMhj+subj*)}(h+``union futex_key *key2`` the to futex key h](j *)}(h``union futex_key *key2``h]jZ)}(hjth]hunion futex_key *key2}(hjthhhNhNubah}(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.chMhjtubj&*)}(hhh]h)}(hthe to futex keyh]hthe to futex key}(hj1thhhNhNubah}(h]h ]h"]h$]h&]uh1hhj-thMhj.tubah}(h]h ]h"]h$]h&]uh1j%*hjtubeh}(h]h ]h"]h$]h&]uh1j*hj-thMhj+subj*)}(hE``struct futex_pi_state **ps`` address to store the pi_state pointer h](j *)}(h``struct futex_pi_state **ps``h]jZ)}(hjQth]hstruct futex_pi_state **ps}(hjSthhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjOtubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjKtubj&*)}(hhh]h)}(h%address to store the pi_state pointerh]h%address to store the pi_state pointer}(hjjthhhNhNubah}(h]h ]h"]h$]h&]uh1hhjfthMhjgtubah}(h]h ]h"]h$]h&]uh1j%*hjKtubeh}(h]h ]h"]h$]h&]uh1j*hjfthMhj+subj*)}(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)}(hjth]hstruct task_struct **exiting}(hjthhhNhNubah}(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.chMhjtubj&*)}(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}(hjthhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjtubah}(h]h ]h"]h$]h&]uh1j%*hjtubeh}(h]h ]h"]h$]h&]uh1j*hjthMhj+subj*)}(hG``int set_waiters`` force setting the FUTEX_WAITERS bit (1) or not (0) h](j *)}(h``int set_waiters``h]jZ)}(hjth]hint set_waiters}(hjthhhNhNubah}(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.chMhjtubj&*)}(hhh]h)}(h2force setting the FUTEX_WAITERS bit (1) or not (0)h]h2force setting the FUTEX_WAITERS bit (1) or not (0)}(hjthhhNhNubah}(h]h ]h"]h$]h&]uh1hhjthMhjtubah}(h]h ]h"]h$]h&]uh1j%*hjtubeh}(h]h ]h"]h$]h&]uh1j*hjthMhj+subeh}(h]h ]h"]h$]h&]uh1j*hjsubh)}(h**Description**h]j)}(hjth]h Description}(hjuhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjtubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjsubh)}(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.}(hjuhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjsubh)}(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}(hj(uhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj$uubh 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.}(hj$uhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chM hjsubh)}(h **Return**h]j)}(hjCuh]hReturn}(hjEuhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjAuubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjsubj))}(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)}(hjbuh]h*0 - failed to acquire the lock atomically;}(hjduhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhj`uubah}(h]h ]h"]h$]h&]uh1jZ hj]uubj[ )}(h>>0 - acquired the lock, return value is vpid of the top_waiterh]h)}(hjzuh]h>>0 - acquired the lock, return value is vpid of the top_waiter}(hj|uhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjxuubah}(h]h ]h"]h$]h&]uh1jZ hj]uubj[ )}(h <0 - errorh]h)}(hjuh]h <0 - error}(hjuhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjuubah}(h]h ]h"]h$]h&]uh1jZ hj]uubeh}(h]h ]h"]h$]h&]j j uh1jU hjquhMhjYuubah}(h]h ]h"]h$]h&]uh1j)hjquhMhjsubeh}(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}(hjuhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjuhhhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMgubj,)}(h h]h }(hjuhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjuhhhjuhMgubje))}(h futex_requeueh]jk))}(h futex_requeueh]h futex_requeue}(hjuhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjuubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjuhhhjuhMgubj.,)}(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}(hjvhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjvubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjvmodnameN classnameNjj)}j](jNj)}jjusbc.it_IT.futex_requeueesbuh1hhj vubj,)}(h h]h }(hj5vhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj vubh__user}(hj vhhhNhNubj,)}(h h]h }(hjGvhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj vubj,)}(hj,h]h*}(hjUvhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj vubjk))}(huaddr1h]huaddr1}(hjbvhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj vubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj vubj4,)}(hunsigned int flags1h](j+)}(hunsignedh]hunsigned}(hj{vhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjwvubj,)}(h h]h }(hjvhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjwvubj+)}(hinth]hint}(hjvhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjwvubj,)}(h h]h }(hjvhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjwvubjk))}(hflags1h]hflags1}(hjvhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjwvubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj vubj4,)}(hu32 __user *uaddr2h](h)}(hhh]jk))}(hu32h]hu32}(hjvhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjvubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjvmodnameN classnameNjj)}j](jNj1vc.it_IT.futex_requeueesbuh1hhjvubj,)}(h h]h }(hjvhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjvubh__user}(hjvhhhNhNubj,)}(h h]h }(hjwhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjvubj,)}(hj,h]h*}(hjwhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjvubjk))}(huaddr2h]huaddr2}(hjwhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjvubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj vubj4,)}(hunsigned int flags2h](j+)}(hunsignedh]hunsigned}(hj4whhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hj0wubj,)}(h h]h }(hjBwhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj0wubj+)}(hinth]hint}(hjPwhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hj0wubj,)}(h h]h }(hj^whhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj0wubjk))}(hflags2h]hflags2}(hjlwhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj0wubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj vubj4,)}(h int nr_wakeh](j+)}(hinth]hint}(hjwhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjwubj,)}(h h]h }(hjwhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjwubjk))}(hnr_wakeh]hnr_wake}(hjwhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjwubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj vubj4,)}(hint nr_requeueh](j+)}(hinth]hint}(hjwhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjwubj,)}(h h]h }(hjwhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjwubjk))}(h nr_requeueh]h nr_requeue}(hjwhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjwubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj vubj4,)}(h u32 *cmpvalh](h)}(hhh]jk))}(hu32h]hu32}(hjwhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjwubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjwmodnameN classnameNjj)}j](jNj1vc.it_IT.futex_requeueesbuh1hhjwubj,)}(h h]h }(hjxhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjwubj,)}(hj,h]h*}(hjxhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjwubjk))}(hcmpvalh]hcmpval}(hj,xhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjwubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj vubj4,)}(hint requeue_pih](j+)}(hinth]hint}(hjExhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjAxubj,)}(h h]h }(hjSxhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjAxubjk))}(h requeue_pih]h requeue_pi}(hjaxhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjAxubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj vubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hjuhhhjuhMgubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjuhhhjuhMgubah}(h]juah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjuhMghjuhhubj))}(hhh]h)}(h%Requeue waiters from uaddr1 to uaddr2h]h%Requeue waiters from uaddr1 to uaddr2}(hjxhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMghjxhhubah}(h]h ]h"]h$]h&]uh1j)hjuhhhjuhMgubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jxj)jxj)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)}(hjxh]h Parameters}(hjxhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjxubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMkhjxubj*)}(hhh](j*)}(h1``u32 __user *uaddr1`` source futex user address h](j *)}(h``u32 __user *uaddr1``h]jZ)}(hjxh]hu32 __user *uaddr1}(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.chMhhjxubj&*)}(hhh]h)}(hsource futex user addressh]hsource futex user address}(hjxhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjxhMhhjxubah}(h]h ]h"]h$]h&]uh1j%*hjxubeh}(h]h ]h"]h$]h&]uh1j*hjxhMhhjxubj*)}(h9``unsigned int flags1`` futex flags (FLAGS_SHARED, etc.) h](j *)}(h``unsigned int flags1``h]jZ)}(hjyh]hunsigned int flags1}(hjyhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjyubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMihjxubj&*)}(hhh]h)}(h futex flags (FLAGS_SHARED, etc.)h]h futex flags (FLAGS_SHARED, etc.)}(hjyhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjyhMihjyubah}(h]h ]h"]h$]h&]uh1j%*hjxubeh}(h]h ]h"]h$]h&]uh1j*hjyhMihjxubj*)}(h1``u32 __user *uaddr2`` target futex user address h](j *)}(h``u32 __user *uaddr2``h]jZ)}(hj>yh]hu32 __user *uaddr2}(hj@yhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj=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)}(hjzh]h8>=0 - on success, the number of tasks requeued or woken;}(hjzhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMuhjzubah}(h]h ]h"]h$]h&]uh1jZ hjzubj[ )}(h <0 - on errorh]h)}(hj{h]h <0 - on error}(hj{hhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMvhj{ubah}(h]h ]h"]h$]h&]uh1jZ hjzubeh}(h]h ]h"]h$]h&]j j uh1jU hj {hMuhjzubah}(h]h ]h"]h$]h&]uh1j)hj {hMuhjxubeh}(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}(hjW{hhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjS{hhhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMubj,)}(h h]h }(hjf{hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjS{hhhje{hMubje))}(hhandle_early_requeue_pi_wakeuph]jk))}(hhandle_early_requeue_pi_wakeuph]hhandle_early_requeue_pi_wakeup}(hjx{hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjt{ubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjS{hhhje{hMubj.,)}(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{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)}jjz{sb&c.it_IT.handle_early_requeue_pi_wakeupesbuh1hhj{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,)}(hstruct futex_q *qh](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_qh]hfutex_q}(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.handle_early_requeue_pi_wakeupesbuh1hhj|ubj,)}(h h]h }(hjD|hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj|ubj,)}(hj,h]h*}(hjR|hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj|ubjk))}(hj6Ph]hq}(hj_|hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj|ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj{ubj4,)}(hstruct hrtimer_sleeper *timeouth](j:,)}(hj=,h]hstruct}(hjw|hhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjs|ubj,)}(h h]h }(hj|hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjs|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.handle_early_requeue_pi_wakeupesbuh1hhjs|ubj,)}(h h]h }(hj|hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjs|ubj,)}(hj,h]h*}(hj|hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjs|ubjk))}(htimeouth]htimeout}(hj|hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjs|ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj{ubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hjS{hhhje{hMubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjO{hhhje{hMubah}(h]jJ{ah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hje{hMhjL{hhubj))}(hhh]h)}(h(Handle early wakeup on the initial futexh]h(Handle early wakeup on the initial futex}(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|hhubah}(h]h ]h"]h$]h&]uh1j)hjL{hhhje{hMubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)j}j)j}j)j)j)uh1jS)hhhj=hNhNubj))}(hX~**Parameters** ``struct futex_hash_bucket *hb`` the hash_bucket futex_q was original enqueued on ``struct futex_q *q`` the futex_q woken while waiting to be requeued ``struct hrtimer_sleeper *timeout`` the timeout associated with the wait (NULL if none) **Description** Determine the cause for the early wakeup. **Return** -EWOULDBLOCK or -ETIMEDOUT or -ERESTARTNOINTRh](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:1413: ./kernel/futex/requeue.chMhj}ubj*)}(hhh](j*)}(hR``struct futex_hash_bucket *hb`` the hash_bucket futex_q was original enqueued on h](j *)}(h ``struct futex_hash_bucket *hb``h]jZ)}(hj:}h]hstruct futex_hash_bucket *hb}(hj<}hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj8}ubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhj4}ubj&*)}(hhh]h)}(h0the hash_bucket futex_q was original enqueued onh]h0the hash_bucket futex_q was original enqueued on}(hjS}hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjO}hMhjP}ubah}(h]h ]h"]h$]h&]uh1j%*hj4}ubeh}(h]h ]h"]h$]h&]uh1j*hjO}hMhj1}ubj*)}(hE``struct futex_q *q`` the futex_q woken while waiting to be requeued h](j *)}(h``struct futex_q *q``h]jZ)}(hjs}h]hstruct futex_q *q}(hju}hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjq}ubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjm}ubj&*)}(hhh]h)}(h.the futex_q woken while waiting to be requeuedh]h.the futex_q woken while waiting to be requeued}(hj}hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj}hMhj}ubah}(h]h ]h"]h$]h&]uh1j%*hjm}ubeh}(h]h ]h"]h$]h&]uh1j*hj}hMhj1}ubj*)}(hX``struct hrtimer_sleeper *timeout`` the timeout associated with the wait (NULL if none) h](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 *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhj}ubj&*)}(hhh]h)}(h3the timeout associated with the wait (NULL if none)h]h3the timeout associated with the wait (NULL if none)}(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}hMhj1}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:1413: ./kernel/futex/requeue.chMhj}ubh)}(h)Determine the cause for the early wakeup.h]h)Determine the cause for the early wakeup.}(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}ubh)}(h **Return**h]j)}(hj~h]hReturn}(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:1413: ./kernel/futex/requeue.chMhj}ubj))}(h--EWOULDBLOCK or -ETIMEDOUT or -ERESTARTNOINTRh]h)}(hj&~h]h--EWOULDBLOCK or -ETIMEDOUT or -ERESTARTNOINTR}(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)hj5~hMhj}ubeh}(h]h ] kernelindentah"]h$]h&]uh1j)hj=hhhNhNubjC))}(hhh]h}(h]h ]h"]h$]h&]entries](jO)(it_IT.futex_wait_requeue_pi (C function)c.it_IT.futex_wait_requeue_pihNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(h}int futex_wait_requeue_pi (u32 __user *uaddr, unsigned int flags, u32 val, ktime_t *abs_time, u32 bitset, u32 __user *uaddr2)h]j_))}(h|int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, u32 val, ktime_t *abs_time, u32 bitset, u32 __user *uaddr2)h](j+)}(hinth]hint}(hj\~hhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjX~hhhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMubj,)}(h h]h }(hjk~hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjX~hhhjj~hMubje))}(hfutex_wait_requeue_pih]jk))}(hfutex_wait_requeue_pih]hfutex_wait_requeue_pi}(hj}~hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjy~ubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjX~hhhjj~hMubj.,)}(hc(u32 __user *uaddr, unsigned int flags, u32 val, ktime_t *abs_time, u32 bitset, u32 __user *uaddr2)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_wait_requeue_piesbuh1hhj~ubj,)}(h h]h }(hj~hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj~ubh__user}(hj~hhhNhNubj,)}(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))}(huaddrh]huaddr}(hj~hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj~ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj~ubj4,)}(hunsigned int flagsh](j+)}(hunsignedh]hunsigned}(hjhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hj~ubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj~ubj+)}(hinth]hint}(hjhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hj~ubj,)}(h h]h }(hj-hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj~ubjk))}(hflagsh]hflags}(hj;hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj~ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj~ubj4,)}(hu32 valh](h)}(hhh]jk))}(hu32h]hu32}(hjWhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjTubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjYmodnameN classnameNjj)}j](jNj~c.it_IT.futex_wait_requeue_piesbu h1hhjPubj,)}(h h]h }(hjvhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjPubjk))}(hvalh]hval}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjPubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj~ubj4,)}(hktime_t *abs_timeh](h)}(hhh]jk))}(hktime_th]hktime_t}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j](jNj~c.it_IT.futex_wait_requeue_piesbuh1hhjubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubj,)}(hj,h]h*}(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubjk))}(habs_timeh]habs_time}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj~ubj4,)}(h u32 bitseth](h)}(hhh]jk))}(hu32h]hu32}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j](jNj~c.it_IT.futex_wait_requeue_piesbuh1hhjubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubjk))}(hbitseth]hbitset}(hj#hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj~ubj4,)}(hu32 __user *uaddr2h](h)}(hhh]jk))}(hu32h]hu32}(hj?hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj<ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjAmodnameN classnameNjj)}j](jNj~c.it_IT.futex_wait_requeue_piesbuh1hhj8ubj,)}(h h]h }(hj^hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj8ubh__user}(hj8hhhNhNubj,)}(h h]h }(hjphhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj8ubj,)}(hj,h]h*}(hj~hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj8ubjk))}(huaddr2h]huaddr2}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj8ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hj~ubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hjX~hhhjj~hMubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjT~hhhjj~hMubah}(h]jO~ah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjj~hMhjQ~hhubj))}(hhh]h)}(hWait on uaddr and take uaddr2h]hWait on uaddr and take uaddr2}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjhhubah}(h]h ]h"]h$]h&]uh1j)hjQ~hhhjj~hMubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)j̀j)j̀j)j)j)uh1jS)hhhj=hNhNubj))}(hX**Parameters** ``u32 __user *uaddr`` the futex we initially wait on (non-pi) ``unsigned int flags`` futex flags (FLAGS_SHARED, FLAGS_CLOCKRT, etc.), they must be the same type, no requeueing from private to shared, etc. ``u32 val`` the expected value of uaddr ``ktime_t *abs_time`` absolute timeout ``u32 bitset`` 32 bit wakeup bitset set by userspace, defaults to all ``u32 __user *uaddr2`` the pi futex we will take prior to returning to user-space **Description** The 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. We 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 If 3, cleanup and return -ERESTARTNOINTR. If 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 If 6, return -EWOULDBLOCK (restarting the syscall would do the same). If 4 or 7, we cleanup and return with -ETIMEDOUT. **Return** - 0 - On success; - <0 - On errorh](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:1413: ./kernel/futex/requeue.chMhjрubj*)}(hhh](j*)}(h>``u32 __user *uaddr`` the futex we initially wait on (non-pi) h](j *)}(h``u32 __user *uaddr``h]jZ)}(hjh]hu32 __user *uaddr}(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 futex we initially wait on (non-pi)h]h'the futex we initially wait on (non-pi)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hMhj ubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hj hMhjubj*)}(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}(hj1hhhNhNubah}(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.}(hjHhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjEubah}(h]h ]h"]h$]h&]uh1j%*hj)ubeh}(h]h ]h"]h$]h&]uh1j*hjDhMhjubj*)}(h(``u32 val`` the expected value of uaddr h](j *)}(h ``u32 val``h]jZ)}(hjih]hu32 val}(hjkhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjgubah}(h]h ]h"]h$]h&]uh1j *hr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjcubj&*)}(hhh]h)}(hthe expected value of uaddrh]hthe expected value of uaddr}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj~hMhjubah}(h]h ]h"]h$]h&]uh1j%*hjcubeh}(h]h ]h"]h$]h&]uh1j*hj~hMhjubj*)}(h'``ktime_t *abs_time`` absolute timeout h](j *)}(h``ktime_t *abs_time``h]jZ)}(hjh]hktime_t *abs_time}(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)}(habsolute timeouth]habsolute timeout}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjubj*)}(hF``u32 bitset`` 32 bit wakeup bitset set by userspace, defaults to all h](j *)}(h``u32 bitset``h]jZ)}(hjہh]h u32 bitset}(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)}(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%*hjՁubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjubj*)}(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}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj)hMhj*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)}(hjOh]h Description}(hjQhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjMubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjр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.}(hjehhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjр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}(hjthhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjр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.chMhjр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}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjрubh)}(hEIf 6, return -EWOULDBLOCK (restarting the syscall would do the same).h]hEIf 6, return -EWOULDBLOCK (restarting the syscall would do the same).}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjрubh)}(h1If 4 or 7, we cleanup and return with -ETIMEDOUT.h]h1If 4 or 7, we cleanup and return with -ETIMEDOUT.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhr/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1413: ./kernel/futex/requeue.chMhjрubh)}(h **Return**h]j)}(hjh]hReturn}(hjÂhhhNhNubah}(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.chMhjрubj))}(h"- 0 - On success; - <0 - On errorh]jV )}(hhh](j[ )}(h0 - On success;h]h)}(hjh]h0 - On success;}(hjhhhNhNubah}(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&]uh1jZ hjۂubj[ )}(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 hjۂubeh}(h]h ]h"]h$]h&]j j uh1jU hjhMhjׂubah}(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_do_wait (C function)c.it_IT.futex_do_waithNtauh1jB)hj=hhhNhNubjT))}(hhh](jY))}(hGvoid futex_do_wait (struct futex_q *q, struct hrtimer_sleeper *timeout)h]j_))}(hFvoid futex_do_wait(struct futex_q *q, struct hrtimer_sleeper *timeout)h](j+)}(hvoidh]hvoid}(hj:hhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hj6hhhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMQubj,)}(h h]h }(hjIhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj6hhhjHhMQubje))}(h futex_do_waith]jk))}(h futex_do_waith]h futex_do_wait}(hj[hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjWubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hj6hhhjHhMQubj.,)}(h4(struct futex_q *q, struct hrtimer_sleeper *timeout)h](j4,)}(hstruct futex_q *qh](j:,)}(hj=,h]hstruct}(hjwhhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjsubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjsubh)}(hhh]jk))}(hfutex_qh]hfutex_q}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j](jNj)}jj]sbc.it_IT.futex_do_waitesbuh1hhjsubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjsubj,)}(hj,h]h*}(hjăhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjsubjk))}(hj6Ph]hq}(hjуhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjsubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjoubj4,)}(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 reftargetj modnameN classnameNjj)}j](jNjc.it_IT.futex_do_waitesbuh1hhjubj,)}(h h]h }(hj&hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubj,)}(hj,h]h*}(hj4hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubjk))}(htimeouth]htimeout}(hjAhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjoubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hj6hhhjHhMQubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj2hhhjHhMQubah}(h]j-ah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjHhMQhj/hhubj))}(hhh]h)}(h#wait for wakeup, timeout, or signalh]h#wait for wakeup, timeout, or signal}(hjkhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMQhjhhhubah}(h]h ]h"]h$]h&]uh1j)hj/hhhjHhMQubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jj)jj)j)j)uh1jS)hhhj=hNhNubj))}(h**Parameters** ``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*)}(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.chMRhjubj&*)}(hhh]h)}(hthe futex_q to queue up onh]hthe futex_q to queue up on}(hjńhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMRhj„ubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjhMRhjubj*)}(hX``struct hrtimer_sleeper *timeout`` the prepared hrtimer_sleeper, or null for no timeouth](j *)}(h#``struct hrtimer_sleeper *timeout``h]jZ)}(hjh]hstruct hrtimer_sleeper *timeout}(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.chMThj߄ubj&*)}(hhh]h)}(h4the prepared hrtimer_sleeper, or null for no timeouth]h4the prepared hrtimer_sleeper, or null for no timeout}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMShjubah}(h]h ]h"]h$]h&]uh1j%*hj߄ubeh}(h]h ]h"]h$]h&]uh1j*hjhMThjubeh}(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}(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.chMlubj,)}(h h]h }(hjNhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj;hhhjMhMlubje))}(hfutex_unqueue_multipleh]jk))}(hfutex_unqueue_multipleh]hfutex_unqueue_multiple}(hj`hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj\ubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hj;hhhjMhMlubj.,)}(h#(struct futex_vector *v, int count)h](j4,)}(hstruct futex_vector *vh](j:,)}(hj=,h]hstruct}(hj|hhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjxubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjxubh)}(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)}jjbsbc.it_IT.futex_unqueue_multipleesbuh1hhjxubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjxubj,)}(hj,h]h*}(hjɅhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjxubjk))}(hvh]hv}(hjօhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjxubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjtubj4,)}(h int counth](j+)}(hinth]hint}(hjhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubjk))}(hcounth]hcount}(hj hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjtubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hj;hhhjMhMlubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hj7hhhjMhMlubah}(h]j2ah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjMhMlhj4hhubj))}(hhh]h)}(h-Remove various futexes from their hash bucketh]h-Remove various futexes from their hash bucket}(hj5hhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMlhj2hhubah}(h]h ]h"]h$]h&]uh1j)hj4hhhjMhMlubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jMj)jMj)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)}(hjWh]h Parameters}(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.chMphjQubj*)}(hhh](j*)}(h:``struct futex_vector *v`` The list of futexes to unqueue h](j *)}(h``struct futex_vector *v``h]jZ)}(hjvh]hstruct futex_vector *v}(hjxhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjtubah}(h]h ]h"]h$]h&]uh1j *hs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMmhjpubj&*)}(hhh]h)}(hThe list of futexes to unqueueh]hThe list of futexes to unqueue}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMmhjubah}(h]h ]h"]h$]h&]uh1j%*hjpubeh}(h]h ]h"]h$]h&]uh1j*hjhMmhjmubj*)}(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.chMnhjubj&*)}(hhh]h)}(hNumber of futexes in the listh]hNumber of futexes in the list}(hjȆhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjĆhMnhjņubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjĆhMnhjmubeh}(h]h ]h"]h$]h&]uh1j*hjQubh)}(h**Description**h]j)}(hjh]h Description}(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.chMphjQubh)}(h5Helper to unqueue a list of futexes. This can't fail.h]h7Helper to unqueue a list of futexes. This can’t fail.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMphjQubh)}(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.chMrhjQubj))}(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)}(hj0h]h.>=0 - Index of the last futex that was awoken;}(hj2hhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMrhj.ubah}(h]h ]h"]h$]h&]uh1jZ hj+ubj[ )}(h-1 - No futex was awokenh]h option_list)}(hhh]hoption_list_item)}(hhh](h option_group)}(hhh]hoption)}(h-1h]h option_string)}(hj]h]h-1}hjasbah}(h]h ]h"]h$]h&]uh1j_hj[ubah}(h]h ]h"]h$]h&]uh1jYhjVubah}(h]h ]h"]h$]h&]uh1jThjQubh description)}(h- No futex was awokenh]jV )}(hhh]j[ )}(hNo futex was awokenh]h)}(hjh]hNo futex was awoken}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMshjubah}(h]h ]h"]h$]h&]uh1jZ hjubah}(h]h ]h"]h$]h&]j j uh1jU hjhMshj|ubah}(h]h ]h"]h$]h&]uh1jzhjQubeh}(h]h ]h"]h$]h&]uh1jOhjLubah}(h]h ]h"]h$]h&]uh1jJhjhMshjFubah}(h]h ]h"]h$]h&]uh1jZ hj+ubeh}(h]h ]h"]h$]h&]j j uh1jU hj?hMrhj'ubah}(h]h ]h"]h$]h&]uh1j)hj?hMrhjQubeh}(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}(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_wait_multiple_setuph]jk))}(hfutex_wait_multiple_setuph]hfutex_wait_multiple_setup}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjhhhjhMubj.,)}(h0(struct futex_vector *vs, int count, int *woken)h](j4,)}(hstruct futex_vector *vsh](j:,)}(hj=,h]hstruct}(hj"hhhNhNubah}(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 reftargetjBmodnameN classnameNjj)}j](jNj)}jjsb!c.it_IT.futex_wait_multiple_setupesbuh1hhjubj,)}(h h]h }(hjahhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubj,)}(hj,h]h*}(hjohhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubjk))}(hvsh]hvs}(hj|hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjubj4,)}(h int counth](j+)}(hinth]hint}(hjhhhNhNubah}(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,hjubj4,)}(h int *wokenh](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ƈubj,)}(hj,h]h*}(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjƈubjk))}(hwokenh]hwoken}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjƈubeh}(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]j؇ah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjhMhjڇhhubj))}(hhh]h)}(h,Prepare to wait and enqueue multiple futexesh]h,Prepare to wait and enqueue multiple futexes}(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)hjڇhhhjhMubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)j5j)j5j)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)}(hj?h]h Parameters}(hjAhhhNhNubah}(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.chMhj9ubj*)}(hhh](j*)}(h6``struct futex_vector *vs`` The futex list to wait on 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.chMhjXubj&*)}(hhh]h)}(hThe futex list to wait onh]hThe futex list to wait on}(hjwhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjshMhjtubah}(h]h ]h"]h$]h&]uh1j%*hjXubeh}(h]h ]h"]h$]h&]uh1j*hjshMhjUubj*)}(h#``int count`` The size of 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.chMhjubj&*)}(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%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjUubj*)}(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)}(hjЉh]h int *woken}(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)}(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)}(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&]uh1j%*hjʉubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjUubeh}(h]h ]h"]h$]h&]uh1j*hj9ubh)}(h**Description**h]j)}(hj h]h Description}(hjhhhNhNubah}(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.chMhj9ubh)}(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.}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhj9ubh)}(h **Return**h]j)}(hj3h]hReturn}(hj5hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj1ubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhj9ubj))}(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)}(hjRh]h21 - One of the futexes was woken by another thread}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhjPubah}(h]h ]h"]h$]h&]uh1jZ hjMubj[ )}(h 0 - Successh]h)}(hjjh]h 0 - Success}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhjhubah}(h]h ]h"]h$]h&]uh1jZ hjMubj[ )}(h%<0 - -EFAULT, -EWOULDBLOCK or -EINVALh]h)}(hjh]h%<0 - -EFAULT, -EWOULDBLOCK or -EINVAL}(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 hjMubeh}(h]h ]h"]h$]h&]j j uh1jU hjahMhjIubah}(h]h ]h"]h$]h&]uh1j)hjahMhj9ubeh}(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 }(hjӊhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjhhhjҊhMubje))}(hfutex_sleep_multipleh]jk))}(hfutex_sleep_multipleh]hfutex_sleep_multiple}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubah}(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 }(hjhhhNhNubah}(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 reftargetj!modnameN classnameNjj)}j](jNj)}jjsbc.it_IT.futex_sleep_multipleesbuh1hhjubj,)}(h h]h }(hj@hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubj,)}(hj,h]h*}(hjNhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubjk))}(hvsh]hvs}(hj[hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjubj4,)}(hunsigned int counth](j+)}(hunsignedh]hunsigned}(hjthhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjpubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjpubj+)}(hinth]hint}(hjhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjpubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjpubjk))}(hcounth]hcount}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjpubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjubj4,)}(hstruct hrtimer_sleeper *toh](j:,)}(hj=,h]hstruct}(hjŋhhhNhNubah}(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}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j](jNj<c.it_IT.futex_sleep_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))}(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#Check sleeping conditions and sleeph]h#Check sleeping conditions and sleep}(hjGhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhjDhhubah}(h]h ]h"]h$]h&]uh1j)hjhhhjҊhMubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)j_j)j_j)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)}(hjih]h Parameters}(hjkhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjgubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhjcubj*)}(hhh](j*)}(h8``struct futex_vector *vs`` List of futexes to wait for 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)}(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%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjubj*)}(h$``unsigned int count`` Length of vs h](j *)}(h``unsigned int count``h]jZ)}(hjh]hunsigned int count}(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.chMhjubj&*)}(hhh]h)}(h Length of vsh]h Length of vs}(hjڌhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj֌hMhj׌ubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hj֌hMhjubj*)}(h'``struct hrtimer_sleeper *to`` Timeout 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)}(hTimeouth]hTimeout}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjubeh}(h]h ]h"]h$]h&]uh1j*hjcubh)}(h**Description**h]j)}(hj5h]h Description}(hj7hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj3ubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhjcubh)}(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.}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhjcubeh}(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}(hjzhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjvhhhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chM ubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjvhhhjhM ubje))}(hfutex_wait_multipleh]jk))}(hfutex_wait_multipleh]hfutex_wait_multiple}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubah}(h]h ](j})j~)eh"]h$]h&]jTjUuh1jd)hjvhhhjhM ubj.,)}(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}(hjՍhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjҍubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj׍modnameN classnameNjj)}j](jNj)}jjsbc.it_IT.futex_wait_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))}(hvsh]hvs}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjubj4,)}(hunsigned int counth](j+)}(hunsignedh]hunsigned}(hj*hhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hj&ubj,)}(h h]h }(hj8hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj&ubj+)}(hinth]hint}(hjFhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hj&ubj,)}(h h]h }(hjThhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj&ubjk))}(hcounth]hcount}(hjbhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj&ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjubj4,)}(hstruct hrtimer_sleeper *toh](j:,)}(hj=,h]hstruct}(hj{hhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hjwubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjwubh)}(hhh]jk))}(hhrtimer_sleeperh]hhrtimer_sleeper}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j](jNjc.it_IT.futex_wait_multipleesbuh1hhjwubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjwubj,)}(hj,h]h*}(hjƎhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjwubjk))}(htoh]hto}(hjӎhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjwubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hjvhhhjhM ubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjrhhhjhM ubah}(h]jmah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjhM hjohhubj))}(hhh]h)}(h.Prepare to wait on and enqueue several futexesh]h.Prepare to wait on and enqueue several futexes}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chM hjhhubah}(h]h ]h"]h$]h&]uh1j)hjohhhjhM ubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jj)jj)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)}(hjh]h Parameters}(hj!hhhNhNubah}(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*)}(h;``struct futex_vector *vs`` The list of futexes to wait on 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.chM hj8ubj&*)}(hhh]h)}(hThe list of futexes to wait onh]hThe list of futexes to wait on}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjShM hjTubah}(h]h ]h"]h$]h&]uh1j%*hj8ubeh}(h]h ]h"]h$]h&]uh1j*hjShM hj5ubj*)}(h-``unsigned int count`` The number of objects h](j *)}(h``unsigned int count``h]jZ)}(hjwh]hunsigned int count}(hjyhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjuubah}(h]h ]h"]h$]h&]uh1j *hs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chM hjqubj&*)}(hhh]h)}(hThe number of objectsh]hThe number of objects}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM hjubah}(h]h ]h"]h$]h&]uh1j%*hjqubeh}(h]h ]h"]h$]h&]uh1j*hjhM hj5ubj*)}(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}(hjɏhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjŏhMhjƏubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjŏhMhj5ubeh}(h]h ]h"]h$]h&]uh1j*hjubh)}(h**Description**h]j)}(hjh]h Description}(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.chMhjubh)}(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.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhjubh)}(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.chMhjubj))}(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)}(hj1h]h'>=0 - Hint to the futex that was awoken}(hj3hhhNhNubah}(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 hj,ubj[ )}(h<0 - On errorh]h)}(hjIh]h<0 - On error}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMhjGubah}(h]h ]h"]h$]h&]uh1jZ hj,ubeh}(h]h ]h"]h$]h&]j j uh1jU hj@hMhj(ubah}(h]h ]h"]h$]h&]uh1j)hj@hMhjubeh}(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))}(hint futex_wait_setup (u32 __user *uaddr, u32 val, unsigned int flags, struct futex_q *q, union futex_key *key2, struct task_struct *task)h]j_))}(hint futex_wait_setup(u32 __user *uaddr, u32 val, unsigned int flags, struct futex_q *q, union futex_key *key2, struct task_struct *task)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.chM>ubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjhhhjhM>ubje))}(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)hjhhhjhM>ubj.,)}(ht(u32 __user *uaddr, u32 val, unsigned int flags, struct futex_q *q, union futex_key *key2, struct task_struct *task)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)}jjsbc.it_IT.futex_wait_setupesbuh1hhjĐubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjĐubh__user}(hjĐhhhNhNubj,)}(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))}(huaddrh]huaddr}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjĐubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjubj4,)}(hu32 valh](h)}(hhh]jk))}(hu32h]hu32}(hj5hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj2ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj7modnameN classnameNjj)}j](jNjc.it_IT.futex_wait_setupesbuh1hhj.ubj,)}(h h]h }(hjThhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj.ubjk))}(hvalh]hval}(hjbhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj.ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjubj4,)}(hunsigned int flagsh](j+)}(hunsignedh]hunsigned}(hj{hhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjwubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjwubj+)}(hinth]hint}(hjhhhNhNubah}(h]h ]j+ah"]h$]h&]uh1j+hjwubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjwubjk))}(hflagsh]hflags}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjwubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjubj4,)}(hstruct futex_q *qh](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_qh]hfutex_q}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j](jNjc.it_IT.futex_wait_setupesbuh1hhjȑubj,)}(h h]h }(hj hhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjȑubj,)}(hj,h]h*}(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjȑubjk))}(hj6Ph]hq}(hj$hhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjȑubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjubj4,)}(hunion futex_key *key2h](j:,)}(hj@h]hunion}(hj<hhhNhNubah}(h]h ]jF,ah"]h$]h&]uh1j9,hj8ubj,)}(h h]h }(hjIhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj8ubh)}(hhh]jk))}(h futex_keyh]h futex_key}(hjZhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjWubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj\modnameN classnameNjj)}j](jNjc.it_IT.futex_wait_setupesbuh1hhj8ubj,)}(h h]h }(hjyhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj8ubj,)}(hj,h]h*}(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hj8ubjk))}(hkey2h]hkey2}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hj8ubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjubj4,)}(hstruct task_struct *taskh](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))}(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](jNjc.it_IT.futex_wait_setupesbuh1hhjubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubj,)}(hj,h]h*}(hjhhhNhNubah}(h]h ]j,ah"]h$]h&]uh1j,hjubjk))}(htaskh]htask}(hjhhhNhNubah}(h]h ]jv)ah"]h$]h&]uh1jj)hjubeh}(h]h ]h"]h$]h&]noemphjTjUuh1j3,hjubeh}(h]h ]h"]h$]h&]jTjUuh1j-,hjhhhjhM>ubeh}(h]h ]h"]h$]h&]jTjUj)uh1j^)j)j)hjhhhjhM>ubah}(h]j~ah ](j)j)eh"]h$]h&]j)j))j)huh1jX)hjhM>hjhhubj))}(hhh]h)}(hPrepare to wait on a futexh]hPrepare to wait on a futex}(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,hhubah}(h]h ]h"]h$]h&]uh1j)hjhhhjhM>ubeh}(h]h ](jfunctioneh"]h$]h&]j)jj)jGj)jGj)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 ``union futex_key *key2`` the second futex_key if used for requeue PI ``struct task_struct *task`` Task queueing this futex **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; - <0 - On error and the hb is unlocked. A possible reason: the uaddr can not be read, does not contain the expected value or is not properly aligned.h](h)}(h**Parameters**h]j)}(hjQh]h Parameters}(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.chMBhjKubj*)}(hhh](j*)}(h2``u32 __user *uaddr`` the futex userspace address h](j *)}(h``u32 __user *uaddr``h]jZ)}(hjph]hu32 __user *uaddr}(hjrhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjnubah}(h]h ]h"]h$]h&]uh1j *hs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chM?hjjubj&*)}(hhh]h)}(hthe futex userspace addressh]hthe futex userspace address}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM?hjubah}(h]h ]h"]h$]h&]uh1j%*hjjubeh}(h]h ]h"]h$]h&]uh1j*hjhM?hjgubj*)}(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.chM@hjubj&*)}(hhh]h)}(hthe expected valueh]hthe expected value}(hj“hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM@hjubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjhM@hjgubj*)}(h8``unsigned int flags`` futex flags (FLAGS_SHARED, etc.) h](j *)}(h``unsigned int flags``h]jZ)}(hjh]hunsigned int flags}(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.chMAhjܓubj&*)}(hhh]h)}(h futex flags (FLAGS_SHARED, etc.)h]h futex flags (FLAGS_SHARED, etc.)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMAhjubah}(h]h ]h"]h$]h&]uh1j%*hjܓubeh}(h]h ]h"]h$]h&]uh1j*hjhMAhjgubj*)}(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.chMBhjubj&*)}(hhh]h)}(hthe associated futex_qh]hthe associated futex_q}(hj4hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj0hMBhj1ubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hj0hMBhjgubj*)}(hF``union futex_key *key2`` the second futex_key if used for requeue PI h](j *)}(h``union futex_key *key2``h]jZ)}(hjTh]hunion futex_key *key2g}(hjVhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjRubah}(h]h ]h"]h$]h&]uh1j *hs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMChjNubj&*)}(hhh]h)}(h+the second futex_key if used for requeue PIh]h+the second futex_key if used for requeue PI}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjihMChjjubah}(h]h ]h"]h$]h&]uh1j%*hjNubeh}(h]h ]h"]h$]h&]uh1j*hjihMChjgubj*)}(h6``struct task_struct *task`` Task queueing this futex h](j *)}(h``struct task_struct *task``h]jZ)}(hjh]hstruct task_struct *task}(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)}(hTask queueing this futexh]hTask queueing this futex}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMDhjubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjhMDhjgubeh}(h]h ]h"]h$]h&]uh1j*hjKubh)}(h**Description**h]j)}(hjȔh]h Description}(hjʔhhhNhNubah}(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.chMFhjKubh)}(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.}(hjޔhhhNhNubah}(h]h ]h"]h$]h&]uh1hhs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMFhjKubh)}(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.chMJhjKubj))}(h- 0 - uaddr contains val and hb has been locked; - <0 - On error and the hb is unlocked. A possible reason: the uaddr can not be read, does not contain the expected value or is not properly aligned.h]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.chMJhj ubah}(h]h ]h"]h$]h&]uh1jZ hj ubj[ )}(h<0 - On error and the hb is unlocked. A possible reason: the uaddr can not be read, does not contain the expected value or is not properly aligned.h]j*)}(hhh]j*)}(h<0 - On error and the hb is unlocked. A possible reason: the uaddr can not be read, does not contain the expected value or is not properly aligned.h](j *)}(hJ<0 - On error and the hb is unlocked. A possible reason: the uaddr can noth]hJ<0 - On error and the hb is unlocked. A possible reason: the uaddr can not}(hj/hhhNhNubah}(h]h ]h"]h$]h&]uh1j *hs/var/lib/git/docbuild/linux/Documentation/translations/it_IT/kernel-hacking/locking:1416: ./kernel/futex/waitwake.chMKhj+ubj&*)}(hhh]h)}(hHbe read, does not contain the expected value or is not properly aligned.h]hHbe read, does not contain the expected value or is not properly aligned.}(hjAhhhNhNubah}(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&]uh1j%*hj+ubeh}(h]h ]h"]h$]h&]uh1j*hj=hMKhj(ubah}(h]h ]h"]h$]h&]uh1j*hj$ubah}(h]h ]h"]h$]h&]uh1jZ hj ubeh}(h]h ]h"]h$]h&]j j uh1jU hjhMJhjubah}(h]h ]h"]h$]h&]uh1j)hjhMJhjKubeh}(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.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjubh)}(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]}(hjϕhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjubeh}(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}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhMubh)}(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.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjhhubh)}(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&]uh1hhjhMhjhhubh)}(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&]uh1hhjhMhjhhubeh}(h]ringraziamentiah ]h"]ringraziamentiah$]h&]uh1jhjhhhjhMubj)}(hhh](j)}(h Glossarioh]h Glossario}(hj7hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj4hhhjhMubj*)}(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}(hjLhhhNhNubah}(h]h ]h"]h$]h&]uh1j *hjhMhjHubj&*)}(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}(hjehhhNhNubah}(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}(hjwhhhNhNubah}(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&]uh1hhjhMhjZubah}(h]h ]h"]h$]h&]uh1j%*hjHubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjEubj*)}(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 }(hjhhhNhNubj)}(h*Bottom Halves*h]h Bottom Halves}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhl sono deprecati, e probabilmente verranno sostituiti dai tasklet. In un dato momento potrà esserci solo un }(hjhhhNhNubj)}(h *bottom half*h]h bottom half}(hjʖhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh in esecuzione.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjEhhubj*)}(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}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j *hjhMhjubj&*)}(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&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjEhhubj*)}(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}(hj!hhhNhNubah}(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 }(hj2hhhNhNubjZ)}(h ``current``h]hcurrent}(hj:hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj2ubhk. Da non confondere con lo spazio utente. Può essere interrotto sia da interruzioni software che hardware.}(hj2hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj/ubah}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjEhhubj*)}(h{interruzione hardware Richiesta di interruzione hardware. in_hardirq() ritorna vero in un gestore d'interruzioni hardware. h](j *)}(hinterruzione hardwareh]hinterruzione hardware}(hjbhhhNhNubah}(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.}(hjshhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjpubah}(h]h ]h"]h$]h&]uh1j%*hj^ubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjEhhubj*)}(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}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j *hjhMhjubj&*)}(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).}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjubeh}(h]h ]h"]h$]h&]uh1j%*hjubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjEhhubj*)}(h_monoprocessore / UP (Uni-Processor) un solo processore, ovvero non è SMP. (``CONFIG_SMP=n``). h](j *)}(hmonoprocessore / UPh]hmonoprocessore / UP}(hjΗhhhNhNubah}(h]h ]h"]h$]h&]uh1j *hjhMhjʗubj&*)}(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}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jYhjߗubh).}(hjߗhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjܗubah}(h]h ]h"]h$]h&]uh1j%*hjʗubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjEhhubj*)}(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 *hjhMhj ubj&*)}(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 (}(hj hhhNhNubjZ)}(h``CONFIG_SMP=y``h]h CONFIG_SMP=y}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1jYhj ubh).}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1j%*hj ubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjEhhubj*)}(hIspazio utente Un processo che esegue il proprio codice fuori dal kernel. h](j *)}(h spazio utenteh]h spazio utente}(hjPhhhNhNubah}(h]h ]h"]h$]h&]uh1j *hjhMhjLubj&*)}(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.}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj^ubah}(h]h ]h"]h$]h&]uh1j%*hjLubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjEhhubj*)}(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 *hjhMhj{ubj&*)}(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.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1j%*hj{ubeh}(h]h ]h"]h$]h&]uh1j*hjhMhjEhhubj*)}(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}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j *hjhMhjubj&*)}(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 }(hjhhhNhNubjZ)}(h``TIMER_SOFTIRQ``h]h TIMER_SOFTIRQ}(hjǘhhhNhNubah}(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*hjhMhjEhhubeh}(h]h ]h"]h$]h&]uh1j*hj4hhhjhNubeh}(h] glossarioah ]h"] glossarioah$]h&]uh1jhjhhhjhMubeh}(h](*l-inaffidabile-guida-alla-sincronizzazionejeh ]h"](*l'inaffidabile guida alla sincronizzazioneit_kernel_hacking_lockeh$]h&]uh1jhhhhhjhK j1 }jjsj3 }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_handlerj&error_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}(jjjjjjjjjjjK 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=jj}jjj1j.jju nametypes}(jjjjjjK 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=jjj1juh}(jjjjjjjjjjjjH 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;j}j=j>j>j?j?jAjBjfEjkEjIjIj&Kj+KjMjMjOjOjQjQjRjRjTjTjXjXjZjZj]j]j6_j;_jej"ej hj%hjykj~kj9oj>ojujujJ{jO{jO~jT~j-j2j2j7j؇j݇jjjmjrj~jjjj.jjj4jjfjeju footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}j4KsRparse_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