/*             ** SECCION  DE INTERFAZ PUBLICA DE KMOS **          */
/* Este  archivo cabecera (KMOSPUB.H) contiene el interfaz público */
/* de exportación, visible al usuario, proporcionada por KMOS      */
/* para su propia implementación y la de las rutinas de usuario    */
/* (aplicaciones) */

/* Tipos públicos de KMOS */
typedef struct k_mens {             /* Prototipo de mensaje            */
  struct k_mens *enlace;            /* enlace para mensajes en buzones */
  int mtipo;                        /* tipo de mensaje                 */
  void *cuerpo;                     /* puntero al cuerpo del mensaje   */
} k_mens, *k_ptrmens;

typedef char procnombre[9];  /* nombre de proceso, limite  9 caracteres*/
typedef unsigned int palabra;    /* tipo generico unsigned int, PALABRA*/
typedef void * puntero;             /* tipo generico puntero           */

/* variables públicas de KMOS  */
extern puntero k_bziniv0;         /*  buzón para interrupciones de nivel_0 */
extern puntero k_bziniv1;         /*  buzón para interrupciones de nivel_1 */
extern puntero k_bziniv2;         /*  buzón para interrupciones de nivel_2 */
extern puntero k_bziniv3;         /*  buzón para interrupciones de nivel_3 */
extern puntero k_bziniv4;         /*  buzón para interrupciones de nivel_4 */
extern puntero k_bziniv5;         /*  buzón para interrupciones de nivel_5 */
extern puntero k_bziniv6;         /*  buzón para interrupciones de nivel_6 */
extern puntero k_bziniv7;         /*  buzón para interrupciones de nivel_7 */


/* Servicio públicos de KMOS, invocables por usuario */

/** K_CREARBUZON ** crea un buzón, inicializando el descriptor  */
/* de buzón cuya dirección se le pasa como parámetro.           */

extern puntero k_crearbuzon (void);


/** K_ENVIAR ** entrega un mensaje, cuya dirección se le pasa como   */
/* segundo parámetro, al primer proceso que esté esperando en el     */
/* buzón designado cuya dirección se le pasa como primer parámetro . */
/* K_ENVIAR es no-bloqueante y los mensajes que tengan que esperar se*/
/* guardan en cola en orden FIFO  */

extern void k_enviar (puntero buzon, k_ptrmens mensaje);


/** K_RECIBIR es una función que entrega al proceso que la invoca */
/* el primer mensaje de la cola asociada al buzón cuya dirección  */
/* se le pasa como primer parámetro. Ignora el segundo parámetro. */
/* K_RECIBIR es bloqueante.                                       */

extern k_ptrmens k_recibir (puntero buzon, int limite);


/** K_CREARPROC ** crea un Bloque de Control de Proceso para un       */
/* un proceso cuyos atributos se le pasan como parámetros. El proceso */
/* es colocado luego en la lista de Preparados. Los parámetros de     */
/*  invocación son:                                                   */
/*   1. (ptrproc) apunta a la dirección inicial del código del proceso*/
/*   2. (pnombre) nombre del proceso, cadena <= 9 caracteres          */
/*   3. (longpila) longitud de pila de proc., normalmente de 80 a 255 */
/*   4. (prioridad) prioridad del proceso : 0-máxima, 255-mínima      */

extern void far *k_crearproc (puntero ptrproc, procnombre pnombre,
                         palabra longpila, int prioridad);


/** K_ELIMINARPROC ** elimina (finaliza) el proceso invocante.     */
/* Este es el servicio de terminacion que proporciona KMOS.        */

extern void k_eliminarproc(void);


/** K_RETARDAR ** retarda el proceso invocante durante el número de */
/* tics del reloj del sistema que se le pasa como parámetro.        */

extern void k_retardar (int tics);


/** K_HABILNVL ** hace que el nivel de interrupción hardware, que se */
/* le pasa como parámetro, sea elegible para activación. No hace nada*/
/* si el nivel no es válido (los niveles válidos en el PC son 0-7 ). */
/* La habilitación de un nivel ya habilitado  no tiene ningún efecto.*/

extern void k_habilnvl (int nivel);


/** KMOSINICIAL ** inicializa las estructuras internas de KMOS. Debería */
/* ser invocado sólo una vez desde el código principal (main) de usuario*/
/* antes de la invocación de cualquier servicio de KMOS                 */
/* (véanse las demos).                                                  */

extern void kmosinicial(void);


/** KMOSINICIAR ** iniciación de KMOS; establece el entorno del sistema.*/
/* Debería ser invocado sólo una vez desde el código de usuario, como   */
/* última sentencia de la sección de iniciación (main) de usuario.      */

extern void kmosiniciar(void);

/*
 * cpc: servicios añadidos para la práctica 
 */

/*
 * k_terminar(retval)
 *      Vuelve a MS-DOS como si se hubiese invocado exit(retval)
 *      en un programa corriente.
 *
 * Entrada: valor de retorno para exit
 */
void k_terminar(int retval);

/*
 * k_cola_enviar()
 *    Enviar un mensaje a un servidor
 *
 * Si el servidor no esta esperando el mensaje, se bloquea al invocador.
 *
 * Entrada: proceso receptor, 
 *          direccion del buffer de origen, 
 *          tamanyo del buffer
 */
void k_cola_enviar(void *receptor, void *datos, unsigned nbytes);

/*
 * k_cola_recibir()
 *    Recibir un mensaje de la cola
 *
 * Si no hay mensajes disponibles, se bloquea al proceso.
 *
 * Entrada: direccion del buffer de destino, tamanyo del buffer
 */
unsigned k_cola_recibir(void *datos, unsigned nbytes);
