void procesarEscritura(t_mensaje* detalle,sock_t* socketMemoria) { pidCondicion = detalle->PID; int32_t status; int32_t resultado; bool buscar = list_any_satisfy(espacioOcupado,validarMismoPid); resultado = buscar; if(buscar == 1) { escribirPagina(detalle->contenidoPagina,detalle->PID,detalle->NumeroDePagina); aumentarEscritura(detalle->PID); } else { log_error(SwapLog,"No existe el proceso %d en memoria",detalle->PID); } status = send(socketMemoria->fd, &resultado, sizeof(int32_t),0); /*chequea envío*/ if(!status) { printf("No se envió la cantidad de bytes a enviar luego\n"); } free(detalle->contenidoPagina); usleep(deSegundoAMicroSegundos(configuracion->retardo_swap)); }
//****MISCELLANEOUS**** void agregar_referencia(int page_referenced, t_proceso * proceso) { if (its_clock_m) eliminar_referencia(page_referenced, proceso); bool esta_en_referencias; bool esta_en_lista(int ref) { return (ref == page_referenced); } esta_en_referencias = list_any_satisfy(proceso->referencias, (void *) esta_en_lista); if (!esta_en_referencias) list_add(proceso->referencias, (void *) page_referenced); }
void procesarLectura(t_mensaje* detalle,sock_t* socketMemoria) { pidCondicion = detalle->PID; int32_t status; int32_t resultado; bool buscar = list_any_satisfy(espacioOcupado,validarMismoPid); resultado = buscar; if(buscar == 1) { char* pagina = buscarPagina(detalle->PID, detalle->NumeroDePagina); int32_t tamanio,offset; char* mensaje; aumentarLectura(detalle->PID); //serializo mensaje, esto se puede mejorar. offset = 0; int32_t tamanioPagina = string_length(pagina) + 1; tamanio = sizeof(int32_t) + sizeof(int32_t) + tamanioPagina; mensaje = malloc(tamanio); memcpy(mensaje + offset, &resultado, sizeof(int32_t)); offset = offset + sizeof(int32_t); memcpy(mensaje + offset, &tamanioPagina, sizeof(int32_t)); offset = offset + sizeof(int32_t); if(tamanioPagina > 0) { memcpy(mensaje + offset, pagina, tamanioPagina); } send(socketMemoria->fd,mensaje,tamanio,0); free(mensaje); free(pagina); } else { log_error(SwapLog,"No existe el proceso %d en memoria",detalle->PID); status = send(socketMemoria->fd, &resultado, sizeof(int32_t),0); /*chequea envío*/ if(!status) { printf("No se envió la cantidad de bytes a enviar luego\n"); } } usleep(deSegundoAMicroSegundos(configuracion->retardo_swap)); }
infoNodo* obtenerProximoWorkerConBloque(t_list* listaNodos,int bloque,int numWorkerActual){ bool nodoBloqueConNumero(infoBloque* bloquee){ return bloquee->numeroBloque == bloque; } bool nodoConNumero(infoNodo* nodo){ return nodo->numero != numWorkerActual && list_any_satisfy(nodo->bloques, (void*) nodoBloqueConNumero) && (nodo->disponibilidad>0); } void restaurarDisp(infoNodo* nodo){ if(nodo->numero != numWorkerActual){ nodo->disponibilidad += getDisponibilidadBase(); } } infoNodo* nodoEncontrado = list_find(listaNodos, (void*) nodoConNumero); if(nodoEncontrado == NULL){ list_iterate(listaNodos,(void*) restaurarDisp); return list_find(listaNodos, (void*) nodoConNumero); } return nodoEncontrado; }
void procesarFinalizacion(t_mensaje* detalle,sock_t* socketMemoria) { pidCondicion = detalle->PID; bool resultado = list_any_satisfy(espacioOcupado,validarMismoPid); if(resultado == 1) { liberarProceso(detalle->PID); mostrarEstadisticas(detalle->PID); } else { log_error(SwapLog,"Se intenta eliminar un proceso que no existe en memoria."); } //Se envia 1 si salio bien y 0 en caso contrario. int32_t mensaje = resultado; int32_t status = send(socketMemoria->fd, &mensaje, sizeof(int32_t),0); if(!status) { printf("Irregularidad en el envio\n"); } }
void procesar_mensaje (int sock_plataforma, int nro_nivel, t_paquete paqueteAux, t_list *ListaItems, t_list *ListaPersonajes, t_configNivel datosNivel, pthread_mutex_t *mutexListaItems, pthread_mutex_t *mutexListaPersonajes, pthread_mutex_t *mutexEnemigos, t_log *logger) { switch(paqueteAux.selector) { case NUEVO_PERSONAJE: { t_nuevoPersonaje *nuevoPersonaje = (t_nuevoPersonaje *) paqueteAux.datos; pthread_mutex_lock(mutexListaItems); pthread_mutex_lock(mutexListaPersonajes); t_personaje *personaje = (t_personaje *) malloc(sizeof(t_personaje)); personaje->personajeID = nuevoPersonaje->personajeID; personaje->nivelID = nuevoPersonaje->nivelID; personaje->recursosAsignados = list_create(); personaje->recursosNecesitados = list_create(); personaje->posX = 0; personaje->posY = 0; personaje->recursoBloqueante = '\0'; personaje->prioridad = prioridad; ++prioridad; crearListaRecursosNecesitados(nuevoPersonaje->recursosNecesitados,personaje->recursosNecesitados); ITEM_NIVEL *itemPersonaje = malloc(sizeof(ITEM_NIVEL)); itemPersonaje->id = nuevoPersonaje->personajeID; itemPersonaje->posx = 0; itemPersonaje->posy = 0; itemPersonaje->item_type = PERSONAJE_ITEM_TYPE; list_add(ListaItems,itemPersonaje); list_add(ListaPersonajes,personaje); nivel_gui_dibujar(ListaItems,datosNivel.nombre); pthread_mutex_unlock(mutexListaItems); pthread_mutex_unlock(mutexListaPersonajes); log_info(logger, "Personaje: %c conectado.", personaje->personajeID); break; } case UBICACION_RECURSO: { log_info(logger, "Mensaje UBICACION_RECURSO recibido."); t_ubicacionRecurso *ubicacionRecurso = (t_ubicacionRecurso *) paqueteAux.datos; pthread_mutex_lock(mutexListaItems); bool _funcBuscarRecurso(ITEM_NIVEL *item) { return item->id == ubicacionRecurso->recursoID; } ITEM_NIVEL *itemBuscado = list_find(ListaItems,(void *)_funcBuscarRecurso); pthread_mutex_unlock(mutexListaItems); ubicacionRecurso->posX = itemBuscado->posx; ubicacionRecurso->posY = itemBuscado->posy; t_paquete *paquete = empaquetar(UBICACION_RECURSO, sizeof(t_ubicacionRecurso), ubicacionRecurso); if(send(sock_plataforma,paquete,sizeof(t_paquete),0) == -1) { log_error(logger, "Error al enviar mensaje UBICACION_RECURSO."); exit(1); } free(paquete); log_info(logger, "Mensaje UBICACION_RECURSO enviado."); break; } case UBICACION_PERSONAJE: { log_info(logger, "Mensaje UBICACION_PERSONAJE recibido."); t_ubicacionPersonaje *ubicacionPersonaje = (t_ubicacionPersonaje *) paqueteAux.datos; pthread_mutex_lock(mutexListaItems); pthread_mutex_lock(mutexListaPersonajes); bool _funcBuscarEnListaItems(ITEM_NIVEL *personaje) { return personaje->id == ubicacionPersonaje->personajeID; } ITEM_NIVEL *itemPersonaje = list_find(ListaItems,(void *)_funcBuscarEnListaItems); bool _funcBuscarEnListaPersonajes(t_personaje *personaje) { return personaje->personajeID == ubicacionPersonaje->personajeID; } t_personaje *personaje = list_find(ListaPersonajes,(void *)_funcBuscarEnListaPersonajes); if((itemPersonaje != NULL) && (personaje != NULL)) { itemPersonaje->posx = ubicacionPersonaje->posX; itemPersonaje->posy = ubicacionPersonaje->posY; personaje->posX = ubicacionPersonaje->posX; personaje->posY = ubicacionPersonaje->posY; bool _funcPisarEnemigo(ITEM_NIVEL *itemEnemigo) { if(itemEnemigo->item_type == ENEMIGO_ITEM_TYPE) { return ((itemPersonaje->posx == itemEnemigo->posx) && (itemPersonaje->posy == itemEnemigo->posy)); } return false; } bool muertePorEnemigo = list_any_satisfy(ListaItems, (void *) _funcPisarEnemigo); if(muertePorEnemigo) { t_victimaEnemigo victimaEnemigo; victimaEnemigo.personajeID = itemPersonaje->id; victimaEnemigo.nivelID = nro_nivel; t_paquete *paquete = empaquetar(VICTIMA_ENEMIGO, sizeof(t_victimaEnemigo), &victimaEnemigo); if(send(sock_plataforma, paquete, sizeof(t_paquete), 0) == -1) { log_error(logger, "Error al enviar mensaje VICTIMA_ENEMIGO."); exit(1); } free(paquete); log_info(logger, "Mensaje VICTIMA_ENEMIGO enviado."); } nivel_gui_dibujar(ListaItems,datosNivel.nombre); pthread_mutex_unlock(mutexListaItems); pthread_mutex_unlock(mutexListaPersonajes); } break; } case INSTANCIA_RECURSO: { log_info(logger, "Mensaje INSTANCIA_RECURSO recibido."); t_instanciaRecurso *instanciaRecurso = (t_instanciaRecurso *) paqueteAux.datos; pthread_mutex_lock(mutexListaItems); pthread_mutex_lock(mutexListaPersonajes); bool _funcBuscarRecursoEnItems(ITEM_NIVEL *rec) { return rec->id == instanciaRecurso->recursoID; } ITEM_NIVEL *itemRecurso = list_find(ListaItems,(void *)_funcBuscarRecursoEnItems); bool _funcBuscarPersonaje(t_personaje *pers) { return pers->personajeID == instanciaRecurso->personajeID; } t_personaje *personaje = list_find(ListaPersonajes,(void *)_funcBuscarPersonaje); if(personaje != NULL) { if(itemRecurso->quantity) { --itemRecurso->quantity; bool _funcBuscarRecurso(t_recurso *recurso) { return recurso->recursoID == instanciaRecurso->recursoID; } t_recurso *recursoAsignado = list_find(personaje->recursosAsignados, (void *) _funcBuscarRecurso); t_recurso *recursoNecesitado = list_find(personaje->recursosNecesitados, (void *) _funcBuscarRecurso); if(recursoAsignado != NULL) { ++recursoAsignado->cantidad; } else { t_recurso *recurso = malloc(sizeof(t_recurso)); recurso->recursoID = instanciaRecurso->recursoID; recurso->cantidad = 1; list_add (personaje->recursosAsignados, recurso); } --recursoNecesitado->cantidad; if(recursoNecesitado->cantidad == 0) { list_remove_by_condition(personaje->recursosNecesitados, (void *) _funcBuscarRecurso); } if (send(sock_plataforma,&paqueteAux,sizeof(t_paquete),0) == -1) { log_error(logger, "Error al enviar mensaje RESPUESTA."); exit(1); } log_info(logger, "Mensaje INSTANCIA_RECURSO enviado."); } else { personaje->recursoBloqueante = instanciaRecurso->recursoID; } }
int hay_frames_libres() { bool es_libre(t_mem_frame * f) { return (f->libre == 1); } return (int) list_any_satisfy(frames_memoria, (void *) es_libre); }
void replanificar(int paraReplanificar,job* jobi,respuestaSolicitudTransformacion* respuestaArchivo, bool** matrix,int bloques,int nodos){ respuestaSolicitudTransformacion* respuestaTransfromacion = malloc(sizeof(respuestaSolicitudTransformacion)); respuestaTransfromacion->workers = list_create(); bool nodoConNumero(workerDesdeYama* worker){ return worker->numeroWorker == paraReplanificar; } workerDesdeYama* worker = list_find(respuestaArchivo->workers, (void*) nodoConNumero); void agregarBloque(bloquesConSusArchivosTransformacion* bloque){ bloquesConSusArchivosTransformacion* bloqueNuevo = malloc(sizeof(bloquesConSusArchivosTransformacion)); bloqueYNodo* nodoBloque = malloc(sizeof(bloqueYNodo)); nodoBloque->bloque= bloque->numBloque; nodoBloque->workerId = paraReplanificar; int nodoNuevo = nodoConOtraCopia(nodoBloque,matrix,nodos,bloques); if(nodoNuevo == -1){ log_trace(logger,"Fallo en replanificar nodo %d", paraReplanificar); finalizarJob(jobi,TRANSFORMACION,FALLO_TRANSFORMACION); } bool nodoYaCargado(workerDesdeYama* workerCargado){ return workerCargado->numeroWorker == nodoNuevo; } workerDesdeYama* nuevoWorker; if(list_any_satisfy(respuestaTransfromacion->workers,(void*)nodoYaCargado)){ nuevoWorker=list_find(respuestaTransfromacion->workers,(void*)nodoYaCargado); } else{ nuevoWorker = malloc(sizeof(workerDesdeYama)); nuevoWorker->numeroWorker = nodoNuevo; pthread_mutex_lock(&mutex_NodosConectados); infoNodo* infoNod = obtenerNodo(nodoNuevo); nuevoWorker->puerto= infoNod->puerto; nuevoWorker->ip.cadena = strdup(infoNod->ip.cadena); nuevoWorker->ip.longitud = infoNod->ip.longitud; pthread_mutex_unlock(&mutex_NodosConectados); list_add(respuestaTransfromacion->workers,nuevoWorker); nuevoWorker->bloquesConSusArchivos =list_create(); } bloqueNuevo->archivoTemporal.cadena = dameUnNombreArchivoTemporal(jobi->id,bloque->numBloque,TRANSFORMACION,nodoNuevo); bloqueNuevo->archivoTemporal.longitud = string_length(bloqueNuevo->archivoTemporal.cadena); bloqueNuevo->bytesOcupados = bloque->bytesOcupados; bloqueNuevo->numBloque = bloque->numBloque; bloqueNuevo->numBloqueEnNodo = bloque->numBloqueEnNodo; list_add(nuevoWorker->bloquesConSusArchivos,bloqueNuevo); log_trace(logger, "Replanifico bloque %i asignado al worker %i ",bloque->numBloque, nodoNuevo); pthread_mutex_lock(&mutexTablaEstados); bool regEnTabla(registroTablaEstados* reg){ return reg->job == jobi->id && reg->etapa == TRANSFORMACION && reg->bloque==bloque->numBloque; } registroTablaEstados* registroViejo =list_find(tablaDeEstados,(void*)regEnTabla); registroViejo->estado = ERROR; registroTablaEstados* registro = malloc(sizeof(registroTablaEstados)); registro->bloque= bloque->numBloque; registro->estado=EN_EJECUCION; registro->etapa= TRANSFORMACION; registro->job = jobi->id; registro->nodo= nodoNuevo; registro->rutaArchivoTemp = strdup(bloqueNuevo->archivoTemporal.cadena); list_add(tablaDeEstados,registro); pthread_mutex_unlock(&mutexTablaEstados); }
bool hayEspacioSecuencial(int32_t CantidadDePaginas) { CantidadDePaginasCondicion = CantidadDePaginas; bool resultado = list_any_satisfy(espacioLibre,validarEspacioLibre); return resultado; }
//Devuelve el numero de marco para asignar o -1 si no había disponibles int marco_libre(int pid) { log_info(logger, "Se busca un marco libre para asignar"); pid_matchear = pid; int paginaNuevoProceso = pagina_matchear; if (marcos_libres() == 0) { //Si no hay marcos disponibles log_info(logger, "No hay marcos libres para asignar"); if (tiene_marcos_asignados(pid)) { loggearInfo( "El proceso ya tiene marcos asignados, se swappea alguno existente"); //Swappea uno que ya tiene if (es_fifo()) { return fifo(); } if (es_lru()) { return lru(); } int marco = clock_m(); pagina_matchear = paginaNuevoProceso; t_item * itemParaMeter = list_find(tabla_paginas, coincide_pid_y_pagina); list_replace(cola_llegada, posicionVictima, itemParaMeter); loggearInfo("Se remplaza la victima con el nuevo elemento"); return marco; } else { loggearInfo("No hay marcos disponibles para asignar"); //No le puedo dar ninguno, se aborta return -1; } } else { //Hay marcos libres loggearInfo("Hay marcos disponibles para asignar"); int cantidad_maxima_marcos_proceso = config_get_int_value(memoriaConfig, "MAXIMO_MARCOS_POR_PROCESO"); if (marcos_asignados(pid) < cantidad_maxima_marcos_proceso) { loggearInfo( "El proceso tiene menos marcos que la cantidad maxima, se le da uno nuevo"); //Le doy un marco nuevo int marco = marco_disponible(); if (es_clock_modificado()) { //Si es clockModificado me fijo si no tiene presentes, //significa que este que tengo acá en pid_matchear y pagina_matchear //es el único elemento presente y pasa a ser puntero t_item * elementoParaHacerPuntero; bool algunoPresente = list_any_satisfy(tabla_paginas, coincide_pid_y_esta_presente); if (!algunoPresente) { elementoParaHacerPuntero = list_find(tabla_paginas, coincide_pid_y_pagina); elementoParaHacerPuntero->puntero = true; } } return marco; } else { loggearInfo( "El proceso ya tiene la cantidad maxima de marcos, se swappea uno existente"); //Tiene el maximo y necesita swappear uno existente if (es_fifo()) { return fifo(); } if (es_lru()) { return lru(); } int marco = clock_m(); pagina_matchear = paginaNuevoProceso; t_item * itemParaMeter = list_find(tabla_paginas, coincide_pid_y_pagina); itemParaMeter->uso = true; list_replace(cola_llegada, posicionVictima, itemParaMeter); loggearInfo("Se remplaza la victima con el nuevo elemento"); return marco; } } }