Operating System-Class 7-Feb. 16th

The system call is implemented by a single instruction in user level code.

single instruction: ta on Sparc, syscall on x86 current OS’s, int on x86 old OS’s.

 

All execution in kernel code looks like a super single instruction to user.

 

 

 

 

 

 

 

 


Semaphores: available in java JDK, and as syscalls in UNIX/Linux, Windows, and Xinu.

·      simplest API: Xinu

·      Ex. semaphores can be used for mutex = mutual exclusion (sometimes called simple locking)

o   some resource(printer) can only be used properly by one person/thread at a time

§  so needs mutex

o   we write codes that set up a mutex

§  every process much use this code before & after using printer

-          get printer – call to get mutex, wait if necessary

-          release printer – call to release mutex

·      Ex. producer-consumer with bounded buffer

 

 

 

 

 

 

 

 

 


Xinu Semaphore API

·         each semaphore has a count:         initial count when created

                                                                        current count during use(held in a kernel var)

·         int semid = screate(int inicount); ßXinu syscall

·         int wait(semid): decrement sem’s count, blocks the callers(caller waits) if new count < 0

-- a process “blocks”(only happens via OS action) meaning it waits without using CPU(OS runs other process)

·         int signal(semid): increment sem’s count, allow one blocked process to run (if any waiters)

·         int count = scount(semid): get semaphore’s current count

·         int status = delete(semid)

 

Silly Example

int sem = screate(2); /* count =2 */

wait (sem);          /* returns immediately, then count = 1 */

wait(sem);           /* returns immediately, then count = 0 */

wait(sem);           /* blocks, hangs forever */

 

 

Need multiple processes for decent example.

 

Mutex is easy

 


int mutex = screate(1);  /* so one process allowed to run/use resource at a time */

 

 

 

 

 

 

 

Trace:                 orig count = 1;

                A gets mutex, ct = 0, A continues;

                A starts using printer;

                B calls wait for printer, ct = -1, B waits;

                A finishes, calls signal, B is unblocked;

                B does printing;

                B calls signal.

 

Read Love book about POSIX, pg. 64

POSIX: portable API across UNIX/Linux 2.6: look for “POSIX compliance”

Linux was slow to adopt POSIX, so older Linux (pre 2.6) harder to use for portable apps

semex.c / semworker.c: Solaris – users.cs.umb.edu

                                                    Linux – sf06.cs.umb.edu

-- semex.c: uses POSIX semaphores shared memory

 

API: a little different than Xinu, but same functionality:

·         int sem_init(sem_t *sem, int pshared, int inicount);

ü  sem_t *sem: type defined in a header

ü  pshared: boolean(1: process-shared)

·         int sem_wait(sem_t *sem);            =             Xinu_wait

ü  decrement a positive count and return; waits if count is 0, never goes negative

·         int sem_post(sem_t *sem);           =             Xinu_signal

ü  increment count if no waiters, or else unblock one waiter

·         int sem_destroy(sem_t *sem);