Wednesday, January 23, 2013

Mutex Vs Semaphore

The Myth: mutexes and semaphores are  similar or even interchangeable.
The Truth:while mutexes and semphores have similarites in their implementation, they should always be used differently.

The most common (but nonetheless incorrect ) answer to the above question is that mutexes and semphore are very similar, with only the significant difference being that semaphores can count higher than one.

When asked to expand on how to use a "counting semaphore" these are used to protect several equivalent resources. A counting semaphore is a synchronization object that can have an arbitrarily large number of states. The internal state is defined by a signed integer variable, the counter.


  •  Negative there are exactly -N threads queued on the semaphore.
  • Zero  no waiting threads, a wait operation would put in queue the invoking thread.
  • Positive no waiting threads, a wait operation would not put in queue the invoking thread.


Two operations are defined for counting semaphores:

  • wait This operation decreases the semaphore counter, if the result is negative then the invoking thread is queued.
  • Signal This operation increases the semaphore counter, if the result is non-negative then a waiting thread is removed from the queue and resumed.
counting semaphores have no ownership attribute and can be signaled by any thread or interrupt  handler regardless of who performed the last wait operation.
Because there is no concept a counting semaphore object can be created with any initial counter value
as long it is non-negative.
The counting semaphore are usually as guards of resources avaliable in a discreate quantity. For example the counter may represent the number of used slots into a circular queue, producer would "signal" the semaphores when inserting items in the queue, consumer threads would "wait"  for an item to appear in queue, this would ensure that no consumer would be able to fetch an item from the queue if there are no items avaliable.

A binary semaphore is a synchronization object that can only two states:

  • Not taken 
  • Taken
Two operations are defined:

  • Take Taking a binary semaphore brings it in the "taken" state, trying to take a semaphore that is already taken enters the invoking thread into a waiting queue.
  • Release Releasing a binary semaphore brings it in the "not taken " state if there are not queued threads. If there are queued threads then a thread is removed from the queue and resumed, the binary semaphore remains in the "taken" state. Releasing a semaphore that is already in its "not taken" state has no effect.
Binary semaphore have no ownership attribute and can be signaled by any thread or interrupt handler regardless of who performed the last taken operation. Because of this binary semaphore are often used to synchronize threads with external events implemented as ISR's .
Ex:waiting for a packet from a network or waiting that a button is pressed.

If a semaphore were a generalization of a mutex able to protect two or more identical shared resources, then in our analogy. The correct use of semaphore is for signaling from one task to another. By contrast, tasks that use semaphores either signal or wait--not both.

mutexwait(mutex_room)
  // safely use shared resource
mutexRelease(mutex_room)

/* task1 producer */
sempost(sem_power_btn);

/*task2 consumer */
sempend(sem_power_btn);

Note: Importantly, semphores can also be used to signal from an interrupt service routine to a task. Signaling a semaphore is a non-blocking RTOS behavior and thus ISR safe. Because this technique eliminates the error-prone need to disable interrupts at the task level, signaling from within an ISR is an excellent embedded software more reliable by design.

Mutex:
A mutex is a synchronization object that can have only two states.
  • Not owned
  • Owned
Two operations are defined for muteses:
  • Lock This operation attempts to take ownership of a mutex, if the mutex is already owned by another thread then the invoking thread is queued.
  • Unlock This operation relinquishes ownership of a mutex. If there are queued therads then a thread is removed from the queue and resumed, ownership is implicitly to the thread.
Note: unlike semaphores, mutexes do have owners. A mutex can be unlocked only by the thread that owns it, this precludes the use of mutexes from interrupt handlers but enables the implementation of the priority Inheritance protocol, most RTOS,s implement this protocol in order to address the priority inversion problem. It must be said that few RTOS's implement this protocol fully and even less do that efficiently. Mutexes have one single use, Mutual Exclusion, and are optimized for that. Semaphores also handle mutual exclusion scenarios but are best used as a communication mechanisum between threads or between ISRs and threads.

Tuesday, January 22, 2013



Grub2 installing in virtual disk





-----------------------------------------------------------------------------------------------------------------------------------------------------

Step1:
$ dd if=/dev/zero  of=hd.img bs=2048 count=100000
$ fdisk hd.img
$ m
$ n
$ p
$ 1
$ m
$ n
$ 2
$ m
$ t
$ 2
$ l
$ 8e
after that
$ p
Device Boot      Start         End      Blocks   Id  System
hd.img1            2048      299999      148976   83  Linux
hd.img2          300000      399999       50000   8e  Linux LVM



