Friday, 18 October 2013

Install Adobe Acrobat Reader in Ubuntu

Install Adobe Acrobat Reader in Ubuntu pc
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Approach-1: Didn't work for me
----------------------------------
Step1) sudo add-apt-repository "deb http://archive.canonical.com/ precise partner"
Step2) sudo apt-get update
Step3) sudo apt-get install acroread
=============================
Result:
--------
Reading package lists... Done
Building dependency tree    
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
  acroread: Depends: acroread-bin but it is not installable
E: Broken packages


Approach-2: Didn't work for me
-------------------------------
Download Adobe*.deb (i386 version .deb file) from ftp://ftp.adobe.com/pub/adobe/reader/unix/9.x/


sudo linux32 dpkg -i AdbeRdr9.5.4-1_i386linux_enu.deb
=======================================================
dpkg: error processing AdbeRdr9.5.4-1_i386linux_enu.deb (--install):
 package architecture (i386) does not match system (amd64)
Errors were encountered while processing:
 AdbeRdr9.5.4-1_i386linux_enu.deb

Approach3: Worked for me..hurray...
----------------------------------------
sudo dpkg -i --force-architecture AdbeRdr9.5.4-1_i386linux_enu.deb
=====================================================
dpkg: warning: overriding problem because --force enabled:
 package architecture (i386) does not match system (amd64)
Selecting previously deselected package adobereader-enu.
(Reading database ... 147879 files and directories currently installed.)
Unpacking adobereader-enu (from AdbeRdr9.5.4-1_i386linux_enu.deb) ...
Setting up adobereader-enu (9.5.4) ...

Processing triggers for man-db ...

Reference for Approach-3: http://notepad2.blogspot.in/2011/04/install-adobe-reader-on-64-bit-ubuntu.html


Wednesday, 16 October 2013

Linux Kernel Version Numbering Methodology

Linux Kernel Version numbering Mechanism:

We can differentiate linux kernel using its version and these versions are mainly two types.

  1. Stable version
  2. Development version

At any point of time, we have many stable linux versions but only one development version.

Linux kernel version numbering system follows a 4 number system
X.Y.Z.W

X --> Kernel Version.
It is incremented when
a really significant changes happen in Kernel
major changes in the concepts and the code of the kernel.

Y --> Major revision of the kernel.
If this number is an even number then it is a stable kernel (Production use)
If it is odd then it is a development kernel
Developers actively work on Development kernel only.
Example: Current stable version is 2.4.x, and development version is 2.5.x
Once the development in 2.5.x is done, eventually it will become 2.6.0 kernel and new stable kernel is then established.
So, 2.7.x series will begun for development.
If only major changes happen, 2,5,x become 3.0.0 and 3.1.x is open for developers.

Z --> Minor revision of the kernel
It will be changes when a new feature or driver is added.

W --> Represents corrections such as security patches and bug fixes.

We can use "uname" command with option "r" to see which release of the kernel is being used in our linux system.
uname -r
Result in my pc: 2.6.32-28-generic

Reference:
http://www.tldp.org/FAQ/Linux-FAQ/kernel.html#linux-versioning
http://www.linfo.org/kernel_version_numbering.html


Sunday, 6 October 2013

