/*******************************************************************/
/* Author: Andreas Ermedahl, DoCS                                  */
/* Date: 961203                                                    */
/* Purpose: An example program on how to create shared memory      */
/* and semaphores, for the OS laboration 2: process_synch          */
/* Compile with:                                                   */
/* gcc -Wall -D__USE_FIXED_PROTOTYPES__ -o kossa kossa.c -L. -lipc */
/*******************************************************************/

/* Include some files  */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include "ipc.h"
#define MAX 10

/* Pointers to shared memory and semaphores */ 
int *food_mem = NULL;
semid_t *chops_sem = NULL;

/* ALTERNATIVE: use an over allocation like:  */
/* int food_mem[MAX]; int chops_sem[MAX]; */

/* Shall create an number of semaphores  */
int main(int argc, char **argv)
{
  int i;                  /* Loop variable */
  int antal_sem;          /* The number of semaphores */
  int size_mem;           /* The size of shared memories,  */
  int created_sem = 0;    /* The number of successfully created semaphores */
  int removed_sem = 0;    /* The number of successfully removed semaphores */

  /* Check argument */
  if(argc!=3)
    {
      printf("Usage: kossa m n, \nwhere m is the number of semaphores
and n is the number of shared memories\n\n");
      exit(0);
    }
  
  /* Convert string to integer */
  antal_sem = atoi(argv[1]);
  size_mem = atoi(argv[2]);

  /* Create shared memory, an integer size */
  if((food_mem = (int *) shmalloc(size_mem * sizeof(*food_mem))) == NULL)
    perror("shmalloc failed");
  else
    printf("Successfully created shared memory\n");
  
  /* We can access the allocated shared memory with 
     food_mem[0], .., food_mem[antal_mem - 1] */
  
  /* Create a number of semid_t, that the chops_sem will point at */
  if((chops_sem = (semid_t *) malloc(antal_sem * sizeof(*chops_sem))) == NULL)
    {
      perror("malloc failed");
      exit(0);
    }   
  
  /* We can access the allocated memory with 
     chops_sem[0], .., chops_sem[antal_sem - 1] */
  
  /* Save -1 in all integers, to be used in the semcreate test */
  for(i = 0; i < antal_sem; i++)
    chops_sem[i] = -1;
  
  /* Initialize a number of semaphores, each with an 
     initial count of 1 */
  for(i = 0; i < antal_sem; i++)
    {
      if((chops_sem[i] = semcreate(1)) == -1)
	perror("semcreate failed");
      else
	created_sem++;
    }
  printf("Successfully created semaphores: %i of %i tries\n", created_sem, antal_sem);
  
  /* Wait for the user to type something. You can investigate the 
     allocated ipc objects using ipcs in another xterm. */
  getchar();
  
  /* Free shared memory */
  if (shfree(food_mem) == -1)
    perror("shfree failed");
  else
    printf("Successfully removed shared memory\n");

  /* Free semaphores */
  for(i = 0; i < created_sem; i++)
    {
      if(semdestroy(chops_sem[i]) == -1)
	perror("semdestroy failed");
      else
	removed_sem++;
    } 
  printf("Successfully removed semaphores: %i of %i tries\n", removed_sem, created_sem);

  return 1;
}





