Task Control Signals and Alarms Chapter 7 and

  • Slides: 35
Download presentation
Task Control: Signals and Alarms Chapter 7 and 8 B. Ramamurthy Page 1

Task Control: Signals and Alarms Chapter 7 and 8 B. Ramamurthy Page 1

Multi-tasking • How to create multiple tasks? Ex: Xinu create() • How to control

Multi-tasking • How to create multiple tasks? Ex: Xinu create() • How to control them? – ready() – resched() • How to synchronize them? How to communicate among them? • XINU: semaphores, send and receive messages • How to (software) interrupt a process? signals Page 2

Examples • Consider g++ my. Prog. c – You want to kill this process

Examples • Consider g++ my. Prog. c – You want to kill this process after you started the compilation. . hit cntrl-C • Consider execution of a program called “badprog” >badprog It core dumps. . What happened? The error in the program results in a signal to kernel to stop and dump the offending code • Consider “kill –p <pid>” – Kill issues a termination signal to the process identified by the pid Page 3

Linux Processes • Similar to XINU Procs. • Lets understand how to create a

Linux Processes • Similar to XINU Procs. • Lets understand how to create a linux process and control it. • Chapter 7 and 8 of text book. • Chapter 7 : multi-tasking • Chapter 8: Task communication and synchronization Page 4

Process creation • Four common events that lead to a process creation are: 1)

Process creation • Four common events that lead to a process creation are: 1) When a new batch-job is presented for execution. 2) When an interactive user logs in / system initialization. 3) When OS needs to perform an operation (usually IO) on behalf of a user process, concurrently with that process. 4) To exploit parallelism an user process can spawn a number of processes. Page 5

Termination of a process • Normal completion, time limit exceeded, memory • • •

Termination of a process • Normal completion, time limit exceeded, memory • • • unavailable Bounds violation, protection error, arithmetic error, invalid instruction IO failure, Operator intervention, parent termination, parent request, killed by another process A number of other conditions are possible. Segmentation fault : usually happens when you try write/read into/from a non-existent array/structure/object component. Or access a pointer to a dynamic data before creating it. (new etc. ) Bus error: Related to function call and return. You have messed up the stack where the return address or parameters are stored. Page 6

Process control • • Process creation in unix is by means of the system

Process control • • Process creation in unix is by means of the system call fork(). OS in response to a fork() call: – Allocate slot in the process table for new process. – Assigns unique pid to the new process. . – Makes a copy of the process image, except for the shared memory. – both child and parent are executing the same code following fork() – Move child process to Ready queue. – it returns pid of the child to the parent, and a zero value to the child. Page 7

Process control (contd. ) • All the above are done in the kernel mode

Process control (contd. ) • All the above are done in the kernel mode in the process context. When the kernel completes these it does one of the following as a part of the dispatcher: – Stay in the parent process. Control returns to the user mode at the point of the fork call of the parent. – Transfer control to the child process. The child process begins executing at the same point in the code as the parent, at the return from the fork call. – Transfer control another process leaving both parent and child in the Ready state. Page 8

Process Creation (contd. ) Parent process create children processes, which, in turn create other

Process Creation (contd. ) Parent process create children processes, which, in turn create other processes, forming a tree of processes • Generally, process identified and managed via a process identifier (pid) • Resource sharing – Parent and children share all resources – Children share subset of parent’s resources – Parent and child share no resources • Execution – Parent and children execute concurrently – Parent waits until children terminate • Page 9

Process Termination Process executes last statement and asks the operating system to delete it

Process Termination Process executes last statement and asks the operating system to delete it (exit) – Output data from child to parent (via wait) – Process’ resources are deallocated by operating system • Parent may terminate execution of children processes (abort) – Child has exceeded allocated resources – Task assigned to child is no longer required – If parent is exiting • Some operating system do not allow child to continue if its parent terminates – All children terminated - cascading termination • Page 10

Task State Diagram Task admitted New Resources allocated Ready rr t en v E

Task State Diagram Task admitted New Resources allocated Ready rr t en v E cu c o Blocked Page 11 Dis pat c ed hed ; cpu allo cat ed Waiting for event k Tas Run 10/18/2021 exit

Resources & Critical Resources • Shared resources: need mutual • • • exclusion Tasks

Resources & Critical Resources • Shared resources: need mutual • • • exclusion Tasks cooperating to complete a job Tasks contending to access a resource Tasks synchronizing Critical resources and critical region A important synchronization and mutual exclusion primitive / resource is “semaphore” Page 12 10/18/2021

Critical sections and Semaphores • When multiples tasks are executing there may be sections

Critical sections and Semaphores • When multiples tasks are executing there may be sections where only one task could execute at a given time: critical region or critical section • There may be resources which can be accessed only be one of the processes: critical resource • Semaphores can be used to ensure mutual exclusion to critical sections and critical resources Page 13 10/18/2021

Semaphores See semaphore. h of xinu Page 14 10/18/2021

