Thursday 29 November 2007

LINUX Çekirdeğini Anlamak – Süreçler 1 (Teknik İngilizce Çeviri Örneği)

LINUX Çekirdeğini Anlamak – Süreçler 1
Ali Rıza SARAL(1)

(1) Daniel P. Bovet, Marco Cesati, Understanding the Linux Kernel ‘den faydalanarak derlenmiştir.
(2) Bu yazı biraz da okuyucunun teknik İngilizce’sini geliştirmek amacı ile yazılmıştır.
(3) Bir diğer amaç ta teknik metinlerin Türkçe’ye tercüme edilişi hakkında tartışmağa imkan sağlamaktır.

Bölüm 3. LINUX’ta Süreçler
Chapter 3. Processes

Süreç kavramı her bir çoğul-programlayıcı (multi-programming) işletim sistemi için temel bir kavramdır. The concept of a process is fundamental to any multiprogramming operating system.

Bir süreç genellikle bir programın çalıştırılmakta olan bir örneğidir (instance);
A process is usually defined as an instance of a program in execution;

böylece, eğer 16 kullanıcı aynı anda vi programını çalıştırıyorsa, 16 tane ayrı süreç vardır
(aynı çalıştırılabilir kodu paylaşabildiklerine karşın).
thus, if 16 users are running vi at once, there are 16 separate processes (although they can share the same executable code).

Süreçlere Linux kaynak kodunda “görev” (task) adı verilir. Processes are often called "tasks" in Linux source code.

3.1 Süreç Tanımlayıcı (Process Descriptor)
Süreçleri yönetmek için, çekirdek, her sürecin ne yaptığına ilişkin net bir resme sahip olmalıdır. In order to manage processes, the kernel must have a clear picture of what each process is doing.

Örneğin, süreç önceliğini, CPU üzerinde çalışır durumda ya da bir olay nedeni ile tıkanmış olduğunu, hangi adres alanının ona atanmış olduğunu, hangi dosyalara erişişine izin verildiğini, ve benzerşeyleri bilmek zorundadır. It must know, for instance, the process's priority, whether it is running on the CPU or blocked on some event, what address space has been assigned to it, which files it is allowed to address, and so on.

Bu süreç tanımlayıcı’nın, yani tek bir sürece ilişkin bütün bilgileri içeren görev_yapısı (task_struct) tipinde bir yapının rolüdür. This is the role of the process descriptor , that is, of a task_struct type structure whose fields contain all the information related to a single process.

Şekil 3-1. Linux süreç tanımlayıcısı


3.1.1 Süreç Hali (Process State)
İsminden anlaşıldığı gibi, süreç tanımlayıcının hal (state) alanı süreç içinde o anda ne olduğunu tarif eder. As its name implies, the state field of the process descriptor describes what is currently happening to the process.

Her biri süreç durumunu tarif eden bir dizi bayraktan oluşur.
It consists of an array of flags, each of which describes a possible process state.

Güncel Linux sürümünde bu haller karşılıklı olarak birbirlerini hariç tutar, ve böylece kümenin yalnız bir bayrağı kaldırılımış diğerleri indirilmiş olur.
In the current Linux version these states are mutually exclusive, and hence exactly one flag of state is set; the remaining flags are cleared.

Aşağıdakiler mümkün süreç halleridir: The following are the possible process states:

GÖREV_ÇALIŞIYOR (TASK_RUNNING) Süreç ya CPU üstünde çalışıyor ya da çalıştırılmak için bekliyor. TASK_RUNNING The process is either executing on the CPU or waiting to be executed.

GÖREV_KESİNTİYE_UĞRAYABİLİR (TASK_INTERRUPTIBLE) Bir koşul gerçekleninceye kadar süreç askıda (uyuyor). TASK_INTERRUPTIBLE The process is suspended (sleeping) until some condition becomes true.

Bir donanım kesintisini başlatmak, sürecin beklediği bir sistem kaynağını serbest bırakmak, veya bir işaret teslim etmek bir süreci uyandıran koşullara örnektir, yani sürecin halini geriye
GÖREV_ÇALIŞIYOR (TASK_RUNNING) ’a getirirler. Raising a hardware interrupt, releasing a system resource the process is waiting for, or delivering a signal are examples of conditions that might wake up the process, that is, put its state back to TASK_RUNNING .

