Month: February 2009

Learning device drivers

I wrote this charater device driver for learning how they work.This is actually an assignment that we got today. .  Prof. TS Reddy  from JNTU helped me to debug the code.  I am planning to make a tutorial on it once I reach home. The course is becoming more and more exciting.  The internet access is very limited now. I will update when I have net access and free time.

Generating number sequences in shell scripts

I learned this technique from a fellow participant .

$ yes |nl |head -100 |cut -f1

You can remove the  new lines as below.

$  yes |nl |head -100 | cut -f1| tr ‘\n’ ‘\t’

Cool.

Otherwise, my course is progressing well. I wrote a simple file transfer daemon and implemented  the client..  Now, I have to do the same with pthreads and non blocking calls.  We had the first glimpse of kernel programming today when some kernel data structures for process and memory managment was iintroduced. I have to read  a lot to get the exact picture.

Update from prepare future

It was pretty heavy work for 2 days.  Yesterday, I was taught about file io and  related system calls followed by environment variables ,  things like parsing command lines etc. I could not finish all the exercises as I went out to see the city. Took a local bus tio HiTech city and then caught an MMTS train and went to Necklace road.  Wandered around tank bund and returned back to JNTU around 10pm. Today, I came early and finished the exercises.

IPC mechanism  were discussed in the morning.  It was followed by an inspirational talk from Venkatesh Choppella from IITM-K Trivandrum on network security from the perspective of software engineering.  Some of my classmates are getting baffled by the exercises and skipping them as there is no compulsion.  Hope I will hold on till the end.  One good thing is that they have restricted Internet from 18.00 to 19.00. :D.  Internet keeps your mind wondering ;I can testify it now. No wonder people invented complex gizmo’s before Internet.

Here there is an Internal portal named E-Sikshak through which they are trying to deliver content, but it seems to malfunction every now and then.  I got this document while exploring E -Sikshak It was in MS Word format and I converted it to a pdf.

Learning Pthreads

I am beginning to enjoy the Prepare Future program on Linux internal and   driver development. Today’s class was about pthreads. I had some prior experience on pthreads library while at CUSAT.   It was refreshed today.

Pthreads is a user space library for  manipulating threads.

Here is what we did today.  First we wrote a small program which created a thread.

It is here.

#include<stdio.h>
#include <sys/types.h>
#include <pthread.h>

void * thread_function ( void *arg)
{
printf(“In Thread\n”);
pthread_exit(“Success”);
}

int main()
{
pthread_t tid;
void * ret_status;
pthread_create( &tid,NULL, &thread_function,NULL);

printf(“In Main\n”);

pthread_join(tid ,&ret_status);

return (0);

}

For compiling this I used.

$gcc -D_REENTRANT -o pt1 pt1.c -l pthread

Then  i tried out   semaphore and mutex in pthread library.

The important semaphore operations are

sem_init  –   int sem_init(sem_t *sem, int pshared, unsigned int value);

sem_ wait    int sem_wait(sem_t *sem);

sem_post         int sem_post(sem_t *sem);

sem_destroy   int sem_destroy(sem_t *sem);

I was forced to RTFM the manual. 😀

I wrote this then.

#include<stdio.h>
#include <sys/types.h>
#include <pthread.h>
#include <semaphore.h>

int y=0;
sem_t sigsem;

void * thread1 ( void *arg)
{
int x;
sem_wait(&sigsem);

x=y+3;

printf(“In Thread1\n”);
printf(” x is %d\n”,x);

pthread_exit(“Success thread1 “);
}

void * thread2 ( void *arg)
{
y=45;
sem_post(&sigsem);
printf(“In Thread2\n”);
printf(” y is %d\n”,y);
pthread_exit(“Success thread2”);
}

int main()
{
pthread_t tid1,tid2;
void * ret_status;

sem_init( &sigsem,0,0);

pthread_create( &tid1,NULL, &thread1,NULL);
pthread_create( &tid2,NULL, &thread2,NULL);
printf(“In Main\n”);

pthread_join(tid1 ,&ret_status);
pthread_join(tid2 ,&ret_status);

sem_destroy(&sigsem);

return (0);

}
This was followed by producer consumer problem as below.

#include<stdio.h>
#include <sys/types.h>
#include <pthread.h>

//sem_t sigsem;
int buffer[10];

void * producer ( void *arg)
{
int i,index;
index=0;

for (i =0;i<40 ;++i)
{

printf(“Producer  trying to produce an item……….\n”);

buffer[index] =i;

printf (“producer put  %d  at buffer [%d]\n”, i,index);

index++;
if (index==10)
index=0;
}

pthread_exit(“Producer ends”);
}

