2 * Leandro Lucarella (77891)
4 * Ejercicio 1.1. Implementa problema del museo usando solamente variables
12 #include <sys/types.h>
16 /// Clave de nuestro segmento shm
17 #define SHM_KEY 0x77891110
19 /// Estado de un mutex para un proceso en particular
20 enum state_t { RELEASED, ACQUIRED };
23 * Estructura de un mutex implementado a través del algoritmo de Decker.
27 // Estados para un flag
28 /// indica el estado del proceso
30 /// el proceso que tiene prioridad ante un race
34 /// Inicializa un mutex
35 void mutex_init(Mutex& m)
37 m.state[0] = RELEASED;
38 m.state[1] = RELEASED;
42 /// Adquiere un mutex para el proceso indicado por nproc
43 void mutex_acquire(Mutex& m, int proc)
45 m.state[proc] = ACQUIRED;
46 while (m.state[(proc+1)%2] == ACQUIRED)
50 m.state[proc] = RELEASED;
51 while (m.turn != proc);
52 m.state[proc] = ACQUIRED;
57 /// Libera un mutex para el proceso indicado por proc
58 void mutex_release(Mutex& m, int proc)
61 m.state[proc] = RELEASED;
65 * Estructura con el contador y su mutex.
66 * Esta estructura será compartida utilizando shared memory.
74 /// Inicializa el molinete
75 void molinete_init(Molinete& m)
81 int main(int argc, char *argv[])
88 cerr << "Faltan parametros: " << argv[0] << " (0|1) [max_iter]\n";
91 int proc = atoi(argv[1]);
96 shm_id = shmget(SHM_KEY, sizeof(Molinete),
97 (proc ? 0 : IPC_CREAT) | 0666); // crea solo si es el proceso 0
99 while (proc != 0 && shm_id == -1);
100 Molinete* molinete = (Molinete*) shmat(shm_id, NULL, 0);
101 if (molinete == (Molinete*) -1)
103 cerr << "Error al attachear shared memory.\n";
107 // Si somos el primer proceso inicializamos el molinete
108 if (proc == 0) molinete_init(*molinete);
110 // Maxima cantidad de iteraciones (puede venir por parametro)
113 max_iter = atoi(argv[2]);
118 for (int i = 0; i < max_iter; ++i)
120 char sdec[] = "sale";
121 char sinc[] = "entra";
123 bool dec = rand() % 2;
125 mutex_acquire(molinete->mutex, proc);
126 if (dec && molinete->count) // Decremento sólo si no es 0
129 count = --molinete->count;
134 count = ++molinete->count;
136 mutex_release(molinete->mutex, proc);
137 // Uso cout directamente porque es line-buffered, mientras que
138 // no use threads no es problema el buffer de cout. Y de todas
139 // formas pongo un flush (el endl es \n+flush) por las dudas.
140 cout << "Proceso " << proc << " (" << s << "): molinete = " << count
142 sched_yield(); // Para ver como se entrelazan mejor
145 if (shmdt(molinete) == -1)
147 cerr << "Error al detachear shared memory.\n";
154 // vim: set et sw=4 sts=4 :