GÖREV_KESİNTİYE_UĞRATILAMAZ (TASK_UNINTERRUPTIBLE) bir önceki hal gibidir, yalnız uyuyan sürece bir işaret teslim edilişi hali değiştirmez. TASK_UNINTERRUPTIBLE Like the previous state, except that delivering a signal to the sleeping process leaves its state unchanged.

Bu süreç nadir olark kullanılır. Yine de, bir sürecin öngörülmüş bir olay oluncaya kadar kesintiye uğramadan beklemesi gerektiği belirli özel koşullar altında değerlidir.
This process state is seldom used. It is valuable, however, under certain specific conditions in which a process must wait until a given event occurs without being interrupted.

Örneğin, bir süreç bir cihaz dosyasını açtığında ve denk düşen cihaz sürücüsü denk düşen donanım cihazını yoklamağa başladığında bu hal kullanılabilir. For instance, this state may be used when a process opens a device file and the corresponding device driver starts probing for a corresponding hardware device.

Cihaz sürücüsü yoklayış tamamlanıncaya kadar kesintiye uğramamak zorundadır, ya da donanım cihazı belirsiz bir halde kalabilir.
The device driver must not be interrupted until the probing is complete, or the hardware device could be left in an unpredictable state.

GÖREV_DURDU (TASK_STOPPED) Süreç çalıştırılışı durduruldu: süreç bu duruma bir SIGSTOP, SIGTSTP, SIGTTIN, veya SIGTTOU işareti aldıktan sonra girer. TASK_STOPPED Process execution has been stopped: the process enters this state after receiving a SIGSTOP, SIGTSTP, SIGTTIN, or SIGTTOU signal.

Bir süreç bir diğeri tarafından izlendiğinde (bir hata bulucu bir test programını denemek için bir ptrace( ) sistem çağrısı çalıştırdığında ki gibi), herhangi bir işaret süreci GÖREV_DURDU (TASK_STOPPED) haline koyar. When a process is being monitored by another (such as when a debugger executes a ptrace( ) system call to monitor a test program), any signal may put the process in the TASK_STOPPED state.

GÖREV_ZOMBİ (TASK_ZOMBIE) Süreç çalıştırışı bitirildi, fakat anne süreç ölü süreç hakkında bilgi geriye vermek için henüz wait( )- benzeri sistem çağrısı (wait( ), wait3( ), wait4( ), veya waitpid( )) çıkarmadı. TASK_ZOMBIE Process execution is terminated, but the parent process has not yet issued a wait( )- like system call (wait( ), wait3( ), wait4( ), or waitpid( )) to return information about the dead process.

wait( )- benzeri çağrı yapılmadan önce, çekirdek ölü süreç tanımlayıcının içerdiği veriyi çöpe atamaz, çünkü ebeveyn ona ihtiyaç duyabilir. Before the wait( )-like call is issued, the kernel cannot discard the data contained in the dead process descriptor because the parent could need it.


3.1.2 Süreci Belirleyiş (Identifying a Process)
Lunix süreçleri kendilerine ait çekirdek veri yapılarınının önemli bir kısmını paylaşabildikleri halde—hafif-sıklet süreçler(lightweight processes)—her süreç kendine ait süreç tanımlayıcısına sahiptir. Although Linux processes can share a large portion of their kernel data structures—an efficiency measure known as lightweight processes—each process has its own process descriptor.

Bağımsız olarak çalıştırım programına alınabilen her çalıştırış bağlamı kendine ait süreç tanımlayıcısı sahibi olmalıdır. Each execution context that can be independently scheduled must have its own process descriptor.

Hafif-sıklet süreçler bir kullanıcı-seviyesinde kütüphane tarafından ele alınıp farklı bir çalıştırış akışı olan, kullanıcı-üslubu bağlar(user-mode threads)’la karıştırılmamalıdır.
Lightweight processes should not be confused with user-mode threads, which are different execution flows handled by a user-level library.

