1 / 44

The OS kernel: Implementing processes and Threads

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.

feleti
Download Presentation

The OS kernel: Implementing processes and Threads

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 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

  2. Kernel Definitions and Objects OS kernel: a basic set of objects, primitive operations, data structures, and processes from which the remainder of the system may be constructed • Process and thread management • Interrupt and trap handling • Resource management • Input and output

  3. A Process Creation Hierarchy ps p1 pj q1 pn qm … … Kernel … Interactions with kernel objects

  4. 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

  5. Implementations of queues Types 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

  6. Queue pointer front front rear rear . . . . . . . . . Occupied portion . . . header Queue pointer . . . null header Single-Level Queues • Circular array • Linked list

  7. Priority queues Queue pointer • Fixed-number priorities . . . front 0 rear 1 . . . i . . . . . . N-1 . . .

  8. 25 125 73 800 650 100 2300 1392 700 • Binary heap 1125

  9. 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

  10. Operations on threads: • 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

  11. Implementing processes and threads • Process and thread descriptors • Implementing operations on processes • Operations on threads

  12. PCB • Identification • State vector • Processors • Status information • Creation tree • other information

  13. PCB ID Cpu_state processors Processor_ID State vector memory Open_files resources Other_resources status type list Creation_tree parent child priority . . . Other information Structure of process descriptor

  14. State vector

  15. running Ready_a Ready_s Blocked_a Blocked_s Status information

  16. Implementing operations on processes • Create Create(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(); }

  17. Suspend suspend(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(); } }

  18. Activate Activate(pid){ p=Get_PCB(pid) if(p->Status.Type==“ready_s”){ p->Status.Type=“ready_a”; Scheduler(); } else p->status.Type=“blocked_a”; }

  19. Destroy Destroy(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_ID Interrupt(cpu); } Remove(p->Status.List,p); Release_all(p->Memory); Release_all(p->Other_Resources); Close_all(p->Open_Files); Delete_PCB(p); }

  20. Implementing synchronization and communication mechanisms • Semaphores and locks • Monitor primitives • Clock and time management • Communication

  21. 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(); } }

  22. Semaphores and locks Bit Test Instruction : • 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;

  23. Spin Locks on Binary Semaphores • Pb(sb): do TS(R,sb); while(!R);/*wait loop*/ • Vb(sb): sb=1;

  24. General Semaphores with spin locks • P p(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);

  25. Avoiding the Busy-Wait P(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; } }

  26. Primitive and atomic operation • Priority • Interrupt request • Switching tasks on single CPU • Switching tasks on multiple CPU

  27. struct semaphore { atomic_t count; int sleepers; wait_queue_head_t wait; #if WAITQUEUE_DEBUG long __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" /* --sem->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"); }

  28. 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" );

  29. 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); }

  30. 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

  31. #define spin_lock_irq(lock) do { local_irq_disable(); spin_lock(lock); } while (0)

  32. 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; }

  33. Clock and Time Management • Countdown Timers -- Set_Timer(tdel) -- Delay(tdel) Delay(tdel){ Set_timer(tdel); P(delsem); } -- TimeOut() TimeOut( ){ V(delsem): } • Wall clock timer -- Update_clock -- Get_Time -- SetClock(tnew)

  34. Implementing logical timers • Logical timer -- tn=Create_LTimer(); -- Destroy_LTimer(tn); -- SetLTimer(tn,tdel);

  35. p4 p3 p2 p1 p1 p2 p4 p3 p5 135 115 150 115 150 138 140 140 135 • Using a Priority Queue with Absolute Wakeup Times Wall-clock countdown Hardware timers 103 12 Timer queue TQ a TQ b

  36. p4 p4 p3 p2 p1 p2 p1 p3 p5 5 15 20 10 10 15 20 3 2 Using a Priority Queue with Time Differences countdown Hardware timers 12 Timer queue TQ a TQ b

  37. 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)

  38. 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

  39. monitor • More uniform abstract model of interrupt handling Fn() P call Hardware device . . . Init c.wait c Fn() . . . IH() call . . . OS c.signal interrupt

More Related