[Operating Systems #3] Sigaction API C code examples

Please refer previous posts for understanding the concepts related to asynchronous signals and useful APIs (including signal API and sigaction API)

Example-1
=========
/*
 *  Child process auto clean-up using sigaction API.
 * If child process is done with its task, then it will be pushed to defunc state.
 * Parent process has to instruct the Kernel Process Manager to destroy the child process using wait function. Instead of blocking parent process until child process termination, we use sigaction API.
 * Using sigaction(), we register a function call back sighandle(), this function will be called when child process has done with its task. In the mean time, parent process can do its own task without dependent on child process.
*/

#include<signal.h>
#include<stdio.h>
#include<string.h>

void sighandler (int signum)
{
printf("Sighandler: I am in sighandler\n");
}

void main()
{
struct sigaction act;
pid_t cpid;

memset(&act, 0, sizeof(act));

act.sa_handler = sighandler;
act.sa_flags = SA_NOCLDWAIT; /* Setting up auto clean-up */

if (sigaction(SIGCHLD, &act, NULL) < 0)
printf("Sigaction reg is failed\n");

cpid = fork();

if (cpid == 0) {
printf("Child: I am in child process\n");
sleep(8);
printf("Child: Done with its task\n");
}
else {
printf("Parent: I am in parent process\n");
while (1) {
printf("main: in loop\n");
sleep(2);
}
}
}

Output:
========
Parent: I am in parent process
main: in loop
Child: I am in child process
main: in loop
main: in loop
main: in loop
Child: Done with its task
Sighandler: I am in sighandler
main: in loop
main: in loop
main: in loop
main: in loop
main: in loop
^C

Observation:
==============
When child and parent process are executing.
rrajk      3044  2067  0 08:56 pts/0    00:00:00 ./sigaction_child
rrajk      3045  3044  0 08:56 pts/0    00:00:00 ./sigaction_child

Once child terminated, sighandler will be called.
rrajk      3044  2067  0 08:56 pts/0    00:00:00 ./sigaction_child

Since we set flag SA_NOCLDWAIT, the child process is destroyed once its done its task.
Otherwise it would be pushed to defunc state.




Example-2
=========
/*
 * Blocking a signal of type 'Y' if another signal of type 'X' is in its handler.
 * Once signal X is completed its task, signal Y's handler is invoked.
 * Use sigaddset() with sigaction() API
*/

#include<signal.h>
#include<stdio.h>
#include<string.h>

void sighandler (int signum)
{
printf("Sighandler: I am in sighandler before sleep\n");
sleep(3);
printf("Sighandler: I am in sighandler after sleep\n");
}

void main()
{
struct sigaction act;
sigset_t sigmask;
int rc;

memset(&act, 0, sizeof(act));
rc = sigemptyset(&sigmask);
printf("sigemptyset return value: %d\n", rc);

rc = sigaddset(&sigmask, SIGQUIT); /* Block this signal if the process is in its handler */
rc = sigaddset(&sigmask, SIGTERM); /* same above */
printf("sigaddset return value: %d\n", rc);

act.sa_handler = sighandler;
act.sa_mask = sigmask;

if (sigaction(SIGINT, &act, NULL) < 0)
printf("Sigaction reg is failed\n");

while (1) {
printf("main: in loop\n");
sleep(2);
}
}

Output:
========
sigemptyset return value: 0
sigaddset return value: 0
main: in loop
main: in loop
main: in loop
^CSighandler: I am in sighandler before sleep
^\Sighandler: I am in sighandler after sleep
Quit (core dumped)

Observation:
==============
If CTRL+C is generated and this signal is in its handler. Now, CTRL+\ (SIGQUIT) is gernerated then it will be blocked until
CTRL+C handler completes its execution.
Once CTRL+C handler done with its task then CTRL+\ handler will be executed.


Example-3
=========
/*
 * sa_flags member in sigaction structure usage.
*/

#include<signal.h>
#include<stdio.h>
#include<string.h>

void sighandler (int signum)
{
printf("Sighandler: I am in sighandler\n");
sleep(3);
}

void main()
{
struct sigaction act;

memset(&act, 0, sizeof(act));

act.sa_handler = sighandler;
act.sa_flags = SA_NODEFER; /* Do not prevent the signal from being received from within its own sighandler */

if (sigaction(SIGINT, &act, NULL) < 0)
printf("Sigaction reg is failed\n");

while (1) {
printf("main: in loop\n");
sleep(2);
}
}

/*Output:
========
main: in loop
main: in loop
^CSighandler: I am in sighandler
^CSighandler: I am in sighandler
^CSighandler: I am in sighandler
^CSighandler: I am in sighandler
main: in loop
main: in loop
main: in loop
main: in loop
main: in loop
main: in loop
^CSighandler: I am in sighandler
^CSighandler: I am in sighandler
main: in loop
User defined signal 1

Observation:
==============
SA_NODEFER flag usage. Since we set the flag NODEFER, the signals are delivered to registered process without any delay once they are generated. So, we saw "I am in sighandler" for 4 times (I pressed CTRL+C 4 times).
If we remove this flag then the behavior is different. Please refer post #2 sigaction section.
Try at your end by commenting SA_NODEFER line and observe the output.



Wednesday, 2 October 2013

[Operating Systems #2] ASynchronous Signals handling using signal and sigaction APIs

Please refer previous post #1: Handling child process. Since, current post is continuation of the post #1.

We already see the use of wait() function. This function call blocks the parent process, reads the exit value of child process and instructs the kernel's process manager to destroy the child process.

Wait() function is synchronous call, it will suspend/block the execution of parent process i.e. parent can't continue its operation/execution until child terminates.

Now, we will see another API "Signals" which uses Asynchronous method.
This method allows the parent process to register a function call back. This function will be executed when the child process terminates. So, the child and parent process can be executed simultaneously without any parent blocking.

Here, we have two different APIs to do this job.

  1. Signal API
  2. Sigaction API

Signal API :
=========

Signals are asynchronous calls, means these will block current execution of process and requires immediate response (registered function call be will be called automatically when the signal interrupt is received).

Once the signal is received, the process can able to perform three different tasks
  1.  Calls default signal handler
  2.  Calls its own defined signal handler
  3.  Ignores the signal
The below Sample code will describe the use of 2nd case (process calls its own defined signal handler).

For 1st case, pass second argument as SIG_DFL in signal() function call. Kernel process manager will call the default function for the signal generated.

For 3rd case (Ignore the signal), use 2nd argument as SIG_IGN in signal() function.

-------------------------------------------------------------------------------------------
Sample code:
----------------

  1. #include<unistd.h>
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include<signal.h>

  5. #define CHILD 0

  6. void sighand(int signum)
  7. {
  8. printf("I am in signal handler: %d\n", signum);
  9. }
  10. int main()
  11. {
  12. pid_t child_pid;

  13. child_pid = fork();
  14. if (child_pid == CHILD) {
  15. /* child process */
  16. printf("child: %d, parent: %d\n", getpid(), getppid());
  17. sleep(10);
  18. exit(100);
  19. } else {
  20. /* parent process */
  21. signal(SIGCHLD, sighand);
  22. printf("Successfully registered sighand for SIGCHLD: %d\n", SIGCHLD);
  23. printf("parent: %d\n", getpid());
  24. while(1) {
  25. printf("in parent\n");
  26. sleep(2);
  27. }
  28. }
  29. return 0;
  30. }

