Operating systems

Semaphores

Prashanth L.A.

2023-10-30

Lecture 35

In the last few lectures, we looked at

Producer-consumer problem using semaphores

Solution 2

Working Solution

Working solution

void *producer(void *arg)
{
    int i;
    for (i = 0; i < loops; i++) {
        Sem_wait(&empty);
        Sem_wait(&mutex);
        do_fill(i);
        Sem_post(&mutex);
        Sem_post(&full);
    }
}
                                                                               
void *consumer(void *arg)
{
    int tmp = 0;
    while (tmp != -1) {
        Sem_wait(&full);
        Sem_wait(&mutex);
        tmp = do_get();
        Sem_post(&mutex);
        Sem_post(&empty);
        printf("%d\n", tmp);
    }
}

The Dining Philosophers

The Dining Philosophers (Cont.)

Referring to the left and the right

int left(int p) {  return  p; }

int right(int p) { return (p + 1) % 5;}

What philosophers do

while (1) {
          think();
          get_forks(p);
          eat();
          put_forks(p);
}

Solution 1

void getforks() {
  sem_wait(forks[left(p)]);
  sem_wait(forks[right(p)]);
}

void putforks() {
  sem_post(forks[left(p)]);
  sem_post(forks[right(p)]);
}

Solution 2

void getforks() {
  if (p == 4) {
    sem_wait(forks[right(p)]);
    sem_wait(forks[left(p)]);
  } 
  else {
    sem_wait(forks[left(p)]);
    sem_wait(forks[right(p)]);
  }
}

Implementing semaphores using CV and locks

typedef struct __Zem_t {
    int             value;
    pthread_cond_t  cond; // cond_signal(c), cond_wait(c, m)
    pthread_mutex_t lock; // mutex_lock(m),  mutex_unlock(m)
} Zem_t;

// can assume only called by one thread
void
Zem_init(Zem_t *z, int value) {
    z->value = value;
    // init lock and cond
}

void Zem_wait(Zem_t *z) {
    // use semaphore definition as your guide
}

void Zem_post(Zem_t *z) {
    // use semaphore definition as your guide
}

Solution

void Zem_wait(Zem_t *z) {
    Mutex_lock(&z->lock);
    while (z->value <= 0)
        Cond_wait(&z->cond, &z->lock);
    z->value--;
    Mutex_unlock(&z->lock);
}

void Zem_post(Zem_t *z) {
    Mutex_lock(&z->lock);
    z->value++;
    Cond_signal(&z->cond);
    Mutex_unlock(&z->lock);
}