18 Aralık 2012 Salı

A threaded server implementation

Hi, today I want to write about a server and a client program I developed under GNU/Linux [source]. And I will write a longer post about what I learned about server design later.

I started off to write a chat server and client but in the end I thought anything related to chat cannot be coded in C easily. I may use the code to make a chat server with C++ someday. Right now the server has a message log and all incoming messages are recorded there. A message coming from one client is sent to all other clients which are connected to the server. Each client records the messages coming from the server to its own message log. The server doesn't use select, poll or epoll. Instead it uses threads. I chose to assign new threads per connection to practice pthreads.

There are three topics I can write about the programs. The queue struct which works as a message buffer, the client application and the server.

12 Aralık 2012 Çarşamba

Bu haftasonu katılınası etkinlikler

Ne zamandır evde kod yazıyorum. Haliyle sıkılmaya başlamıştım ve sosyal etkinlikleri iple çeker olmuştum. Şansa bakın ki bu haftasonu üç etkinlik birden üst üste geldi. Fırsatım olsa (mesela gerçek hayatta clone() syscallu çağırabilsek) üçüne de katılmak isterdim ama maalesef yalnız birini seçmek zorundayım.

Hepsinin değerli etkinlikler olduğunu düşündüğümden burada biraz bahsetmek istiyorum. Bakarsınız ilerde blogun trafiği artar da hem etkinliklere hem de etkinliklerden haberdar olmayan insanlara faydam dokunur.

10 Aralık 2012 Pazartesi

Yeni yazılar yolda

Merhaba,

Üç haftadır yazmadım. Basit bir server ve client yazmaya çalışıyordum ama bu işler tahmin ettiğimden daha kapsamlıymış. Zaten geçen hafta da pek verimli çalışamadım. Ama sonuçları yarın yine GitHub'dan paylaşacağım.

Tabii digraph'ta olduğu gibi bununla ilgili de bir yazı yazacağım. Threadlerle ve server tasarımı hakkında bayağı bir şey görmüş oldum. Şimdi event handlerlar ve state machineler hakkında bir şeyler yapmayı düşünüyorum. Eğer bununla ilgili çalışmaya zaman bulursam amatör de olsa çok daha kapsamlı bir sunucu tasarımı yazı dizisi yazacağım. Notlarım var ama event handling ve multiplexing konularında elimde somut örnek yok. Kod yazmadan yazı yazmak istemiyorum.

Driver yazma ile ilgili iki yazım olacak. Onların da notları var, yazıya çevirmem gerekli. Bir de Gentoo altında sanal sunucu oluşturarak kernel test ortamı oluşturmayı anlatacağım. Xen 4.1'de bazı sorunlar çıkabiliyor çünkü. Xen 4.2'de sanırım yazıya filan gerek duymadan kolayca halledilebilecek bu işler, bakalım.

Özetle önümüzdeki iki hafta yeni yazılar gelecek.

18 Kasım 2012 Pazar

Digraph Code - II

continues from digraph code - i ...

Also you can access the source code on GitHub

Implementation


We have a directed graph class named digraph. It holds the nodes of the graph and provides necessary functions to add/remove nodes/arcs. It also provides functions to solve some graph theory related problems. (currently only shortest path problem on non-weighted graphs). Inside it is dgNode class which holds the nodes. If you want to use digraph class as a container your data is held inside these dgNode objects. Finally we have links. Every node is responsible for keeping the arcs it sends to other nodes but they also hold a list of incoming arcs for performance reasons.

Digraph Code - I

Hi, welcome back for an English blog entry. I will be writing about stuff I coded in last moths and I think some of them will be useful for anyone interested in learning about the Linux kernel, Linux system programming or C++/STL.

Well, I wrote some code which finds the exit of a 2d maze by using a stack, back when I saw a problem in the Larry Nyhoff's book. One can call it some sort of "depth-first search". Then I enhanced it to find the shortest path possible. You can read its code on GitHub. It's very crude and may be inefficient but I was just beginning to use C++ back then.