Semaphores See semaphore. h of xinu Page 14 10/18/2021

Semaphores in exinu • • #include <kernel. h> #include <queue. h> • • •

Semaphores in exinu • • #include <kernel. h> #include <queue. h> • • • /* Semaphore state definitions */ #define SFREE 0 x 01 /**< this semaphore is free #define SUSED 0 x 02 /**< this semaphore is used • • /* type definition of "semaphore" */ typedef ulong semaphore; • • /* Semaphore table entry */ struct sentry { char state; /**< the state SFREE or SUSED short count; /**< count for this semaphore queue; /**< requires q. h. }; 15 /**< queue. h must define # of sem queues */ */ */

Semaphores in exinu (contd. ) • extern struct sentry semtab[]; • • • /**

Semaphores in exinu (contd. ) • extern struct sentry semtab[]; • • • /** * isbadsem - check validity of reqested semaphore id and state * @param s id number to test; NSEM is declared to be 100 in kernel. h A system typically has a predetermined limited number of semaphores */ #define isbadsem(s) (((ushort)(s) >= NSEM) || (SFREE == semtab[s]. state)) • • /* Semaphore function declarations */ syscall wait(semaphore); syscall signaln(semaphore, short); semaphore newsem(short); syscall freesem(semaphore); syscall scount(semaphore); 16

Definition of Semaphores functions • • • • • • static semaphore allocsem(void); /**

Definition of Semaphores functions • • • • • • static semaphore allocsem(void); /** * newsem - allocate and initialize a new semaphore. * @param count - number of resources available without waiting. * example: count = 1 for mutual exclusion lock * @return new semaphore id on success, SYSERR on failure */ semaphore newsem(short count) { irqmask ps; semaphore sem; ps = disable(); /* disable interrupts */ sem = allocsem(); /* request new semaphore */ if ( sem != SYSERR && count >= 0 ) /* safety check */ { semtab[sem]. count = count; /* initialize count */ restore(ps); /* restore interrupts */ return sem; /* return semaphore id */ } restore(ps); 17 }

 • • • • • Semaphore: newsem contd. /** * allocsem - allocate

• • • • • Semaphore: newsem contd. /** * allocsem - allocate an unused semaphore and return its index. * Scan the global semaphore table for a free entry, mark the entry * used, and return the new semaphore * @return available semaphore id on success, SYSERR on failure */ static semaphore allocsem(void) { int i = 0; while(i < NSEM) /* loop through semaphore table */ { /* to find SFREE semaphore */ if( semtab[i]. state == SFREE ) { semtab[i]. state = SUSED; return i; } i++; } 18 return SYSERR; }

 • • • • • • Semaphore: wait(…) /** * wait - make

• • • • • • Semaphore: wait(…) /** * wait - make current process wait on a semaphore * @param semaphore for which to wait * @return OK on success, SYSERR on failure */ syscall wait(semaphore sem) { irqmask ps; struct sentry *psem; pcb *ppcb; ps = disable(); /* disable interrupts */ if ( isbadsem(sem) ) /* safety check */ { restore(ps); return SYSERR; } ppcb = &proctab[currpid]; /* retrieve pcb from process table */ psem = &semtab[sem]; /* retrieve semaphore entry */ if( --(psem->count) < 0 ) /* if requested resource is unavailable */ { ppcb->state = PRWAIT; /* set process state to PRWAIT*/ 19

Semaphore: wait() • • ppcb->sem = sem; /* record semaphore id in pcb */

Semaphore: wait() • • ppcb->sem = sem; /* record semaphore id in pcb */ enqueue(currpid, psem->queue); resched(); /* place in wait queue and reschedule */ } restore(ps); /* restore interrupts */ return OK; } 20

Semaphore: signal() • • • • • /*signal - signal a semaphore, releasing one

Semaphore: signal() • • • • • /*signal - signal a semaphore, releasing one waiting process, and block * @param sem id of semaphore to signal * @return OK on success, SYSERR on failure */ syscall signal(semaphore sem) { irqmask ps; register struct sentry *psem; } 21 ps = disable(); /* disable interrupts */ if ( isbadsem(sem) ) /* safety check */ { restore(ps); return SYSERR; } psem = &semtab[sem]; /* retrieve semaphore entry */ if ( (psem->count++) < 0 ) /* release one process from wait queue */ { ready(dequeue(psem->queue), RESCHED_YES); } restore(ps); /* restore interrupts */ return OK;

Semaphore: usage • Problem 1: – Create 3 tasks that each sleep for a

Semaphore: usage • Problem 1: – Create 3 tasks that each sleep for a random time and update a counter. – Counter is the critical resources shared among the processes. – Only one task can update the counter at a time so that counter value is correct. • Problem 2: – Create 3 tasks; task 1 updates the counter by 1 and then signal task 2 that updates the counter by 2 and then signals task 3 to update the counter by 3. 22

Problem 1 #include <. . > //declare semaphore mutex 1 = newsem(1); int counter