Süreç ile süreç tanımlayıcı arasında çok katı bire-bir denk düşüş 32-bit süreç tanımlayıcı adresini [1] süreci belirlemek için kullanışlı bir araç yapar. The very strict one-to-one correspondence between the process and process descriptor makes the 32-bit process descriptor address[1] a convenient tool to identify processes.

Bu adreslere süreç tanımlayıcı adresleri (process descriptor pointers) olarak değinilir. Çekirdeğin yarattığı süreçlere yaptığı değinişlerin çoğu süreç tanımlayıcı işaret-vericileri(pointer) aracılığı iledir. These addresses are referred to as process descriptor pointers. Most of the references to processes that the kernel makes are through process descriptor pointers.

[1] Teknik açıdan 32 bit mantıksal adresin(logical) yalnız öteleyiş(offset) bileşenidir.
Technically speaking, these 32 bits are only the offset component of a logical address.

Yine de, Linux tek bir çekirdek veri kesimi(segment) kullandığı için, öteleyişin tam bir mantıksal adrese(whole logical address) eşdeğer kabul edebiliriz. However, since Linux makes use of a single kernel data segment, we can consider the offset to be equivalent to a whole logical address.

Dahası, kodun ve veri kesimleri(data segments)’nin taban adres(base address)’i 0 yapıldığı için, öteleyişi(offset) doğrusal bir addres gibi kullanabiliriz. Furthermore, since the base addresses of the code and data segmentsare set to 0, we can treat the offset as a linear address.

Öte yandan, herhangi bir UNIX-benzeri sistem, kullanıcılarının süreçleri Süreç Kimlik Nosu(Process ID (or PID)) adı verilen bir sayı aracılığıyla belirleyişine müsaade eder.
Any Unix-like operating system, on the other hand, allows users to identify processes by means of a number called the Process ID (or PID).

Süreç Kimlik NO’su (PID) süreç tanımlayıcının pid alanında tutulan 32-bit işaretsiz bir sayıdır. The PID is a 32-bit unsigned integer stored in the pid field of the process descriptor.

PID’ler sıra ile sayılandırılmıştır:yeni yaratılan bir sürecin PID’i normalde bir öncekinin PID’inin bir ile arttırılmışıdır. PIDs are numbered sequentially: the PID of a newly created process is normally the PID of the previously created process incremented by one.

Yine de, 16-bit donanım platformları için üretilmiş geleneksel UIX sistemleri ile uyumluluk için, LINUX üzerinde izin verilen en büyük PID sayısı 32767’dir. However, for compatibility with traditional Unix systems developed for 16-bit hardware platforms, the maximum PID number allowed on Linux is 32767.

Çekirdek sistemdeki 32768’inci süreci yarattığı zaman, aşağıdaki kullanılmamış PID’ları yeniden kullanmaya başlamalıdır. When the kernel creates the 32768th process in the system, it must start recycling the lower unused PIDs.

Etkinlik önemlidir çünkü öldür() ( kill( )) gibi bir çok sistem çağrısı etkilenen süreci belirtmek için PID’ı kullanır. Efficiency is important because many system calls like kill( ) use the PID to denote the affected process.

3.1.2.1 Görev dizisi (The task array)
Süreçler sistem içinde yaşam süreleri birkaç milisaniyeden aylara kadar uzanan devinimsel (dynamic) varlıklardır (entities). Processes are dynamic entities whose lifetimes in the system range from a few milliseconds to months. Thus, the kernel must be able to handle many processes at the same time.

Linux SY_GÖREV (NR_TASKS) kadar sürece muamele edebilir.
Linux is able to handle up to NR_TASKS processes.

Çekirdek kendi adress alanında görev (task) adı verilen SY_GÖREV (NR_TASKS) büyüklüğünde küresel sabit bi dizi (global static array) ayırır. Bu dizinin elemanları süreç tanımlayıcıya işaret edicilerdir (process descriptor pointers); boşluğa(null) işaret edici bir süreç tanımlayıcının o dizi elemanı ile ilişkilendirilmediğini belirtir. The kernel reserves a global static array of size NR_TASKS called task in its own address space. The elements in the array are process descriptor pointers; a null pointer indicates that a process descriptor hasn't been associated with the array entry.