void * consumer ( void *arg)
{
int i,index=0;
for (i=0;i<40;++i)
{
printf(” Consumer  trying to consume  an item ……….\n”);
printf ( ” Consumer ate  %d from buffer[%d]\n”, buffer [index] ,index);

index++;
if (index==10)
index=0;
}

pthread_exit(“Consumer ends”);
}

int main()
{
pthread_t tid1,tid2;
void * ret_status;
pthread_create( &tid1,NULL, &producer,NULL);
pthread_create( &tid2,NULL, &consumer,NULL);

pthread_join(tid1 ,&ret_status);
pthread_join(tid2 ,&ret_status);

return (0);

}
The mutex in it  was then rewritten with pthread_mutex functions. Again lot of RTFM.

Then as an assignment we did the readers and writers problem.

#include<stdio.h>
#include <sys/types.h>
#include <pthread.h>
#include <semaphore.h>

sem_t  mutex,rcmutex;
int reader_count=0;
int buffer=10;

void reader_action(int r )
{

printf ( “\nReader %d  buffer is %d “,r, buffer);
}

void  write_action (int i)
{
int j;
buffer+=10;
for (j=0;j<10;++j) ; //Waste some time

printf ( “\n Writing for %d time buffer is %d “,i, buffer);

}

void * reader1 ( void *arg)
{

sem_wait(&rcmutex);
reader_count++;
if(reader_count==1)
sem_wait(&mutex);
sem_post(&rcmutex);

reader_action(1);

sem_wait(&rcmutex);

reader_count–;
if ( reader_count==0)
sem_post(&mutex);

sem_post(&rcmutex);

pthread_exit(“Success reader1 “);
}

void * reader2 ( void *arg)
{

sem_wait(&rcmutex);
reader_count++;
if(reader_count==1)
sem_wait(&mutex);
sem_post(&rcmutex);

reader_action(2);

sem_wait(&rcmutex);

reader_count–;
if ( reader_count==0)
sem_post(&mutex);

sem_post(&rcmutex);

pthread_exit(“Success reader2 “);
}

void * writer ( void *arg)
{
int i;
for (i=0 ; i<10;++i)
{

sem_wait (&mutex);
write_action(i);
sem_post(&mutex);
}
pthread_exit(“Success writer”);
}

int main()
{
pthread_t tid1,tid2,tid3,tid4,tid5,tid6;
void * ret_status;

sem_init( &mutex,0,1);
sem_init( &rcmutex,0,1);

pthread_create( &tid1,NULL, &reader1,NULL);
pthread_create( &tid2,NULL, &writer,NULL);
pthread_create( &tid3,NULL, &reader2,NULL);
pthread_create( &tid4,NULL, &reader1,NULL);
pthread_create( &tid5,NULL, &reader2,NULL);
pthread_create( &tid6,NULL, &reader1,NULL);

pthread_join(tid1 , &ret_status);
pthread_join(tid2 ,&ret_status);
pthread_join(tid3 ,&ret_status);
pthread_join(tid4 , &ret_status);
pthread_join(tid5 , &ret_status);
pthread_join(tid6 , &ret_status);

sem_destroy(&mutex);
sem_destroy(&rcmutex);
return (0);

}
The course is progressing smoothly. and looks interesting several fellow participants are also stimulating.

I forgot to take the card reader, so I am unable to post photos.  I had a walk around the JNTU campus in the morning and took several photos. May be I will beautify these blog enties with  photos and proper code snippets ( and build   proper pthread tutorial)   when I return.

How to create static and dynamic libraries with gcc

This is an exercise I did   today. I  am documenting it for my own reference.

The problem was simple.

Create a library with functions.

add(int,int) and sub (int,int)

and then use the library  in another program.

Here is the code

/*add.c*/

#include “a.h”

int add( int a,int b)

{
return (a+b);
}
int sub (int a, int b)
{
return( a-b);
}

Here is the header

/* a.h*/

int add(int,int);
int sub(int,int);

Compile add.c to get add.o

gcc -c add.c 

You will have an object file add.o .

Now  create a static library  with

ar rcs  libadd.a add.o

If you have a program which uses functions from your new library as below

/*  main.c */

#include “a.h”
int main()
{
printf (“%d\n”, add(5,10));
printf (“%d\n”, sub(10,5));
return 0;
}
You can link against  our new  library  like this.

gcc -o main main.c -L. -ladd

( Note the -L. and -ladd. -L. say that look for library in current directory and -ladd says that the name of the library is libadd.a)

For creating dynamic libraries, first compile the file containing library as below.

gcc -c -fPIC   add.c

and

 ld -shared -soname libadd.so.1 -o libadd.so.1.0 -lc add.o

 ln -sf libadd.so.1 libadd.so

/sbin/ldconfig -v -n .

( Dont forget .)

Now you are ready to use the library

gcc -o main  main.c -L. -ladd