/*
 * CS560: Operating Systems
 * Jim Plank / Rich Wolski
 * dphil_4.c -- Dining philosophers solution #4 -- an asymmetrical solution.
   Modified for Kthreads
 */


#include <stdio.h>
#include "kt.h"
#include "dphil.h"



typedef struct sticks {
  kt_sem lock[MAXTHREADS];
  int phil_count;
} Sticks;


void pickup(Phil_struct *ps)
{
  Sticks *pp;
  int phil_count;

  pp = (Sticks *) ps->v;
  phil_count = pp->phil_count;
  
  if (ps->id % 2 == 1) {
    P_kt_sem(pp->lock[ps->id]);       /* lock up left stick */
    P_kt_sem(pp->lock[(ps->id+1)%phil_count]); /* lock right stick */ 
  } else {
    P_kt_sem(pp->lock[(ps->id+1)%phil_count]); /* lock right stick */ 
    P_kt_sem(pp->lock[ps->id]);       /* lock up left stick */
  }
}

void putdown(Phil_struct *ps)
{
  Sticks *pp;
  int i;
  int phil_count;

  pp = (Sticks *) ps->v;
  phil_count = pp->phil_count;

  if (ps->id % 2 == 1) {
    V_kt_sem(pp->lock[(ps->id+1)%phil_count]); /* unlock right stick */ 
    V_kt_sem(pp->lock[ps->id]);  /* unlock left stick */
  } else {
    V_kt_sem(pp->lock[ps->id]);  /* unlock left stick */
    V_kt_sem(pp->lock[(ps->id+1)%phil_count]); /* unlock right stick */ 
  }
}

void *initialize_v(int phil_count)
{
  Sticks *pp;
  int i;

  pp = (Sticks *) malloc(sizeof(Sticks));
  pp->phil_count = phil_count;
  for (i = 0; i < phil_count; i++) {
    pp->lock[i] = make_kt_sem(1);
  }

  return (void *) pp;
}