output:
=======
Successfully registered sighand for SIGCHLD: 17
parent: 2274
in parent
child: 2275, parent: 2274
in parent
in parent
in parent
in parent
in parent
I am in signal handler: 17
in parent
in parent
in parent
.
.

observation:
=========
signal is not a blocking call like wait().
Since in wait() case, parent process is blocked until child terminated.
But here in signal() case, parent process is executing continuously and received asynchronous interrupt (SIGCHLD) when child terminates. sighand() is called in response to this interrupt.
ps -Af (Before SIGCHLD interrupt received)
-----------------
rrajk      2285  2039  0 10:59 pts/0    00:00:00 ./fork4_signal
rrajk      2286  2285  0 10:59 pts/0    00:00:00 ./fork4_signal

ps -Af (After SIGCHLD received:)
----------------
rrajk      2285  2039  0 10:59 pts/0    00:00:00 ./fork4_signal
rrajk      2286  2285  0 10:59 pts/0    00:00:00 [fork4_signal] <defunct>

Since child process terminated, but parent process is still executing then child process put into defunc state.
------------------------------------------------------------------------------------------

Sigaction API:
============

Signal API is an ANSI C Standard API.
Sigaction API is a POSIX standard API.

We use sigaction APIs for changing the signal disposition in better way compared to signal.
Using sigaction, we can block/unblock required set of signals with ease of operations.

Sigaction() prototype declaration
--------------------------------------
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

struct sigaction {
  void (*sa_handler)(int);
  void (*sa_sigaction)(int, siginfo_t *, void *);
  sigset_t sa_mask;
  int sa_flags;
  void (*sa_restorer)(void);
};

