> Prosesin sayfalarının "lock" edilmesi: Anımsanacağınız üzere prosesin sanal bellek tablosu dolduğunda, işletim sistemi bazı programların daha az kullanılan sayfalarını ilgili tablodan çıkartıyordu ("swap out"). İşte bunu engellemek için de bir mekanizma geliştirilmiştir. Bu mekanizma sayesinde "swap out" engellenmektedir. Böylelikle şu iki avantaja sahip olabiliriz; -> "swap in/out" yapılmayacağı için görece bir hız kazancı elde edebiliriz. Fakat "Real Time OS" sistemlerde bu tip kız kazançları önemli olabilir. -> "swap" dosyalarından bilgi çalmak isteyen kişiler de engellenmiş olur. Bu mekanizmayı bir takım alternatif yönmtemlerle kullanabiliriz. Örneğin, "mmap" fonksiyonunun dördüncü parametresine "MAP_LOCKED" bayrağını geçmemiz, "mapping" sırasında ilgili sayfayı da kilitleyecektir. Fakat bu bayrak POSIX standartlarında mevcut değildir. Linux ve türevi sistemlerde, belli bir "kernel" serisinden itibaren kullanılabilir. Buna ek olarak "mlock" fonksiyonlarını kullanabiliriz. Son olarak bir prosesin, normal kullanıcılar tarafından, en fazla kaç sayfasının kilitlenebileceği "RLIMIT_MEMLOCK" isimli değer ile sınırlandırılmıştır. >> "RLIMIT_MEMLOCK" : Bünyesinde iki adet alt limit barındırır. Bunlar "soft-limit" ve "hard-limit" değerleridir. Her iki limit değerinin kaç olduğu "ulimit -a" kabuk komutu ile öğrenebiliriz. Örneğin, bazı sistemlerde "64 kB", bazılarında "497904 kB" değerindedir. Tabii uygun önceliğe sahip prosesler ("root" veya "appropriate priviledged users") bu limit değerine takılmamaktadır. Şimdi de "lock" işlemini gerçekleştirme yöntemlerini inceleyelim. >> "mlock" isimli fonksiyon aşağıdaki prototipe sahiptir: #include int mlock(const void *addr, size_t len); Fonksiyon birinci parametresiyle başlangıç adresini, ikinci parametresiyle de uzunluk bilgisini almaktadır. Buradaki "addr + len" içerisinde kalan bütün sayfalar "lock" edilmektedir. Örneğin, "addr" adresi bir sayfanın ortasına denk gelmektedir. "addr + len" konumu da bir sonraki sayfaya tekabül eder olsun. Bu fonksiyon her iki sayfayı da "lock" etmektedir. POSIX standartlarınca "addr" değerinin sayfa katlarında olması bir zorunluluk değildir. Bu zorunluluğu işletim sistemini yazanlara bırakmıştır. Benzer şekilde Linux sistemlerinde de bu değerin sayfa katlarında olması bir zorunluluk değildir. İkinci parametre herhangi bir değerde olabilir. Fonksiyonun geri dönüş değeri ise başarı durumuna göre "0", başarısızlık durumunda "-1" ile geri döner ve herhangi bir değişiklik yapmaz. Yani ("No changes is made to any locks"). Tabii burada kısmi kilitleme de yapılmamaktadır. "errno" değişkeni de uygun biçimde "set" edilir. Bu fonksiyon ile genellikle "mapping" yaptığımız adresleri kilitleriz. * Örnek 1, Aşağıdaki örnekte ilgili adres değeri sayfa katları olacak şekilde yeniden ayarlanmıştır. #include #include #include #include void exit_sys(const char* msg); char buffer[4096]; int main(void) { /* # OUTPUT # Address : [0x556bbafaa000] Ok */ void* addr = (void*)((uintptr_t)buffer & ~0xFFF); printf("Address : [%p]\n", addr); if(mlock(addr, 4096) == -1) exit_sys("mlock"); puts("Ok"); return 0; } void exit_sys(const char* msg) { perror(msg); exit(EXIT_FAILURE); } * Örnek 2, Aşağıdaki örnekte ilgili adres değeri direkt olarak kullanılmıştır. #include #include #include void exit_sys(const char* msg); char buffer[4096]; int main(void) { /* # OUTPUT # Address : [0x563cdb255040] Ok */ printf("Address : [%p]\n", buffer); if(mlock(buffer, 4096) == -1) exit_sys("mlock"); puts("Ok"); return 0; } void exit_sys(const char* msg) { perror(msg); exit(EXIT_FAILURE); } Bu fonksiyon ile kilitlenmeye çalışılan sayfalar o anda bellekte değilse, bu fonksiyon ilgili sayfaları önce belleğe almakta ve devamında kilitleme işlemini gerçekleştirmektedir. Dolayısıyla bu fonksiyon başarılı bir şekilde geri döndüyse, ilgili sayfaların kilitlenmiş olması garanti edilmiştir. >> "mmap" fonksiyonu kullanılarak sayfaların kilitlenmesi: "mmap" fonksiyonunun "flags" isimli dördüncü parametresine "MAP_LOCKED" bayrağını geçerek "map" yaptığımız alanları aynı zamanda "lock" edebiliriz. Tabii bu işlem sırasında da "RLIMIT_MEMLOCK" isimli limit değerine takılabiliriz. Fakat Linux sistemlerindeki bu bayrak, talep edilen bütün sayfaları belleğe çekemeyebilir. Bu durumda ilgili "mmap" fonksiyonu BAŞARISIZ OLMAMAKTADIR. >> "mlockall" fonksiyonu: Bir POSIX fonksiyonu olup, bir prosesin bütün sayfalarını "lock" eder. Aşağıdaki parametrik yapıya sahiptir: #include int mlockall(int flags); Fonksiyonun parametresi şu bayrak değerlerinden bir yada bir kaçını alabilir: "MCL_CURRENT" ve "MCL_FUTURE". Bu bayraklardan, -> "MCL_CURRENT" : An itibariyle bellekte bulunan bütün sayfaların kilitleneceği anlamına gelir. -> "MCL_FUTURE" : Şu andan itibaren belleğe aktarılacak olan bütün sayfaların kilitleneceği anlamına gelir. Bu bayrakları "bit-wise OR" işlemine sokarak beraber kullanabiliriz. Fonksiyonun geri dönüş değeri de başarı ya da başarısızlık durumuna göre sırasıyla "0" ya da "-1" biçimindedir. Fakat bu fonksiyonu kullanırken "RLIMIT_MEMLOCK" isimli limit değerine takılabiliriz. > Prosesin sayfalarının "unlock" edilmesi: Bu işlemi gerçekleştirmek için "munlock" isimli POSIX fonksiyonunu kullanabiliriz. >> "munlock" fonksiyonu aşağıdaki parametrik yapıya sahiptir: #include int munlock(const void *addr, size_t len); Fonksiyonun birinci parametresi "unlock" edilecek sayfaya ilişkin adres bilgisi, ikinci parametre ise uzunluk bilgisidir. Tıpkı "mlock" fonksiyonunda olduğu gibi ilgili adres bilgilerinin bulunduğu sayfalar "unlock" edilecektir. Fonksiyon başarı durumunda "0" ile başarısızlık durumunda "-1" ile geri dönecektir. Aşağıdaki biçimde kullanımı vardır: if(munlock(buffer, 4096) == -1) exit_sys("munlock"); Tabii programın sonlanmasıyla otomatik olarak "unlock" işlemi gerçekleştirilmektedir. Öte yandan birden fazla "lock" işlemini de tek bir "munlock" fonksiyon çağrısı ile "unlock" yapabiliriz. Bütün bunlara ek olarak, "munlockall" isimli POSIX fonksiyonu ile bir prosesin bütün sayfalarını "unlock" edebiliriz. >> "munlockall" fonksiyonu aşağıdaki parametrik yapıya sahiptir: #include int munlockall(void); Tabii bu fonksiyon da yukarıda belirtilen "RLIMIT_MEMLOCK" değerine takılabilir.