C programcıları genellikle değişkenin mevcut yürütme iş parçasının dışında değiştirilebileceği anlamına gelen uçucu hale gelmiştir; sonuç olarak, paylaşılan veri yapıları kullanıldığında bazen çekirdek kodunda kullanmaya eğilimlidirler. Başka bir deyişle, uçucu türleri, kolay olmayan bir tür atomik değişken olarak tedavi ettikleri bilinmektedir. Çekirdek kodunda uçucu kullanımı neredeyse hiçbir zaman doğru değildir; bu belge nedenini açıklamaktadır.
Değişken ile ilgili anlaşılması gereken kilit nokta, amacının optimizasyonu bastırmaktır, ki bu aslında hiç yapmak istemediği şeydir. Çekirdekte, paylaşılan veri yapılarını, çok farklı bir görev olan istenmeyen eşzamanlı erişime karşı korumak gerekir. İstenmeyen eşzamanlılığa karşı koruma süreci, optimizasyonla ilgili neredeyse tüm sorunları daha verimli bir şekilde önleyecektir.
Uçucu gibi, verilere aynı anda erişimi sağlayan çekirdek ilkelleri (kilitlenmeler, muteksler, bellek bariyerleri, vb.) İstenmeyen optimizasyonu önlemek için tasarlanmıştır. Düzgün bir şekilde kullanılıyorlarsa, uçucu da kullanmaya gerek kalmayacaktır. Uçucu hala gerekliyse, kodda bir yerde neredeyse kesinlikle bir hata vardır. Düzgün yazılmış çekirdek kodunda, uçucu yalnızca işleri yavaşlatmaya yarar.
Tipik bir çekirdek kodu bloğunu düşünün:
spin_lock(&the_lock);
do_something_on(&shared_data);
do_something_else_with(&shared_data);
spin_unlock(&the_lock);
Tüm kod kilitleme kurallarına uyarsa, the_lock basılıyken shared_data değeri beklenmedik şekilde değişemez. Bu verilerle oynamak isteyebilecek diğer tüm kodlar kilitte bekliyor olacaktır. Spinlock ilkelleri bellek bariyerleri gibi davranırlar - açıkça yapmak için yazılırlar - yani veri erişimleri bunlar arasında optimize edilmez. Böylece derleyici, paylaşılan_verilerde ne olacağını bildiğini düşünebilir, ancak spin_lock () çağrısı, bir bellek engeli görevi gördüğünden, bildiği her şeyi unutmaya zorlar. Bu verilere erişimde hiçbir optimizasyon problemi olmayacaktır.
Shared_data değişken olarak bildirilirse, kilitleme yine de gerekli olacaktır. Ancak, başka kimsenin onunla çalışamayacağını bildiğimizde , derleyicinin kritik bölüm içindeki paylaşılan_verilere erişimi optimize etmesi de engellenir . Kilit basılı tutulurken shared_data değişken olmaz. Paylaşılan verilerle uğraşırken uygun kilitleme, uçucu gereksiz ve potansiyel olarak zararlı hale getirir.
Uçucu depolama sınıfı başlangıçta bellek eşlemeli G / Ç kayıtları içindir. Çekirdek içinde, yazmaç erişimi de kilitlerle korunmalıdır, ancak derleyici kritik bir bölüm içinde kayıt erişimini "optimize etmek" istemez. Ancak, çekirdek içinde G / Ç bellek erişimleri her zaman erişimci işlevleri aracılığıyla yapılır; G / Ç belleğine doğrudan işaretçilerden erişerek kaşlarını çatar ve tüm mimarilerde çalışmaz. Bu erişimciler istenmeyen optimizasyonu önlemek için yazılmıştır, bu nedenle bir kez daha uçucu olmak gereksizdir.
Birinin uçucu kullanmak için cazip gelebileceği bir başka durum, işlemcinin bir değişkenin değerini beklerken meşgul olmasıdır. Yoğun bir bekleme gerçekleştirmenin doğru yolu:
while (my_variable != what_i_want)
cpu_relax();
Cpu_relax () çağrısı, CPU güç tüketimini azaltabilir veya hiper iş parçacıklı bir çift işlemciye verim verebilir; aynı zamanda bir bellek engeli görevi görür, bu yüzden bir kez daha uçucu olmak gereksizdir. Tabii ki, meşgul beklemek genellikle başlamak için anti-sosyal bir eylemdir.
Çekirdeğin içinde uçucunun mantıklı olduğu birkaç nadir durum vardır:
Yukarıda belirtilen erişimci işlevleri, doğrudan G / Ç bellek erişiminin çalıştığı mimarilerde uçucu olabilir. Esasen, her erişimci çağrısı kendi başına küçük bir kritik bölüm haline gelir ve erişimin programcı tarafından beklendiği gibi gerçekleşmesini sağlar.
Belleği değiştiren, ancak başka görünür yan etkisi olmayan satıriçi montaj kodu, GCC tarafından silinme riskidir. Asm ifadelerine geçici anahtar kelime eklemek bu kaldırmayı önleyecektir.
Jiffies değişkeni, her başvuru yapıldığında farklı bir değere sahip olabileceği için özeldir, ancak herhangi bir özel kilitleme olmadan okunabilir. Yani jiffies uçucu olabilir, ancak bu tipteki diğer değişkenlerin eklenmesi kesinlikle kaşlarını çatmıştır. Jiffies bu konuda bir "aptal miras" sorunu (Linus'un sözleri) olarak kabul edilir; sabitlemek değerinden daha fazla sorun olurdu.
G / Ç aygıtları tarafından değiştirilebilen tutarlı bellekteki veri yapılarına işaretçiler, bazen yasal olarak değişken olabilir. Ağ bağdaştırıcısı tarafından kullanılan ve bağdaştırıcının hangi tanımlayıcıların işlendiğini belirtmek için işaretçileri değiştirdiği bir halka arabelleği, bu tür bir duruma örnektir.
Çoğu kod için, uçucuya ilişkin yukarıdaki gerekçelerin hiçbiri geçerli değildir. Sonuç olarak, uçucu madde kullanımının bir hata olarak görülmesi muhtemeldir ve koda ilave inceleme getirecektir. Uçucu kullanmaya meyilli olan geliştiriciler geri adım atmalı ve gerçekten neyi başarmaya çalıştıklarını düşünmelidir.