sigaction is alternative signal API for changing signal disposition.
Sample code:
            struct sigaction sa;
            memset(&sa, 0, sizeof(sa));
  
          /* Install signal Handler */
            sa.sa_handler = handler;
            if (sigaction(SIGALRM, &sa, NULL) < 0)
                        printf(“Sigaction failed\n”);

When a signal is generated and it is being currently handled, another occurrence of the same signal shall be queued (queue size = 1) until handler returns. If more than 1 signal is generated in this case, they will be lost.

But, occurrence of Real Time signals are never lost, they will be queued.

sa.sa_flags:
==========
           sa.sa_flags = SA_NODEFER;
           Signals are not queued, they directly send to the registered process. No delay in delivery. No queue also.

sa.sa_mask:
==========
If one signal is in its handler, and if another signal is generated then 1st signal is terminated immediately and 2nd signal handler will start its execution.
Ex: CTRL+C SIGTERM and CTRL+\ SIGQUIT

Sigaction provide a mechanism to block this 2nd signal until 1st signal completed its handler function.
Sample code:
            sigset_t sigmask;
            sigemptyset(&sigmask);

            sigaddset(&sigmask, SIGQUIT); /* block SIGQUIT if a signal is already in its handler */
            sigaddset(&sigmask, SIGTERM);

            sa.sa_handler = handler;
            sa.sa_mask = sigmask;

            if (sigaction(SIGINT, &sa, NULL) < 0)
                        printf(“sigaction is failed\n”);

Sigprocmask:
=============
Applications can also block/unblock signal delivery while executing the primary functionality in the main thread.
            Int sigprocmask(int how, const sigset_t *set, sigset_t *old_set);

how: SIG_BLOCK or SIG_UNBLOCK

Sample code:
            struct sigaction sa;
            sigset_t set;

            memset(&sa, 0, sizeof(sa));
            sigemptyset(&set);

            sigaddset(&set, SIGQUIT);
            sigaddset(&set, SIGTERM);

            /* ovrride signal mask set */
            sigprocmask(SIG_BLOCK | SIG_SETMASK, &set, NULL);

           /* Append to signal mask list */

            sigprocmask(SIG_BLOCK, &set, NULL); 