3.1.2.2 Bir Süreç Tanımlayıcının Saklanışı (Storing a process descriptor)
görev (task) dizisi yalnız süreç tanımlayıcıların işaret edicilerini içine alır, çok yer kaplayan tanımlayıcıların kendilerini değil. The task array contains only pointers to process descriptors, not the sizable descriptors themselves.

Süreçler devinimsel varlıklar (dynamic entities) olduğu için, süreç tanımlayıcılar çekirdeğe kalıcı olarak atanan bellek alanına değil devinimsel belleğe depolanırlar. Since processes are dynamic entities, process descriptors are stored in dynamic memory rather than in the memory area permanently assigned to the kernel.

Linux her süreç için, 8KB bellek alanına, iki farklı veri yapısı saklar: süreç tanımlayıcı ve Çekirdek-üslubu (Kernel Mode) süreç yığını. Linux stores two different data structures for each process in a single 8 KB memory area: the process descriptor and the Kernel Mode process stack.


Şekil 3-2. Süreç tanımlayıcı ve süreç çekirdek yığınının saklanışı
Figure 3-2. Storing the process descriptor and the process kernel stack

esp kayıt-tutucusu(register) yığının en üst konum adresini tutan yığın eşaret-edicisidir.
The esp register is the CPU stack pointer, which is used to address the stack's top location.

Intel sistemlerinde, yığın sonda başlar ve bellek alanının başlangıcına doğru genişler.
On Intel systems, the stack starts at the end and grows toward the beginning of the memory area.

Kullanıcı-Üslubundan Çekirdek-Üslubuna geçişten hemen sonra, bir sürecin çekirdek yığını her zaman boştur, ve bu yüzden esp kayıt-tutucusu bellek alanından hemen sonra gelen byte’a işaret eder. Right after switching from User Mode to Kernel Mode, the kernel stack of a process is always empty, and therefore the esp register points to the byte immediately following the memory area….

3.1.2.3 Güncel Makrosu (The current macro)
Çekirdek-üslubu yığını ile süreç tanımlayıcı eşleştirişi etkinlik açısından anahtar bir fayda sağlar: çekirdek esp kayıt-tutucusunun değerinden CPU üzerinde çalışan sürecin süreç tanımlayıcısına işaret-ediciyi kolaylıkla elde edebilir.
The pairing between the process descriptor and the Kernel Mode stack just described offers a key benefit in terms of efficiency: the kernel can easily obtain the process descriptor pointer of the process currently running on the CPU from the value of the esp register.

Aslında, bellek alanı 8 KB(213 byte) uzunluğunda olduğundan, süreç tanımlayıcının taban adresini elde etmek için, çekirdeğin bütün yapması gereken, esp ‘nin en az önemli 13 bitini maskeleyerek çıkarmaktır. Bu şuanki (current) makrosu tarafından yapılır.
In fact, since the memory area is 8 KB (213 bytes) long, all the kernel has to do is mask out the 13 least significant bits of esp to obtain the base address of the process descriptor. This is done by the current macro…

Görev_yapısı-dizisi (task_struct_stack) arabölge (cache) içindeki süreç tanımlayıcılarının işaret edicilerini içinde bulundurur. The task_struct_stack array contains the pointers to the process descriptors in the cache.

İsmi süreç tanımlayıcı serbest bırakılışı ve istekte bulunuluşunun dizi üzerinde “it”(push) ve “çek”(pop) işlemleri ile yapılışından gelir:
Its name comes from the fact that process descriptor releases and requests are implemented respectively as "push" and "pop" operations on the array:

Görev_yapısını_serbest_birak (free_task_struct( )) Bu fonksiyon 8 KB’lık görev_birimi (task_union) bellek alanlarını serbest bırakır ve onları eğer boş değilse arabölge(cache)’ye yerleştirir.
free_task_struct( ) This function releases the 8 KB task_union memory areas and places them in the cache unless it is full.

