Universidad de Costa Rica

Escuela de Ciencias de la Computación e Informática

CI-0122 Sistemas Operativos

Temas

CI0122 / Temas revisados / Semana-06 / ForkAndSems / H2O


/**
 *
 *   Resuelve el problema del agua utilizando procesos y un monitor "Natural"
 * 
 *   Author: Sistemas Operativos (Francisco Arroyo)
 * 
 *   Version: 2023/Abr/23
 *
 *  Problem description:
 *
 *    You have just been hired by Mother Nature to help her out with the chemical reaction to form water,
 *    which she doesn't seem to be able to get right due to synchronization problems. The trick is to get two
 *    H atoms and one O atom react together at the same time. For our problem, each atom is represented by
 *    a thread. Each H atom thread invokes a procedure called H() when it is ready to react, and each O
 *    atom thread invokes a procedure called O() when it is ready
 */

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>


#include "Natural.h"


Natural natural;
Natural * naturalShared;


/**
 *  Código para el oxígeno
**/
int Oxigeno( int cual ) {

   printf( "Se produjo un atomo de O\n" );
   naturalShared->registraYEspera( AtomoOxigeno, cual );

   exit( 0 );

}


/**
 *  Código para el hidrógeno
**/
int Hidrogeno( int cual ) {

   printf( "Se produjo un atomo de H\n" );
   naturalShared->registraYEspera( AtomoHidrogeno, cual );

   exit( 0 );

}


/*
 *
 */
int main( int argc, char ** argv ) {
   long workers;
   int worker, pid, memId;

   workers = 100;
   if ( argc > 1 ) {
      workers = atol( argv[ 1 ] );
   }

// Create shared memory area and copy object image to it
   memId = shmget( IPC_PRIVATE, sizeof( struct Natural ), IPC_CREAT | 0600 );
   if ( -1 == memId ) {
      perror( "Fail to create shared memory segment" );
      exit( 1 );
   }

   naturalShared = (Natural *) shmat( memId, NULL, 0 );
   memcpy( (void *) naturalShared, (const void *) & natural, sizeof( Natural ) );	// Copy object to shared segment

// Create atoms
   for ( worker = 0; worker < workers; worker++ ) {
      pid = fork();
      if ( ! pid ) {
         srand( getpid() );
         if ( 0 == random() % 2 ) {
            Oxigeno( worker );
         } else {
            Hidrogeno( worker );
         }
      }
   }

   for ( worker = 0; worker < workers; worker++ ) {
      int status;
      pid_t pid = wait( &status );
   }

   shmdt( naturalShared );
   shmctl( memId, IPC_RMID, NULL );

}