]> git.llucax.com Git - z.facultad/75.74/practicos.git/blobdiff - practicas/practica2/P02e1201.cpp
Completo 2.1.1 y arreglo 1.2.
[z.facultad/75.74/practicos.git] / practicas / practica2 / P02e1201.cpp
index 24e3f6329a09698fa12fd4f71a553a2d5cc8aa3a..9c0cb6b255495ea65e7390bf9aa2bca417b84ed2 100644 (file)
 /// Ahora el contador es un simple unsigned
 typedef unsigned Molinete;
 
 /// Ahora el contador es un simple unsigned
 typedef unsigned Molinete;
 
-/// Union para utilizar semaforo
-union semun
+/// Hace un wait (P) al semaforo (devuelve false si hubo error).
+bool sem_wait(int sem_id)
 {
 {
-       int val;
-       struct semid_ds* buf;
-       unsigned short* array;
-};
+       struct sembuf op;
+       op.sem_op = -1; // sacar 1
+       op.sem_num = 0; // al semaforo 1
+       op.sem_flg = 0; // esperando
+       return semop(sem_id, &op, 1) >= 0;
+}
+
+/// Hace un signal (V) al semaforo (devuelve false si hubo error).
+bool sem_signal(int sem_id)
+{
+       struct sembuf op;
+       op.sem_op =  1; // agregar 1
+       op.sem_num = 0; // al semaforo 1
+       op.sem_flg = 0; // esperando
+       return semop(sem_id, &op, 1) >= 0;
+}
 
 int main(int argc, char *argv[])
 {
 
 int main(int argc, char *argv[])
 {
@@ -63,26 +75,21 @@ int main(int argc, char *argv[])
                cerr << "Error al crea/obtener semaforo.\n";
                return 4;
        }
                cerr << "Error al crea/obtener semaforo.\n";
                return 4;
        }
-       semun sem_arg;
-       sem_arg.val = 0;
-       if (semctl(sem_id, 0, SETVAL, sem_arg) < 0)
+       // Si es el primero, inicializo
+       if (!proc)
        {
        {
-               cerr << "No se pudo inicializar semaforo.\n";
-               return 5;
+               *molinete = 0;
+               if (semctl(sem_id, 0, SETVAL, 1) < 0)
+               {
+                       cerr << "No se pudo inicializar semaforo.\n";
+                       return 5;
+               }
+               cout << "Semaforo inicializado id = " << sem_id << "\n";
        }
        }
-       struct sembuf ops; 
-       ops.sem_op = 1; // agregar 1
-       ops.sem_num = 0; // al semaforo 1
-       ops.sem_flg = 0; // esperando
-       if (semop(sem_id, &ops, 1) < 0)
+       else // Si soy otro espero un poco por las dudas para que corra el 1ro
        {
        {
-               cerr << "No se pudo agregar al semaforo.\n";
-               return 6;
+               usleep(1000);
        }
        }
-       cout << "Semaforo inicializado id = " << sem_id << "\n";
-
-       // Si somos el primer proceso inicializamos el molinete
-       if (!proc) *molinete = 0;
 
        // Maxima cantidad de iteraciones (puede venir por parametro)
        int max_iter = 100000;
 
        // Maxima cantidad de iteraciones (puede venir por parametro)
        int max_iter = 100000;
@@ -94,20 +101,16 @@ int main(int argc, char *argv[])
        {
                bool dec = rand() % 2;
                int count;
        {
                bool dec = rand() % 2;
                int count;
-               // lock
-               ops.sem_op = -1; // saco 1 (== adquirir el mutex)
-               if (semop(sem_id, &ops, 1) < 0)
+               if (!sem_wait(sem_id)) // lock
                {
                        cerr << "No se pudo sacar al semaforo.\n";
                        return 6;
                }
                {
                        cerr << "No se pudo sacar al semaforo.\n";
                        return 6;
                }
-               if (dec && molinete) // Decremento sólo si no es 0
+               if (dec && *molinete) // Decremento sólo si no es 0
                        count = --*molinete;
                else
                        count = ++*molinete;
                        count = --*molinete;
                else
                        count = ++*molinete;
-               // unlock
-               ops.sem_op = 1; // pongo 1 (== liberar el mutex)
-               if (semop(sem_id, &ops, 1) < 0)
+               if (!sem_signal(sem_id)) // unlock
                {
                        cerr << "No se pudo sacar al semaforo.\n";
                        return 6;
                {
                        cerr << "No se pudo sacar al semaforo.\n";
                        return 6;