Görev_yapısına_yer_ata (alloc_task_struct( )) Bu fonksiyon görev_birimi (task_union) bellek alanları için 8 KB yer atar. alloc_task_struct( ) This function allocates 8 KB task_union memory areas.

Bu fonksiyon eğer yarı-dolu ise ya da art arda gelen bir çift sayfa çerçevesi(page frame) yok ise arabölge(cache)’den bellek alanları alır.
The function takes memory areas from the cache if it is at least half-full or if there isn't a free pair of consecutive page frames available.

LINUX Çekirdeğini Anlamak – Süreçler 1


Şekil 3-1. Linux süreç tanımlayıcısı Şekil 3-2. Süreç tanımlayıcı ve süreç çekirdek yığınının saklanışı

LINUX Çekirdeğini Anlamak – Süreçler 1

Ali Rıza SARAL(1)


(1) Daniel P. Bovet, Marco Cesati, Understanding the Linux Kernel ‘den faydalanarak derlenmiştir.
(2) Bu yazı biraz da okuyucunun teknik İngilizce’sini geliştirmek amacı ile yazılmıştır.
(3) Bir diğer amaç ta teknik metinlerin Türkçe’ye tercüme edilişi hakkında tartışmağa imkan sağlamaktır. Bu amaçla cümle cümle tercümeyi içeren bir sürümünü de bulmak mümkündür.


Bölüm 3. LINUX’ta Süreçler (Processes)
Süreç kavramı her bir çoğul-programlayıcı (multi-programming) işletim sistemi için temel bir kavramdır. Bir süreç genellikle bir programın çalıştırılmakta olan bir örneğidir (instance);
böylece, eğer 16 kullanıcı aynı anda vi programını çalıştırıyorsa, 16 tane ayrı süreç vardır
(aynı çalıştırılabilir kodu paylaşabildiklerine karşın). Süreçlere Linux kaynak kodunda “görev” (task) adı verilir.

3.1 Süreç Tanımlayıcı (Process Descriptor)
Süreçleri yönetmek için, çekirdek, her sürecin ne yaptığına ilişkin net bir resme sahip olmalıdır. Örneğin, süreç önceliğini, CPU üzerinde çalışır durumda ya da bir olay nedeni ile tıkanmış olduğunu, hangi adres alanının ona atanmış olduğunu, hangi dosyalara erişişine izin verildiğini, ve benzerşeyleri bilmek zorundadır. Bu süreç tanımlayıcı’nın, yani tek bir sürece ilişkin bütün bilgileri içeren görev_yapısı (task_struct) tipinde bir yapının rolüdür.
.
Şekil 3-1. Linux süreç tanımlayıcısı


3.1.1 Süreç Hali (Process State)
İsminden anlaşıldığı gibi, süreç tanımlayıcının hal (state) alanı süreç içinde o anda ne olduğunu tarif eder. Her biri süreç durumunu tarif eden bir dizi bayraktan oluşur.
Güncel Linux sürümünde bu haller karşılıklı olarak birbirlerini hariç tutar, ve böylece kümenin yalnız bir bayrağı kaldırılımış diğerleri indirilmiş olur. Aşağıdakiler mümkün süreç halleridir:

GÖREV_ÇALIŞIYOR (TASK_RUNNING) Süreç ya CPU üstünde çalışıyor ya da çalıştırılmak için bekliyor.

GÖREV_KESİNTİYE_UĞRAYABİLİR (TASK_INTERRUPTIBLE) Bir koşul gerçekleninceye kadar süreç askıda (uyuyor). Bir donanım kesintisini başlatmak, sürecin beklediği bir sistem kaynağını serbest bırakmak, veya bir işaret teslim etmek bir süreci uyandıran koşullara örnektir, yani sürecin halini geriye GÖREV_ÇALIŞIYOR (TASK_RUNNING) ’a getirirler.

