Lines Matching refs:un
33 In un normale programma, potete incrementare un contatore nel seguente modo:
84 Questa sovrapposizione, ovvero quando un risultato dipende dal tempo che
92 interrompendo un processo nella sua sezione critica otterremo comunque
97 simultanei, ed utilizzare i *lock* per accertarsi che solo un'istanza
105 Se posso darvi un suggerimento: non dormite mai con qualcuno più pazzo di
106 voi. Ma se dovessi darvi un suggerimento sulla sincronizzazione:
113 pensare a prendervi un cane bello grande.
119 spinlock (``include/asm/spinlock.h``), un semplice *lock* che può essere
120 trattenuto solo da un processo: se non si può trattenere lo spinlock, allora
125 ma potreste bloccarvi trattenendolo. Se non potete trattenere un mutex
129 permettervi di sospendere un processo (vedere
140 gli spinlock non esistono. Questa è un'ottima scelta di progettazione:
142 non c'è la necessità di avere un *lock*.
147 la prelazione equivalente ad un sistema multi-processore senza preoccuparci
151 ``CONFIG_PREEMPT`` abilitate, anche quando non avete un sistema
162 allora, per proteggerla, potete utilizzare un semplice mutex
181 Se un softirq condivide dati col contesto utente, avete due problemi.
182 Primo, il contesto utente corrente potrebbe essere interroto da un softirq,
183 e secondo, la sezione critica potrebbe essere eseguita da un altro
187 l'opposto. (Il suffisso '_bh' è un residuo storico che fa riferimento al
188 "Bottom Halves", il vecchio nome delle interruzioni software. In un mondo
203 Questo caso è uguale al precedente, un tasklet viene eseguito da un softirq.
208 Anche questo caso è uguale al precedente, un timer viene eseguito da un
215 Qualche volta un tasklet od un timer potrebbero condividere i dati con
216 un altro tasklet o timer
221 Dato che un tasklet non viene mai eseguito contemporaneamente su due
228 Se un altro tasklet/timer vuole condividere dati col vostro tasklet o timer,
231 in un tasklet ed avete la garanzia che nessun altro verrà eseguito sullo
237 Spesso un softirq potrebbe condividere dati con se stesso o un tasklet/timer.
242 Lo stesso softirq può essere eseguito su un diverso processore: allo scopo
257 su un diverso processore.
264 Solitamente le interruzioni hardware comunicano con un tasklet o un softirq.
266 preso in carico da un softirq.
271 Se un gestore di interruzioni hardware condivide dati con un softirq, allora
273 un'interruzione hardware, e secondo, la sezione critica potrebbe essere
274 eseguita da un'interruzione hardware su un processore diverso. Questo è il caso
281 hardware è in esecuzione: per questo si può usare spin_lock(), che è un po'
282 più veloce. L'unica eccezione è quando un altro gestore d'interruzioni
294 potrà essere utilizzato in un'interruzione hardware (dove le interruzioni sono
295 già disabilitate) e in un softirq (dove la disabilitazione delle interruzioni
299 da un'interruzione hardware, quindi spin_lock_irq() interrompe
317 - Se siete in un contesto utente (una qualsiasi chiamata di sistema)
321 - Altrimenti (== i dati possono essere manipolati da un'interruzione) usate
333 da un processore per volta, quindi non ci sono requisiti per la
334 sincronizzazione (per esempio, un thread può essere eseguito solo su un
335 processore alla volta, ma se deve condividere dati con un altro thread, allora
339 spin_lock_irqsave(), che è un sovrainsieme di tutte le altre funzioni
376 Ci sono funzioni che provano a trattenere un *lock* solo una volta e
384 se ci riesce al primo colpo ritorna un valore diverso da zero, altrimenti
385 se fallisce ritorna 0. Questa funzione può essere utilizzata in un qualunque
390 ritorna un valore diverso da zero se è possibile trattenere il lock al primo
398 Guardiamo un semplice esempio: una memoria che associa nomi a numeri.
521 essere un timer che elimina oggetti dalla memoria.
589 se erano attive, altrimenti non farà niente (quando siamo già in un contesto
596 questa opzione deve diventare un parametro di cache_add().
603 codice potrebbero avere un puntatore a questi oggetti piuttosto che cercarli
608 rende la sincronizzazione più complicata dato che non avviene più in un unico
611 Il secondo problema è il problema del ciclo di vita: se un'altra struttura
612 mantiene un puntatore ad un oggetto, presumibilmente si aspetta che questo
615 cache_delete() o peggio, aggiungere un oggetto che riutilizza lo
618 Dato che c'è un solo *lock*, non potete trattenerlo a vita: altrimenti
621 La soluzione a questo problema è l'uso di un contatore di riferimenti:
622 chiunque punti ad un oggetto deve incrementare il contatore, e decrementarlo
720 per ogni puntatore ad un oggetto: quindi il contatore di riferimenti è 1
722 non trattiene un riferimento per se, ma diventa più complicato.
728 Ci sono un certo numbero di operazioni atomiche definite
823 trattenere il *lock* prima di modificare il nome di un oggetto.
830 un altro *lock* è necessario per la protezione del nome.
832 Teoricamente, possiamo avere un *lock* per ogni campo e per ogni oggetto.
835 - un *lock* che protegge l'infrastruttura (la lista ``cache`` di questo
838 - un *lock* che protegge l'infrastruttura (inclusi i puntatori alla lista
839 negli oggetti), e un *lock* nell'oggetto per proteggere il resto
842 - *lock* multipli per proteggere l'infrastruttura (per esempio un *lock*
843 per ogni lista), possibilmente con un *lock* per oggetto.
845 Qui di seguito un'implementazione con "un lock per oggetto":
891 Inoltre, da notare che ho aggiunto un commento che descrive i dati che sono
904 Esiste un tipo di baco dove un pezzo di codice tenta di trattenere uno
911 Un caso un pochino più complesso; immaginate d'avere una spazio condiviso
912 fra un softirq ed il contesto utente. Se usate spin_lock() per
913 proteggerlo, il contesto utente potrebbe essere interrotto da un softirq
918 può succedere anche con un solo processore (Ma non sui sistemi
928 Esiste un caso più complesso che è conosciuto come l'abbraccio della morte;
929 questo coinvolge due o più *lock*. Diciamo che avete un vettore di hash in cui
931 stesso hash. In un gestore di interruzioni software, dovete modificare un
932 oggetto e spostarlo su un altro hash; quindi dovrete trattenete lo spinlock
936 Qui abbiamo due problemi. Primo, se il vostro codice prova a spostare un
939 interruzione software su un altro processore sta tentando di spostare
940 un altro oggetto nella direzione opposta, potrebbe accadere quanto segue:
953 aspettando che l'altro lo rilasci. Sembra e puzza come un blocco totale.
959 ordine non avrete mai un simile stallo. La pratica vi dirà che questo
960 approccio non funziona all'ingrandirsi del sistema: quando creo un nuovo
967 non tenterà mai di trattenere un altro *lock* quando lo ha già.
972 chiamate mentre trattenete un *lock*, rischiate uno stallo o un abbraccio
978 Gli stalli sono un problema, ma non così terribile come la corruzione dei dati.
979 Un pezzo di codice trattiene un *lock* di lettura, cerca in una lista,
981 trattiene un *lock* di scrittura ed inserisce un oggetto; questo genere di
987 corsa fra temporizzatori: un passatempo del kernel
992 ha un temporizzatore che sta per distruggerlo.
994 Se volete eliminare l'intera collezione (diciamo quando rimuovete un modulo),
1010 Primo o poi, questo esploderà su un sistema multiprocessore perché un
1038 Dato che questo è un problema abbastanza comune con una propensione
1048 la velocità d'esecuzione di un pezzo di codice che necessita di
1050 mentre qualcuno trattiene un *lock*. La seconda è il tempo necessario per
1051 acquisire (senza contese) e rilasciare un *lock*. La terza è di usare meno
1055 La concorrenza dipende da quanto a lungo un *lock* è trattenuto: dovreste
1056 trattenere un *lock* solo il tempo minimo necessario ma non un istante in più.
1061 Il tempo di acquisizione di un *lock* dipende da quanto danno fa
1066 rapidamente. Consideriamo un processore Intel Pentium III a 700Mhz: questo
1067 esegue un'istruzione in 0.7ns, un incremento atomico richiede 58ns, acquisire
1068 un *lock* che è nella memoria cache del processore richiede 160ns, e un
1069 trasferimento dalla memoria cache di un altro processore richiede altri
1073 Questi due obiettivi sono in conflitto: trattenere un *lock* per il minor
1075 parti (come nel nostro ultimo esempio con un *lock* per ogni oggetto),
1077 spesso è che tutto è più lento che con un singolo *lock*. Questo è un altro
1103 Esiste un metodo di sincronizzazione per letture e scritture detto
1108 un'ottimizzazione.
1135 Rimuovere un elemento dalla lista è anche più facile: sostituiamo il puntatore
1157 l'elemento rimosso? Ricordate, un lettore potrebbe aver avuto accesso a questo
1175 dedurre che un qualsiasi lettore che abbia consultato la lista durante la
1177 codice RCU è un po' più ottimizzato di così, ma questa è l'idea di fondo.
1260 che ne abbiamo fatto qui, non ci interessano queste corse critiche perché un
1264 sincronizzazione con le altre funzioni, quindi è veloce su un sistema
1265 multi-processore tanto quanto lo sarebbe su un sistema mono-processore.
1267 Esiste un'ulteriore ottimizzazione possibile: vi ricordate il codice originale
1269 semplicemente tratteneva il *lock* prima di accedere ad un oggetto? Questo è
1270 ancora possibile: se trattenete un *lock* nessuno potrà cancellare l'oggetto,
1274 Ora, dato che il '*lock* di lettura' di un RCU non fa altro che disabilitare
1275 la prelazione, un chiamante che ha sempre la prelazione disabilitata fra le
1292 avere un contatore di qualcosa, potreste utilizzare uno spinlock ed un
1296 dimostrato che lo è devvero), potreste usare un contatore per ogni processore
1306 Da notare che non esiste un modo facile ed affidabile per ottenere il valore
1307 di un simile contatore senza introdurre altri *lock*. In alcuni casi questo
1308 non è un problema.
1319 se i dati vengono occasionalmente utilizzati da un contesto utente o
1320 da un'interruzione software. Il gestore d'interruzione non utilizza alcun
1331 un altro processore). Lo spinlock, invece, previene accessi simultanei.
1344 dovete necessariamente essere nel contesto utente: chiamarle da un
1354 aspettano d'essere chiamante da un contesto utente e quindi che possono
1373 Comunque, non deve essere usata in un contesto d'interruzione dato
1376 usata in un contesto d'interruzione perché un mutex deve essere rilasciato
1383 contesto, o trattenendo un qualsiasi *lock*.
1425 pulita e aggiunto un po' di stile.
1451 sostituiti dai tasklet. In un dato momento potrà esserci solo un
1459 Il kernel che esegue qualcosa per conto di un particolare processo (per
1460 esempio una chiamata di sistema) o di un thread del kernel. Potete
1466 Richiesta di interruzione hardware. in_irq() ritorna vero in un
1474 In soldoni, un softirq è uno delle 32 interruzioni software che possono
1479 (Uni-Processor) un solo processore, ovvero non è SMP. (``CONFIG_SMP=n``).
1490 d'essere eseguita solo su un processore alla volta.
1494 (circa) in un determinato momento. Quando è in esecuzione è come un tasklet