Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
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);
	}
Exemplo n.º 4
0
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 *) &parametros)) {
        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;
}