The OS kernel: Implementing processes and Threads
• Kernel Definitions and Objects
• Queue Structures
• Threads
• Implementing Processes and Threads
• Implementing Synchronization and Communication Mechanisms
• Interrupt Handling
Kernel Definitions and Objects
• Process and thread management
• Interrupt and trap handling
• Resource management
• Input and output
OS kernel: a basic set of objects, primitive operations, data structures, and processes from which the remainder of the system may be constructed
Kernel
ps
p1 pj
q1
pn
qm
… …
…
Interactions with kernel objects
A Process Creation Hierarchy
Queue structures
• Queues in OSs--queue for PCB--queues for hardware managers--queues for synchronization--queues for shared software components
• Implementations of Queues--single-level queues--priority queues
Implementations of queuesTypes of queues:
--FIFO
--priority based
Elements of queues
Operations related to queues
--insert( queue Q, element x)
--remove( queue Q, element x)
--empty( queue Q)
Header or descriptor of queues
Single-Level Queues• Circular array
• Linked list
Queue pointer
front
rear
. . .
. . . Occupied portion . . .
header
Queue pointer
front
rear
. . .
header
null. . .
Priority queues• Fixed-number priorities
Queue pointer
front
rear0
1
. . .
i
. . .
N-1
. . .
. . .
. . .
• Binary heap
25
125 73
800 650 100 2300
1125 7001392
Threads
• The normal implementation of processes results in much runtime overhead. To alleviate this problem, multiple “lightweight” scheduling units is implemented within a process. These units share the same resources as there host process
• Create a new thread;• Initiate or make a thread ready;• Destroy or terminate a thread;• Delay or terminate a thread• Delay or put a thread to sleep for a given
amount of time;• Synchronize threads through semaphores,
events or condition variables;• Perform lower-level operations, such as
blocking, suspending, or scheduling a thread
Operations on threads:
Implementing processes and threads
• Process and thread descriptors
• Implementing operations on processes
• Operations on threads
PCB
• Identification
• State vector
• Processors
• Status information
• Creation tree
• other information
Structure of process descriptor
PCB
ID
Cpu_state
Processor_ID
memory
Open_files
Other_resources
listtype
priority
parent child
. . .
processors
resources
State vector
statusCreation_tree
Other information
State vector
Status information
running
Ready_a Ready_s
Blocked_aBlocked_s
Implementing operations on processes
• CreateCreate(so,mo,pi,pid){
p=Get_New_PCB();pid=Get_New_PID();p->ID=pid;p->CPU_State=s0;p->Memory=m0;p->Priority=pi;p->State.Type=“ready_s”;p->Creation_tree.Parent=self;p->Creation_Tree.child=NULL;insert(self->Creation_tree.child,p);insert(RL,p);Scheduler();
}
• Suspendsuspend(pid){
p=Get_PCB(pid);s=p->Status.Type;if((s==“blocked_a”)||(s==“blocked_s”))
p->status.Type=“block_s”;else
p->status.Type=“ready_s”;if(s==“running”){
cpu=p->Processor_ID;p->CPU_State=Interrupt(cpu);Scheduler();
}}
• ActivateActivate(pid){
p=Get_PCB(pid)if(p->Status.Type==“ready_s”){
p->Status.Type=“ready_a”;Scheduler();
}else
p->status.Type=“blocked_a”;}
• DestroyDestroy(pid){
p=Get_PCB(pid);Kill_Tree(p);Scheduler();
}Kill_Tree(p){
for(each q in p->Creation_Tree.Child)Kill_Tree(q);
if(p->Status.Type==“running”){cpu=p->Processor_IDInterrupt(cpu);
}Remove(p->Status.List,p);Release_all(p->Memory);Release_all(p->Other_Resources);Close_all(p->Open_Files);Delete_PCB(p);
}
Implementing synchronization and communication mechanisms
• Semaphores and locks
• Monitor primitives
• Clock and time management
• Communication
General version of the Request/Release
Request(res){if(Free(res))
Allocate(res,self);else{
Block(self,res);Scheduler();
}}Release(res){
Deallocate(res,self);if(Process_Blocked_on(res,pr){
Allocate(res,pr);Unblock(pr,res);Scheduler();
}}
Semaphores and locks
• BT : carry appointed bit to CF;
• BTC : carry appointed bit to CF, and reverse it;
• BTR : carry appointed bit to CF, and change it to 0;
• BTS : carry appointed bit to CF, and change it to 1;
Bit Test Instruction :
Spin Locks on Binary Semaphores
• Pb(sb):
do
TS(R,sb);
while(!R);/*wait loop*/
• Vb(sb):sb=1;
General Semaphores with spin locks
• Pp(s){
s=s-1;if(s<0){
Pb(delay_s;}
}• V
v(s){
s=s+1;if(s<=0)
Vb(delay_s);else
}
Pb(mutex_s);
Vb(mutex_s);
Vb(mutex_s);
Pb(mutex_s);
Vb(mutex_s);
Avoiding the Busy-WaitP(s){
Inhibit_Interrupts;
Pb(mutex_s);
s=s-1;
if(s<0){
Block(self, Ls);
Vb(mutex_s);
Enable_Interrupts;
Scheduler();
}
else{
Vb(mutex_s);
Enable_Interrupts;
}
}
V(s){
Inhibit_Interrupts;
Pb(mutex_s);
s=s+1;
if(s<=0){
Unblock(q, Ls);
Vb(mutex_s);
Enable_Interrupts;
Scheduler();
}
else{
Vb(mutex_s);
Enable_Interrupts;
}
}
Primitive and atomic operation
• Priority
• Interrupt request
• Switching tasks on single CPU
• Switching tasks on multiple CPU
struct semaphore {atomic_t count;int sleepers;wait_queue_head_t wait;
#if WAITQUEUE_DEBUGlong __magic;
#endif};
static inline void down(struct semaphore * sem){#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);#endif
__asm__ __volatile__("# atomic down operation\n\
t"LOCK "decl %0\n\t" /* --se
m->count */"js 2f\n""1:\n"LOCK_SECTION_START
("")"2:\tcall __down_failed\n\t""jmp 1b\n"LOCK_SECTION_END:"=m" (sem->count):"c" (sem):"memory");
}
asm(".text\n"".align 4\n"".globl __down_failed\n""__down_failed:\n\t"#if defined(CONFIG_FRAME_POINTER)
"pushl %ebp\n\t""movl %esp,%ebp\n\t"
#endif"pushl %eax\n\t""pushl %edx\n\t""pushl %ecx\n\t""call __down\n\t""popl %ecx\n\t""popl %edx\n\t""popl %eax\n\t"
#if defined(CONFIG_FRAME_POINTER)"movl %ebp,%esp\n\t""popl %ebp\n\t"
#endif"ret"
);
void __down(struct semaphore * sem){
struct task_struct *tsk = current;DECLARE_WAITQUEUE(wait, tsk);tsk->state = TASK_UNINTERRUPTIBLE;add_wait_queue_exclusive(&sem->wait, &wait);
spin_lock_irq(&semaphore_lock);sem->sleepers++;for (;;) {
int sleepers = sem->sleepers;
/* * Add "everybody else" into it. They aren't * playing, because we own the spinlock. */if (!atomic_add_negative(sleepers - 1, &sem->count)) {
sem->sleepers = 0;break;
}sem->sleepers = 1; /* us - see -1 above */spin_unlock_irq(&semaphore_lock);
schedule();tsk->state = TASK_UNINTERRUPTIBLE;spin_lock_irq(&semaphore_lock);
}spin_unlock_irq(&semaphore_lock);remove_wait_queue(&sem->wait, &wait);tsk->state = TASK_RUNNING;wake_up(&sem->wait);
}
static inline void spin_lock(spinlock_t *lock){#if SPINLOCK_DEBUG
__label__ here;here:
if (lock->magic != SPINLOCK_MAGIC) {printk("eip: %p\n", &&here);
BUG();}
#endif__asm__ __volatile__(
spin_lock_string:"=m" (lock->lock) : : "memory");
}#define spin_lock_string \
"\n1:\t" \"lock ; decb %0\n\t" \"js 2f\n" \LOCK_SECTION_START("") \"2:\t" \"cmpb $0,%0\n\t" \"rep;nop\n\t" \"jle 2b\n\t" \"jmp 1b\n" \LOCK_SECTION_END
#define spin_lock_irq(lock) do { local_irq_disable(); spin_lock(lock); } while (0)
Monitor primitives• Body of each procedure:
p(mutex);procedure_body;if(urgentcnt)
V(urgent);else
V(mutex);• C.wait:
condcnt_c=condcnt_c+1;if(urgentcnt)
V(urgent);else
V(mutex);P(condsem_c)condcnt_c=condcnt-1;
• C.signal:if(condcnt_c){
urgentcnt=urgentcnt+1;V(condsem_c);P(urgent);urgentcnt=urgentcnt-1;
}
Clock and Time Management
• Wall clock timer
-- Update_clock
-- Get_Time
-- SetClock(tnew)
• Countdown Timers
-- Set_Timer(tdel)
-- Delay(tdel)Delay(tdel){
Set_timer(tdel);
P(delsem);
}
-- TimeOut()TimeOut( ){
V(delsem):
}
Implementing logical timers
• Logical timer
-- tn=Create_LTimer();
-- Destroy_LTimer(tn);
-- SetLTimer(tn,tdel);
• Using a Priority Queue with Absolute Wakeup Times
Hardware timers
Wall-clock countdown
103 12
Timer queue TQ
a
p1 115 p2 135 p3 140 p4 150
b
p1 115 p2 135 p3 138 p4 140TQ p5 150
Using a Priority Queue with Time Differences
Hardware timers
countdown
12
Timer queue TQ
a
p1 15 p2 20 p3 5 p4 10
b
p1 15 p2 20 p3 3 p4 2TQ p5 10
Communication primitives
• Generic form of message-passing primitives
-- send(p,m)
-- receive(q, m)
• Two issues must be resolved-- how does the sender know that sbuf has been copied and may be reused?
-- how does the system know that the contents of rbuf are no longer needed by the receiver and may be overwritten?
• Solutions-- blocking
-- nonblocking (system buffers)
Interrupt Handling
• Interrupt concept-- an event occurring at an unpredictable time that forces a transfer of control out of the normal processing sequence of a computer
-- the purpose of interrupt handling is to remove the notion of asynchronous events from higher levels of the kernel, the OS, and applications
• Common operations on interrupts-- enable
-- disable
-- inhibit
• More uniform abstract model of interrupt handling
Hardware device
interrupt
monitor
Fn()
IH()
P
Fn()
. . .
Init
c.wait. . .. . .
c.signal
OS
call
c
call