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 cout << "Shared memory id = " << shm_id << "\n";
109 // Si somos el primer proceso inicializamos el molinete
110 if (proc == 0) molinete_init(*molinete);
112 // Maxima cantidad de iteraciones (puede venir por parametro)
115 max_iter = atoi(argv[2]);
120 for (int i = 0; i < max_iter; ++i)
122 char sdec[] = "sale";
123 char sinc[] = "entra";
125 bool dec = rand() % 2;
127 mutex_acquire(molinete->mutex, proc);
128 if (dec && molinete->count) // Decremento sólo si no es 0
131 count = --molinete->count;
136 count = ++molinete->count;
138 mutex_release(molinete->mutex, proc);
139 // Uso cout directamente porque es line-buffered, mientras que
140 // no use threads no es problema el buffer de cout. Y de todas
141 // formas pongo un flush (el endl es \n+flush) por las dudas.
142 cout << "Proceso " << proc << " (" << s << "): molinete = " << count
144 sched_yield(); // Para ver como se entrelazan mejor
147 if (shmdt(molinete) == -1)
149 cerr << "Error al detachear shared memory.\n";
156 // vim: set et sw=4 sts=4 :