]> git.llucax.com Git - z.facultad/75.74/practicos.git/commitdiff
Mejora y coding style de 1.1 y 1.2 (terminados).
authorLeandro Lucarella <llucax@gmail.com>
Sat, 22 Apr 2006 15:48:54 +0000 (15:48 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Sat, 22 Apr 2006 15:48:54 +0000 (15:48 +0000)
practicas/practica2/P02e1101.cpp
practicas/practica2/P02e1201.cpp

index 185d14f75f095e3756e8cfab0ca6197d8b22138c..4c5cd03e1679b6074dc3e2609868e5a2b7a34606 100644 (file)
@@ -24,41 +24,41 @@ enum state_t { RELEASED, ACQUIRED };
  */
 struct Mutex
 {
-       // Estados para un flag
-       /// indica el estado del proceso
-       state_t state[2];
-       /// el proceso que tiene prioridad ante un race
-       int turn;
+    // Estados para un flag
+    /// indica el estado del proceso
+    state_t state[2];
+    /// el proceso que tiene prioridad ante un race
+    int turn;
 };
 
 /// Inicializa un mutex
 void mutex_init(Mutex& m)
 {
-       m.state[0] = RELEASED;
-       m.state[1] = RELEASED;
-       m.turn = 0;
+    m.state[0] = RELEASED;
+    m.state[1] = RELEASED;
+    m.turn = 0;
 }
 
 /// Adquiere un mutex para el proceso indicado por nproc
 void mutex_acquire(Mutex& m, int proc)
 {
-       m.state[proc] = ACQUIRED;
-       while (m.state[(proc+1)%2] == ACQUIRED)
-       {
-               if (m.turn != proc)
-               {
-                       m.state[proc] = RELEASED;
-                       while (m.turn != proc);
-                       m.state[proc] = ACQUIRED;
-               }
-       }
+    m.state[proc] = ACQUIRED;
+    while (m.state[(proc+1)%2] == ACQUIRED)
+    {
+        if (m.turn != proc)
+        {
+            m.state[proc] = RELEASED;
+            while (m.turn != proc);
+            m.state[proc] = ACQUIRED;
+        }
+    }
 }
 
 /// Libera un mutex para el proceso indicado por proc
 void mutex_release(Mutex& m, int proc)
 {
-       m.turn = (proc+1)%2;
-       m.state[proc] = RELEASED;
+    m.turn = (proc+1)%2;
+    m.state[proc] = RELEASED;
 }
 
 /**
@@ -67,75 +67,90 @@ void mutex_release(Mutex& m, int proc)
  */
 struct Molinete
 {
-       unsigned count;
-       Mutex mutex;
+    unsigned count;
+    Mutex mutex;
 };
 
 /// Inicializa el molinete
 void molinete_init(Molinete& m)
 {
-       m.count = 0;
-       mutex_init(m.mutex);
+    m.count = 0;
+    mutex_init(m.mutex);
 }
 
 int main(int argc, char *argv[])
 {
-       using std::cerr;
-       using std::cout;
-
-       if (argc < 2)
-       {
-               cerr << "Faltan parametros: " << argv[0] << " (0|1) [max_iter]\n";
-               return 1;
-       }
-       int proc = atoi(argv[1]);
-
-       int shm_id = shmget(SHM_KEY, sizeof(Molinete), IPC_CREAT | 0666);
-       if (shm_id == -1)
-       {
-               cerr << "Error al crea/obtener shared memory.\n";
-               return 2;
-       }
-       Molinete* molinete = (Molinete*) shmat(shm_id, NULL, 0);
-       if (molinete == (Molinete*) -1)
-       {
-               cerr << "Error al attachear shared memory.\n";
-               return 3;
-       }
-
-       cout << "Shared memory id = " << shm_id << "\n";
-
-       // Si somos el primer proceso inicializamos el molinete
-       if (!proc) molinete_init(*molinete);
-
-       // Maxima cantidad de iteraciones (puede venir por parametro)
-       int max_iter = 100000;
-       if (argc > 2)
-               max_iter = atoi(argv[2]);
-
-       // Loop principal
-       for (int i = 0; i < max_iter; ++i)
-       {
-               bool dec = rand() % 2;
-               int count;
-               mutex_acquire(molinete->mutex, proc);
-               if (dec && molinete->count) // Decremento sólo si no es 0
-                       count = --molinete->count;
-               else
-                       count = ++molinete->count;
-               mutex_release(molinete->mutex, proc);
-               // Uso cout directamente porque es line-buffered, mientras que
-               // no use threads no es problema el buffer de cout. Y de todas
-               // formas pongo un flush (el endl es \n+flush) por las dudas.
-               cout << "Proceso " << proc << ": molinete = " << count << std::endl;
-               //sched_yield(); // Para ver como se entrelazan mejor
-       }
-
-       if (shmdt(molinete) == -1)
-       {
-               cerr << "Error al detachear shared memory.\n";
-               return -1;
-       }
-
-       return 0;
+    using std::cerr;
+    using std::cout;
+
+    if (argc < 2)
+    {
+        cerr << "Faltan parametros: " << argv[0] << " (0|1) [max_iter]\n";
+        return 1;
+    }
+    int proc = atoi(argv[1]);
+
+    int shm_id = shmget(SHM_KEY, sizeof(Molinete), IPC_CREAT | 0666);
+    if (shm_id == -1)
+    {
+        cerr << "Error al crea/obtener shared memory.\n";
+        return 2;
+    }
+    Molinete* molinete = (Molinete*) shmat(shm_id, NULL, 0);
+    if (molinete == (Molinete*) -1)
+    {
+        cerr << "Error al attachear shared memory.\n";
+        return 3;
+    }
+
+    cout << "Shared memory id = " << shm_id << "\n";
+
+    // Si somos el primer proceso inicializamos el molinete
+    if (!proc) molinete_init(*molinete);
+    else usleep(1000); // espero que el 1er proceso inicialice
+
+    // Maxima cantidad de iteraciones (puede venir por parametro)
+    int max_iter = 100000;
+    if (argc > 2)
+        max_iter = atoi(argv[2]);
+
+    srand(getpid());
+
+    // Loop principal
+    for (int i = 0; i < max_iter; ++i)
+    {
+        char sdec[] = "sale";
+        char sinc[] = "entra";
+        char* s;
+        bool dec = rand() % 2;
+        int count;
+        mutex_acquire(molinete->mutex, proc);
+        if (dec && molinete->count) // Decremento sólo si no es 0
+        {
+            s = sdec;
+            count = --molinete->count;
+        }
+        else
+        {
+            s = sinc;
+            count = ++molinete->count;
+        }
+        mutex_release(molinete->mutex, proc);
+        // Uso cout directamente porque es line-buffered, mientras que
+        // no use threads no es problema el buffer de cout. Y de todas
+        // formas pongo un flush (el endl es \n+flush) por las dudas.
+        cout << "Proceso " << proc << " (" << s << "): molinete = " << count
+                << std::endl;
+        sched_yield(); // Para ver como se entrelazan mejor
+    }
+
+    if (shmdt(molinete) == -1)
+    {
+        cerr << "Error al detachear shared memory.\n";
+        return -1;
+    }
+
+    return 0;
 }
+
+// vim: set et sw=4 sts=4 :
index 9c0cb6b255495ea65e7390bf9aa2bca417b84ed2..b53feaa1ed3ac244b4db60e134dca7fb9bf0ded2 100644 (file)
@@ -1,8 +1,8 @@
 /**
  * Leandro Lucarella (77891)
  *
- * Ejercicio 1.1. Implementa problema del museo usando solamente variables
- * (shared memory)
+ * Ejercicio 1.2. Implementa problema del museo usando variables (shared memory)
+ * y semaforos.
  */
 
 #include <iostream>
 typedef unsigned Molinete;
 
 /// Hace un wait (P) al semaforo (devuelve false si hubo error).
-bool sem_wait(int sem_id)
+void sem_wait(int sem_id)
 {
-       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;
+    struct sembuf op;
+    op.sem_op = -1; // sacar 1
+    op.sem_num = 0; // al semaforo 1
+    op.sem_flg = 0; // esperando
+    if (semop(sem_id, &op, 1) < 0)
+    {
+        std::cerr << "No se pudo sacar al semaforo.\n";
+        exit(100);
+    }
 }
 
 /// Hace un signal (V) al semaforo (devuelve false si hubo error).
-bool sem_signal(int sem_id)
+void 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;
+    struct sembuf op;
+    op.sem_op =  1; // agregar 1
+    op.sem_num = 0; // al semaforo 1
+    op.sem_flg = 0; // esperando
+    if (semop(sem_id, &op, 1) < 0)
+    {
+        std::cerr << "No se pudo poner en el semaforo.\n";
+        exit(101);
+    }
 }
 
 int main(int argc, char *argv[])
 {
-       using std::cerr;
-       using std::cout;
+    using std::cerr;
+    using std::cout;
 
-       if (argc < 2)
-       {
-               cerr << "Faltan parametros: " << argv[0] << " N [max_iter]\n";
-               return 1;
-       }
-       int proc = atoi(argv[1]);
+    if (argc < 2)
+    {
+        cerr << "Faltan parametros: " << argv[0] << " N [max_iter]\n";
+        return 1;
+    }
+    int proc = atoi(argv[1]);
 
-       // Shared memory
-       int shm_id = shmget(SHM_KEY, sizeof(Molinete), IPC_CREAT | 0666);
-       if (shm_id == -1)
-       {
-               cerr << "Error al crea/obtener shared memory.\n";
-               return 2;
-       }
-       Molinete* molinete = (Molinete*) shmat(shm_id, NULL, 0);
-       if (molinete == (Molinete*) -1)
-       {
-               cerr << "Error al attachear shared memory.\n";
-               return 3;
-       }
-       cout << "Shared memory id = " << shm_id << "\n";
+    // Shared memory
+    int shm_id = shmget(SHM_KEY, sizeof(Molinete), IPC_CREAT | 0666);
+    if (shm_id == -1)
+    {
+        cerr << "Error al crea/obtener shared memory.\n";
+        return 2;
+    }
+    Molinete* molinete = (Molinete*) shmat(shm_id, NULL, 0);
+    if (molinete == (Molinete*) -1)
+    {
+        cerr << "Error al attachear shared memory.\n";
+        return 3;
+    }
+    cout << "Shared memory id = " << shm_id << "\n";
 
-       // Semaforo
-       int sem_id = semget(SEM_KEY, 1, 0666 | IPC_CREAT);
-       if (sem_id == -1)
-       {
-               cerr << "Error al crea/obtener semaforo.\n";
-               return 4;
-       }
-       // Si es el primero, inicializo
-       if (!proc)
-       {
-               *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";
-       }
-       else // Si soy otro espero un poco por las dudas para que corra el 1ro
-       {
-               usleep(1000);
-       }
+    // Semaforo
+    int sem_id = semget(SEM_KEY, 1, 0666 | IPC_CREAT);
+    if (sem_id == -1)
+    {
+        cerr << "Error al crea/obtener semaforo.\n";
+        return 4;
+    }
+    // Si es el primero, inicializo
+    if (!proc)
+    {
+        *molinete = 0;
+        if (semctl(sem_id, 0, SETVAL, 1) < 0) // pongo 1 en el sem
+        {
+            cerr << "No se pudo inicializar semaforo.\n";
+            return 5;
+        }
+        cout << "Semaforo inicializado id = " << sem_id << "\n";
+    }
+    else // Si soy otro espero un poco por las dudas para que corra el 1ro
+    {
+        usleep(10000);
+    }
 
-       // Maxima cantidad de iteraciones (puede venir por parametro)
-       int max_iter = 100000;
-       if (argc > 2)
-               max_iter = atoi(argv[2]);
+    srand(getpid());
 
-       // Loop principal
-       for (int i = 0; i < max_iter; ++i)
-       {
-               bool dec = rand() % 2;
-               int count;
-               if (!sem_wait(sem_id)) // lock
-               {
-                       cerr << "No se pudo sacar al semaforo.\n";
-                       return 6;
-               }
-               if (dec && *molinete) // Decremento sólo si no es 0
-                       count = --*molinete;
-               else
-                       count = ++*molinete;
-               if (!sem_signal(sem_id)) // unlock
-               {
-                       cerr << "No se pudo sacar al semaforo.\n";
-                       return 6;
-               }
-               // Uso cout directamente porque es line-buffered, mientras que
-               // no use threads no es problema el buffer de cout. Y de todas
-               // formas pongo un flush (el endl es \n+flush) por las dudas.
-               cout << "Proceso " << proc << ": molinete = " << count << std::endl;
-               //sched_yield(); // Para ver como se entrelazan mejor
-       }
+    // Maxima cantidad de iteraciones (puede venir por parametro)
+    int max_iter = 100000;
+    if (argc > 2)
+        max_iter = atoi(argv[2]);
 
-       if (shmdt(molinete) == -1)
-       {
-               cerr << "Error al detachear shared memory.\n";
-               return -1;
-       }
+    // Loop principal
+    for (int i = 0; i < max_iter; ++i)
+    {
+        char sdec[] = "sale";
+        char sinc[] = "entra";
+        char* s;
+        bool dec = rand() % 2;
+        int count;
+        sem_wait(sem_id); // lock
+        if (dec && *molinete) // Decremento sólo si no es 0
+        {
+            s = sdec;
+            count = --*molinete;
+        }
+        else
+        {
+            s = sinc;
+            count = ++*molinete;
+        }
+        sem_signal(sem_id); // unlock
+        // Uso cout directamente porque es line-buffered, mientras que
+        // no use threads no es problema el buffer de cout. Y de todas
+        // formas pongo un flush (el endl es \n+flush) por las dudas.
+        cout << "Proceso " << proc << " (" << s << "): molinete = " << count
+                << std::endl;
+        sched_yield(); // Para ver como se entrelazan mejor
+    }
 
-       return 0;
+    if (shmdt(molinete) == -1)
+    {
+        cerr << "Error al detachear shared memory.\n";
+        return -1;
+    }
+
+    return 0;
 }
+
+// vim: set et sw=4 sts=4 :