$ kpartx -a hd.img
>next give loop support
$ losetup /dev/loop0 hd.img
$ mkfs.ext4 /dev/loop0
$ mount -v -t ext4 /dev/loop0 /mnt/lfs
copy all file system files in mounting directory
as well as create a directories in mounting directory
mkdir -p /mnt/lfs/dev
mkdir -p /mnt/lfs/proc
mkdir -p /mnt/lfs/sys
mknod -m 600 /mnt/lfs/dev/console c 5 1
mknod -m 666 /mnt/lfs/dev/null c 1 3

next
$ echo “(hd0) /dev/loop0  > device.map
$ echo “set prefix=(hd0)/boot/grub >mycfg.cfg
$ /mnt/grub2/bin/grub-mkimage --config=mycfg.cfg-p /boot -O i386-pc  -o /mnt/lfs/boot/grub/core.img  loadenv chain biosdisk part_dvh part_msdos msdospart part_gpt exfat ext2 fat vbe vga ntfs echo test configfile minicmd hdparm normal multiboot

$ /mnt/grub2/lib/grub/i386-pc/boot.img /mnt/lfs/boot/grub
$ /mnt/grub2/sbin/grub-bios-setup -m device.map -d /mnt/lfs/boot/grub /dev/loop0
umount /mnt/lfs
kpartx -d hd.img


$ qemu-system-i386 -hda hd.img
$ qemu-system-i386 -hda /dev/loop0


Thursday, September 20, 2012

Usage of extern keyword



Important points to remember about extern keyword:

1. It is default storage class of all global variables as well all functions. For example, Analyze following two c code and its output:

(a)
#include <stdio.h>
int i;    //By default it is extern variable
int main(){
    printf("%d",i);
    return 0;
}

Output: 0

(b)

#include <stdio.h>
extern int i;    //extern variable
int main(){
    printf("%d",i);
    return 0;
}

Output: Compilation error, undefined symbol i.

Question: In Both program variable i is extern variable. But why output is different? Read second and third points.

(c)

