/*
* Branton Boehm (bxb57)
* EECS 338 - HW5
* Mar. 26, 2002
*
* Filename: assn5.h
* Solaris 7 / gcc version 2.95.3
* Special Instructions:
*   This file contains shared code for student.c and worker.c
*/

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/time.h>

#define NUM_SEMS     4	/* The number of semaphores in the set */
#define WORKER       0	/* Names for each semaphore */
#define STUDENT      1
#define NUM_STUDENTS 2
#define MEAL_SLOT    3

#define TRUE  1
#define FALSE 0

/* This definition is missing in the current Solaris environment */
union semun
{
	int val;
	struct semid_ds *buf;
	ushort *array;
};

/*
* This structure has two data members that are
* to be shared by the worker & student processes
*/
struct common
{
	int num_students;	/* The number of students in the cafeteria  */
	int meal_id;		/* The current meal in the slot (0 => none) */
};

/*
* This function implements the wait operation given on slide 7.32
* from the course webpage.
*
* Input:
*  int semid   -- the semaphore identifier obtained from semget
*  int sem_num -- index into array structure of the semaphore
*
* Output:
*  The semaphore is decremented using the semop system call and
*  its return value is returned to the calling routine
*/
int wait( int semid, int sem_num )
{
	struct sembuf waitsembuf;

	waitsembuf.sem_num = sem_num;
	waitsembuf.sem_op  = -1;
	waitsembuf.sem_flg = SEM_UNDO;

	return semop( semid, &waitsembuf, 1 );
}

/*
* This function implements the signal operation given on slide 7.32
* from the course webpage.
*
* Input:
*  int semid   -- the semaphore identifier obtained from semget
*  int sem_num -- index into array structure of the semaphore
*
* Output:
*  The semaphore is incremented using the semop system call and
*  its return value is returned to the calling routine.
*/
int signal( int semid, int sem_num )
{
	struct sembuf signalsembuf;

	signalsembuf.sem_num = sem_num;
	signalsembuf.sem_op  = 1;
	signalsembuf.sem_flg = SEM_UNDO;

	return semop( semid, &signalsembuf, 1 );
}

/*
* This function checks to see if a return value from a function is
* less than zero. If it is, an error message is printed and the
* process exits with code 1.
*
* Input:
*  int retval   -- the value to be checked
*  char *errmsg -- the error message to be displayed if necessary
*
* Output:
*  Process exits if there was an error
*/
void check_error( int retval, char *errmsg )
{
	if( retval < 0 )
	{
		printf( "(%d) %s", (int)getpid(), errmsg );
		perror( (char *)NULL );
		exit( 1 );
	}
}

/*
* This function maps a meal number to a meal type.
*
* Input:
*  int meal_id -- the meal number
*
* Output:
*  A char* with the name of the meal
*/
char* meal_type( int meal_id )
{
	switch( meal_id )
	{
	case 1:  return "Meatloaf Surprise";
	case 2:  return "Shepard's Pie";
	case 3:  return "Pizza";
	case 4:  return "Tacos";
	case 5:  return "Chicken Nuggets";
	default: return "MEAL ERROR";
	}
}