/*
 * CS560: 
 * dphil.h -- Dining philosophers header file
 * James S. Plank
 * January, 2009
 */

/* There is one simluation struct for the entire simulation */
typedef struct {
  int nphil;            /* Simulation parameters */
  double thinkavg;
  double eatavg;
  double sticktime;
  double duration;
  double interval;
  int verbose;
  int *chopsticks_in_use;

  void *v;             /* Information that you define */

  struct philosopher **p;  /* Philosophers */
} Simulation;

#define STARTING 0
#define THINKING 1
#define HUNGRY 2
#define GOTSTICKS 3
#define EATING 4
#define SATED 5

/* There is one Philosopher struct for each philosopher */

typedef struct philosopher {
  int id;
  int state;
  Simulation *s;
  double thinktime;
  double eattime;
  double blocked_time;
  double last_event_time;
  void (*func)();             /* This is a temporary variable you can use */
} Philosopher;

/* -------------------------------------------------------------- */
/* These are implemented for you in dphil_skeleton.c */

extern void philosopher(Philosopher *p);  
extern void pick_up_stick(Philosopher *p, int stick, void (*func)());
extern void put_down_stick(Philosopher *p, int stick, void (*func)());

/* -------------------------------------------------------------- */
/* Initialize_Simluation is called before any threads are forked. */

extern void initialize_simulation(Simulation *s);   

/* -------------------------------------------------------------- */
/* I_am_hungry() is called by a philosopher to pick up the sticks.  
 * The philosopher's state will be HUNGRY.  When i_am_hungry() is done,
 * the continuation philosopher(p) should be called, 
 * the philosopher's state should be GOTSTICKS, and the philosopher  
 * should have the sticks (by calling pick_up_stick() on his/her two
 * chopsticks). */

extern void i_am_hungry(Philosopher *p);  

/* -------------------------------------------------------------- */
/* I_am_sated() is called by a philosopher to put down up the sticks.  
 * The philosopher's state will be SATED.  When i_am_sated() is done,
 * the continuation philospher(p) should be called, 
 * the philosopher's state should be STARTING, and the philosopher
 * should have released the sticks (by calling put_down_sticks() 
 * on his/her two * chopsticks).   */

extern void i_am_sated(Philosopher *p); 