GÖREV_KESİNTİYE_UĞRATILAMAZ (TASK_UNINTERRUPTIBLE) bir önceki hal gibidir, yalnız uyuyan sürece bir işaret teslim edilişi hali değiştirmez. Bu süreç nadir olark kullanılır. Yine de, bir sürecin öngörülmüş bir olay oluncaya kadar kesintiye uğramadan beklemesi gerektiği belirli özel koşullar altında değerlidir. Örneğin, bir süreç bir cihaz dosyasını açtığında ve denk düşen cihaz sürücüsü denk düşen donanım cihazını yoklamağa başladığında bu hal kullanılabilir. Cihaz sürücüsü yoklayış tamamlanıncaya kadar kesintiye uğramamak zorundadır, ya da donanım cihazı belirsiz bir halde kalabilir.

GÖREV_DURDU (TASK_STOPPED) Süreç çalıştırılışı durduruldu: süreç bu duruma bir SIGSTOP, SIGTSTP, SIGTTIN, veya SIGTTOU işareti aldıktan sonra girer. Bir süreç bir diğeri tarafından izlendiğinde (bir hata bulucu bir test programını denemek için bir ptrace( ) sistem çağrısı çalıştırdığında ki gibi), herhangi bir işaret süreci GÖREV_DURDU (TASK_STOPPED) haline koyar.

GÖREV_ZOMBİ (TASK_ZOMBIE) Süreç çalıştırışı bitirildi, fakat anne süreç ölü süreç hakkında bilgi geriye vermek için henüz wait( )- benzeri sistem çağrısı (wait( ), wait3( ), wait4( ), veya waitpid( )) çıkarmadı. wait( )- benzeri çağrı yapılmadan önce, çekirdek ölü süreç tanımlayıcının içerdiği veriyi çöpe atamaz, çünkü ebeveyn ona ihtiyaç duyabilir.


3.1.2 Süreci Belirleyiş (Identifying a Process)
Lunix süreçleri kendilerine ait çekirdek veri yapılarınının önemli bir kısmını paylaşabildikleri halde—hafif-sıklet süreçler(lightweight processes)—her süreç kendine ait süreç tanımlayıcısına sahiptir. Bağımsız olarak çalıştırım programına alınabilen her çalıştırış bağlamı kendine ait süreç tanımlayıcısı sahibi olmalıdır. Hafif-sıklet süreçler bir kullanıcı-seviyesinde kütüphane tarafından ele alınıp farklı bir çalıştırış akışı olan, kullanıcı-üslubu bağlar(user-mode threads)’la karıştırılmamalıdır. Süreç ile süreç tanımlayıcı arasında çok katı bire-bir denk düşüş 32-bit süreç tanımlayıcı adresini [1] süreci belirlemek için kullanışlı bir araç yapar. Bu adreslere süreç tanımlayıcı adresleri (process descriptor pointers) olarak değinilir. Çekirdeğin yarattığı süreçlere yaptığı değinişlerin çoğu süreç tanımlayıcı işaret-vericileri(pointer) aracılığı iledir.

[1] Teknik açıdan 32 bit mantıksal adresin(logical) yalnız öteleyiş(offset) bileşenidir. Yine de, Linux tek bir çekirdek veri kesimi(segment) kullandığı için, öteleyişin tam bir mantıksal adrese(whole logical address) eşdeğer kabul edebiliriz. Dahası, kodun ve veri kesimleri(data segments)’nin taban adres(base address)’i 0 yapıldığı için, öteleyişi(offset) doğrusal bir addres gibi kullanabiliriz.

Öte yandan, herhangi bir UNIX-benzeri sistem, kullanıcılarının süreçleri Süreç Kimlik Nosu(Process ID (or PID)) adı verilen bir sayı aracılığıyla belirleyişine müsaade eder.
Süreç Kimlik NO’su (PID) süreç tanımlayıcının pid alanında tutulan 32-bit işaretsiz bir sayıdır. PID’ler sıra ile sayılandırılmıştır:yeni yaratılan bir sürecin PID’i normalde bir öncekinin PID’inin bir ile arttırılmışıdır. Yine de, 16-bit donanım platformları için üretilmiş geleneksel UIX sistemleri ile uyumluluk için, LINUX üzerinde izin verilen en büyük PID sayısı 32767’dir. Çekirdek sistemdeki 32768’inci süreci yarattığı zaman, aşağıdaki kullanılmamış PID’ları yeniden kullanmaya başlamalıdır. Etkinlik önemlidir çünkü öldür() ( kill( )) gibi bir çok sistem çağrısı etkilenen süreci belirtmek için PID’ı kullanır.

