HEAP SİSTEMİ Oğuz Karan [V: 1] Özet: Bu makalede heap sistemi hakkında bilgiler verilmiş ve çeşitli sistemlerde heap sisteminin aşağı seviyeli çalışması anlatılmıştır. Ayrıca son bölümde CSD işletim sisteminin heap sisteminde kullanılan yapılar ve sistem fonksiyonlarının aşağı seviyeli çalışma biçimleri üzerinde durulmuştur. 1. GİRİŞ Bir programın çalışma zamanı sırasında bellekte ardışıl(sürekli) olarak belli büyüklükte yer tahsis etmesine ve istediğinde geri bırakmasına imkan sağlayan işlemlere dinamik bellek işlemleri, tahsis etme işlemine ise dinamik bellek tahsisatı denir. Dinamik bellek tahsisatı hemen hemen tüm büyük programların çalışma zamanı sırasında ihtiyaca göre kullanılmaktadır. Standart C kütüphanesinde dinamik tahsisat için kullanılan fonksiyonlar mevcuttur. Bunun yanında derleyicilerin de dinamik tahsisat işlemlerini gerçekleştiren kendi oluşturdukları çeşitli fonksiyonlar olabilir. Her ne şekilde olursa olsun bu fonksiyonlar dinamik tahsisatlar için işletim sistemine başvururlar. Yani bu fonksiyonlar kendi içlerinde işletim sisteminin kendi sistem fonksiyonlarını kullanarak dinamik tahsisat işlemini gerçekleştirirler. Dinamik bellek fonksiyonlarının tahsisat işlemini gerçekleştirdileri bellek bölgelerine heap denir. İşletim sistemleri bir processi belleğe yüklediğinde, bu process için heap alanını çeşitli biçimlerde oluştururlar. Heap oluşturulma işlemi sistemler arasında farklılık gösterebilir. 2. PROCESS’LERİN HEAP ALANLARI HAKKINDA GENEL BİLGİLER 2.1 Dos İşletim Sisteminde Processlerin Heap Alanları DOS .com ve .exe dosyalarını belleğe yüklemek için o andaki tüm boş belleği tahsis eder. Program yüklenirken ya da derleyicinin oluşturduğu başlangıç kodu tarafından yapılan bu tahsisatlarda DOS’ un INT 21h, Function:48h,ve INT 21h, Funtion:49h kesmeleri kullanılır. Standart C kütüphanesinin dinamik tahsisat işlemini gerçekleştiren malloc ve diğer fonksiyonlar tahsis edilmiş bellek bölgelerini kendi içlerinde bir tabloda tutarlar. DOS zaten tüm boş alanı tahsis ettiğinden tutulan bu tablo yaterlidir. DOS tek işlemli(singleprocessing) bir işletim sistemi olduğundan bir program bellekteyken diğer program bellekte olamaz. 2.2 Win32 Sistemlerinde Processlerin Heap Alanları Win32 sistemlerinin heap yapısı bir processin birden çok heap’i olabilecek biçiminde tasarlanmıştır. Yani tahsis edilebilecek olan tüm boş bölgeler tek bir heap biçiminde değil birden çok heap oluşturulabilecek biçimde organize edilmiştir. Ayrıca Win32 sistemlerinde bir process CreateProcess API fonksiyonu ile yaratıldığında processin varsayılan (default) bir heap alanı vardır. Yaratılan heap bölgeleri işletim sistemi tarafından bir bağlı listede tutulmaktadır. Her bir heap içerisinde boş bölgeler dört farklı bağlı listede tutulur. Bu bağlı listelerin herbiri farklı 1 C ve Sistem Programcıları Derneği - CSD İşletim Sistemi Geliştirme Projesi uzunlukta boş bölgeleri tutar. Böylece yapılacak tahsisat uzunluğuna göre uygun bağlı liste bulunarak tahsisat gerçekleştirilebilir. Bu teknik ile bellek bölünmesi en aza indirilmiştir. Win32 sistemlerinin heap sistemi için bir diğer özelliği heap bölgesinin otomatik olarak büyüyebilmesidir. Bu işlem heap bölgesi yaratılırken belirlenebilmektedir. Heap bölgesinin büyütülebilmesi için oluşturulan yeni alanlara altheap (subheap) denmektedir. Buna göre bir processin heap durumu aşağıdaki gibidir. Heap alanı Heap alanı Alt heap Processin varsayılan heap’i Alt heap Processin default heap’ i eğer derleyicinin seçeneklerinden ayarlanmamışsa 1MB ile sınırlıdır. Win32 sistemlerinde bir heap bölgesi başlık kısmı ile başlamaktadır. Bu başlık kısmında heap alanını uzunluğu, boş alanların tutulacağı veri yapısı türünden dizi, kritik kod nesnesi ve diğer değişkenler gibi heap alanına ilişkin çeşitli kritik bilgiler bulunmaktadır. Tabii buradaki elamanların bir kısmı kontrol amaçlı olup yalnızca debug versiyonunda kullanılacak biçimde organize edilmiştir. Başlık kısmından hemen sonra heap blokları gelmektedir. Bu heap blokları da debug versiyonunda farklılık göstermektedir. Bu durumda heap alanının görünümü aşağıdaki gibi olur. Heap Alanının Başlık Kısmı Heap Bölgesi 2 C ve Sistem Programcıları Derneği - CSD İşletim Sistemi Geliştirme Projesi 2.2.1. Win32 Sistemlerinde Heap Alanının Başlık Kısmı Win32 sistemlerinde yeni bir heap alanı HeapCreate API fonksiyonu ile yaratılmaktadır. Ayrıca process’in varsayılan heap’i de bulunmaktadır. Process’in ihtiyacı olan dinamik tahsisatlar HeapCreate veya GetProcessHeap fonksiyonlarından elde edilen handle değerleri kullanılarak işletim sisteminin tahsisat fonksiyonları ile yapılmaktadır. Heap handle değeri heap alanının başlık kısmını gösteren adrestir. Heap alanının başlık kısmına ilişkin yapının elemanları debug versiyonunda farklılık gösterebilir. Ancak genel olarak biçimi aynıdır. DWORD dwSize: Heap üzerindeki tahsisat yapılacak bölgenin uzunluğudur. Process’in default heap’ i için bu uzunluk 1MB’dir. Bu eleman tüm versiyonlarda bulunmaktadır. DWORD nextBlock: İşletim sistemi heap bölgesi otomatik büyüyebilecek biçimde yaratılmışsa (yani HeapCreate fonksiyonunun son parametresi 0 (sıfır) olarak girilmişse) yaratılan alt heapleri bir bağlı listede tutar. Bu bağlı listenin bir sonraki elemanı bu değişkende saklanmaktadır. Bu eleman tüm versiyonlarda bulunmaktadır. FREE_LIST_HEADER_RETAIL/FREE_LIST_HEADER_DEBUG freeListArray[4]: Bu dizi boş bağlı listeleri belirtir. Bu dizi elemanları boyutu 20h’ den küçük, 80h’ den küçük, 200h’ den küçük ve FFFFFFFFh‘den küçük blokların listesini ifade etmektedir. Buna göre tahsis edilmek istenen boyuta göre uygun bağlı liste bulunarak arama yapılır. FREE_LIST_HEADER_DEBUG yapısı debug versiyonu için kullanılmaktadır. PVOID nextHeap: Bu eleman processin yaratılan diğer heap alanını göstermektedir. Tüm versiyonlarda kullanılmaktadır. HCRITICAL_SECTION hCriticalSection: Heap’ e erişimde kernel tarafından oluşturulan ve heap fonksiyonlarının senkronizasyon amaçlı kullandıkları kritik bölgenin hendle değeridir. Tüm versiyonlarda kullanılmaktadır. CRITICAL_SECTION criticalSection: Heap alanı için senkronizasyon amaçlı kullanılmaktadır. Kritik koda girildiğinde kernel EnterCriticalSection fonksiyonu ile bu elemanı kullanarak senkronizasyonu sağlamaktadır. Senkronizasyon istenip istenmeyeceği heap yaratılırken ya da heap üzerinde tahsisat durumunda belirlenebilmektedir. Bu eleman tüm versiyonlarda kullanılmaktadır. DWORD unknown1[14]: Bu elemanın ne olduğu bilinmemektedir. Tüm versiyonlarda kullanılmaktadır. DWORD creatingEIP: Heap yaratılıken heap i oluşturan HPInit kernel fonksiyonun EIP yazmacının değerini tutmaktadır. Sadece debug versiyonunda kullanılmaktadır. DWORD checksum: Heap’ in durumunu kontrol için kullanılır. dwSize elamanını XOR lanmış değeri bulunur. Sadece debug versiyonunda kullanılmaktadır. WORD creatingthreadnumber: Heap’ i yaratan threadin numarasını tutmaktadır. Sadece debug versiyonunda kullanılmaktadır. WORD unknown2: Bu elemanın da ne olduğu bilinmemektedir. Sadece debug versiyonunda kullanılmaktadır. BYTE flags: Heap alanı HeapCreate fonksiyonu ile yaratılırken heap’in durumunu belirleyen bit bit anlamlı değerleri tutar. Tüm versiyonlarda kullanılmaktadır. BYTE unknown3: Bu elemanın da ne olduğu tam olarak bilinmemektedir. Tüm versiyonlarda kullanılmaktadır. WORD signature: Bu eleman heap’in hangi heap olduğunu belirlemekte kullanılmaktadır. Tüm versiyonlarda bulunur. 3 C ve Sistem Programcıları Derneği - CSD İşletim Sistemi Geliştirme Projesi 2.2.2. Win32 Sistemlerinde Heap Bölgesi Heap yaratıldığında başlık kısmından hemen sonraki bölüm olan heap bölgesi dinamik tahsisatların yapıldığı bölgedir. Bu bölgede tahsis edilmiş bloklar ve boş bloklar bulunmaktadır. Bilindiği gibi boş bloklar 4 farklı bağlı liste ile tutulmaktadır. 2.2.2.1. Tahsis edilmiş(In-Use) Bloklara İlişkin Yapının Elemanları Tahsis edilmiş bloklara ilişkin yapının elemanları debug versiyonunda farklı olabilmektedir. DWORD size: Tahsis edilen bloğun uzunluğunu gösteren elemandır. Tüm versiyonlarda bulunur. DWORD allocating EIP: Bloğun tahsis edildiği yani HeapAlloc veya HeapRealloc fonksiyonlarının çağrıldığı kodun offset değerini (program adresini) tutar. Sadece debug versiyonunda bulunur. WORD threadnumber: Alanı tahsis eden threadin numarasını tutmaktadır. Sadece Debug versiyonunda kullanılır. WORD signature: Bloğun tahsis edilmiş olup olmadığını gösterir. Tahsis edilmiş bloklar için 0x4842 özel değeri kullanılır. Sadece debug versiyonunda bulunur. DWORD checksum: Diğer elemanların checksum değerini tutar. Yapıda bir bozulma olup olmadığının kontrolü için yalnızca debug versiyonunda bulunur. 2.2.2.2. Boş (free) Bloklara İlişkin Yapının Elemanları Boş bloklara ilişkin yapının elemanları da debug versiyonunda farklı elemanlar içermektedir. DWORD size: Boş bloğun uzunluğunu gösteren elemandır. Tüm versiyonlarda kullanılmaktadır. DWORD prev: Bir önceki boş bloğu göstermektedir. Tüm versiyonlarda kullanılmaktadır. WORD threadnumber: Bu elaman boş bloklar için 0xFEFE özel değerini alır. Sadece debug versiyonunda bulunmaktadır. WORD signature: Bloğun boş olup olmadığını göstermektedir. Boş bloklar için 0x4846 özel değeri kullanılmaktadır. Sadece debug versiyonunda kullanılmaktadır. DWORD next: Bir sonraki boş bloğu göstermektedir. Tüm versiyonlarda kullanılmaktadır. DWORD checksum: Yapıdaki diğer elemanların checksum değerini tutar. Yapıda bir bozulma olup olmadığının kontrolü için yalnızca debug versiyonunda bulunur. 2.3 UNIX/LINUX SİSTEMLERİNDE PROCESSLERİN HEAP ALANLARI UNIX/LINUX sistemlerinin genelinde bir process belleğe yüklendiğinde ilgili processin bellek alanı aşağıdaki gibidir. .text .data .bss HEAP .stack STACK 4 C ve Sistem Programcıları Derneği - CSD İşletim Sistemi Geliştirme Projesi Görüldüğü gibi heap için .stack ile .bss arasında belirli bir bölge ayrılmaktadır. Tahsisat işlemleri tahsisat yapan fonksiyonlar tarafından bu bölgede gerçekleştirilir. Tahsisat yapan fonksiyonlar kendi içlerinde sistem fonksiyonu olan sbrk fonksiyonunu çağırırlar. UNIX/LINUX sistemlerinde de boş olan bloklar bir bağlı listede tutulur. Boş blokların herbirinde bloğun uzunluğu ve bir sonraki bloğun adresi tutulur. Bağlı listenin son elemanı olan blok en baştaki bloğu gösterir. Böylece boş bloklar döngüsel bir bağlı liste ile tutulmuş olur. Buna göre UNIX/LINUX sistemlerinde heap aşağıdaki gibi bir görünümdedir. HEAP Boş Kullanımda Boş Kullanımda Henüz tahsisat yapılmamış Kullanımda Boş Henüz tahsisat yapılmamış Boş Yapılacak tahsisatlar için çeşitli algoritmalar kullanılmaktadır. Bunlardan biri first fit algoritmasıdır. Bu algoritmaya göre tahsisat durumunda yeterince büyük ilk blok bulunduğunda tahsisat yapılır. Diğer bir algoritma ise best fit algoritmasıdır. Bu algoritmaya göre tahsisat için gereken alanın en uygunu aranır. Bulunan blok istenen uzunluktaysa bu blok bağlı listeden çıkartılır. Bulunan blok istenen uzunluktan büyükse istenen uzunluk kadarı alınır. Geri kalan kısım bağlı listeye eklenir. Eğer herhangi bir alan bulunamıyorsa henüz tahsisat yapılmamış alanlardan tahsisat işlemi gerçekleştirilir. 5 C ve Sistem Programcıları Derneği - CSD İşletim Sistemi Geliştirme Projesi 3. CSD İŞLETİM SİSTEMİNİN HEAP YAPISI CSD işletim sisteminin heap yapısı birden çok heap oluşturulabilecek biçimde tasarlanmıştır. Bu sisteme göre bir process bir heap yarattığında bir sistem fonksiyonu yardımıyla bir handle alanı ve bu handle alanına ilişkin bir heap alanı tahsis edilecektir ve fonksiyon heap alanının adresi ile geri dönecektir. Bu durumda bir heap içerisinde tahsisat işlemi tahsisat yapan sistem fonksiyonuna heap alanının adresi geçirilerek yapılacaktır. CSD işletim sisteminde bir process için yaratılan heap alanları sistem tarafından bir bağlı listede tutulacaktır. Her bir heap alanı içerisinde boş bölgeler boyutlarına göre 4 farklı bağlı listede tutulacaktır. Bu durum bellek bölünmesini azaltması ve istenen alanın daha hızlı bir biçimde tahsis edilebilmesi için tasarlanmıştır. Ayrıca her bir processin yaratıldığında varsayılan heap denilen bir heap’ i de bulunacaktır. Bu heap alanı, process’i yaratan sistem fonksiyonu tarafından yaratılacaktır. Bunun yanı sıra bir process için derleyicinin başlangıç kodu tarafından yaratılan ve standart C fonksiyonlarının tahsisatları için gereken heap de bulunacaktır. Bu sistemde heap otomatik olarak büyüyebilecek şekilde yaratılabilecektir. Bu şekilde yaratılıp yaratılmayacağı heap yaratan sistem fonksiyonunda belirlenecektir. Bu şekilde yaratılmış olan heaplerde başlangıçta belirlenmiş olan bölgenin büyütülmesi için yaratılan ek alanlara altheap (subheap) denilmektedir. Altheap uzunluğu istenen bellek boyutundan daha büyük tahsis edilecektir. Tahsis edilen altheap’ lerde kendi içlerinde bağlı listede tutulacaktır. Bu durumda sistem fonksiyonu tarafından yaratılan heap alanı aşağıdaki gibi olacaktır. Heap Header Heap bölgesi Görüldüğü gibi CSD işletim sisteminde heap alanı iki bölümden oluşmaktadır. Birinci bölüm heap alanına ilişkin çeşitli kritik bilgileri tutan başlık kısmı, ikinci bölüm ise tahsisat işlemlerinin yapılacağı bölgedir. Heap alanının başlık kısmı tipik olarak bir yapı ile temsil edilmektedir. Boş bloklar da kendi içerisinde iki bölgeye ayrılmaktadır. 3.1 CSD İŞLETİM SİSTEMİNDE BİR PROCESS’ İN HEAP ORGANİZASYONUNDA KULLANILAN YAPILAR CSD işletim sisteminde bir processin heap organizasyonunda kullanılan bloklar çeşitli yapılarla ilişkilendirilmiştir. Bu yapılar işletim sistemi geliştirilirken heap.h dosyası içerisinde 6 C ve Sistem Programcıları Derneği - CSD İşletim Sistemi Geliştirme Projesi bildirilmişlerdir. Bu dosya heap fonksiyonları yazılırken heap.c dosyasında include edilerek kullanılacaktır. 3.1.1 tagFREE_NODE YAPISI Bu yapı boş blokları temsil eden yapıdır. Aşağıdaki gibi bildirilmiştir. typedef tagFREE_NODE { DWORD dwSize; #ifdef _DEBUG DWORD dwSignature; DWORD dwCheckSum; #endif DLIST_NODE dlink; } FREE_NODE, *PFREE_NODE; DWORD dwSize: Bu eleman boş bloğun uzunluğunu tutar. DWORD dwSignature: Bloğun boş blok olup olmadığını gösterir. Sadece debug versiyonu için kullanılan bu eleman 0x4142 özel değeri için bloğun boş blok olduğunu gösterir. Bu özel değer HEAP_FREE_NODE_SIGNATURE sembolik sabiti olarak debug versiyonu için tanımlanmıştır. DWORD dwCheckSum: Bu eleman yapının önceki elemanlarının negatif checksum değerini tutar. Kontrol amaçlı olarak debug versiyonunda kullanılmaktadır. DLIST_NODE dLink: Boş alanların tutulduğu bağlı listede bir önceki ve sonraki elemanı gösterir. Bu eleman ile boş blok bağlı listenin elemanı olur. 3.1.2 tagALLOCATED_BLOCK YAPISI Bu yapı tahsis edilmiş blokları temsil eden yapıdır. Aşağıdaki gibi bildirilmiştir. typedef struct tagALLOCATED_BLOCK { DWORD dwSize; #ifdef _DEBUG WORD dwSignature; DWORD dwChecksum; #endif } ALLOCATED_BLOCK, *PALLOCATED_BLOCK; DWORD dwSize: Tahsis edilmiş bloğun uzunluğunu tutar. WORD dwSignature: Bloğun tahsis edilmiş blok olup olmadığını gösterir. 0x4143 özel değeri için blok boş bloktur. Bu değer debug versiyonu için HEAP_ALLOCATED_BLOCK_SIGNATURE sembolik sabiti olarak tanımlanmıştır. dwSignature elemanı sadece debug versiyonunda kullanılmaktadır. DWORD dwChecksum: Yapının önceki elemanlarının negatif checksum değerini tutar. Sadece debug versiyonunda kullanılmaktadır. 7 C ve Sistem Programcıları Derneği - CSD İşletim Sistemi Geliştirme Projesi 3.1.3 FREE_NODE_HEADER YAPISI Boş blokların tutulduğu bağlı listelerin herbiri için başlangıç kısmını temsil eden yapıdır. Aşağıdaki gibi bildirilmiştir. typedef struct tagFREE_NODE_HEADER { DWORD dwMaxSize; DLIST_HEADER dlistFreeNode; } FREE_NODE_HEADER, *PFREE_NODE_HEADER; DWORD dwMaxSize: Bağlı listenin hangi bağlı liste olduğunu belirtir. Bu elaman 0x20, 0x80, 0x200 ve 0xFFFFFFFF değerlerinden birisi olabilir. Aranan boş bloğun uzunluğuna göre bu elemana bakılarak hangi bağlı listede aranacağı belirlenir. DLIST_HEADER dlistFreeNode: İlgili bağlı listenin ilk ve son elemanını gösteren yapıdır. 3.1.4 SUBHEAP YAPISI Bu yapı alt heap’i temsil eden yapıdır. Aşağıdaki gibi bildirilmiştir. typedef struct tagSUBHEAP { DWORD dwSize; FREE_NODE_HEADER freelist[4]; DLIST_NODE dlink; } SUBHEAP, *PSUBHEAP; DWORD dwSize: Tahsis edilen altheap’in uzunluğunu tutar. Subheap’in uzunluğu istenen uzunluktan 2MB fazla tahsis edilir. FREE_NODE_HEADER freelist[4]: Altheap’ e ilişkin boş blokları tutan elemandır. Burada tutulan bağlı listeler sırasıyla 0x20, 0x80, 0x200 ve 0xFFFFFFFF uzunluktan küçük boş bölgeleri tutmaktadır. Yani tahsis edilmek istenen uzunluğa uygun bağlı liste bulunarak tahsisat işlemi gerçekleştirilecektir. DLIST_NODE dlink: Altheaplerin tutulduğu bağlı listede bir sonraki ve bir önceki elemanı gösterir. 3.1.5 HEAP YAPISI Bu yapı heap alanının başlık kısmını temsil eden yapıdır. Aşağıdaki gibi bildirilmiştir. typedef struct tagHEAP { DWORD size; FREE_NODE_HEADER freeList[4]; DLIST_HEADER dlistSubHeap; WORD wSignature; DWORD dwHeapFlags; #ifdef _DEBUG DWORD dwChecksum; #endif DLIST_NODE dlink; } HEAP, *PHEAP, *HHEAP 8 C ve Sistem Programcıları Derneği - CSD İşletim Sistemi Geliştirme Projesi DWORD dwSize: Bu eleman heap bölgesinin uzunluğunu tutar. FREE_NODE_HEADER freeList[4]: Boş bölgelerin tutulduğu bağlı listeleri temsil eden elemandır. Burada tutulan bağlı listeler sırasıyla 0x20, 0x80, 0x200 ve 0xFFFFFFFF uzunluktan küçük boş bölgeleri tutmaktadır. Yani tahsis edilmek istenen uzunluğa uygun bağlı liste bulunarak tahsisat işlemi gerçekleştirilecektir. DLIST_HEADER dlistSubHeap: Heap’ e ait alt heaplerin tutulduğu bağlı listenin ilk ve son elemanını gösteren başlangıç elemanıdır. WORD wSignature: Bloğun heap’e ilişkin olup olmadığını gösterir. 0x41441 özel değeri için bloğun heap’ e ilişkin olduğunu gösterir. Bu özel değer HEAP_HEADER_SIGNATURE sembolik sabiti olarak tanımlanmıştır. DWORD dwHeapFlags: Heap’e ilişkin ek özelliklerin tutulduğu elemandır. Heap’ i yaratan CreateHeap sistem fonksiyonunun ikinci parametresinde belirtilen değerle doldurulur. DWORD dwChecksum: Yapının önceki elemanlarının negatif checksum değerini tutar. Sadece debug versiyonunda kullanılmaktadır. DLIST_NODE dLink: Heaplerin tutulduğu bağlı listede bir sonraki ve bir önceki elemanı gösterir. 3.2 CSD İŞLETİM SİSTEMİNİN HEAP SİSTEMİNDE KULLANILAN API(SİSTEM) FONKSİYONLARI CSD işletim sisteminde program geliştirme düzeyinde bir process için heap oluşturulup işlemlerin yapılabilmesi için bir grup API (Sistem) fonksiyonu kullanılacaktır. Programcı heap oluşturmak için ilk önce heap tahsis eden CreatHeap API fonksiyonunu çağıracak ve bu fonksiyondan elde edilen handle değeri ile tahsisat işlemlerini gerçekleştiren diğer sistem fonksiyonlarını kullanacaktır. Tahsis edilen heap’i yine handle değerinden hareketle HeapDestroy sistem fonksiyonu ile geri bırakacaktır. 3.2.1 CreateHeap FONKSİYONU Bu fonksiyon belirlenen uzunlukta heap yaratır. Fonksiyonun prototipi aşağıdaki gibidir. HHEAP CreateHeap(DWORD dwSize, DWORD dwFlags); Fonksiyonun birinci parametresi yaratılacak heap’ in uzunluğudur. Bu parametre 0 (sıfır) olarak girilirse heap otomatik olarak büyüyebilecek biçimde yaratılır. Otomatik olarak büyüyecek heap için ilk yaratıldığındaki varsayılan uzunluk 2MB olarak belirlenmiştir. Bu değer HEAP_DEFAULT_SIZE sembolik sabiti olarak tanımlanmıştır. Fonksiyonun ikinci parametresi heap’ e ilişkin ek özelliklerin belirlenmesinde kullanılır. Bir takım sembolik sabitler OR’ lanarak fonksiyona geçirilir. Fonksiyonun geri dönüş değeri yaratılan heap’in handle değeridir. Bu değer heap içerisinde tahsisat yapan ve heap’ i geri bırakan fonksiyonlarda kullanılır. Fonksiyon kendi içerisinde HEAP yapısı ve bu yapının dwSize elemanının toplamı kadar alan tahsis ederek bu alanın başlangıç adresiyle döner. Ayrıca bu heap yapısını processin tüm heap lerinin tutulduğu bağlı listeye ekler. Şüphesiz bu tahsisatlar CreateHeap fonksiyonu içerisinde çekirdek düzeyinde sayfalama işlemini gerçekleştiren sistem fonksiyonları çağrılarak yapılır. 9 C ve Sistem Programcıları Derneği - CSD İşletim Sistemi Geliştirme Projesi 3.2.2 AllocMem FONKSİYONU Bu fonksiyon handle değeri ile belirlenen heap içerisinde istenilen uzunlukta tahsisat yapmak için kullanılır. Fonksiyonun prototipi aşağıdaki gibidir. PVOID AllocMem(HHEAP hHeap, DWORD dwSize, DWORD dwFlags); Fonksiyonun birinci parametresi içerisinde tahsisat yapılacak heap’ in handle değeridir. Bu değer CreateHeap fonksiyonuyla elde edilen handle değeridir. Fonksiyonun ikinci parametresi yapılacak tahsisatın byte uzunluğudur. Fonksiyonun üçüncü parametresi tahsisat yapılan bölgeye ilişkin ek özelliklerin belirlenmesinde kullanılır. Fonksiyon eğer tahsisat yapılabilmişse tahsis edilen bölgenin başlangıç adresine, başarısızsa NULL değerine geri döner. Fonksiyon boş alanları tutan bağlı listelerden ikinci parametresiyle belirtilen uzunluğa uygun olanını bularak tahsisat işlemini bu bağlı listeden gerçekleştirir. Bulduğu elemanı bu bağlı listeden çıkartarak ALLOCATED_BLOCK yapısı ile ilişkilendirir. Bu yapının ilk elemanına bloğun uzunluğunu yerleştirir ve bu elemandan sonraki adresi fonksiyonun geri dönüş değeri olarak verir. Bunun sebebi tahsis edilen alanı geri bırakmakta kullanılan fonksiyonun bu adresten bir geriye giderek uzunluğu belirleyebilmesini sağlamaktır. Şüphesiz yukarıdaki işlemlerde herhangi bir başarısızlık durumunda fonksiyon NULL değeri ile döner. 3.2.3 ReallocMem FONKSİYONU Bu fonksiyon daha önce AllocMem veya ReallocMem fonksiyonuyla tahsis edilmiş olan alanın büyütülmesi ya da küçültülmesi için kullanılır. Fonksiyonun prototipi aşağıdaki gibidir. PVOID ReallocMem(HHEAP hHeap, PVOID pBlock, DWORD dwSize, DWORD dwFlags); Fonksiyonun birinci parametresi içerisinde tahsisat yapılacak heap’ in handle değeridir. İkinci parametresi daha önce tahsis edilmiş alanın başlangıç adresidir. Bu adres daha önce AllocMem veya ReallocMem fonksiyonundan elde edilen adrestir. Üçüncü parametre yeni uzunluk değeridir. Fonksiyonun son parametresi tahsisat yapılan bölgeye ilişkin ek özellikleri belirlemekte kullanılır. Fonksiyon eğer büyütme işlemi yapacaksa pBlock parametresiyle belirtilen adresi büyütmeye çalışır. Büyütülebilecek ardışıl alan bulamazsa yeni uzunluk kadar bölgeyi boş bloklar arasından AllocMem fonksiyonunda kullanılan algoritma ile bularak yeni alanı tahsis eder ve geri dönüş değeri olarak verir. Tabi bu durumda eski alanı geri bırakarak uygun bağlı listeye ekler. Fonksiyon eğer ardışıl alanı bulursa aynı adresle geri döner. Küçültme işlemi yapılacaksa aynı alandan istenen kısım kadar alınır. Geri kalan bölge boş alan olarak uygun bağlı listeye eklenir. 3.2.4 FreeMem FONKSİYONU Bu fonksiyon AllocMem yada ReallocMem ile tahsis edilmiş alanları geri bırakır. Fonksiyonun prototipi aşağıdaki gibidir. BOOL FreeMem(HHEAP hHeap, PVOID pBlock); 10 C ve Sistem Programcıları Derneği - CSD İşletim Sistemi Geliştirme Projesi Fonksiyonun birinci parametresi heap’ in handle değeridir. İkinci parametresi AllocMem veya ReallacMem fonksiyonları tarafından tahsis edilmiş alanın başlangıç adresidir. Fonksiyonun geri dönüş değeri geri bırakma işleminin başarıyla gerçekleştirilip gerçekleştirilmediğini belirtir. Geri bırakma işlemi başarılıysa TRUE, başarısızsa FALSE değerine geri döner. Fonksiyon ikinci parametresiyle belirtilen alanı boş bölgeleri tutan bağlı listelerden uygun olana ekler. 3.2.5 HeapDestroy FONKSİYONU Bu fonksiyon CreateHeap fonksiyonuyla oluşturulmuş heap’ i geri bırakmak için kullanılır. Fonksiyonun prototipi aşağıdaki gibidir. BOOL HeapDestroy(HHEAP hHeap); Fonksiyonun birinci parametresi CreateHeap fonksiyonu ile oluşturulan heap alanının handle değeridir. Geri dönüş değeri geri bırakma işlemi başarılıysa TRUE, başarısızsa FALSE değeridir. Fonksiyon birinci parametresinde verilen handle değerine ilişkin heap’ i process’ in tüm heaplerinin tutulduğu bağlı listeden çıkartır. Böylece heap geri bırakılmış olur. Kaynaklar 1. Windows 95 System Programming Secrets, Matt Pietrek, IDG Books, 1995 2. The C Programming Language(Second Edition), Brian W.Kernighan, Dennis M.Ritchie, Prentice-Hall Inc, 1988 3. Mmurtl V1.0 (Writing Your Own 32 bit Operating System), Burgess Richard A., Sensory Publishing Inc-2002 4. Programming Applications For Microsoft Windows(Fourth Edition), Jeffrey Richter, Mirosoft Press, 1999 5. Win32 Sistem Programlama Ders Notları, Kaan Aslan, C ve Sistem Programcıları Derneği, 2000 6. Windows 2000 System Programming Black Book, Al Williams, CORIOLIS, 2000 7. Advanced Programming In The Unix Environment, W. Richard Stevens, AddisonWesley , 1999 8. UNIX/LINUX Sistem Programlama Ders Notları, Kaan Aslan, C ve Sistem Programcıları Derneği, 2002 9. A’ dan Z’ ye C Klavuzu(5.Baskı), Kaan Aslan, Pusula Yayınevi, 2001 11 C ve Sistem Programcıları Derneği - CSD İşletim Sistemi Geliştirme Projesi