Arka fon:
Sistem çağrısı yükü, çoğunlukla kullanıcı alanından çekirdek alanına ve geri içeriğe geçiş nedeniyle işlev çağrısı yükünden (tahminler 20-100x arasında değişir) çok daha büyüktür. İşlev çağrısı ek yükünü kaydetmek için satır içi işlevlerin yaygın olması ve işlev çağrıları sistem çağrılarından çok daha ucuzdur. Geliştiricilerin, bir sistem çağında mümkün olduğunca çok çekirdek içi işlemle ilgilenerek bazı sistem çağrısı yüklerinden kaçınmak istedikleri mantıklıdır.
Sorun:
Bu gibi (? Gereksiz) sistemi bir çok görüşme yarattı sendmmsg () , recvmmsg () kuyu gibi Chdir açık, lseek ve / veya sembolik bağı kombinasyonları gibi: openat
, mkdirat
, mknodat
, fchownat
, futimesat
, newfstatat
, unlinkat
, fchdir
, ftruncate
, fchmod
, renameat
, linkat
, symlinkat
, readlinkat
, fchmodat
, faccessat
, lsetxattr
, fsetxattr
, execveat
, lgetxattr
, llistxattr
, lremovexattr
, fremovexattr
, flistxattr
, fgetxattr
, pread
, pwrite
vb ...
Şimdi Linux copy_file_range()
okuma lseek ve yazma sistem çağrılarını birleştiren ekledi . Bunun fcopy_file_range (), lcopy_file_range (), copy_file_rangeat (), fcopy_file_rangeat () ve lcopy_file_rangeat () haline gelmesi sadece bir zaman meselesidir ... ancak X daha fazla çağrı yerine 2 dosya olduğu için X ^ 2 olabilir Daha. Tamam, Linus ve çeşitli BSD geliştiricileri, bu kadar ileri gitmesine izin vermedi, ancak benim açımdan, bir toplu sistem sistemi olsaydı, bunların hepsinin (en çok?) Kullanıcı alanına uygulanabileceği ve çok fazla eklemeden çekirdek karmaşıklığını azaltabileceği libc tarafında herhangi bir ek yük varsa.
Toplu işlem sistem çağrılarını bloke etmeyen sistem çağrıları için bazı özel sistem çağrısı ipliği içeren birçok karmaşık çözüm önerilmiştir; ancak bu yöntemler hem çekirdeğe hem de kullanıcı alanına libxcb ve libX11 ile aynı şekilde karmaşıklık katar (eşzamansız çağrılar çok daha fazla kurulum gerektirir)
Çözüm?:
Genel bir yığın sistem çağrısı. Bu, özel çekirdek iş parçacığına sahip olmayla ilgili karmaşıklıklar olmadan en büyük maliyeti (çoklu mod anahtarları) azaltacaktır (ancak bu işlevsellik daha sonra eklenebilir).
Temel olarak socketcall () sistem çağrısında bir prototip için zaten iyi bir temel vardır. Bunun yerine, bir dizi argüman almak, işaretçi argüman dizilerine (sistem çağrı numarasını içeren), sistem çağrılarının sayısını ve bayrak argümanını almak için bir dizi argüman almaktan uzatın ...
batch(void *returns, void *args, long ncalls, long flags);
Bir önemli fark argümanlar muhtemelen olacağını olacağını tüm önceki sistem çağrıları sonuçları (gelen örneğin dosya tanıtıcı müteakip sistem çağrıları tarafından kullanılabilir böylece ihtiyaç basitlik için işaretçileri olmak open()
kullanılmak üzere read()
/ ' write()
)
Bazı olası avantajlar:
- daha az kullanıcı alanı -> çekirdek alanı -> kullanıcı alanı değiştirme
- Otomatik derleme yapmaya çalışmak için olası derleyici anahtarı -fcombine-syscalls
- eşzamansız çalışma için isteğe bağlı bayrak (hemen izlemek için fd döndür)
- gelecekteki birleşik sistem çağrılarını kullanıcı alanında uygulama becerisi
Soru:
Yığınlı bir sistem çağrısı uygulamak mümkün müdür?
- Bazı bariz yakaları kaçırıyor muyum?
- Avantajları fazla tahmin ediyor muyum?
Toplu bir sistem çağrısı uygulama zahmetine girmem bana değer mi (Intel, Google veya Redhat'ta çalışmıyorum)?
- Daha önce kendi çekirdeğimi yamaladım, ancak LKML ile uğraşmaktan korktum.
- Geçmiş, "normal" kullanıcılar (git yazma erişimi olmayan kurumsal olmayan son kullanıcılar) için yaygın olarak yararlı bir şey olsa bile, asla yukarı akışa kabul edilmeyebileceğini (unionfs, aufs, cryptodev, smokin vb.)
Referanslar:
batch
Sistem çağrılarını sistembatch
çağrılarına yerleştirerek , keyfi sistem çağrılarının keyfi olarak derin bir çağrı ağacı oluşturabilirsiniz. Temel olarak, tüm uygulamanızı tek bir sisteme koyabilirsiniz.