3.1.2.1 Görev dizisi (The task array)
Süreçler sistem içinde yaşam süreleri birkaç milisaniyeden aylara kadar uzanan devinimsel (dynamic) varlıklardır (entities). Linux SY_GÖREV (NR_TASKS) kadar sürece muamele edebilir. Çekirdek kendi adress alanında görev (task) adı verilen SY_GÖREV (NR_TASKS) büyüklüğünde küresel sabit bi dizi (global static array) ayırır. Bu dizinin elemanları süreç tanımlayıcıya işaret edicilerdir (process descriptor pointers); boşluğa(null) işaret edici bir süreç tanımlayıcının o dizi elemanı ile ilişkilendirilmediğini belirtir.

3.1.2.2 Bir Süreç Tanımlayıcının Saklanışı (Storing a process descriptor)
görev (task) dizisi yalnız süreç tanımlayıcıların işaret edicilerini içine alır, çok yer kaplayan tanımlayıcıların kendilerini değil. Süreçler devinimsel varlıklar (dynamic entities) olduğu için, süreç tanımlayıcılar çekirdeğe kalıcı olarak atanan bellek alanına değil devinimsel belleğe depolanırlar. Linux her süreç için, 8KB bellek alanına, iki farklı veri yapısı saklar: süreç tanımlayıcı ve Çekirdek-üslubu (Kernel Mode) süreç yığını.


Şekil 3-2. Süreç tanımlayıcı ve süreç çekirdek yığınının saklanışı
Figure 3-2. Storing the process descriptor and the process kernel stack

esp kayıt-tutucusu(register) yığının en üst konum adresini tutan yığın eşaret-edicisidir. Intel sistemlerinde, yığın sonda başlar ve bellek alanının başlangıcına doğru genişler. Kullanıcı-Üslubundan Çekirdek-Üslubuna geçişten hemen sonra, bir sürecin çekirdek yığını her zaman boştur, ve bu yüzden esp kayıt-tutucusu bellek alanından hemen sonra gelen byte’a işaret eder.

3.1.2.3 Güncel Makrosu (The current macro)
Çekirdek-üslubu yığını ile süreç tanımlayıcı eşleştirişi etkinlik açısından anahtar bir fayda sağlar: çekirdek esp kayıt-tutucusunun değerinden CPU üzerinde çalışan sürecin süreç tanımlayıcısına işaret-ediciyi kolaylıkla elde edebilir. Aslında, bellek alanı 8 KB(213 byte) uzunluğunda olduğundan, süreç tanımlayıcının taban adresini elde etmek için, çekirdeğin bütün yapması gereken, esp ‘nin en az önemli 13 bitini maskeleyerek çıkarmaktır. Bu şuanki (current) makrosu tarafından yapılır.

Görev_yapısı-dizisi (task_struct_stack) arabölge (cache) içindeki süreç tanımlayıcılarının işaret edicilerini içinde bulundurur. İsmi süreç tanımlayıcı serbest bırakılışı ve istekte bulunuluşunun dizi üzerinde “it”(push) ve “çek”(pop) işlemleri ile yapılışından gelir:

Görev_yapısını_serbest_birak (free_task_struct( )) Bu fonksiyon 8 KB’lık görev_birimi (task_union) bellek alanlarını serbest bırakır ve onları eğer boş değilse arabölge(cache)’ye yerleştirir.
Görev_yapısına_yer_ata (alloc_task_struct( )) Bu fonksiyon görev_birimi (task_union) bellek alanları için 8 KB yer atar. alloc_task_struct( ). Bu fonksiyon eğer yarı-dolu ise ya da art arda gelen bir çift sayfa çerçevesi(page frame) yok ise arabölge(cache)’den bellek alanları alır.