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]);
93 int shm_id = shmget(SHM_KEY, sizeof(Molinete), IPC_CREAT | 0666);
96 cerr << "Error al crea/obtener shared memory.\n";
99 Molinete* molinete = (Molinete*) shmat(shm_id, NULL, 0);
100 if (molinete == (Molinete*) -1)
102 cerr << "Error al attachear shared memory.\n";
106 cout << "Shared memory id = " << shm_id << "\n";
108 // Si somos el primer proceso inicializamos el molinete
109 if (!proc) molinete_init(*molinete);
111 // Maxima cantidad de iteraciones (puede venir por parametro)
112 int max_iter = 100000;
114 max_iter = atoi(argv[2]);
117 for (int i = 0; i < max_iter; ++i)
119 bool dec = rand() % 2;
121 mutex_acquire(molinete->mutex, proc);
122 if (dec && molinete->count) // Decremento sólo si no es 0
123 count = --molinete->count;
125 count = ++molinete->count;
126 mutex_release(molinete->mutex, proc);
127 // Uso cout directamente porque es line-buffered, mientras que
128 // no use threads no es problema el buffer de cout. Y de todas
129 // formas pongo un flush (el endl es \n+flush) por las dudas.
130 cout << "Proceso " << proc << ": molinete = " << count << std::endl;
131 //sched_yield(); // Para ver como se entrelazan mejor
134 if (shmdt(molinete) == -1)
136 cerr << "Error al detachear shared memory.\n";