int get_instruction_line(t_list *instruction_addresses_list, void ** instruction_line) { void * recv_bytes_buffer = NULL; int buffer_index = 0; while(list_size(instruction_addresses_list) > 0) { logical_addr * element = list_get(instruction_addresses_list, 0); // sprintf(aux_buffer, "%d%04d%04d%04d", PEDIDO_BYTES, element->page_number, element->offset, element->tamanio); void * aux_buffer = NULL; int aux_buffer_index = 0; char operacion = PEDIDO_BYTES; serialize_data(&operacion, sizeof(char), &aux_buffer,&aux_buffer_index); serialize_data(&element->page_number, sizeof(int), &aux_buffer, &aux_buffer_index); serialize_data(&element->offset, sizeof(int), &aux_buffer, &aux_buffer_index); serialize_data(&element->tamanio, sizeof(int), &aux_buffer, &aux_buffer_index); log_info(cpu_log, "Fetching for (%d,%d,%d) in UMC", element->page_number, element->offset, element->tamanio); //Send bytes request to UMC if( send(umcSocketClient, aux_buffer, aux_buffer_index, 0) < 0) { puts("Last Fetch failed"); return ERROR; } //Recv response recv_bytes_buffer = calloc(1, (size_t) element->tamanio); if(recv_bytes_buffer == NULL) { log_error(cpu_log, "get_instruction_line recv_bytes_buffer mem alloc failed"); return ERROR; } if(check_umc_response(recv_umc_response_status()) != SUCCESS) { return ERROR; } if( recv(umcSocketClient , recv_bytes_buffer , (size_t ) element->tamanio , 0) <= 0) { log_error(cpu_log, "UMC bytes recv failed"); return ERROR; } log_info(cpu_log, "Bytes Received: %s", (char*) recv_bytes_buffer); *instruction_line = realloc(*instruction_line, (size_t) buffer_index+element->tamanio); memcpy(*instruction_line+buffer_index, recv_bytes_buffer, (size_t) element->tamanio); buffer_index += element->tamanio; free(recv_bytes_buffer); list_remove_and_destroy_element(instruction_addresses_list, 0, free); } *instruction_line = realloc(*instruction_line, (size_t) (sizeof(char) + buffer_index)); * (char*)(*instruction_line+buffer_index) = '\0'; return SUCCESS; }
void fin_programa(int pid) { int i = 0; finalizar_en_archivo(pid); void limpio_todo(t_swap * reg) { if (reg->pid == pid) { list_replace(bitmap, reg->posicion_en_swap, (void *) 0); list_remove_and_destroy_element(list_swap, i, (void *) free); } else { i++; } } list_iterate(list_swap, (void *) limpio_todo); }
void algoritmoInterbloqueo(int32_t numeroPersonajes) { t_log *log = log_create(logName,"Nivel",FALSE,LOG_LEVEL_INFO); t_log *log2 = log_create("matriz.log","matriz",FALSE,LOG_LEVEL_INFO); t_list *peticionesActuales, *asignados,*disponibles,*simbolosPersonajes; t_list *peticionesPorProceso,*procesoAsignados; simboloStruct *unSimbolo; void* buffer; int32_t nProcesos; int32_t socketOrquestador; int32_t nRecursos = list_size(nivel.cajas); int32_t i; colaNoSerializadaStruct colaInterbloqueo; int32_t length; int16_t size=0; unRecursoPaquetizadoStruct *instanciasDisponibles,*instanciasPedidas,*instanciasAsignadas; int32_t aux= TRUE, proc,r; t_queue *enInterbloqueo; if (!listaPersonajes) listaPersonajes = list_create(); nProcesos = numeroPersonajes; if (nProcesos > 0) { disponibles=obtenerMatrizDisponibles(); asignados=obtenerMatrizAsignados(listaPersonajes,numeroPersonajes); peticionesActuales=obtenerPeticionesActuales(listaPersonajes,numeroPersonajes); simbolosPersonajes=obtenerListaSimbolos(listaPersonajes,numeroPersonajes); mostrarMatrizPeticiones(peticionesActuales,simbolosPersonajes); mostrarMatrizASIG(asignados,simbolosPersonajes); disponiblesMatriz(disponibles); //elimino los que no tienen asignados for (proc = 0; proc < nProcesos; proc++) { procesoAsignados = (t_list *) list_get(asignados,proc); bool condicionCeros(void* recurso) { return (((unRecursoPaquetizadoStruct *) recurso)->recurso != 0); } if ( list_size(list_filter(procesoAsignados,condicionCeros)) == 0 ) { list_remove_and_destroy_element(peticionesActuales,proc,element_destroyer); list_remove_and_destroy_element(asignados,proc,element_destroyer); unSimbolo = list_remove(simbolosPersonajes,proc); free(unSimbolo); nProcesos--; proc--; } } aux = TRUE; proc = 0; if (nProcesos > 0) { for (proc = 0; proc < nProcesos; proc++ ) { log_info(log2,"Chequeando proceso %c",((simboloStruct *) list_get(simbolosPersonajes,proc))->simbolo); aux = TRUE; //lista de un solo proceso (como si fuera un arreglo) peticionesPorProceso = (t_list *) list_get(peticionesActuales,proc); procesoAsignados = (t_list *) list_get(asignados,proc); for (r=0; r < nRecursos; r++) { instanciasDisponibles = (unRecursoPaquetizadoStruct *) list_get(disponibles,r); instanciasPedidas = (unRecursoPaquetizadoStruct *) list_get(peticionesPorProceso,r); instanciasAsignadas = (unRecursoPaquetizadoStruct *) list_get(procesoAsignados,r); // comprobamos que haya recursos suficientes aux = (instanciasPedidas->recurso - instanciasDisponibles->recurso) <= 0; if (!aux) { log_info(log2,"%c todavia necesita %d instancias de %c",((simboloStruct *) list_get(simbolosPersonajes,proc))->simbolo,instanciasPedidas->recurso,((cajaStruct *)list_get(nivel.cajas,r))->simbolo); log_info(log2,"hay %d instancias",instanciasDisponibles->recurso); break; } } if (aux) { log_info(log2,"suponemos que %c termina",((simboloStruct *) list_get(simbolosPersonajes,proc))->simbolo); aniadirYeliminar(disponibles, asignados, proc); //remover indice de maximos list_remove_and_destroy_element(peticionesActuales,proc,element_destroyer); unSimbolo = list_remove(simbolosPersonajes,proc); free(unSimbolo); nProcesos--; proc = -1; if (nProcesos == 0) { log_info(log,"Es estado seguro"); log_info(log2,"Es estado seguro"); log_destroy(log); log_destroy(log2); list_destroy(disponibles); list_destroy(asignados); list_destroy(peticionesActuales); list_destroy(simbolosPersonajes); return; } } } log_info(log,"Es Interbloqueo"); log_info(log2,"Es Interbloqueo"); for (i=0 ; i < list_size(simbolosPersonajes) ; i++) log_info(log,"Personaje en interbloqueo: %c",((simboloStruct *) list_get(simbolosPersonajes,i))->simbolo); if (nivel.recovery == 1) { enInterbloqueo=queue_create(); socketOrquestador = socketCreateClient(getIp(nivel.orquestador), getPort(nivel.orquestador)); for (i=0 ; i < list_size(simbolosPersonajes) ; i++) { queue_push(enInterbloqueo,list_get(simbolosPersonajes,i)); } colaInterbloqueo.cantidadPersonajes=list_size(simbolosPersonajes); colaInterbloqueo.cola = enInterbloqueo; buffer = serializador_interbloqueo(&colaInterbloqueo,&size); length = size + sizeof(header_t); socketSend(socketOrquestador,buffer,length); socketSend(socketOrquestador, &(nivel.nombre), sizeof(char[30])); shutdown(socketOrquestador,2); queue_destroy(enInterbloqueo); free(buffer); } } list_destroy(disponibles); list_destroy(asignados); list_destroy(peticionesActuales); list_destroy(simbolosPersonajes); }
int main(int argc, char* argv[]) { // Lo puse t0d0 en el llamado de abajo, no se porque y si se puede capturar 2 veces la señal como estaba hecho. // signal(SIGINT, notificarPersonajes); pthread_mutex_init(&semNiv, NULL); logger = logInit(argv, argv[1]); // Capturamos sigint y avisamos a los personajes para que cierren y cerramos el nivel. signal(SIGINT, cerrarForzado); t_config *configNivel; char** arrCaja; char* nom_nivel; char* ip_orq; char* port_orq; char* dir_orq; char ip[16]; int puerto; //--Creamos el config configNivel = config_try_create( //"nivel1.config" //Modo Debug argv[1], "Nombre,orquestador,TiempoChequeoDeadlock,Recovery,ip,puerto,Caja1"); ITEM_NIVEL *ListaItems = NULL; //--Creamos cada caja de recursos char* cajaAux; cajaAux = malloc(sizeof(char) * 6); sprintf(cajaAux, "Caja1"); //--Inicializa la lista con los personajes y sus recursos personajes = list_create(); personaje_t pjAux; int t = 1; int cols = 0; int rows = 0; int posXCaja = 0; int posYCaja = 0; nivel_gui_inicializar(); // Conseguimos el area del nivel char state = nivel_gui_get_area_nivel(&cols, &rows); // Validamos que no haya habido error if (state != EXIT_SUCCESS) { cerrarNivel("Error al intentar conseguir el area del nivel (GUI)."); exit(EXIT_FAILURE); } char* messageLimitErr; messageLimitErr = malloc(sizeof(char) * 100); //--Mientras pueda levantar el array while ((arrCaja = config_try_get_array_value(configNivel, cajaAux)) != NULL ) { posXCaja = atoi(arrCaja[3]); posYCaja = atoi(arrCaja[4]); // Validamos que la caja a crear esté dentro de los valores posibles del mapa if (posXCaja > rows || posYCaja > cols || posXCaja < 1 || posYCaja < 1) { sprintf(messageLimitErr, "La caja %c excede los limites de la pantalla. (%d,%d) - (%d,%d)", arrCaja[1][0], posXCaja, posYCaja, rows, cols); cerrarNivel(messageLimitErr); exit(EXIT_FAILURE); } // Si pasó la validacion, la creamos. CrearCaja(&ListaItems, arrCaja[1][0], atoi(arrCaja[3]), atoi(arrCaja[4]), atoi(arrCaja[2])); //--Rearma el cajaAux para la iteracion sprintf(cajaAux, "Caja%d", ++t); } free(cajaAux); //--Boludeces de los sockets message_t message; fd_set master, temp; struct sockaddr_in myAddress; struct sockaddr_in remoteAddress; int maxSock; int sockListener; int sockOrq; //--Saludo al orquestador //--Obetenemos el string del nombre y dirección del orquestador nom_nivel = config_get_string_value(configNivel, "Nombre"); dir_orq = config_get_string_value(configNivel, "orquestador"); puerto = config_get_int_value(configNivel, "puerto"); memcpy(ip, config_get_string_value(configNivel, "ip"), 16); // Conseguimos el tiempo de espera de chequeo int tiempoChequeo = config_get_int_value(configNivel, "TiempoChequeoDeadlock"); ip_orq = strtok(dir_orq, ":"); //--Separar ip port_orq = strtok(NULL, ":"); //--Separar puerto // Crear un socket: struct sockaddr_in socketInfo; if ((sockOrq = socket(AF_INET, SOCK_STREAM, 0)) != 0) { socketInfo.sin_family = AF_INET; socketInfo.sin_addr.s_addr = inet_addr(ip_orq); socketInfo.sin_port = htons(atoi(port_orq)); // Conectar el socket con la direccion 'socketInfo'. if (connect(sockOrq, (struct sockaddr*) &socketInfo, sizeof(socketInfo)) == -1) { perror("Connect"); exit(EXIT_FAILURE); } log_info(logger, "Conexión con orquestador."); orq_t orqMsj; orqMsj.type = NIVEL; orqMsj.detail = SALUDO; strcpy(orqMsj.name, nom_nivel); //memcpy(orqMsj.ip, &localhost->sin_addr.s_addr, 16); strcpy(orqMsj.ip, ip); orqMsj.port = puerto; //--Envía el "Saludo" para ser agregado if (send(sockOrq, &orqMsj, sizeof(orq_t), 0) == -1) { perror("Saludo"); exit(EXIT_FAILURE); } } // Definimos los threads pthread_t thr_interbloqueos; paramInterbloqueo_t parametros; parametros.numSock = sockOrq; parametros.tiempoChequeo = tiempoChequeo; parametros.recovery = config_get_int_value(configNivel, "Recovery"); // y los lanzamos if (pthread_create(&thr_interbloqueos, NULL, (void*) detectInterbloqueos, (void *) ¶metros)) { log_error(logger, strerror(errno)); exit(EXIT_FAILURE); } int maxRows, maxCols; int posX, posY; int posItemY, posItemX; int i; nivel_gui_get_area_nivel(&maxRows, &maxCols); nivel_gui_dibujar(ListaItems, nom_nivel); iniSocks(&master, &temp, &myAddress, remoteAddress, &maxSock, &sockListener, puerto, logger); while (1) { //--Gestiona un cliente ya conectado i = getSockChanged(&master, &temp, &maxSock, sockListener, &remoteAddress, &message, sizeof(message_t), logger); if (i != -1) { pthread_mutex_lock(&semNiv); int contPj; int contRec; char *auxRec; personaje_t *tempAux; //--Recibe mensaje y define comportamiento según el tipo switch (message.type) { case SALUDO: //--Agregamos personaje a la lista de items y a la de personajes/recursos CrearPersonaje(&ListaItems, i, message.name, INIX, INIY); pjAux.numSock = i; pjAux.chirimbolo = message.name; pjAux.blocked = false; pjAux.recursos = list_create(); list_add_new(personajes, &pjAux, sizeof(personaje_t)); //--Armamos la estrucura para enviar la posición inicial message.type = SALUDO; message.detail = INIX; message.detail2 = INIY; log_info(logger, "Se agregó el personaje %c con el socket %d", message.name, i); if (send(i, &message, sizeof(message), 0) == -1) perror("Respuesta posición inicial"); break; case POSICION: //--Obtiene posición del item pedido getPosRec(ListaItems, message.detail, &posX, &posY); //--Armamos la estrucura para enviar la posición del recurso pedido message.type = POSICION; message.detail = posX; message.detail2 = posY; if (send(i, &message, sizeof(message), 0) == -1) perror("Respuesta posición recurso"); break; case MOVIMIENTO: //--Devuelve las posiciones X e Y del item if (getPosPer(ListaItems, i, &posX, &posY) == -1) perror("GetPosItem"); switch (message.detail) { case ARRIBA: if (posY > 1) posY--; break; case ABAJO: if (posY < maxRows) posY++; break; case IZQUIERDA: if (posX > 1) posX--; break; case DERECHA: if (posX < maxCols) posX++; break; } //--Define confirmación y la devuelve message.type = MOVIMIENTO; message.detail2 = message.detail; message.detail = 1; if (send(i, &message, sizeof(message), 0) == -1) perror("Confirmacion"); //--Desbloquear en caso de que esté bloqueado for (contPj = 0; contPj < list_size(personajes); contPj++) { tempAux = list_get(personajes, contPj); if (tempAux->numSock == i && tempAux->blocked) tempAux->blocked = false; } MoverPersonaje(ListaItems, i, posX, posY); break; case PEDIDO: //--Obtiene posición del item pedido y del personaje getPosRec(ListaItems, message.detail, &posItemX, &posItemY); getPosPer(ListaItems, i, &posX, &posY); //--Valida si llegó al recurso if ((posItemX == posX) && (posItemY == posY)) { //-- Siempre le tiene que agregar a la lista de recursos, este o no bloqueado //--Agrega el recurso a la lista de recursos del personaje int contPj; personaje_t* tempAux; for (contPj = 0; contPj < list_size(personajes); contPj++) { tempAux = list_get(personajes, contPj); if (tempAux->numSock == i) { list_add_new(tempAux->recursos, &(message.detail), sizeof(message.detail)); break; } } //--Resta uno a la cantidad del item int result = restarQuantityRec(ListaItems, message.detail); if (result >= 0) { log_info(logger, "A %d se le da el recurso %c", i, message.detail); //--Si pudo restar la cantidad tempAux->blocked = false; //--Define confirmación y la devuelve message.detail = 1; if (send(i, &message, sizeof(message), 0) == -1) perror("Confirmacion"); } else { //--Si el recurso ya no tiene instacias tempAux->blocked = true; log_info(logger, "A %d se le niega el recurso %c", i, message.detail); //--Define rechazo y lo devuelve message.detail = 0; if (send(i, &message, sizeof(message), 0) == -1) perror("Confirmacion"); } } else { log_error(logger, "Posicion erronea al pedir recurso"); exit(EXIT_FAILURE); } break; case SALIR: for (contPj = 0; contPj < list_size(personajes); contPj++) { tempAux = list_get(personajes, contPj); if (tempAux->numSock == i) { //--Elimina y libera la lista de recursos de personaje for (contRec = 0; contRec < list_size(tempAux->recursos); contRec++) { auxRec = list_get(tempAux->recursos, contRec); //--Suma la cantidad de recursos que el personaje libera sumarQuantityRec(ListaItems, *auxRec, 1); } list_destroy_and_destroy_elements(tempAux->recursos, free); //--Elimina y libera al personaje de la lista de personajes list_remove_and_destroy_element(personajes, contPj, free); BorrarPer(&ListaItems, i); break; } } log_debug(logger, "%d se desconectó", i); break; } nivel_gui_dibujar(ListaItems, nom_nivel); pthread_mutex_unlock(&semNiv); } } nivel_gui_terminar(); return 0; }