Examples will be posted in next post [Operating Systems #3].

[Operating System #1] Handling Child Process

We know that a new process can be created using fork() system call. This new process we call it as a Child Process.

fork():
---------
fork() prototype declaration:
            #include<unistd.h>
            pid_t fork(void);
Return: It returns two results. One result is Process ID (PID) of new process (child process), which is returned to parent process.  Second result is 0 (if child process is created successfully.), which is returned to child process.

We will identify child and parent process using this return value only.

Sample code:
----------------
                pid_t child_pid;
                child_pid = fork();
                if (child_pid == 0)
                {  /* child process */
                } else {
                    /* parent process */
                }

The child will have its own PCB (Process Control Block), so this process is assigned with a PID. We use getpid() call to get the PID of the process. Similarly, we use getppid() call to get the PID of its parent process.
getpid() & getppid():
--------------------------
These calls returns PID of the process of integer datatype.
This child process will share same address space with its parent i.e. it shares stack segment, data segment and code segment and it has its own PCB.

------------------------------------------------------------------------------
Example-1
========

  1. #include<unistd.h>
  2. #include<stdio.h>

  3. #define CHILD 0

  4. int main()
  5. {
  6. pid_t child_pid;

  7. printf("Before fork: pid: %d\n", getpid());
  8. child_pid = fork();
  9. printf("Hello Fork: pid: %d, parent_pid: %d, childpid: %d\n", getpid(), getppid(), child_pid);
  10. return 0;
  11. }

output:
======
Before fork: pid: 2164
Hello Fork: pid: 2164, parent_pid: 1924 (bash), childpid: 2165
Hello Fork: pid: 2165, parent_pid: 1, childpid: 0

Observation:
==========
The code after fork() function will be executed twice. One time for parent process and 2nd time for child process. Since, child process shares same address space it includes code segment also.

Parent process (2164) is executed before child and got terminated, its parent process is 1924 (terminal). The fork() return value is 2165 (child process PID).

After parent, child is executed and its has PID 2165. Since the parent process is terminated, the child process is taken care by root process "init"(1).

On success, fork() returns
1. PID of the child process in the parent process
2. 0 is returned in the child process
-----------------------------------------------------------------------------------------

There are few cases, we need to look at them very carefully.
Child Process terminated first
Parent process terminates first

The above example is for 2nd case, where parent process is terminated first.
The below example is for 1st case: Child process is terminated first.
-----------------------------------------------------------------------------------------
Example-2 
========

  1. #include<unistd.h>
  2. #include<stdio.h>

  3. #define CHILD 0

  4. int main()
  5. {
  6. pid_t child_pid;

  7. child_pid = fork();
  8. if (child_pid == CHILD) {
  9. /* child process */
  10. printf("child: my pid: %d..parent_pid: %d\n", getpid(), getppid());
  11. } else {
  12. /* parent process */
  13. printf("parent: my pid: %d\n", getpid());
  14. while(1);
  15. }
  16. return 0;
  17. }


Output:
=======
parent: my pid: 2244
child: my pid: 2245..parent_pid: 2244

Observation: ps -Af
===============
rrajk     2244  1924 86 09:47 pts/2    00:00:39 ./fork2
rrajk      2245  2244  0 09:47 pts/2    00:00:00 [fork2] <defunct>

Child process is done with its code execution. There is no code left to continue.
And, parent is still alive, child process is put into "defunc" state, until immediate parent process instructs kernel to destroy terminated process.
This child process is called as "Zombie Process".
------------------------------------------------------------------------------------------

We know that child process shares same address space with its parent process. If one process modifies the shared data then a new address space is allocated for that process. This concept is called Copy-On-Write approach.

The below example #3 will show, how copy-on-write approach works.
-------------------------------------------------------------------------------------------
Example-3
========

  1. #include<unistd.h>
  2. #include<stdio.h>
  3. #include<stdlib.h>

  4. #define CHILD 0

  5. int main()
  6. {
  7. pid_t child_pid;
  8. int k =10;

  9. child_pid = fork();
  10. if (child_pid == CHILD) {
  11. /* child process */
  12. printf("child: %d, parent: %d\n", getpid(), getppid());
  13. k = 44;
  14. printf("child: k value: %d\n", k);
  15.         } else {
  16. /* parent process */
  17. printf("parent: %d\n", getpid());
  18. wait(NULL);
  19. printf("parent: k value: %d\n", k);
  20. while(1);
  21. }
  22. return 0;
  23. }


output:
======
parent: 2124
child: 2125, parent: 2124
child: k value: 44
parent: k value: 10

observation:
===========
wait(): Suspends caller until child terminates and instructs the process manager to destroy child PCB that is in defunc (exit) state.
And, the value of k is not affected due to change in child process. Since either of the process modifies the shared values then copy-on-write procedure will takes place and new address space is created for that process.

If we observe, there is no child process with defunc status using "ps -Af" command.
rrajk      2134  2039 77 10:45 pts/0    00:00:09 ./fork3_wait
-------------------------------------------------------------------------------------------

Next: Synchronization of child and parent process execution
====

How famous companies got their names


Google: The name started as a joke boasting about the amount of information the search-engine would be able to search. It was originally named 'Googol', a word for the number represented by 1 followed by 100 zeros. After founders - Stanford graduate students Sergey Brin and Larry Page presented their project to an angel investor; they received a cheque made out to 'Google'. So, instead of returning the cheque for correction, they decided to change the name to Google.

Microsoft: Coined by Bill Gates to represent the company that was devoted to MICROcomputer SOFTware. Originally christened Micro-Soft, the '-' was removed later on.

LG: Combination of two popular Korean brands Lucky and Goldstar.
Linux: Linus Torvalds originally used the Minix OS on his system which here placed by his OS. Hence the working name was Linux (Linus' Minix). He thought the name to be too egotistical and planned to name it Freax (free+freak+x). His friend Ari Lemmke encouraged Linus to upload it to a network so it could be easily downloaded. Ari gave Linus a directory called 'Linux' on his FTP server, as he did not like the name Freax. (Linus parents named him after two-time Nobel Prize winner Linus Pauling).


Nike: Named for the greek goddess of victory. The swoosh symbolises her flight.

Skype: The original concept was ‘Sky-Peer-to-Peer’, which morphed into Skyper, then Skype.


Mercedes: This was actually financier's daughter's name.


Adidas: The company name was taken from its founder Adolf (ADI) Dassler whose first name was shortened to the nickname Adi. Together with first three letters of his surname it formed ADIDAS.


Adobe: This came from the name of the river Adobe Creek that ran behind the house of founder John Warnock.


Apple Computers: It was the favourite fruit of founder Steve Jobs. He was three months late for filing a name for the business, and he threatened to call his company Apple Computers if the other colleagues didn't suggest a better name by 5 o'clock.


CISCO: It is not an acronym as popularly believed. It's short for San Francisco.


Compaq: This name was formed by using COMP, for computer and PAQ to denote a small integral object.


Corel: The name was derived from the founder's name Dr. Michael Cowpland. It stands for COwpland Research Laboratory.


Hotmail: Founder Jack Smith got the idea of accessing e-mail via the web from a computer anywhere in the world. When Sabeer Bhatia came up with the business plan for the mail service, he tried all kinds of names ending in 'mail' and finally settled for hotmail as it included the letters "html" - the programming language used to write web pages. It was initially referred to as HoTMaiL with selective uppercasing.

Hewlett Packard: Bill Hewlett and Dave Packard tossed a coin to decide whether the company they founded would be called Hewlett-Packard or Packard-Hewlett.


Intel: Bob Noyce and Gordon Moore wanted to name their new company 'Moore Noyce' but that was already trademarked by a hotel chain so they had to settle for an acronym of INTegrated ELectronics.


Lotus (Notes): Mitch Kapor got the name for his company from 'The Lotus Position' or 'Padmasana'. Kapor used to be a teacher of transcendental Meditation of Maharishi Mahesh Yogi.


Motorola: Founder Paul Galvin came up with this name when his company started manufacturing radios for cars. The popular radio company at the time was called Victrola.

Sony: It originated from the Latin word 'sonus' meaning sound and 'sonny' as lang used by Americans to refer to a bright youngster.


SUN: Founded by 4 Stanford University buddies, SUN is the acronym for Stanford University Network. Andreas Bechtolsheim built a microcomputer; Vinod Khosla recruited him and Scott McNealy to manufacture computers based on it, and Bill Joy to develop a UNIX-based OS for the computer.


Apache: It got its name because its founders got started by applying patches to code written for NCSA's httpd daemon. The result was 'A PAtCHy' server - thus, the name Apache Jakarta (project from Apache): A project constituted by SUN and Apache to create a web server handling servlets and JSPs. Jakarta was name of the conference room at SUN where most of the meetings between SUN and Apache took place.


Tomcat: The servlet part of the Jakarta project. Tomcat was the code name for the JSDK 2.1 project inside SUN.


C: Dennis Ritchie improved on the B programming language and called it 'New B'. He later called it C. Earlier B was created by Ken Thompson as a revision of the Bon programming language (named after his wife Bonnie).


C++: Bjarne Stroustrup called his new language 'C with Classes' and then 'newC'. Because of which the original C began to be called 'old C' which was considered insulting to the C community. At this time Rick Mascitti suggested the name C++ as a successor to C.


GNU: A species of African antelope. Founder of the GNU project Richard Stallman liked the name because of the humour associated with its pronunciation and was also influenced by the children's song 'The Gnu Song' which is a song sung by a gnu. Also it fitted into the recursive acronym culture with 'GNU's Not Unix'.


Java: Originally called Oak by creator James Gosling, from the tree that stood outside his window, the programming team had to look for a substitute as there was no other language with the same name. Java was selected from a list of suggestions. It came from the name of the coffee that the programmers drank.


Mozilla: When Marc Andreessen, founder of Netscape, created a browser to replace Mosaic (also developed by him), it was named Mozilla (Mosaic-Killer, Godzilla). The marketing guys didn't like the name however and it was re-christened Netscape Navigator.

Red Hat: Company founder Marc Ewing was given the Cornell lacrosse team cap (with red and white stripes) while at college by his grandfather. He lost it and had to search for it desperately. The manual of the beta version of Red Hat Linux had an appeal to readers to return his Red Hat if found by anyone!


SAP: "Systems, Applications, Products in Data Processing", formed by 4 ex-IBM employees who used to work in the 'Systems/Applications/Projects' group of IBM.


UNIX: When Bell Labs pulled out of MULTICS (MULTiplexed Information and Computing System), which was originally a joint Bell/GE/MIT project, Ken Thompson and Dennis Ritchie of Bell Labs wrote a simpler version of the OS. They needed the OS to run the game 'Space War' which was compiled under MULTICS. It was called UNICS - UNIplexed operating and Computing System by Brian Kernighan. It was later shortened to UNIX.


SCO (UNIX): From Santa Cruz Operation. The company's office was in Santa Cruz.


Xerox: The inventor, Chestor Carlson, named his product trying to say 'dry' (as it was dry copying, markedly different from the then prevailing wet copying). The Greek root 'xer' means dry.


Yahoo: The word was invented by Jonathan Swift and used in his book 'Gulliver's Travels'. It represents a person who is repulsive in appearance and action and is barely human. Yahoo! founders Jerry Yang and David Filo selected the name because they considered themselves yahoos.


3M: Minnesota Mining and Manufacturing Company started off by mining the material corundum used to make sandpaper. It was changed to 3M when the company changed its focus to Innovative Products.

Tuesday, 6 August 2013

[Kernel Programming#6] Busy waiting & Delay of execution in Kernel

Busy waiting

The current execution of process can wait for some events should occur (like availability of required resources/data, passage of time or release of a lock). Here, the passage of times means delaying the current execution.
This waiting can be done in two ways
1.       Busy waiting
2.       Sleeping

Busy waiting

Here, the process/thread run in a loop by constantly checking the event has occurred condition. For example, if you want to wait for 5millisec then,
wait = getCurrentTime() + 5;
while(wait > getCurrentTime())
cpu_relax(); // do nothing
cpu_relax() is an architecture way of saying that there is no much work with CPU at this time.
This function does nothing.
The CPU cycles are being wasted for this amount of time. If the wait time is small then it is advisable to use the busy waiting concepts. Since, there is no overhead of context switching and performance is good.
But, if the wait time is more then it will be better to use sleeping concepts instead of busy waiting.

Sleeping

Here, the process/thread will be put into wait-queue so that CPU can start execution of other process/thread (using context switching). Kernel will wake up the process when the required condition for that process is met.
Advantage: There is no wastage of CPU cycles.
Overhead: context switching

Delaying the execution:

There are few scenarios where the current process has to wait for some period of time like for example h/w needs to accomplish few tasks. There are different techniques to achieve this delay.
We can divide delays into two types:
Long delays: Delays those are reliably longer than clock tick. It can use system clock for implementation.
Short delays: Implemented with s/w loops.
Long delays: below techniques can be used
è Busy waiting: cpu_relax()
è Release processor: schedule(). Releasing the CPU when the process doesn’t require it. There is a possibility of going to infinite sleep since CPU starts serving other process, and current sleep process may not get CPU in worst case. The above two approaches uses jiffi counter.
To avoid infinite sleep, another way is to ask the kernel to do this task like below.
è wait_event_timeout(): using this technique, the process can be wake up when somebody calls wake_up() and when the timeout expires.
But, If process specifically require to wake up with timeout value only then below technique will be used.
è Schedule_timeout():
Short Delays: techniques (Busy waiting)
ndelay(): set nano seconds delay. Optional.
udelay(): set micro seconds delay. Every architecture implements it.
mdelay(): set milli seconds delay. Optional.
Delay achieved and it is at least the value of delay and it could be more.
There are other techniques which doesn’t involve in busy waiting.
msleep(): puts the calling process in sleep.
msleep_interruptible(): puts the calling process in sleep.
ssleep(): --same—but in seconds.

You might also like

Related Posts Plugin for WordPress, Blogger...