Problem 1 #include <. . > //declare semaphore mutex 1 = newsem(1); int counter = 0; //declare functions: proc 1, proc 3 ready(create((void *)proc 1, INITSTK, INITPRIO, “PROC 1", , 2, 0, NULL), RESCHED_NO); ready(create((void *)proc 2, INITSTK, INITPRIO, “PROC 2", , 2, 0, NULL), RESCHED_NO); ready(create((void *)proc 3, INITSTK, INITPRIO, “PROC 3", , 2, 0, NULL), RESCHED_NO); 23

Problem 1: multi-tasks void proc 1() { while (1) { sleep (rand()%10); wait(mutex 1);

Problem 1: multi-tasks void proc 1() { while (1) { sleep (rand()%10); wait(mutex 1); counter++; signal(mutex 1); }} void proc 2() { while (1) { sleep (rand()%10); wait(mutex 1); counter++; signal(mutex 1); }} //similarly proc 3 24

Problem 1 Task 1 Counter 1 Task 3 25 Task 2

Problem 1 Task 1 Counter 1 Task 3 25 Task 2

Problem 2 semaphore synch 12 = newsem(0); semaphore synch 23 = newsem(0); semaphore synch

Problem 2 semaphore synch 12 = newsem(0); semaphore synch 23 = newsem(0); semaphore synch 31 = newsem(0); ready(create((void *)proc 1, INITSTK, INITPRIO, “PROC 1", , 2, 0, NULL), RESCHED_NO); ready(create((void *)proc 2, INITSTK, INITPRIO, “PROC 2", , 2, 0, NULL), RESCHED_NO); ready(create((void *)proc 3, INITSTK, INITPRIO, “PROC 3", , 2, 0, NULL), RESCHED_NO); signal(synch 31); 26

Task flow void proc 1() void proc 2() void proc 3() • { •

Task flow void proc 1() void proc 2() void proc 3() • { • while (1) { • sleep (rand()%10); • wait(synch 31); • counter++; • signal(synch 12); • } } • { • while (1) { • sleep (rand()%10); • wait(synch 12); • counter++; • signal(synch 23); • } } • { • while (1) { • sleep(rand()%10); • wait(synch 23); • counter++; • signal(synch 31); } } 27

Signals • Signals provide a simple method for transmitting • • software interrupts to

Signals • Signals provide a simple method for transmitting • • software interrupts to UNIX process Signals cannot carry information directly, which limits their usefulness as an general inter-process communication mechanism However each type of signal is given a mnemonic name; Ex: SIGINT See signal. h for others SIGHUP, SIGINT, SIGILL, SIGTRAP, SIGFPE, SIGKILL SIGALRM (sent by kernel to a process after an alarm timer has expired) SIGTERM signal (signal id, function) simply arms the signal Page 28

Intercept Signals Task 1 Task 2 Two essential parameters are destination process identifier and

Intercept Signals Task 1 Task 2 Two essential parameters are destination process identifier and the signal code number: kill (pid, signal) Signals are a useful way of handling intermittent data arrivals or rare error conditions. Page 29

Handling Signals • Look at the examples: • Catching SIGALRM • Ignoring SIGALRM •

Handling Signals • Look at the examples: • Catching SIGALRM • Ignoring SIGALRM • sigtest. c • sig. Handler. c • pingpong. c • See /usr/include/sys/iso/signal_iso. h for signal numbers Page 30

Signals and Alarms #include <signal. h> unsigned int alarm( unsigned int seconds ); alarm(a);

Signals and Alarms #include <signal. h> unsigned int alarm( unsigned int seconds ); alarm(a); will start a timer for a secsonds and will interrupt the calling process after a secs. time(&t); will get you current time in the variable t declared as time_t t ctime(&t); will convert time to ascii format Alarm has a sigaction function that is set for configuring the alarm handler etc. sigaction(SIGALRM, &act, &oldact) ; the third paramter is for old action configuration Page 31

Sample programs • Starting new tasks in linux: page 165 • Programs in pages:

Sample programs • Starting new tasks in linux: page 165 • Programs in pages: 174 -180 on signals and alarms • See demos directory for first • See page 175 for the second program • See page 178 … for the third program Page 32

Pingpong Parent PSIG 43 Child CSIG 42 Page 33

Pingpong Parent PSIG 43 Child CSIG 42 Page 33

Observe in pingpong. c • pause(): indefinite • sleep(): sleep is random/finite time •

Observe in pingpong. c • pause(): indefinite • sleep(): sleep is random/finite time • While loop • Signal handlers • Re-arming of the signals

Volatile (from code reading: last lecture) • A variable should be declared volatile whenever

Volatile (from code reading: last lecture) • A variable should be declared volatile whenever its value could change unexpectedly. In practice, only three types of variables could change: – Memory-mapped peripheral registers – Global variables modified by an interrupt service routine – Global variables within a multi-threaded application Page 35