#include <stdio.h>
void sum(int,int//By default it is extern.
int main(){
    int a=5,b=10;
    sum(a,b);
    return 0;
}
void sum(int a,int b){
    printf("%d”",a+b);
}

Output: 15

2. When we use extern modifier with any variables it is only declaration i.e. memory is not allocated for these variable. Hence in second case compiler is showing error unknown symbol i. To define a variable i.e. allocate the memory for extern variables it is necessary to initialize the variables. For example:

#include <stdio.h>
extern int i=10;    //extern variable
int main(){
    printf("%d",i);
    return 0;
}

Output: 10

3. If you will not use extern keyword with global variables then compiler will automatically initialize with default value to extern variable.

4. Default initial value of extern integral type variable is zero otherwise null. For example:

#include <stdio.h>
char c;
int i;
float f;
char *str;  
int main(){
    printf("%d %d %f %s",c,i,f,str);
    return 0;
}

Output: 0 0 0.000000 (null)

5. We cannot initialize extern variable locally i.e. within any block either at the time of declaration or separately. We can only initialize extern variable globally. For example:

(a)
#include <stdio.h>
int main(){
extern int i=10; //Try to initialize extern variable
                 //locally.
    printf("%d",i);
    return 0;
}
Output: Compilation error: Cannot initialize extern variable.

(b)
#include <stdio.h>
int main(){
    extern int i; //Declaration of extern variable i.
    int i=10;     //Try to locally initialization of
                  //extern variable i.
    printf("%d",i);
    return 0;
}

Output: Compilation error: Multiple declaration of variable i.

6. If we declare any variable as extern variable then it searches that variable either it has been initialized or not. If it has been initialized which may be either extern or static* then it is ok otherwise compiler will show an error. For example:

(a)
#include <stdio.h>
int main(){
    extern int i; //It will search the initialization of
                  //variable i.
    printf("%d",i);
    return 0;
}
int i=20;    //Initialization of variable i.

Output: 20

(b)
#include <stdio.h>
int main(){
extern int i; //It will search the any initialized
              //variable i which may be static or 
              //extern.
printf("%d",i);
    return 0;
}
extern int i=20; //Initialization of extern variable i.

Output: 20
(c)
#include <stdio.h>
int main(){
extern int i; //It will search the any initialized
              //variable i which may be static or 
              //extern.
    printf("%d",i);
    return 0;
}
static int i=20; //Initialization of static variable i.


Output: 20

(d)
#include <stdio.h>
int main(){
    extern int i;   //variable i has declared but not
                    //initialized
    printf("%d",i);
    return 0;
}

Output: Compilation error: Unknown symbol i.

7. A particular extern variable can be declared many times but we can initialize at only one time. For example:

(a)
extern int i; //Declaring the variable i.
int i=25;     //Initializing the variable.
extern int i; //Again declaring the variable i.
#include <stdio.h>
int main(){
    extern int i; //Again declaring the variable i.
    printf("%d",i);
    return 0;
}


Output: 25

(b)
extern int i; //Declaring the variable
int i=25;     //Initializing the variable
#include <stdio.h>
int main(){
         printf("%d",i);
    return 0;
}
int i=20; //Initializing the variable


Output: Compilation error: Multiple initialization variable i.

8. We cannot write any assignment statement globally. For example:

#include <stdio.h>
extern int i;
int i=10;   //Initialization statement
i=25;       //Assignment statement
int main(){
    printf("%d",i);
    return 0;
}

Output: Compilation error
Note: Assigning any value to the variable at the time of declaration is known as initialization while assigning any value to variable not at the time of declaration is known assignment.
(b)
#include <stdio.h>
extern int i;
int main(){
    i=25;       //Assignment statement
    printf("%d",i);
    return 0;
}
int i=10;   //Initialization statement

Output: 25

9. If declared an extern variables or function globally then its visibility will whole the program which may contain one file or many files. For example consider a c program which has written in two files named as one.c and two.c:
(a)

//one.c

#include<conio.h>
int i=25; //By default extern variable
int j=5;  //By default extern variable
/**
Above two line is initialization of variable i and j.
*/
void main(){
    clrscr();
    sum();
    getch();
}

//two.c

#include<stdio.h>
extern int i; //Declaration of variable i.
extern int j; //Declaration of variable j.
/**
Above two lines will search the initialization statement of variable i and j either in two.c (if initialized variable is static or extern) or one.c (if initialized variable is extern) 
*/
void sum(){
    int s;
    s=i+j;
    printf("%d",s);
}

Compile and execute above two file one.c and two.c at the same time:

Friday, August 10, 2012

Data structures

Data structures: A data structure is a specialized format for organizing and storing data.Any data structure is designed to organize a data to suit a specific purpose so that it can be accessed  and worked with in appropriate ways. In computer programming a data structure may be selected or designed to store data for the purpose of working on it with various algorithms.

There are different types of data structures for different types of application.
Basically or mainly data structures are divide into two types;
1)Linear
2)Non-linear
Linear:
1)Arrays  2)Stacks  3)Queues  4)Linked Lists .
Non-Linear:
1)Trees 2)Graphs 3)Tables 4)sets.

Sunday, July 22, 2012

Creating Static Libraries


Step1:-create the source files( .c files)

#vim main.c

#vim add.c

#vim sub.c

#vim multi.c

#vim div.c 

 

Step2:-create a relocatable files to the corresponding source files

#gcc -c main.c -o main.o

#gcc -c add.c -o add.o

#gcc -c sub.c -o sub.o

#gcc -c multi.c -o multi.o

#gcc -c div.c -o div.o

 

Step3:-By using a archiver tool("ar")to create static libraries

#gcc rcs libstatic.a add.o sub.o multi.o div.o

A static library must start with the three letters 'lib' and have the suffix '.a'

 

Step4:- Linking static library

#gcc -static main.c libstatic.a -o main 

 

Step5:-finally run the executable

#./main

Compileing Stages

Step1:- Source file-------------------------------------------------------->.c File

#gcc<space>-E<space>.c filename<space>-o<space>targetfilename1.i

By using -E flag preprocessor is invoked 

#gcc -E Hello.c -o Hello.i

#vim Hello.i file


Step2:-Preprocessor file------------------------------------------------>.i File

#gcc<space>-S<space>targetfilename1.i<space>-o<space>targetfilename2.s

By using -S flag Compiler is invoked

 

Step3:-Assembly file---------------------------------------------------->.s File

#gcc<space>-c<space>targetfilename2.s<space>-o<space>targetfilename3.o

By using -c flag Assembler is invoked to generate Relocatable file.


Step4:-Relocatable file------------------------------------------------>.o File

#gcc<space>targetfilename3.o<space>-o<space>targetfilename.

Finally Executable file will be created.