/* * LLAMADA AL SISTEMA: sis_dormir */ int sis_dormir() { TipoBCP * procesoAnterior; unsigned int segundos; segundos = (unsigned int) leer_registro(1); /*Asignamos el valor de despertarEnTicks*/ procesoActual->despertarEnTicks = ticks + (segundos*TICK); /*Insertamos el proceso en la lista de dormidos y cambiamos su estado*/ insertarOrdenadoListaBCP(&listaDormidos,procesoActual); procesoActual->estado = BLOQUEADO; /*Cambiamos al siguiente proceso que nos devuelve el planificador*/ procesoAnterior = procesoActual; procesoActual = planificador(); /*En caso de que el proceso recuperado sea NULL, esperamos a que se encuentre el siguiente no NULL*/ while (procesoActual == NULL) { esperaInterrupcion(); procesoActual=planificador(); } /*Cambiamos el estado del proceso y realizamos el cambio de contexto entre los dos procesos*/ procesoActual->estado = EJECUCION; cambio_contexto(&(procesoAnterior->contextoRegs), &(procesoActual->contextoRegs)); return 0; }
/* * Funcion auxiliar que termina proceso actual liberando sus recursos. * Usada por llamada terminar_proceso y por rutinas que tratan excepciones */ void liberarProceso() { TipoBCP * procesoAnterior; liberar_imagen(procesoActual->infoMemoria); /* liberar mapa */ procesoActual->estado=TERMINADO; /* Realizar cambio de contexto */ procesoAnterior=procesoActual; procesoActual=planificador(); while (procesoActual == NULL) { //printk("-> liberarProceso: esperaInterrupcion()\n"); esperaInterrupcion(); //printk("-> liberarProceso: FIN esperaInterrupcion()\n"); procesoActual=planificador(); } printk("-> C.CONTEXTO POR FIN: de %d a %d\n", procesoAnterior->id, procesoActual->id); liberar_pila(procesoAnterior->pila); cambio_contexto(NULL, &(procesoActual->contextoRegs)); return; /* no deberÌa llegar aqui */ }
static void nuevo_proceso(void) { salvar_contexto; planificador(); restaurar_contexto; }
/* * Funcion que realiza una peticion de lectura/escritura * de un caracter al dispositivo de teclado */ int peticionCaracter_teclado(int descDispositivo, char *caracter, int operacion) { TipoDatosPropiosDispositivo_teclado *datosPropiosDispositivo; TipoBCP * proceso; int ret; /* si la operacion NO es de lectura abortar */ if (operacion != OP_READ) { return (-1); } /* obtener datos propios del dispositivo */ datosPropiosDispositivo = (TipoDatosPropiosDispositivo_teclado *) tablaDispositivos[descDispositivo].datosPropiosDispositivo; if ( estaVacioBufferCaracteres(&(datosPropiosDispositivo->bufferCaracteres)) ) { /* si esta vacio bloquear el proceso y seleccionar otro */ proceso = procesoActual; insertarUltimoListaBCP (&(datosPropiosDispositivo->listaProcesosBloqueados),proceso); proceso->estado = BLOQUEADO; procesoActual = planificador(); while (procesoActual == NULL) { esperaInterrupcion(); procesoActual=planificador(); } procesoActual->estado = EJECUCION; /* saltar al otro proceso */ cambio_contexto(&(proceso->contextoRegs), &(procesoActual->contextoRegs)); } /* cuando vuelva a ejecutar, obtener caracter y terminar con exito*/ ret = extraerBufferCaracteres(&(datosPropiosDispositivo->bufferCaracteres),caracter); return (ret); }
/*--------------------------------------------------------------------------*/ static int sys_kill_bill(void) { /* by tarantino */ struct PCB *tmp = (void *)0; unsigned long dir; unsigned int desplazamiento; unsigned int segmento; int pid = current->contexto->cx; int senal = current->contexto->dx; if (pid < 1 || pid == current->pid) return EINVAL; /* no podemos matar al proceso 0 */ if ((tablaprocesos[pid].estado) == PCB_LIBRE) return 0; if (senal == SIGKILL) { tablaprocesos[pid].estado = PROCESO_KILL; current = tablaprocesos + pid; planificador(); } else if (senal == SIGUSR) { if (tablaprocesos[pid].signal != 0) { tmp = tablaprocesos + pid; segmento = (unsigned int)tmp->contexto->cs; desplazamiento = (unsigned int)tmp->signal; asm { mov bx, segmento push bx mov bx, desplazamiento push bx push bp mov bp,sp call dword ptr [bp+2] pop bp pop bx pop bx pop bx } } else { return 0;