Linux Internals & Networking: System Programming Using Kernel Interfaces
Linux Internals & Networking: System Programming Using Kernel Interfaces
Team Emertxe
Contents
Linux Internals & Networking
Contents
● Introduction
● Transition to OS programmer
● System Calls
● Process
● IPC
●
Signals
● Networking
● Threads
● Synchronization
● Process Management
● Memory Management
Introduction
Introduction
Let us ponder ...
OS
Hardware
Applications
Kernel Linux
Operating System
main() Modules
Boot Initialization
Supervisor Mode
RTI
User Mode
History
Humans
Program
Interface
User
Programs
Compiler Assembler Text Editor Database
OS
System and Application Programs Interface
Operating
System Operating System
HW
Interface/
Privileged
Instr
Hardware
Introduction
Kernel Architecture
Hardware Hardware
Introduction
Mono vs Micro
0101100
C LS
010110
01001
DS
Kernel
EOS Abstracts HW
from users
Device Drivers
LDD Hardware
MC
Application vs OS
C Algorithms, Syntax, Logic ● Preprocessor
● Compiler
● Assembler
● Linker
● Executable file
(a.out)
OS Memory segments, process, ● Executing a program
Threads ●
Loader
Signals, IPC, Networking
Application Programming
Compilation Stages
●
Preprocessor
– Expands header files
– Substitute all macros
– Remove all comments
– Expands and all # directives
●
Compilation
– Convert to assembly level instructions
●
Assembly
– Convert to machine level instructions
– Commonly called as object files
– Create logical address
●
Linking
– Linking with libraries and other object files
Application Programming
Compilation Stages
Expanded Source
Compiler .i Code
gcc -E file.c
Assembly Source
Assembler .s Code
gcc -S file.c
Executable
Loader .out
● Create two files file1.c & file2.c with appropriate functions in them
● Compile them to create object files ("gcc -c fun1.c fun2.c"). It will
create fun1.o and fun2.o files as output
● Create a static library by using ("ar rcs fun1.o fun2.o -o libstatic.a),
with this you have completed creating your static library
● Create your main.c file by calling these two functions
● Perform a static linking (gcc main.c libstatic.a)
● This will generate your a.out, execute the program and observe the
output
Linking
Static Dynamic
Parameter
Executable Size
Loding Time
Memory Usage
No of Sys Calls
Executing a process
RAM Memory Layout Stack
Frame
P1
P1 Command Line
Arguments Local Variables
Parameter List
Hole
P3
Heap
. .BSS
Segment
(Uninitialized)
. Data
. Initialized
Pn-1
Code Segment
Pn
Quiz
● How a user defined function works?
● How a library function works?
Storage Classes
Storage Class Scope Lifetime Memory Allocation
Within the
Till the end of the block /
auto block / Stack
function
Function
Within the block / Till the end of the block /
register Register
Function function
Within the block /
static local Till the end of the program Data Segment
Function
static global File Till the end of the program Data segment
extern Program Till the end of the program Data segment
Hands-on
● Access a static variable from outside file.
● Access a global variable from outside file.
● Combination of both static and local.
Common errors
with various memory segments
Hole
Eg int arr[5]; arr[100];
Memory Leak
Heap
● When you never free memory after allocating.
(Uninitialized)
Data
Initialized
Segmentation
Fault
● When you try to change text segment, which is a
Text Segment
read-only memory or try trying to access a memory
beyond process memory limit (like NULL pointer)
Introduction
What is Linux?
User Space
Application
hardware, hard disks
● Linux Kernel: The kernel abstracts and
GNU mediates access to the hardware resources,
C
Library
including the CPU. A kernel is the core of the
operating system
Linux
Architecture Dependent
● User Applications: The set of applications in
Kernel Code
use on a particular Linux system (e.g. web
Hardware Platform browser)
Introduction
Linux Kernel Subsystem
●
Process Scheduler (SCHED):
– To provide control, fair access
of CPU to process, while
interacting with HW on time
●
Memory Manager (MM):
– To access system memory
securely and efficiently by
multiple processes. Supports
Virtual Memory in case of
huge memory requirement
●
Virtual File System (VFS):
– Abstracts the details of the
variety of hardware devices
by presenting a common file
interface to all devices
Introduction
Linux Kernel Subsystem
● Network Interface (NET):
– provides access to several
networking standards and a
variety of network hardware
● Inter Process
Communications (IPC):
– supports several
mechanisms for process-to-
process communication on a
single Linux system
Introduction
Virtual File System
User Processes
User space
System Calls
Kernel space
FIFO
ext2 ext3 /proc sockets
Pipes
Linux Internals
Polling Interrupts
Interrupts
Interrupts
Hardware Software
For a OS programmer, calling a system call is no different from a normal function call.
But the way system call is executed is way different.
System calls
User
Application
open()
User Mode
System Call Interface
Kernel Mode
● open()
● Implementation
of open() system
call
● ●
●
●
return
System Call
Calling Sequence
user task
user mode
user task executing calls system call return from system call (mode bit = 1)
Logically the system call and regular interrupt follow the same flow of steps. The
source (I/O device v/s user program) is very different for both of them. Since system
call is generated by user program they are called as ‘Soft interrupts’ or ‘Traps’
System Call
vs Library Function
system_call:
xyz() { … sys_xyz() {
…. …. sys_xyz()
xyz() int 0x80 … …
…. …. ret_from_sys_call:
} … }
iret
● open
● read
●
write
●
exit
● close
●
wait
● waitpid
●
getpid
● sync
●
nice
●
kill etc..
Process
Process
● Running instance of a program is called a PROCESS
● If you have two terminal windows showing on your screen,
then you are probably running the same terminal program
twice-you have two terminal processes
● Each terminal window is probably running a shell; each
running shell is another process
● When you invoke a command from a shell, the corresponding
program is executed in a new process
● The shell process resumes when that process complete
Process
vs Program
int global_1 = 0;
int global_2 = 0; local_1
stack
local_2 5
void do_somthing()
{
int local_2 = 5;
local_2 = local_2 + 1;
CPU Registers
}
heap
int main()
{ global_1
data
char *local_1 = malloc(100); global_2
.start main
do_somthing(); code
.call do_somthing
…..
}
…..
Process
More processes in memory!
P0
Stack
Free Space
P1
Heap
P2
Data
Free Space
Code
OS
Each Process will have its own Code, Data, Heap and Stack
Process
State Transition Diagram
ready running
scheduler dispatch
waiting
Process
State Transition Diagram
Priority
Round Robin
FCFS
Preemptive
interrupted
ready running
scheduler dispatch
waiting
I/O: Keyboard
Even: Signal
Process
States
State Description
New The process is being created
Running Instructions are being executed
Waiting The process is waiting for some event to occur
Ready The process is waiting to be assigned to processor
Terminated The process has finished execution
Process
Descriptor
● To manage tasks:
– OS kernel must have a clear picture of what each task is
doing.
– Task'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.
● Usually the OS maintains a structure whose fields contain
all the information related to a single task
Process
Descriptor
●
● Memory-management
●
●
information
●
● I/O status information
Process
Descriptor – State Field
State Description
TASK_RUNNING Task running or runnable
TASK_INTERRUPTIBLE process can be interrupted while sleeping
P1 P2 P3 P4
Stack Stack Stack Stack
User space
user@user:~] ps -aef
UID PID PPID C STIME TTY TIME CMD
Process
root 1 0 0 12:17 ? 00:00:01 /sbin/init
ID root 2 0 0 12:17 ? 00:00:00 [kthreadd]
root 3 2 0 12:17 ? 00:00:02 [ksoftirqd/0]
Parent
root 4 2 0 12:17 ? 00:00:00 [kworker/0:0]
Process root 5 2 0 12:17 ? 00:00:00 [kworker/0:0H]
ID root 7 2 0 12:17 ? 00:00:00 [rcu_sched]
Process
Context Switching
●
idle
executing
Process
Creation
●
fork makes a child process that is an exact copy of its
parent process
●
When a program calls fork, a duplicate process, called the
child process, is created
●
The parent process continues executing the program from
the point that fork was called
●
The child process, too, executes the same program from
the same place
●
All the statements after the call to fork will be executed
twice, once, by the parent process and once by the child
process
Process
Creation - fork()
PID = 25
Data
Text
Stack
Process Status
Linux
Kernel
Process
fork() - The Flow
PID = 25
Files
Data
Text
Stack Resources
Process Status
ret = fork();
switch (ret)
{
case -1:
perror(“fork”);
exit(1);
case 0:
<code for child>
exit(0);
default:
<code for parent>
wait(&child_status); Linux
}
Kernel
Process
fork() - The Flow
PID = 25
Files
Data
Text
Stack Resources
Process Status
ret = fork();
switch (ret)
{
case -1:
perror(“fork”);
exit(1);
case 0:
<code for child>
exit(0);
default:
<code for parent>
wait(&child_status); Linux
}
Kernel
Process
fork() - The Flow
PID = 25 PID = 26
Files
Data Data
Text Text
Stack Resources Stack
Process Status Process Status
PID = 25 PID = 26
Files
Data Data
Text Text
Stack Resources Stack
Process Status Process Status
PID = 25 PID = 26
Files
Data Data
Text Text
Stack Resources Stack
Process Status Process Status
PID = 25 PID = 26
Files
Data Data
Text Text
Stack Resources Stack
Process Status Process Status
PID = 25 PID = 26
Files
Data Data
Text Text
Stack Resources Stack
Process Status Process Status
PID = 25
Files
Data
Text
Stack Resources
Process Status
●
First, the child process is a new process and therefore has a
new process ID, distinct from its parent’s process ID
●
One way for a program to distinguish whether it’s in the
parent process or the child process is to call getpid
●
The fork function provides different return values to the
parent and child processes
●
One process “goes in” to the fork call, and two processes
“come out,” with different return values
●
The return value in the parent process is the process ID of the
child
●
The return value in the child process is zero
Process
fork() - Example
printf(“Hello World\n”);
return 0;
}
Process
fork() - Example
P
int main()
{
fork();
fork();
fork();
printf(“Hello World\n”);
return 0;
}
Process
fork() - Example
P
int main()
{
fork(); C1
fork();
fork();
printf(“Hello World\n”);
return 0;
}
Process
fork() - Example
P
int main()
{
fork(); C1 C2
fork();
fork();
printf(“Hello World\n”);
return 0; C3
}
P
int main()
{
fork(); C1 C2 C4
fork();
fork();
printf(“Hello World\n”);
C3 C5 C6
return 0;
}
C7
●
Zombie process is a process that has terminated but has not
been cleaned up yet
●
It is the responsibility of the parent process to clean up its
zombie children
●
If the parent does not clean up its children, they stay
around in the system, as zombie
●
When a program exits, its children are inherited by a special
process, the init program, which always runs with process ID
of 1 (it’s the first process started when Linux boots)
●
The init process automatically cleans up any zombie child
processes that it inherits.
Process
Orphan
●
The exec functions replace the program running in a process
with another program
●
When a program calls an exec function, that process
immediately ceases executing and begins executing a new
program from the beginning
● Because exec replaces the calling program with another one, it
never returns unless an error occurs
● This new process has the same PID as the original process, not
only the PID but also the parent process ID, current directory,
and file descriptor tables (if any are open) also remain the same
●
Unlike fork, exec results in still having a single process
Process
Overlay - exec()
Program
Counter
int main()
{ Stack
print(“Executing my ls :)\n”);
execlp(“/bin/ls”, “ls”, NULL); Heap
}
Data
Code
Process
Overlay - exec()
● After executing the exec function, you will note the following
changes
PID Preserved
Program
Counter
int main()
{ Stack Overwritten by New Code
print(“Executing my ls :)\n”);
execlp(“/bin/ls”, “ls”, NULL); Heap Overwritten by New Code
}
Data Overwritten by New Code
●
Copy-on-write (called COW) is an optimization strategy
●
When multiple separate process use same copy of the same
information it is not necessary to re-create it
●
Instead they can all be given pointers to the same resource,
thereby effectively using the resources
●
However, when a local copy has been modified (i.e. write) ,
the COW has to replicate the copy, has no other option
●
For example if exec() is called immediately after fork()
they never need to be copied the parent memory can be
shared with the child, only when a write is performed it
can be re-created
Process
Termination
Polling Interrupts
sleep wait
Process
Wait
waitpid (pid_t pid, int* status, int options) Similar to wait, but only blocks on a child
with specific PID
wait3(int *status, int options, struct rusage Returns resource usage information
*rusage) about the exiting child process.
wait4 (pid_t pid, int *status, int options, struct Similar to wait3, but on a specific child
rusage *rusage)
Process
Resource Structure
struct rusage {
struct timeval ru_utime; /* user CPU time used */
struct timeval ru_stime; /* system CPU time used */
long ru_maxrss; /* maximum resident set size */
long ru_ixrss; /* integral shared memory size */
long ru_idrss; /* integral unshared data size */
long ru_isrss; /* integral unshared stack size */
long ru_minflt; /* page reclaims (soft page faults) */
long ru_majflt; /* page faults (hard page faults) */
long ru_nswap; /* swaps */
long ru_inblock; /* block input operations */
long ru_oublock; /* block output operations */
long ru_msgsnd; /* IPC messages sent */
long ru_msgrcv; /* IPC messages received */
long ru_nsignals; /* signals received */
long ru_nvcsw; /* voluntary context switches */
long ru_nivcsw; /* involuntary context switches */
};
Inter Process Communications (IPC)
Communication
in real world
● Face to face
● Fixed phone
● Mobile phone
● Skype
● SMS
Inter Process Communications
Introduction
Communication Synchronization
● Pipes ● Semaphores
● FIFO
● Shared memory
● Signals
● Sockets
Each IPC mechanism offers some advantages & disadvantages. Depending on the
program design, appropriate mechanism needs to be chosen.
Application and Tasks
T1
T2
T4
Inter Process Communications
User vs Kernel Space
User
Kernel
process 1
process 2
process n
How can processes communicate with each other and the kernel? The
answer is nothing but IPC mechanisms
Inter Process Communications
Pipes
Pipe read and write can be done simultaneously between two processes by
creating a child process using fork() system call.
Inter Process Communications
Pipes – Direction of communication
Parent Child
Inter Process Communications
Pipes – Direction of communication
Parent Child
Inter Process Communications
Pipes – Working
Process Kernel
fd[1]
Pipe
Buffer
fd[0]
Inter Process Communications
Pipes - Pros & Cons
PROS CONS
● We have covered
Communication Synchronization
● Pipes ● Semaphores
● FIFO
● Shared memory
● Signals
● Sockets
Inter Process Communications
FIFO - Properties
User Kernel
P1
Pipe
file Buffer
P2
Inter Process Communications
FIFO - Creation
Function Meaning
int mknod( path: Where the FIFO needs to be created (Ex:
const char *path, “/tmp/Emertxe”)
mode_t mode, mode: Permission, similar to files (Ex: 0666)
dev_t dev) dev: can be zero for FIFO
Inter Process Communications
FIFO - Access
user@user:~] ls -l my_fifo
prw-rw-r-- 1 biju biju 0 Mar 8 17:36 my_fifo
prw-
Inter Process Communications
FIFO vs Pipes
Shell 1
Shell 2
user@user:~] cat /tmp/my_fifo
Hai hello
Inter Process Communications
FIFO - Pros & Cons
PROS CONS
communicate.
● One directional
communication
● No extra system calls
required to communicate
● Kernel is involved
(read/write)
● Work like normal file
Inter Process Communications
Summary
● We have covered
Communication Synchronization
● Pipes ● Semaphores
● FIFO
● Shared memory
● Signals
● Sockets
Inter Process Communications
Shared Memories - Properties
●
Shared memory allows two or more processes to access the same
memory
●
When one process changes the memory, all the other processes see
the modification
●
Shared memory is the fastest form of Inter process communication
because all processes share the same piece of memory
●
It also avoids copying data unnecessarily
Note:
• Each shared memory segment should be explicitly de-allocated
• System has limited number of shared memory segments
• Cleaning up of IPC is system program’s responsibility
Inter Process Communications
Shared vs Local Memory
Kernel
Space Shared Memory
Inter Process Communications
Shared Memories - Procedure
● Create
● Attach
● Read/Write 95%
● Detach
● Remove
Inter Process Communications
Shared Memories - Procedure
Function Meaning
int shmget( Create a shared memory segment
key_t key, key: Seed input
size_t size, size: Size of the shared memory
int shmflag) shmflag: Permission (similar to file)
RETURN: Shared memory ID / Failure
void *shmat( Attach to a particular shared memory location
int shmid, shmid: Shared memory ID to get attached
void *shmaddr, shmaddr: Exact address (if you know or leave it
int shmflag) 0)
shmflag: Leave it as 0
RETURN: Shared memory address / Failure
int shmdt(void *shmaddr) Detach from a shared memory location
shmaddr: Location from where it needs to get
detached
RETURN: SUCCESS / FAILURE (-1)
shmctl(shmid, IPC_RMID, NULL) shmid: Shared memory ID
Remove and NULL
Inter Process Communications
Synchronization - Debugging
user@user:~] ipcs -s
● We have covered
Communication Synchronization
● Pipes ● Semaphores
● FIFO
● Shared memory
● Signals
● Sockets
Signals
Signals
● Signals are used to notify a process of a particular event
● Signals make the process aware that something has
happened in the system
● Target process should perform some pre-defined actions
to handle signals
● This is called ‘signal handling’
● Actions may range from 'self termination' to 'clean-up'
Get Basics Right
Function pointers
● What is function pointer?
● Datatype *ptr ; normal pointer
● Datatype (*ptr)(datatype,..); Function pointer
● How it differs from normal data pointer?
Function Pointer Data Pointer
● The kernel
● A Process may also send a Signal to another Process
● A Process may also send a Signal to itself
● User can generate signals from command prompt:
‘kill’ command:
$ kill <signal_number> <target_pid>
$ kill –KILL 4481
Sends kill signal to PID 4481
$ kill –USR1 4481
Sends user signal to PID 4481
Signals
Handling
Function Meaning
signal (int signal_number, void *(fptr) (int)) signal_number : Interested signal
fptr: Function to call when signal handles
Signals
Handling
P1
Registering handler
User Signal
signal / sigaction
Space handler
Signal handler
Kernel
Space executed
Process
Pointer
State
Signal generated
Process ID
Signals
Registers
Memory Limits
● The signal() function can be called by the user for capturing signals
and handling them accordingly
● It mainly handles user generated signals (ex: SIGUSR1), will not alter
default behavior of other signals (ex: SIGINT)
● In order to alter/change actions, sigaction() function to be used
● Any signal except SIGKILL and SIGSTOP can be handled using this
Function Meaning
sigaction( signum : Signal number that needs to be handled
int signum,
const struct sigaction *act, act: Action on signal
struct sigaction *oldact)
oldact: Older action on signal
Signals
Advanced Handling – sigaction structure
struct sigaction
{
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
}
Sending Signal
P2 P1
System call
User S/w interrupt from
Space U/S to K/S
Kernel Signals
Space S/w interrupt from
K/S to U/S
Synchronous & Asynchronous
● Wait for child to finish
Synchronous Asynchronous
Polling Interrupts
sleep wait
sleep Pause
Signals
Self Signaling
● We have covered
Communication Synchronization
● Pipes ● Semaphores
● FIFO
● Shared memory
● Signals
● Sockets
Networking Fundamentals
Networking Fundamentals
Introduction
●
Networking technology is key behind today’s success of Internet
●
Different type of devices, networks, services work together
●
Transmit data, voice, video to provide best in class
communication
●
Client-server approach in a scaled manner towards in Internet
●
Started with military remote communication
●
Evolved as standards and protocols
Application
7 Application details
User
6 Presentation Application process
5 Session
socket
XTI
4 Transport TCP UDP
Ethernet
Networking Fundamentals
ATM Protocols stack
Higher
ATM Network Higher
User
process Layer Layer
AAL AAL
Data
Link
Layer
ATM Layer ATM Layer
ATM switch ATM switch
ATM ATM
Physical Physical
PHY PHY
layer layer
Networking Fundamentals
x.25 Protocols stack
X.25 Network
User Higher Higher
process Layer Layer
Network
PLP PLP
Layer
X.25 Data
Protocol Link LAPB LAPB
suite Layer
EIA/TIA-232, EIA/TIA-232,
Physical EIA/TIA-449
EIA/TIA-449
Layer EIA-530
EIA-530
Networking Fundamentals
Addressing
● IP layer: IP address
– Dotted decimal notation (“192.168.1.10”)
– 32 bit integer is used for actual storage
– IP address must be unique in a network
– Two modes IPv4 (32 bits) and IPv6 (128 bits)
– Total bits divided into two parts
● Network
● Host
– Host part obtained using subnet mask
Networking Fundamentals
IPv4
172 . 16 . 254 . 1
10101100.00010000.11111110.00000001
A 0 1.0.0.0 to 127.255.255.255
Network Host
16 Bits
B 1 0 128.0.0.0 to 191.255.255.255
Network Host
24 Bits
C 1 1 0 192.0.0.0 to 223.255.255.255
Network Host
D 1 11 0 224.0.0.0 to 239.255.255.255
Multi-cast Address
E 1 11 1 240.0.0.0 to 255.255.255.255
Reserved for future use
Networking Fundamentals
Ipv6
2001:0DB8:AC10:FE01:0000:0000:0000:0000
0010000000000001:0000110110111000:0000010000010000:1111111000000001:
0000000000000000:0000000000000000:0000000000000000:0000000000000000
Networking Fundamentals
ip address and domain name
Visitor Packet
Networking Fundamentals
Ports
Socket
Process Process
Networking Fundamentals
TCP/IP three way handshake connection
Server
Client
Syn req
K
Syn req + AC
ACK
Connection established
Socket
Sockets
● Sockets is another IPC mechanism, different from other
mechanisms as they are used in networking
● Apart from creating sockets, one need to attach them
with network parameter (IP address & port) to enable it
communicate it over network
● Both client and server side socket needs to be created &
connected before communication
● Once the communication is established, sockets provide
‘read’ and ‘write’ options similar to other IPC
mechanisms
Get Basics Right
Between big endian & little endian
return 0;
}
●
Since machines will have different type of byte orders (little
endian v/s big endian), it will create undesired issues in the
network
●
In order to ensure consistency network (big endian) byte
order to be used as a standard
●
Any time, any integers are used (IP address, Port number
etc..) network byte order to be ensured
●
There are multiple help functions (for conversion) available
which can be used for this purpose
●
Along with that there are some utility functions (ex:
converting dotted decimal to hex format) are also available
Sockets
Address
struct sockaddr_in
{
short int sin_family; /* Address family */
unsigned short int sin_port; /* Port number */
struct in_addr sin_addr; /* IP address structure */
unsigned char sin_zero[8]; /* Zero value, historical purpose */
};
Function Meaning
int socket( Create a socket
int domain, domain: Address family (AF_INET, AF_UNIX etc..)
int type, type: TCP (SOCK_STREAM) or UDP (SOCK_DGRAM)
int protocol) protocol: Leave it as 0
RETURN: Socket ID or Error (-1)
Example usage:
sockfd = socket(AF_INET, SOCK_STREAM, 0); /* Create a TCP socket */
Sockets
Calls - bind
Function Meaning
int bind( Bind a socket to network address
int sockfd, sockfd: Socket descriptor
struct sockaddr *my_addr, my_addr: Network address (IP address & port number)
int addrlen) addrlen: Length of socket structure
RETURN: Success or Failure (-1)
Example usage:
int sockfd;
struct sockaddr_in my_addr;
my_addr.sin_family = AF_INET;
my_addr.sin_port = 3500;
my_addr.sin_addr.s_addr = 0xC0A8010A; /* 192.168.1.10 */
memset(&(my_addr.sin_zero), ’\0’, 8);
Example usage:
struct sockaddr_in my_addr, serv_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = 4500; /* Server port */
serv_addr.sin_addr.s_addr = 0xC0A8010B; /* Server IP = 192.168.1.11 */
Sockets
Calls - listen
Function Meaning
int listen( Prepares socket to accept connection
int sockfd, MUST be used only in the server side
int backlog) sockfd: Socket descriptor
Backlog: Length of the queue
Example usage:
listen (sockfd, 5);
Sockets
Calls - accept
Function Meaning
int accept( Accepting a new connection from client
int sockfd, sockfd: Server socket ID
struct sockaddr *addr, addr: Incoming (client) address
socklen_t *addrlen) addrlen: Length of socket structure
RETURN: New socket ID or Error (-1)
Example usage:
new_sockfd = accept(sockfd,&client_address, &client_address_length);
Function Meaning
int recv Receive data through a socket
(int sockfd, sockfd: Socket ID
void *buf, msg: Message buffer pointer
int len, len: Length of the buffer
int flags) flags: Mark it as 0
RETURN: Number of bytes actually sent or Error(-1)
Sockets
Calls – send
Function Meaning
int send( Send data through a socket
int sockfd, sockfd: Socket ID
const void *msg, msg: Message buffer pointer
int len, len: Length of the buffer
int flags) flags: Mark it as 0
RETURN: Number of bytes actually sent or Error(-1)
Sockets
Calls – close
Function Meaning
close (int sockfd) Close socket data connection
sockfd: Socket ID
Sockets
TCP - Summary
Server Client
socket socket
bind
listen
accept
Connection establishment
connect
Data (request)
recv send
Data (reply)
send recv
close close
D1
App App
TCP UDP
1
2 Socket D 1
D2
3 2
3 Socket
D3
Sockets
UDP
Server
socket
Client
socket bind
sendto recvfrom
recvfrom sendto
close
Function Meaning
int sendto( Send data through a UDP socket
int sockfd, sockfd: Socket ID
const void *msg, msg: Message buffer pointer
int len, len: Length of the buffer
unsigned int flags, flags: Mark it as 0
const struct sockaddr *to, to: Target address populated
socklen_t length); length: Length of the socket structure
RETURN: Number of bytes actually sent or Error(-1)
● Iterative Model
– The Listener and Server portion coexist in the same task
– So no other client can access the service until the current
running client finishes its task.
● Concurrent Model
– The Listener and Server portion run under control of different
tasks
– The Listener task is to accept the connection and invoke the
server task
– Allows higher degree of concurrency
Client – Server Models
Iterative Model – The Flow
● Create a socket
● Bind it to a local address
● Listen (make TCP/IP aware that the socket is
available)
● Accept the connection request
● Do data transaction
● Close
Client – Server Models
Iterative Model – The Flow
Iterative
Server Listen
Client – Server Models
Iterative Model – The Flow
Client A
Iterative
Connect Listen
Server
Client – Server Models
Iterative Model – The Flow
Client A
Iterative
Connect Accept and Process
Server
Client – Server Models
Iterative Model – The Flow
Client A
Iterative Processing
Connected
Server Client A
Client B
Connect
Client – Server Models
Iterative Model – The Flow
Client A
Iterative Processing
Connected
Server Client A
Client B
Wait
Client – Server Models
Iterative Model – The Flow
Client A
Iterative Processing
Close Client A
Server
Done
Client B
Wait
Client – Server Models
Iterative Model – The Flow
Iterative
Server Listen
Client B
Connect
Client – Server Models
Iterative Model – The Flow
Client B
Connect
Client – Server Models
Iterative Model – The Flow
Iterative Processing
Server Client B
Done
Client B
close
Client – Server Models
Iterative Model – The Flow
Iterative
Server Listen
Client – Server Models
Iterative Model – Pros and Cons
● Pros:
– Simple
– Reduced network overhead
– Less CPU intensive
– Higher single-threaded transaction throughput
● Cons
– Severely limits concurrent access
– Server is locked while dealing with one client
Client – Server Models
Concurrent Model – The Flow
Concurrent
Server Listen
Client – Server Models
Concurrent Model – The Flow
Client A
Connect Concurrent
Server Listen
Client – Server Models
Concurrent Model – The Flow
Client A
Connect Concurrent
Server Accept and fork
Client – Server Models
Concurrent Model – The Flow
Server
Child 1
Client A
Connect Concurrent
Server Listen
Client – Server Models
Concurrent Model – The Flow
Server Process
Child 1 Client A
Client A
Connected Concurrent
Server Listen
Client – Server Models
Concurrent Model – The Flow
Server Process
Child 1 Client A
Client A
Connected Concurrent
Server Accept and fork
Client B
Connect
Client – Server Models
Concurrent Model – The Flow
Server Process
Child 1 Client A
Client A
Connected Concurrent
Server Accept and fork
Client B
Connect Server
Child 2
Client – Server Models
Concurrent Model – The Flow
Server Process
Child 1 Client A
Client A
Connected Concurrent
Server Listen
Client B
Process
Server Client A
Child 1 Done
Client A
close Concurrent
Server Listen
Client B
Concurrent
Server Listen
Client B
Concurrent
Server Listen
Client B
Concurrent
Server Listen
Client – Server Models
Concurrent Model – Pros and Cons
● Pros:
– Concurrent access
– Can run longer since no one is waiting for
completion
– Only one listener for many clients
● Cons
– Increased network overhead
– More CPU and resource intensive
Inter Process Communications
Summary
● We have covered
Communication Synchronization
● Pipes ● Semaphores
● FIFO
● Shared memory
● Signals
● Sockets
Threads
Threads
● Threads, like processes, are a mechanism to allow a program
to do more than one thing at a time
● As with processes, threads appear to run concurrently
● The Linux kernel schedules them asynchronously, interrupting
each thread from time to time to give others a chance to
execute
● Threads are a finer-grained unit of execution than processes
● That thread can create additional threads; all these threads
run the same program in the same process
● But each thread may be executing a different part of the
program at any given time
Threads
Single and Multi threaded Process
Threads are similar to handling multiple functions in parallel. Since they share
same code & data segments, care to be taken by programmer to avoid issues.
Threads
Advantages
Function Meaning
int pthread_create( A pointer to a pthread_t variable, in which the
pthread_t *thread, thread ID of the new thread is stored
const pthread_attr_t *attr, A pointer to a thread attribute object. If you
void *(*start_routine) (void *), pass NULL as the thread attribute, a thread will
void *arg) be created with the default thread attributes
A pointer to the thread function. This is an
ordinary function pointer, of this type: void* (*)
(void*)
A thread argument value of type void *.
Whatever you pass is simply passed as the
argument to the thread function when thread
begins executing
Threads
Creation
Function Meaning
int pthread_join( Thread ID of the thread to wait
pthread_t thread, Pointer to a void* variable that will receive
void **value_ptr) thread finished value
If you don’t care about the thread return
value, pass NULL as the second argument.
Threads
Passing Data
●
Occasionally, it is useful for a sequence of code to determine
which thread is executing it.
●
Also sometimes we may need to compare one thread with
another thread using their IDs
● Some of the utility functions help us to do that
Function Meaning
pthread_t pthread_self() Get self ID
●
It is possible to cancel a particular thread
●
Under normal circumstances, a thread terminates normally
or by calling pthread_exit.
●
However, it is possible for a thread to request that another
thread terminate. This is called cancelling a thread
Function Meaning
int pthread_cancel(pthread_t Cancel a particular thread, given the
thread) thread ID
●
Synchronization is defined as a mechanism which ensures that two
or more concurrent processes do not simultaneously execute some
particular program segment known as critical section
●
When one process starts executing the critical section (serialized
segment of the program) the other process should wait until the
first process finishes
●
If not handled properly, it may cause a race condition where, the
values of variables may be unpredictable and vary depending on the
timings of context switches of the processes
●
If any critical decision to be made based on variable values (ex: real
time actions – like medical system), synchronization problem will
create a disaster as it might trigger totally opposite action than
what was expected
Synchronization
Race Condition in Embedded Systems
●
Embedded systems are typically lesser in terms of resources,
but having multiple processes running. Hence they are more
prone to synchronization issues, thereby creating race
conditions
●
Most of the challenges are due to shared data condition. Same
pathway to access common resources creates issues
●
Debugging race condition and solving them is a very difficult
activity because you cannot always easily re-create the
problem as they occur only in a particular timing sequence
●
Asynchronous nature of tasks makes race condition simulation
and debugging as a challenging task, often spend weeks to
debug and fix them
Synchronization
Critical Section
● The way to solve race condition is to have the critical section access in
such a way that only one process can execute at a time
● If multiple process try to enter a critical section, only one can run and the
others will sleep (means getting into blocked / waiting state)
Critical Section
Synchronization
Critical Section
● Only one process can enter the critical section; the other two have to
sleep. When a process sleeps, its execution is paused and the OS will run
some other task
Critical Section
Synchronization
Critical Section
● Once the process in the critical section exits, another process is woken up
and allowed to enter the critical section. This is done based on the existing
scheduling algorithm
● It is important to keep the code / instructions inside a critical section as
small as possible (say similar to ISR) to handle race conditions effectively
Critical Section
Synchronization
Priority Inversion
●
One of the most important aspect of critical section is to ensure
whichever process is inside it, has to complete the activities at one
go. They should not be done across multiple context switches. This
is called Atomicity
●
Assume a scenario where a lower priority process is inside the
critical section and higher priority process tries to enter
●
Considering atomicity the higher priority process will be pushed into
blocking state. This creates some issue with regular priority
algorithm
●
In this juncture if a medium priority tasks gets scheduled, it will
enter into the critical section with higher priority task is made to
wait. This scenario is further creating a change in priority algorithm
●
This is called as ‘Priority Inversion’ which alters the priority schema
Synchronization
Priority Inversion
Synchronization
Priority Inversion
Quick refresher
● Before moving onto exploring various solutions for critical
section problem, ensure we understand these
terminologies / definitions really well.
– Difference between scheduling & Synchronization
– Shared data problem
– Critical section
– Race condition
– Atomicity
– Priority inversion
Critical section - Solutions
Critical Section
Solutions
●
There are multiple algorithms (ex: Dekker’s algorithm) to implement
solutions that is satisfying all three conditions. From a programmers point
of view they are offered as multiple solutions as follows:
– Locks / Mutex
– Readers–writer locks
– Recursive locks
– Semaphores
– Monitors
– Message passing
– Tuple space
● Each of them are quite detailed in nature, in our course two varieties of
solutions are covered they are Mutex and Semaphores
● Let us look into them in detail!
Critical Section
Solutions - Mutual Exclusion
Protected Resource
Critical Section
Solutions - Mutual Exclusion
● During the time that a task holds the mutex, all other tasks waiting on the
mutex sleep.
Mutex
Protected Resource
lock
Critical Section
Solutions - Mutual Exclusion
● Once a task has finished using the shared resource, it releases the mutex.
Another task can then wake up and grab the mutex.
Mutex
release
Protected Resource
Critical Section
Solutions - Mutual Exclusion – Locking / Blocking
●
A semaphore is a counter that can be used to synchronize
multiple processes. Typically semaphores are used where
multiple units of a particular resources are available
●
Each semaphore has a counter value, which is a non-negative
integer. It can take any value depending on number of
resources available
●
The ‘lock’ and ‘unlock’ mechanism is implemented via ‘wait’
and ‘post’ functionality in semaphore. Where the wait will
decrement the counter and post will increment the counter
●
When the counter value becomes zero that means the
resources are no longer available hence remaining processes
will get into blocked state
Critical Section
Semaphores - Sleeping barber problem
● Wait operation:
– Decrements the value of the semaphore by 1
– If the value is already zero, the operation blocks until the value of the
semaphore becomes positive
– When the semaphore’s value becomes positive, it is decremented by 1
and the wait operation returns
● Post operation:
– Increments the value of the semaphore by 1
– If the semaphore was previously zero and other threads are blocked in
a wait operation on that semaphore
– One of those threads is unblocked and its wait operation completes
(which brings the semaphore’s value back to zero)
Critical Section
Mutex & Semaphores
●
Semaphores which allow an arbitrary resource count (say 25) are
called counting semaphores
●
Semaphores which are restricted to the values 0 and 1 (or
locked/unlocked, unavailable/available) are called binary
semaphores
●
A Mutex is essentially the same thing as a binary semaphore,
however the differences between them are in how they are used
●
While a binary semaphore may be used as a Mutex, a Mutex is a
more specific use-case, in that only the process that locked the
Mutex is supposed to unlock it
●
This constraint makes it possible to implement some additional
features in Mutexes
Critical Section
Practical Implementation
●
The problem is critical section / Global Variable
race condition is common in multi- Head Space
threading and multi-processing Environmental Strings
environment. Since both of them
offer concurrency & common Thread Thread Thread
stack stack stack
resource facility, it will raise to
race conditions
thread thre`ad thread
● However the common resource can
be different. In case of multiple
threads a common resource can be
a data segment / global variable
P1 P2 P3 Pn
which is a shared resource
between multiple threads
●
In case of multiple processes a Shared Memory
common resource can be a shared
memory
Synchronization
Treads - Mutex
● Wait operation:
– Decrements the value of the semaphore by 1
– If the value is already zero, the operation blocks until the value of the
semaphore becomes positive
– When the semaphore’s value becomes positive, it is decremented by 1
and the wait operation returns
● Post operation:
– Increments the value of the semaphore by 1
– If the semaphore was previously zero and other threads are blocked in
a wait operation on that semaphore
– One of those threads is unblocked and its wait operation completes
(which brings the semaphore’s value back to zero)
Synchronization
Treads - Semaphores
● pthread library offers multiple Semaphore related library functions
● These functions help to synchronize between multiple threads
Function Meaning
int sem_init ( sem: Points to a semaphore object
sem_t *sem, pshared: Flag, make it zero for threads
int pshared, value: Initial value to set the semaphore
unsigned int value) RETURN: Success (0)/Failure (Non zero)
int sem_wait(sem_t *sem) Wait on the semaphore (Decrements count)
sem: Semaphore variable
RETURN: Success (0)/Failure (Non-zero)
●
Semaphores are similar to counters
●
Process semaphores synchronize between multiple processes, similar
to thread semaphores
●
The idea of creating, initializing and modifying semaphore values
remain same in between processes also
●
However there are different set of system calls to do the same
semaphore operations
Inter Process Communications
Synchronization – Semaphore Functions
Function Meaning
int semget( Create a process semaphore
key_t key, key: Seed input
int nsems, nsems: Number of semaphores in a set
int flag) flag: Permission (similar to file)
RETURN: Semaphore ID / Failure
int semop( Wait and Post operations
int semid, semid: Semaphore ID
struct sembuf *sops, sops: Operation to be performed
unsigned int nsops) nsops: Length of the array
RETURN: Operation Success / Failure
semctl(semid, 0, IPC_RMID) Semaphores need to be explicitly removed
semid: Semaphore ID
Remove and NULL
Inter Process Communications
Summary
● We have covered
Communication Synchronization
● Pipes ● Semaphores
● FIFO
● Shared memory
● Signals
● Sockets
Process Management - Concepts
Process Management - Concepts
Scheduling
When a scheduler schedules tasks and gives a predictable response, they are
called as “Real Time Systems”
Process Management - Concepts
CPU Scheduling
:
● Maximum CPU utilization load store
add store CPU Burst
obtained with multi
read from file
programming
wait for I/O I/O Burst
● CPU–I/O Burst Cycle – Process
execution consists of a cycle store increment
Index CPU Burst
of CPU execution and I/O write to file
wait
wait for I/O I/O Burst
load store
add store CPU Burst
read from file
:
Process Management - Concepts
States
ready running
scheduler dispatch
waiting
Process Management - Concepts
States
State Description
New The process is being created
Running Instructions are being executed
Waiting The process is waiting for some event to occur
Ready The process is waiting to be assigned to processor
Terminated The process has finished execution
Process Management - Concepts
Schedulers
●
Selects from among the processes in memory that are ready
to execute
●
Allocates the CPU to one of them
●
CPU scheduling decisions may take place when a process:
– Switches from running to waiting state
– Switches from running to ready state
– Switches from waiting to ready
– Terminates
●
Scheduling under 1 and 4 is non-preemptive
●
All other scheduling is preemptive
Process Management - Concepts
Scheduling - Types
Round Robin:
Co-operative
Serve (FCFS)
Round Robin:
Priority based
Static: Rate
Dynamic: Earliest Deadline First (EDF)
Monotonic (RM)
Pre-emptive Priority Based
Dynamic: Earliest
Deadline First (EDF)
Process Management - Concepts
Scheduling – Types – Co-operative vs Pre-emptive
● Suppose processes arrive in the order: P1, P2, P3 , The Gantt Chart
for the schedule is
P1 P2 P3
0 20 25 28
Process Management - Concepts
Scheduling – Types – RR: Time Sliced
● Suppose processes arrive in the order: P1, P2, P3 , The Gantt Chart
for the schedule is
P1 P2 P3 P1 P1 P1
0 4 9 12 17 22
Process Management - Concepts
Scheduling – Types – RR: Priority
P1 P2 P3 P1 P1 P1
0 4 11 16 21 24
Process Management - Concepts
Scheduling – Types – Pre-emptive
●
Pre-emption means while a lower priority process is executing on the
processor another process higher in priority than comes up in the ready
queue, it preempts the lower priority process.
●
Rate Monotonic (RM) scheduling:
– The highest Priority is assigned to the Task with the Shortest Period
– All Tasks in the task set are periodic
– The relative deadline of the task is equal to the period of the Task
– Smaller the period, higher the priority
●
Earliest Deadline First (EDF) scheduling:
– This kind of scheduler tries to give execution time to the task that is
most quickly approaching its deadline
– This is typically done by the scheduler changing priorities of tasks on-
the-fly as they approach their individual deadlines
Process Management - Concepts
Scheduling – Types – Rate Monotonic (RM)
● LynxOS
● OSE
● QNX
● VxWorks
● Windows CE
● RT Linux
Memory Management - Concepts
Memory Management - Concepts
Introduction
● Relocation
● Protection
● Sharing
● Logical Organization
● Physical Organization
Memory Management - Concepts
Requirements - Relocation
●
Programmer does not know where the program will be placed in
memory when it is executed
●
Before the program is loaded, address references are usually
relative addresses to the entry point of program
●
These are called logical addresses, part of logical address space
● All references must be translated to actual addresses
● It can be done at compile time, load time or execution
●
Mapping between logical to physical address mechanism is
implemented as “Virtual memory”
●
Paging is one of the memory management schemes where the
program retrieves data from the secondary storage for use in main
memory
Memory Management - Concepts
Virtual memory – Why?
●
If programs access physical memory we will face three
problems
– Don't have enough physical memory.
– Holes in address space (fragmentation).
– No security (All program can access same memory)
●
These problems can be solved using virtual memory.
– Each program will have their own virtual memory.
– They separately maps virtual memory space to physical
memory.
– We can even move to disk if we run out of memory
(Swapping)
Memory Management - Concepts
Virtual memory – Paging & page table
● Virtual memory 0
divided into 1
small chunks 00000 frame number valid-invalid bit 2 page 0
page 0
called pages. 3 page 1
2 v
page 1
●
Similarly 3 v 4 page 2
4 v
physical memory page 2
7 v
5
divided into page 3 8 v
6
frames. 9 v
page 4 0 i 7 page 3
●
Virtual memory 10,468
0 i
8 page 4
page 5 page table
and physical 12,287 9 page 5
memory mapped :
:
using page
page n
table.
Memory Management - Concepts
Virtual memory – TLB
logical
● For faster access page address
table will be stored in
CPU p d
CPU cache memory.
page frame
● But limited entries number number
only possible.
●
If page entry available
TLB hit
in TLB (Hit), control physical
goes to physical address
address directly
physical
(Within one cycle). f d
memory
●
If page entry not TLB
available in TLB (Miss), ____
it use page table from p
____
main memory and TLB miss
maps to physical f
address(Takes more ____
cycles compared to ____
TLB).
page table
Memory Management - Concepts
Page fault
● When a process
try access a
frame using a
page table and
that frame
moved to swap
memory,
generates an
interrupt called
page fault.
Memory Management - Concepts
Page fault – Handling
Memory Management
Unit (MMU)
Memory Management - Concepts
Requirements - Protection
● Processes should 0
not be able to 1
reference memory 00000 frame number valid-invalid bit 2 page 0
locations in another page 0
process without 2 v
3 page 1
page 1
permission 3 v 4 page 2
page 2 4 v
5
● Impossible to check 7 v
page 3 8 v
absolute addresses 9 v
6
when using 6 6
Ed3 7
shared 7 Ed3
Data2 page table p2
memory IPC, 8 Data2
P2
we need two Ed1 3 9
processes to Ed2 4
share the Ed3
6
10
2
same memory Data3 page table p3
segment
P3
Memory Management - Concepts
Requirements – Logical Organization
● WPN
➔ Consumer home networking
➔ Connected home ‘experience’
➔ Connect everything
➔ Low range, high power
➔ Office on the move
Networking – concept
Protocols