So I later found out (in the same book) that shortest paths can be found much more easily by using breadth-first search on a directed graph (namely Dijkstra's method). And I set off to write my own digraph class right away. Well, it took more time than I anticipated but more on that below.

Finally I want to say writing a digraph class/container helped me see how the design process is important. Also I realized I had the whole encapsulation principle wrong in OOP. It took time but it was well worth it. Unfortunately some parts are a little cryptic but it works alright.

You can get the source from GitHub.

5 Kasım 2012 Pazartesi

Geçtiğimiz 6 ay

İyi günler,

Yaklaşık altı ay önce sistem admini olarak çalıştığım iş yerimden sistem programlama alanında çalışmak istediğim için ayrıldım. (eski işyerimde çalıştığım alanlar için Mayıs ayında hazırladığım eski CV’me bakabilirsiniz.) Bu sürenin bilgisayar ile ilgili olmayan işlerle ilgilendiğim iki buçuk ayı haricinde yazılım konusunda kendimi yetiştirmeye çalıştım. Aşağıda daha detaylı aktaracağım gibi temel bazı konuları öğrenebildiğimi düşünüyorum.
  1. Önceki işyerimde çalışırken network ve işletim sistemleri konusunda detaylı bilgi edinmiştim. Bu dönemde ayrıca “C Programming Language” kitabını okuma ve C bilgilerimi güncelleme fırsatı buldum. Yine bu dönemde “Reversing - Secrets of Reverse Engineering” kitabını okudum ve genel olarak CPU’ların çalışma şekli hakkında bilgi sahibi oldum. Disassembler kullanarak 32-bit x86 için derlenmiş basit kodları inceleyerek pratik yaptım. 
  2. Linux Program Development” kitabı ile memory ve dosya işlemlerine ek olarak Linux işletim sisteminin sağladığı olanakları kullanarak yazılım geliştirmeyi öğrendim. Burada öğrendiklerimle basit bir concurrent (her connection’a özel thread açan) chat server uygulaması yazdım. 
  3. Web programlama yaparken OOP konusunda deneyim sahibi olmuştum. Ama C++ ve özellikle STL konusunda bilgim olmadığı için “ADTs, Data Structures and Problem Solving with C++” kitabını okudum. Kitabı okurken yazdığım küçük programcıklardan birkaçını GitHub'da bulabilirsiniz. 
  4. Daha önce Python ile PyQt kullanarak GUI geliştirmiştim. C++ ile Qt kullanarak komut satırından çalışan bir program için arayüz yazdım. 
  5. Linux Device Drivers 3rd edition” kitabını okudum. ARP paketlerine sahte yanıtlar üreterek kendisini başka network cihazları ile iletişimde gibi gösteren basit bir network driver yazdım. Bir de basit bir char driver yazdım. Henüz gerçek bir donanım için driver yazmadım.
Örnek uygulamalar hakkında daha detaylı bilgiye ve kaynak kodlarına Kod Örnekleri bölümünden ulaşabilirsiniz. Bu örneklerin küçük olduğunun ve ancak giriş seviyesinde bilgi sahibi olduğumu gösterdiklerinin farkındayım. Daha kapsamlı uygulamalar geliştirmek için zamanım olmadı.

Orta ölçekli projelerde deneyim kazanabilmek için zod-engine isimli open-source bir proje ile bir süre uğraştım. Ama proje şu anda aktif olarak geliştirilmiyor. Proje kodunu kullanarak kendim bazı şeyler yaptıysam da şu anda paylaşabileceğim somut bir örnek yok.

8 Ekim 2012 Pazartesi

Tekrar merhaba

Merhabalar,

Aylardan sonra yine bloga bir şeyler yazayım diye login oldum ve bir şey farkettim. Blogdaki bazı yazıları ben bakmıyorken de okuyan insanlar varmış. Özellikle virtual memory nedir yazısı, biraz da Google aramalarında üst sıralarda çıktığı için sanırım değişik kişiler tarafından okunmuş.

Blogun düzenli takipçisi olduğunu sanmıyorum (zaten ben de düzenli yazmıyorum) ama yine de bir şey paylaşmak istiyorum. Ben bu bloga yalnızca iş aramaya başladığım zaman yazı yazıyorum. Sebebi de CV'mde yazan bazı konuları bildiğimi, en azından bir fikir sahibi olduğumu gösterebilmek. Dolayısıyla iş başvurusu yaptığım şirketler dışında herhangi bir trafik beklemiyordum.


Geçen sefer Mayıs ayında iş aramaya başlamıştım. Eski işimden mutlu bir şekilde ayrıldım fakat halletmem gereken özel işlerim olduğu için yeni iş yerine başlayamadım. Gerçi bir yandan iyi oldu. Hem uzun süredir çözmem gereken işlerle ilgilendim hem de sistem programlama alanına kendimi daha iyi hazırlama şansı buldum.

Şu anda temel eksiklerimi iyi - kötü kapatabildiğimi düşündüğüm için buradan yaz boyu yaptıklarımla ilgili yazı ve kod paylaşmaya başlayacağım. Gönlümden geçen VPS kiralayıp wordpress temelli bir blog yapmaktı ama şu anda dikkatimi ayıramıyorum.

Nisan'da son yazdığım yazıda virtual memory'nin sistem adminliği kısmından bahsedeceğim demişim. O yazılar bir yerlerde duruyor bildiğim kadarıyla. Sanırım aşırı swapping ve genel olarak pagingden kaynaklanan performans kayıplarıyla ilgili bir şeyler vardı. İsteyen olursa yorum yazsın, yazıları bulup paylaşayım. Network yazıları da benzer bir şekilde bölük pörçük olsa da duruyor. Onlar da Linux bonding driver ve TCP sessionları replay etmekle ilgiliydi galiba. Bir şeyler daha olabilir. Web programlama döneminde kullandığım blog uçtu gitti ama o yazılar da duruyor. Çoğu son derece out-dated. Bir tek CSS yazısı güzeldi galiba ama zaten o konularda çok daha güzel tonla kaynak var.


Gelelim önümüzdeki günlerde neler paylaşacağıma:
  • Mayıs ayında Linux soketleri ile basit bir chat programı yazmıştım. Bir kaç eksiği vardı. Sanırım server tarafında multi-thread yapacaktım, bağlanan her client'a ayrı thread açacaktı. Onun kodunu paylaşacağım.
  • Larry Nyhoff'un ADTs, Data Structures and Problem Solving with C++ kitabını okudum. Kitabı okurken basit veri yapıları hakkında yazdığım bazı kodları paylaşacağım.
  • Küçükken benim de severek oynadığım oyunlardan Z'nin remake'ini yapmışlar. C++ kullanan open-source proje ararken rastladım. Oyun komut satırından çalıştırılıyor ve içinde pek kullanışlı bir menü yok. Qt ile komut satırı parametrelerinin girilebildiği bir GUI yazdım. Github'da duruyor. Qt ve sinyaller ile ilgili de kısa bir yazı yazabilirim.
  • Linux Device Drivers 3 kitabını okuyorum. Kitabın başında "Hello, world" örneği olarak printk ile uyarı yazdırılıyor ama bu bir driver "Hello, world"ü değil sonuçta. Char driver bölümündeki scull driver örneği ise kocaman bir şey. İkisinin arasında, concurrency ve memory işlerine girmeden, çalışan bir char driver örneği yazdım. Hiçbir iş yapmayan bir driver yazmak için bile pek çok formalite var, kernel tarafında çalışıyoruz sonuçta. Bunları en aza indirmiş ve çalışan bir örnek görmek device driver yazmaya yeni başlayanları motive edecektir.

4 Nisan 2012 Çarşamba

Yeni yazılar

Kalan iki virtual memory yazısından önce araya bir kaç network yazısı sıkıştırmak istiyorum. Elimdekilerden bir ya da ikisini seçip yayınlanabilir hale getireceğim.

Bir de Blogger'ın kod görüntülemek için ayrı bir stili yok sanırım. Bu temada da kodlar çok kötü çıkıyor. Ya temayı değiştireceğim ya da biraz CSS yazacağım.

Ya da uğraşmayıp Wordpress.com'a da geçebilirim.

Virtual Memory nedir? - II - free()

alloc() sülalesi komutların tersi olan free() komutunu kullandığımızda memory managera aldığımız alanların boşa çıktığını söyleriz. Bu durumda Windows ile Linux'un davranışları biraz farklılık gösteriyor. Örnek için aşağıdaki kodu kullanabiliriz. Derlediğimizde program karakter girişi aldığında 1024 pagelik bir alanı doldurur, tekrar karakter girişi aldığında boşaltır.
#define PAGECOUNT 1024 //1024 tane 1024 int dolduracagiz = 1024 sayfa
#define LISTCOUNT 1024

int j=0;
int i=0;
char c;
int *chunklist[PAGECOUNT]; //int 4 byte oldugundan 1024 sayfalik alan
//bu pointer dizisinin kendisi de stackte 1 sayfa tutuyor

//lowmem pointerlardan higmem pointerlara dogru gidiyoruz.
//heap grows upwards.  
printf("ENTER'a basinca 1024 page doldurulacak.\n");
getchar();
while(i<PAGECOUNT) {
 chunklist[i]=(int *) calloc(1024,sizeof(int)); //1 page yer ayır
 for(j=0;j<LISTCOUNT;j++) { // ayrilan alan içinde 1 page boyutunda int array oluştur.
  int *p = chunklist[i];
  p[j]=j;
 }
 i++;
}

printf("Toplam 1024 page dolduruldu.\n1024 page bosaltmak icin ENTER'a basin...\n",i);
getchar();

while(i>1) {
 free(chunklist[--i]);
}
printf("Tum sayfalar bosaltildi.\nCikmak icin ENTER'a basin\n");
getchar();
Programı derleyip Linux altında çalıştırdığımızı düşünelim. İlk açtığımızda tuşa basmadan PID'sini öğrenip
cat /proc/$PID/status | grep VmData
dersek heapin kullandığı alanı görebiliriz. Bellek talep edip doldurduktan ve boşalttıktan sonra da processin status bilgisine baktığımızda 4 MB civarı alanın dolduğunu ve boşaldığını görebiliriz. Bu sayı her zaman page boyutuna bölünebilir, page boyutuna bölersek processin bu iş için kullandığı page sayısına erişiriz. (Doğrudan sayfa sayılarını görmek isterseniz /proc/$PID/statm'e bakın.)

Virtual Memory nedir? - II - segfault

Bir önceki yazıda uygulamaların gerçek memory adreslerinden haberdar olmadığını, her bir uygulamanın sürekli ve adresleyebileceği en büyük memory alanında çalıştığını sandığını söylemiştik. Şimdi memory managera inanan uygulamaların nasıl hatalar yapabileceğine bakalım.

Başlamadan önce bir bilgilendirme; yazıda bol bol stack ve heap kelimelerini kullandım. Executableların bölümlerini anlatan ayrı bir yazı yazacağım ama basit olarak stacki fonksiyonların içinde doğrudan tanımladığınız değişkenlerin tutulduğu, heapi de malloc ile dinamik olarak bellek isteyip kullandığınız alanlar olarak düşünebilirsiniz. Stackin boyutu sınırlı olduğundan alloc() tipi komutları hiç kullanmadan büyük işler yapmaya kalkarsanız segfault ile karşılaşmanız kaçınılmazdır.

Segfault 1 


C'yi yeni öğrenirken sık yapılan hatalardandır, &'ler *'lar karışır, unutulur.

Pointer oluştururken değişkenin adının önüne & koymayı unuttuğumuz şöyle bir kod düşünelim:
 int x=5;
 int *p=x;  //int *p = &x; olacakti
 
 printf("pointerin tuttugu adres %x \n", p);
 printf("pointerin adresindeki deger %d \n");


Bu durumda zaten kodu derlerken compiler bir hata ya da uyarı verir. 

Eğer programı derleyebildiysek programı çalıştırdığımızda hata ile karşılaşırız. Neden? Çünkü x'in adresine değil, 0x5 adresine gidip bir değere ulaşmaya çalıştık. İkinci printf'i kaldırın; sorun yok.

Hata taa CPU üzerindeki MMU'dan geliyor ve işletim sisteminin uygulamayı durdurmasına yol açıyor. Process 5 adresine ulaşmak istediğinde memory manager bu processin kullandığı sayfalar içinde 0x5 adresinin bulunduğu sayfanın gerçek adresine öğrenmeye çalışıyor, MMU ise bu processe 0x5 adresini içeren bir sayfa vermediğini söyleyerek exception gönderiyor.

MSVC 2010 yukarıdaki kodu derlemeye izin vermediği için daha genel bir örnek verelim.

Virtual Memory nedir? - I


Virtual memory hem C programlamada hem de sistem yöneticiliğinde muhattap olduğumuz bir konu. Virtual memory'nin çalışma prensiplerini bilmek bazı durumlarda yazılan uygulamanın ya da genel olarak sistemin verimli çalışması için çok önemli olabiliyor.

Temelde virtual memorynin yaptığı iki iş var:
  1. Processlere kendilerine ait sürekli bir hafıza alanını kullanıyorlarmış gibi hissettirmek
  2. Pagefile/swap kullanarak aktif olmayan uygulamaların fiziksel RAM'i gereksiz yere işgal etmesini engellemek
Virtual memory'den bahsetmeden önce bazı kavramları bir kaç cümle ile açıklamakta fayda var.

23 Mart 2012 Cuma

Dosya sistemi nedir? - III

Bir önceki yazıda dosya sistemini muhtarlığa, verileri de muhtarlığa bağlı sokakta ikamet eden insanlara benzetmiştim. Şimdi bu benzetme ile dosya sistemi kullanmanın getirdiği bazı sonuçlara bakalım.

Dosya sistemi kullanmanın sonuçları 


Diskteki verilere dosya sistemleri aracılığıyla erişmenin iyi ya da kötü bazı sonuçları vardır. Bunlardan da basitliği bozmadan bir kaç örnek vereyim.

Dosya sistemi nedir? - II

Dosya sistemi nasıl çalışır? Tek sokaklı muhtarlık...


Aslında bu yazıyı yazmamın tek sebebi az sonra kullanacağım analojinin çok hoşuma gitmiş olması.

Dediğim gibi I/O yaparken disk bilgisayar için yalnızca uzuuun bir satırdır. Bilgisayar diske bana satırın 15. sırasındaki harfi ver der, disk verir. Bana 498567. sıradan 7893249. sıraya kadar ki harfleri ver der, disk verir. Diskin ne dosyalardan ne de dizinlerden haberi yoktur.

Şimdi diski uzun bir sokak, diskin üzerine yazılan verileri de bu sokakta ikamet eden insanlar olarak düşünelim. Dosya sistemi dediğimiz şey bu mahalledeki ikametgahları tutan muhtarlıktır. Mahalle dışından biri gelip birini bulmak istediğinde dosya sistemine sorar, dosya sistemi de sokağın neresinde olduğunu söyler. Bilgisayar bir dosyanın diskin kaçıncı sırasından başladığını, nerede bittiğini, ne kadar yer kapladığını dosya sistemi sayesinde bilebilmektedir.

Peki diski biçimlendirmek/formatlamak ne anlama gelmektedir? Diski formatlarken elimizde ne gibi seçeneklerimiz vardır? Farklı dosya sistemlerinin farkı nerededir?

Dosya sistemi nedir? - I

Bu yazıda genel olarak dosya sistemlerinin neden kullanıldığını ve dosya sistemlerinin temelde nasıl çalıştığını basit olarak anlatmaya çalışacağım.

Dosya sistemleri seneler içinde teknik olarak çok fazla geliştiklerinden dolayı bu yazı hem eksiktir, hem de basitliği korumaya çalıştığım için çoğu modern dosya sistemi için yalnıştır. Bir de kolayıma geldiği için yazı boyunca disk kelimesini hep block device anlamında kullandım.

Neden dosya sistemlerine ihtiyaç duyarız? 


Dosya sistemleri bir ihtiyaç mıdır yoksa işimizi kolaylaştıran özellikler sundukları için mi onları kullanıyoruz?

Örneğin bir USB flashdiski formatlamadan kullansak daha fazla yerimiz olmaz mı? Uğraşıp 4 GBlık USB flashdiske tam 4GBlık bir dosyayı doğrudan disk I/O ile yazamaz mıyız?

Bu elbette mümkün olsa da, çok uzun bir süre önce dosya sistemleri lüks olmaktan çıkmıştır. Peki neden diskleri illa ki biçimlendirilmiş halde kullanıyoruz? Şöyle ki; disk, disket, CD/DVD dediğimiz şeyler bize şekil olarak yuvarlak görünse de bilgisayar tarafından erişilirken upuzun bir satır gibi kullanılmaktadır. Dolayısıyla;
  1. Bilgisayarın satırın ortasındaki bir dosyaya erişmesi için dosyanın satırın tam olarak neresinde olduğunu bilmesi gerekmektedir.
  2. Yeni dosyalar yazılıp ortalardan eski dosyalar silindikçe satırda irili ufaklı boş alanlar ortaya çıkmaktadır. Bu boşlukları dikkatli ve düzenli bir şekilde değerlendirmek gerekmektedir.
  3. Satırın ne kadarının dolu ne kadarının boş olduğunu anlamak ya da satıra yazılmış dosyaların tamamının isimlerini öğrenmek için her seferinde tüm satırı baştan sona okumak çok zahmetli ve zaman kaybettirici bir iştir.
Aklıma ilk bunlar gelse de daha pek çok sebepten ötürü hemen hemen tüm kaydedilebilir ortamlarda dosya sistemleri kullanılmaktadır. Devamı...
Acılıketcap.com'un wordpress temasını güncelleyene kadar burayı kullanacağım. Arada geçen iki yılda yazdığım ama yayınlamadığım yazıları da bugünden itibaren, burada yayınlıyorum...