Diseño de Sistemas Operativos Tema 8. Gestión de Interrupciones Concurso a la Plaza de Profesor...

Post on 24-Jan-2016

219 views 0 download

Transcript of Diseño de Sistemas Operativos Tema 8. Gestión de Interrupciones Concurso a la Plaza de Profesor...

Diseño de Sistemas Operativos

Tema 8.

Gestión de Interrupciones

Concurso a la Plaza de Profesor Titular de Universidad DF 1452/TUÁrea de Conocimiento: Física Aplicada

Juan Carlos Pérez DariasDiciembre 2003

2

Diseño de Sistemas Operativos1. Introducción al Sistema Operativo Unix

2. Optimización de prestaciones: Buffer cache

3. Gestión de ficheros y directorios

4. Interfaz de acceso al subsistema de Entrada/Salida

5. Controladores de dispositivos

6. Procesos e hilos

7. Gestión de memoria

8. Gestión de interrupciones9. Gestión de procesos

10. Planificación de procesos

11. Comunicación entre procesos

12. Introducción a los sistemas operativos distribuidos

Bloque 1: Subsistema de Entrada/Salida

Bloque 2: Subsistema de procesos

Bloque 3: Sistemas operativos distribuidos

Pro

gra

ma d

e t

eorí

a

3

Esquema general

A

B

Tem

a 8

. G

est

ión d

e inte

rru

pci

ones

4

Índice

8.0 Repaso conceptos básicos

8.1 Interrupciones y excepciones

8.2 Llamadas al sistema

8.3 Señales

8.4 ResumenTem

a 8

. G

est

ión d

e inte

rru

pci

ones

5

Introducción

Estructura interna de un proceso en Linux

int main (int argc, char** argv) { int i, size, status,n_sons = 0; pid_t name_sons[16];  do { rank = fork(); name_sons[n_sons] = rank; n_sons++; } while ((rank != 0) && (n_sons < 16));  if (rank != 0) waitpid (name_sons[15], &status, 0); else Multiplica(); return (0);

}código

datos

pila

4 Gb

Modo usuario 0

3 Gb

8.0

. R

epaso

de c

once

pto

s bási

cos

6

Introducción

Estructura interna de un proceso en Linux

código

datos

pila

int main (int argc, char** argv) { int i, size, status,n_sons = 0; pid_t name_sons[16];  do { rank = fork(); name_sons[n_sons] = rank; n_sons++; } while ((rank != 0) && (n_sons < 16));  if (rank != 0) waitpid (name_sons[15], &status, 0); else Multiplica(); return (0);

}

código kernel

datos kernel

pila kernel

Modo usuario

Interrupción

Llamada sistema

asmlinkage void schedule(void){struct schedule_data * sched_data;struct task_struct * prev, * next;int this_cpu;prev = current;/* move an exhausted RR process to be last.. */prev->need_resched = 0;if (!prev->counter && prev->policy == SCHED_RR) {prev->counter = prev->priority;move_last_runqueue(prev);}switch (prev->state) {case TASK_INTERRUPTIBLE:

Modo

kernel

0

4 Gb

3 Gb

8.0

. R

epaso

de c

once

pto

s bási

cos

7

Introducción

Estructura interna de un proceso en LinuxEl kernel se “mapea” en todos los procesos

Cuando se ejecuta en modo kernel se ejecuta en el modo supervisor del procesadorArquitectura Intel:

Anillo 0: KernelAnillo 3: Procesos usuario

código A

datos A

pila A

código B

datos B

pila B

código kernel

datos kernel

código kernel

datos kernelpila kernel

código kernel

datos kernelpila kernel

Pro

ceso

AP

roceso B

Kernel

8.0

. R

epaso

de c

once

pto

s bási

cos

8.1. Interrupciones y excepciones

val = a/0;

9

Esquema

Interrupciones y excepciones

Introducción

Soporte hardware para la gestión de interrupciones

Gestión de interrupciones y excepciones en Linux

Gestión de excepciones

Gestión de interrupciones

Procedimientos diferidos: Bottom Half

Finalización de gestión de interrupciones y excepciones

8.1

. In

terr

upci

ones

y e

xce

pci

ones

10

Introducción

Interrupción:Evento que altera la secuencia de instrucciones ejecutadas por el procesador

Clasificación de interrupciones:Interrupciones síncronas (excepciones):

Producidas por la unidad de control de la CPU mientras se ejecutan instrucciones.

Se producen después de la ejecución de una instrucción.

Interrupciones asíncronas (interrupciones):Son generadas por otros dispositivos hardware

Se producen de forma independiente a las señales de reloj de la CPU

8.1

. In

terr

upci

ones

y e

xce

pci

ones

a=a/0

11

Introducción

Situación típica:Interrupción de reloj

8.1

. In

terr

upci

ones

y e

xce

pci

ones

var=3;If(var>2) printf(“mayor”);

var=3;If(var>2) printf(“mayor”);

Código de usuarioCódigo de usuario

jiffies++; lost_ticks++;

mark_bh(TIMER_BH);

jiffies++; lost_ticks++;

mark_bh(TIMER_BH);

Código de kernelCódigo de kernel

12

Introducción

Aspectos a considerar:Las interrupciones pueden llegar en cualquier instante

El kernel necesita atenderlas lo más rápidamente posibleAcciones urgentes: top-half

Acciones diferidas: bottom-half

Ejemplo:

Marca la presencia de los datos

Continúa con las operaciones previas

Realiza el resto del procesado de la interrupción

8.1

. In

terr

upci

ones

y e

xce

pci

ones

13

Introducción

Aspectos a considerarLas interrupciones pueden producirse mientras se está atendiendo otras interrupciones/excepciones

Secciones críticas

8.1

. In

terr

upci

ones

y e

xce

pci

ones

Ejecución anidada de interrupciones

Bloqueo de interrupciones

14

Introducción

Secciones críticas

8.1

. In

terr

upci

ones

y e

xce

pci

ones

Ejecución anidada de interrupciones

Bloqueo de interrupciones

Gestor de interrupciones 1:

• Insertar elemento en lista

C

BA

Gestor de interrupciones 2:

• Buscar elemento en lista

15

Soporte hardware

Interrupciones y excepciones en IntelCada interrupción o excepción se identifica con un número de 0 a 255 vector de interrupción

Linux usa los siguientes vectores

8.1

. In

terr

upci

ones

y e

xce

pci

ones

Excepciones

0 31

Interrupciones

32 47

Inter. software

48 255

Llamadas al sistema

128

16

Soporte hardware

Tabla de Descriptores de Interrupción

8.1

. In

terr

upci

ones

y e

xce

pci

ones

descriptor 1

descriptor 2

descriptor nAsocia cada vector de interrupción o excepción con la dirección del gestor correspondiente

Dirección de la función

Permisos

IDTR

17

Soporte hardware

Gestión hardware de interrupciones y excepcionesAntes de ejecutar una instrucción se comprueba si se ha producido una excepción o interrupción.

1. Determina el vector (0 i 255) asociado

2. Lee la entrada i de la IDT y obtiene la dirección de la función que atiende ese evento

3. Comprueba los permisos asociados. No se puede atender una interrupción en un nivel de protección inferior a donde se produce

4. Si CPL DPL Se cambia a la pila del nivel específico (pila de kernel)

8.1

. In

terr

upci

ones

y e

xce

pci

ones

18

Soporte hardware

Gestión hardware de interrupciones y excepcionesCambio de pila

8.1

. In

terr

upci

ones

y e

xce

pci

ones

valor=suma*3; for(i=0; i<100;i++)

valor=valor+ i;

valor=suma*3; for(i=0; i<100;i++)

valor=valor+ i;

Código de usuarioCódigo de usuario

marco main()

marco func1()

Pila u

suario

posx = x+desp; posy = y – desp;

posx = x+desp; posy = y – desp;

Código de kernelCódigo de kernel

jiffies++; lost_ticks++;

mark_bh(TIMER_BH);

jiffies++; lost_ticks++;

mark_bh(TIMER_BH);

Código de kernelCódigo de kernel

marco raton()

Pila kernel

Cambiopila

marco reloj()

19

Soporte hardware

Gestión hardware de interrupciones y excepcionesAntes de ejecutar una instrucción se comprueba si se ha producido una excepción o interrupción.

1. Determina el vector (0 i 255) asociado

2. Lee la entrada i de la IDT y obtiene la dirección de la función que atiende ese evento

3. Comprueba los permisos asociados. No se puede atender una interrupción en un nivel de protección inferior a donde se produce

4. Si CPL DPL Se cambia a la pila del nivel específico (pila de kernel)

5. Invoca la función gestora

8.1

. In

terr

upci

ones

y e

xce

pci

ones

20

Gestión de excepciones

Gestión de excepciones en LinuxLinux aprovecha las excepciones para conseguir dos objetivos:

Enviar una señal a un proceso para notificar una condición anómala

Implementar la estrategia de paginación bajo demanda

8.1

. In

terr

upci

ones

y e

xce

pci

ones

var=0; temp=suma/var;

printf(“%d”, temp);

var=0; temp=suma/var;

printf(“%d”, temp);

Código de usuarioCódigo de usuario

Proceso

Señal

SIGPFE

21

Gestión de excepciones

Gestión de excepciones en LinuxLos gestores de excepciones tienen una estructura estándar

que consiste en tres fases:

1. Guarda los contenidos de la mayoría de los registros en la pila de kenel

8.1

. In

terr

upci

ones

y e

xce

pci

ones

Pila kernel

Cont. Programa (pc)

pila usuario (sp)

Registros (A,B,...)

Cont. Programa (pc)

pila usuario (sp)

Registros (A,B,...)

Registros procesador

Gestión de excepción

22

Gestión de excepciones

Gestión de excepciones en LinuxLos gestores de excepciones tienen una estructura estándar

que consiste en tres fases:

1. Guarda los contenidos de la mayoría de los registros en la pila de kenel

2. Invoca a la función correspondiente: do_excepcion

8.1

. In

terr

upci

ones

y e

xce

pci

ones

Pila kernel

Cont. Programa (pc)

pila usuario (sp)

Registros (A,B,...)

Cont. Programa (pc)

pila usuario (sp)

Registros (A,B,...)

Registros procesador

Gestión de excepción

do_excepcion

pila kernel (sp)

Registros (A,B,...)

do_excepcion ()

23

Gestión de excepciones

Gestión de excepciones en LinuxLos gestores de excepciones tienen una estructura estándar

que consiste en tres fases:

1. Guarda los contenidos de la mayoría de los registros en la pila de kenel

2. Invoca a la función correspondiente: do_excepcion

3. Continúa la ejecución en la siguiente instrucción

8.1

. In

terr

upci

ones

y e

xce

pci

ones

24

Gestión de interrupciones

Gestión de interrupciones en Linux

Consideraciones previas:

Las interrupciones pueden llegar en cualquier instante

Con frecuencia, no están relacionadas con el proceso al cual interrumpen. Ejemplo: Transferencia de datos de disco

Por limitaciones hardware, varios dispositivos pueden compartir la misma línea de interrupciones (IRQ)

El vector de interrupciones no es suficiente

Se asocian varias “rutinas de servicio de interrupciones” a un gestor

Cuando ocurre una interrupción, no todas las acciones tienen la misma urgencia.

8.1

. In

terr

upci

ones

y e

xce

pci

ones

25

Gestión de interrupciones8.1

. In

terr

upci

ones

y e

xce

pci

ones

PIC

IRQn

IDT[32+n]

Procedimiento de gestión

1. Guardar el valor de IRQ y el contenido de los registros en la pila de kernel

2. Enviar el acuse de recibo de la interrupción al PIC, permitiendo que éste atienda nuevas interrupciones

3. Ejecutar las rutinas de servicio de interrupciones asociadas con todos los dispositivos asociados a la IRQ

4. Finalizar la gestión

ISR 1 ISR 3ISR 2

descriptor n

Estructuras involucradas

26

Procedimientos diferidosProcedimientos diferidos: Bottom-halves

Un procedimiento diferido es una función de baja prioridad que espera a que el kernel encuentre un momento conveniente para ejecutarse.

Este mecanismo permite al sistema operativo la gestión rápida de las interrupciones de múltiples dispositivos.

Los procedimientos diferidos se ejecutan cuando:

Finaliza la gestión de una llamada al sistema

Finaliza la gestión de una excepción

Finaliza la gestión de una interrupción

Cuando se desplanifica a un proceso

Implementación:Lista de funciones por bottom-half

8.1

. In

terr

upci

ones

y e

xce

pci

ones

Timer

Red

Teclado

Tim_1 Tim_2 Tim_3

Net_2Net_1

27

Finalización de la gestión

Procedimiento:

8.1

. In

terr

upci

ones

y e

xce

pci

ones

Bottom

half?Ejecuta los

procedimientos

No

Gestión de interrupción

o excepción

Interrupciones

anidadas

Si

Recupera contexto hardware

marco raton()

Pila kernel

marco reloj()

marco raton()

posx = x+desp; posy = y – desp;

posx = x+desp; posy = y – desp;

Código de kernelCódigo de kernel

gestor ratón

jiffies++; lost_ticks++;

mark_bh(TIMER_BH);

jiffies++; lost_ticks++;

mark_bh(TIMER_BH);

Código de kernelCódigo de kernel

gestor reloj

28

Finalización de la gestión

Procedimiento:

8.1

. In

terr

upci

ones

y e

xce

pci

ones

Bottom

half?Ejecuta los

procedimientos

Si

No

Gestión de interrupción

o excepción

Interrupciones

anidadas

Si

Recupera contexto hardware

Si Planificador schedule()

Planificación

No

Si Gestor señales do_signal()

señales

No

8.2. Llamadas al sistema

read(fd,buf,5)

write(f,buf2,3)

30

Esquema

Llamadas al sistema

Introducción

Visión de las llamadas al sistema desde el espacio de usuario

Implementación a nivel de núcleo de las llamadas al sistema

8.2

. Ll

am

ad

as

al si

stem

a

31

Introducción

Llamadas al sistema:Interfaz entre los procesos que se ejecutan en modo usuario y los dispositivos hardware

Objetivos:Facilita la programación de aplicaciones

Aísla al programador de las características de bajo nivel de los dispositivos

Incrementa la seguridad del sistema

El acceso a las zonas claves se realiza a través de un conjunto bien definido de funciones

Incrementa la portabilidad de las aplicaciones

Las aplicaciones pueden ser compiladas en otros sistemas que ofrezcan la misma interfaz

8.2

. Ll

am

ad

as

al si

stem

a

32

Visión general de las llamadas

pid=fork();

8.2

. Ll

am

ad

as

al si

stem

a

modo usuario

modo kernel

open() { }fork(){ }

libc

sys_open() { }sys_ fork(){ }

Interrupción software

33

Visión desde el espacio de usuario

La biblioteca libc contiene todas las llamadasOculta los detalles de la implementación de la llamada en la arquitectura correspondiente

Se invoca de forma análoga a cualquier función en CRecogen el código de retorno en la variable errno.

Inicialmente mantenida por Linus Torvalds. Actualmente se utiliza la librería de GNU (glibc)El código de la biblioteca no se encuentra en espacio de kernelDos versiones:

Librería estática: libc.aLibrería dinámica: libc.so

Se puede obtener todos los ficheros que la componen:# ar t /usr/lib/libc.a

8.2

. Ll

am

ad

as

al si

stem

a

34

Implementación de la biblioteca

Implementación de la interfaz ofrecida al usuario:En la arquitectura i386 se utiliza la instrucción int 0x80 como puerta única de entrada al núcleo.

Un proceso en modo usuario no puede acceder al espacio de direcciones del kernel:

En el registro A (eax) se especifica el código de la llamadaCada llamada tiene un código estático que la representa

En caso de tener que pasar algún parámetro en la llamada, se realiza a través de los registros del procesador

Arg 1 Registro ebx

Arg 2 Registro ecx

Arg 5 Registro edi

Si se necesitan más parámetros se interpreta el último como una dirección donde reside el resto de los parámetros

8.2

. Ll

am

ad

as

al si

stem

a

35

Implementación de la biblioteca

Implementación de la interfaz ofrecida al usuario:

Código de retorno:En la arquitectura i386 se devuelve el código de retorno en el registro eax

Cuando ocurre un error valor negativoCopia el valor ( entre –1 y – 125 ) a la variable global errno

Devuelve –1 como valor de retorno de la función

La variable errno contiene el código de error de la última llamada al sistema que falló (-eax)

Si no existe error:Devuelve como código de retorno el valor almacenado en eax8

.2.

Llam

ad

as

al si

stem

a

36

4. Tratamiento de errores

y código de retorno

3. Interrupción software:

Entrada al kernel

2. Código de la llamada en registro eax

1. Copia de parámetros a los registros

Implementación de la biblioteca Ejemplo: num=read(fd,buf,count);

# ar x /usr/lib/libc.a read.o

# objdump –d read.o

8.2

. Ll

am

ad

as

al si

stem

a read.o: file format elf32-i386

Disassembly of section .text:

00000000 <__libc_read>:

0: 53 push %ebx

1: 8b 54 24 10 mov 0x10(%esp,1),%edx

5: 8b 4c 24 0c mov 0xc(%esp,1),%ecx

9: 8b 5c 24 08 mov 0x8(%esp,1),%ebx

d: b8 03 00 00 00 mov $0x3,%eax

12: cd 80 int $0x80

14: 5b pop %ebx

15: 3d 01 f0 ff ff cmp $0xfffff001,%eax

1a: 0f 83 fc ff ff ff jae 1c <__libc_read+0x1c>

20: c3 ret

37

Implementación en el kernel

Situación de entrada al núcleo

main() { •••num=read(fd,buf,count); •••

8.2

. Ll

am

ad

as

al si

stem

a

código A

datos A

marco main()

marco read()pila

usuario

mov 0xc(%esp,1),%ecxmov 0x8(%esp,1),%ebxmov $0x3,%eaxint $0x80pop %ebx

system_call: sys_read()ret_from_sys_call:iret

int $0x80

código A

datos A

marco main()

marco read()

Pila kernel

marco sys_read()

• Parámetros de la función (fd, buf, count)

• Dirección retorno

38

Implementación en el kernel

Gestión de la llamada al sistemaLa llamada al sistema se produce cuando se ejecuta la instrucción int 0x80 Interrupción

Misma interrupción para todas las llamadas al sistemaPermite implementar un número ilimitado de llamadas

Necesita algún mecanismo para diferenciar llamadas

Se accede al vector de interrupciones 128 de la IDT

La función asociada a esta interrupción es system_call:Guarda los contenidos de los registros en la pila de kernel

Se comprueba si el número de llamada es válido o no está implementada la función asociada

Invoca a la rutina de servicio correspondientecall *SYMBOL_NAME(sys_call_table)(,%eax,4)

Se finaliza la gestión de la llamada:ret_from_sys_call

8.2

. Ll

am

ad

as

al si

stem

a

sys_exit()sys_fork()sys_read()sys_write()sys_open()

39

Implementación en el kernel

Finalización de las llamadas: ret_from_sys_callDurante la ejecución de la llamada pudieron haber ocurrido distintos eventos

Operaciones de Entrada/Salida

Aparición de otros procesos más prioritarios

Interrupciones de reloj, ...

Se comprueba si alguno de estos eventos hace necesario desplanificar al proceso:

Variable need_resched planificadorSe comprueba si el proceso ha recibido alguna señal

Atiende la señal

Se copia el código de retorno en el registro eax

Se recupera el contexto de registros salvados en la pila

8.2

. Ll

am

ad

as

al si

stem

a

Continúa la ejecución en modo usuario

8.3. Señales en Unix

proceso A proceso B

kernel

41

Esquema

8.3. Señales

Introducción

Fuentes de señales

Estructuras del núcleo para la gestión de señales

Envío de una señal

Recepción de una señal

Tratamiento de las señales8.3

. Señale

s

42

Introducción

Señales en Unix:

Una señal es un mensaje corto que puede ser enviado a un proceso o grupo de procesos

Se utilizan para comunicar eventos del sistema a los procesos

Constituyen un mecanismo primitivo de comunicación entre procesos

No proporciona más información que el tipo de señal

Presentes en los sistemas Unix durante más de 30 años

La interfaz de programación, el comportamiento y la implementación interna varían de una versión de Unix a otra

8.3

. Señale

s

43

Introducción

Características de las señales:Pueden ser enviadas a un proceso en cualquier instante independientemente del estado del proceso receptor

Cuando se envían a procesos que no están ejecutándose, deben ser almacenadas para atenderlas cuando el proceso continúe su ejecución

Sólo se “recuerda” la recepción de una señal

Pueden ser selectivamente bloqueadas por un procesoEl proceso no recibirá la señal hasta que la desbloquee

Cuando un proceso “atiende” una señal, por defecto la bloquea hasta que finalice la gestión de la misma

Evita un “anidamiento” de señales

8.3

. Señale

s

44

Fuentes de señales

Las señales se originan por diversas situaciones:Exepciones

Otros procesosLlamada al sistema kill

Interrupciones de terminal

8.3

. Señale

s

a=b/0 excepción

Instrucción ilegal

kernel

señal

SIGINT

Ctrl+C

45

Fuentes de señales

Las señales se originan por diversas situaciones:Control de ejecución:

Alarmas

8.3

. Señale

s

pid=fork(); if(pid>0)

wait (status);

pid=fork(); if(pid>0)

wait (status);

CódigoCódigo pid=fork(); if(pid>0)

wait (status); else exit(0);

pid=fork(); if(pid>0)

wait (status); else exit(0);

CódigoCódigoSIGCLD

padre hijo

SIGALRM

46

Estructuras de datos asociadas

Representación de los procesos en Linux

Task_structInformación de cada proceso:

ycpidppidpid

Identificación del proceso o hilo

• Número de identificación (pid)

• Relación con otros procesos

•Padre, hermanos

ycpidppidpid

need_reschedprioritycounter

Parámetros de planificación

• prioridad

• tiempo ejecutadoneed_reschedprioritycounter

Gestión de señales

• Señales

• Bloqueadas

• Pendientes

• Gestión

gestiónpendientesbloqueadas

señales

gestiónpendientesbloqueadas

señales

8.3

. Señale

s

47

Estructuras de datos asociadas

Estructuras de datos para la gestión de señales

Task_structInformación de cada proceso:

ycpidppidpid

need_reschedprioritycounter

gestiónpendientesbloqueadas

señales

Array de 64 bits (1 por cada señal pendiente)

Array de señales bloqueadas

0: No hay señales pendientes

1: Existe alguna señal pendiente

hand_sighup()

hand_sigint()

0

1

mifunc()

Funciones que atienden las señales:

• 0: Acción por defecto

• 1: Ignora la señal

8.3

. Señale

s

48

Envío de señales

Primera fase de la gestión de señales: EnvíoUn proceso recibe una señal porque:

El kernel le notifica un evento (excepción, interrupción)

Otro proceso envía la señal (llamada al sistema kill)

La señal puede ir destinada al proceso que se está ejecutando u a otro proceso (activo o en estado dormido)

Procesos dormidos:Los procesos duermen a la espera de un determinado evento

Finalización de una operación de E/S

Liberación de recursos del sistema, ...

Dependiendo de la certeza en la que se produzca el evento, se clasifican:

Procesos ininterrumpibles: Existe seguridad que el evento ocurra

Procesos interrumpibles: La ocurrencia del evento no es segura

Introducción de datos desde teclado

Liberación de un semáforo de usuario, ...

Estos procesos despiertan al recibir una señal

Rec

orda

tori

o

8.3

. Señale

s

49

Envío de señales

Procedimiento de envío de señalesObjetivo: Comunicarle a un proceso t la ocurrencia de un determinado evento n

1. Comprobación de parámetrosNúmero de señal correcta ( 0 < n < 64)

2. Comprobación de permisosSi la señal es enviada por un proceso en modo usuario

8.3

. Señale

s

Usuario Juan

Usuario María

Un proceso en modo usuario (salvo el superusuario) sólo puede enviar señales a procesos de su propiedad

50

Envío de señales

Procedimiento de envío de señalesObjetivo: Comunicarle a un proceso t la ocurrencia de un determinado evento n

1. Comprueba los parámetrosNúmero de señal correcta ( 0 < n < 64)

2. Comprueba los permisosSi la señal es enviada por un proceso en modo usuario

3. Comprueba si el proceso destino t ignora la señal n

8.3

. Señale

s

task

_str

uct

pro

ceso

t

ycpidppidpid

need_reschedprioritycounter

gestiónpendientesbloqueadas

señaleshand_sighup()

hand_sigint()

0

1

mifunc()

01

2

3

n handler

handler = 1

Ignora la señal

51

Envío de señales

Procedimiento de envío de señalesObjetivo: Comunicarle a un proceso t la ocurrencia de un determinado evento n

1. Comprueba los parámetrosNúmero de señal correcta ( 0 < n < 64)

2. Comprueba los permisosSi la señal es enviada por un proceso en modo usuario

3. Comprueba si el proceso destino t ignora la señal n

4. Activa el bit correspondiente a la señal8.3

. Señale

s

task

_str

uct

pro

ceso

t

ycpidppidpid

need_reschedprioritycounter

gestiónpendientesbloqueadas

señales

Array de 64 bits

0 1 2 3 4 n

1

pendientes = 1

52

Envío de señales

Procedimiento de envío de señalesObjetivo: Comunicarle a un proceso t la ocurrencia de un determinado evento n

1. Comprueba los parámetrosNúmero de señal correcta ( 0 < n < 64)

2. Comprueba los permisosSi la señal es enviada por un proceso en modo usuario

3. Comprueba si el proceso destino t ignora la señal n

4. Activa el bit correspondiente a la señal

5. Si el proceso está durmiendo en una prioridad interrumpible

8.3

. Señale

s

Despierta al proceso

53

Recepción de señales

Instante de recepciónUn proceso necesita estar ejecutándose para comprobar la presencia de señales pendientes

La detección de señales se realiza en ciertos puntos durante la ejecución de un proceso

Cuando finaliza la ejecución de una llamada al sistema

Cuando finaliza la gestión de una interrupción o excepción

Cuando se ejecuta un proceso que estaba en estado “dormido”

Procedimiento de detección:8.3

. Señale

s

task

_str

uct

pro

ceso

t

ycpidppidpid

need_reschedprioritycounter

gestiónpendientesbloqueadas

señales

pendientes = 1

Señal pendiente de

gestionar

pendientes

54

Tratamiento de las señales

Acciones que se realizan cuando se recibe una señal

Los procesos pueden reaccionar de dos formas cuando detectan que han recibido una señal:

Ejecutar la acción por defecto asociada a la señal

Abortar el proceso (Ej. Señal SIGINT)

Generar un fichero (core) con el estado actual de ejecución del proceso y abortar el proceso (Ej. violación segmento SIGSEGV)

Ignorar la señal

Detener el proceso

Continuar el proceso

Atrapar la señal

La señal se atiende ejecutando una función especificada por el usuario

Las señales KILL y STOP no pueden ser atrapadas

8.3

. Señale

s

55

Tratamiento de las señales

Ejecución de la acción por defectoDetener el proceso

Situación típica utilizada por los depuradores

8.3

. Señale

s

hijo(depurado)

task

_str

uct

pro

ceso

t

estadoppidpid

need_reschedprioritycounter

gestiónpendientesbloqueadas

señales

estado = STOPPED

padre(depurador)

señal

56

Tratamiento de las señales

Ejecución de la acción por defectoDetener el proceso

Situación típica utilizada por los depuradores

Continuar el proceso

8.3

. Señale

s

hijo(depurado)

task

_str

uct

pro

ceso

t

estadoppidpid

need_reschedprioritycounter

gestiónpendientesbloqueadas

señales

estado = RUNNING

57

Tratamiento de las señales

Ejecución de la acción por defectoDetener el proceso

Situación típica utilizada por los depuradores

Continuar el proceso

Abortar el procesoInvoca la función do_exit() para finalizar el proceso

Abortar el proceso y generar fichero core

8.3

. Señale

s

datos A

marco main() datospila

datos

datos A

marco main()

código A

datos A

marco main()

fichero core

do_exit()

zombie

58

Tratamiento de las señales

Captura de la señalImplica la ejecución de una función de usuario para atender la señal.

Situación complejaInsertar código de usuario dentro del ciclo de ejecución en modo kernel

Cambios de pilas de ejecución

8.3

. Señale

s main(){signal(SIGINT,funcion); while(1);}

main(){signal(SIGINT,funcion); while(1);}

Código de usuarioCódigo de usuario

/* gestión interrup. do_signal();}

/* gestión interrup. do_signal();}

Código de kernelCódigo de kernel

CTRL+C

void funcion(){printf(“hola mundo”);}

void funcion(){printf(“hola mundo”);}

Código de usuarioCódigo de usuario

59

Tratamiento de las señales

Captura de la señalSolución propuesta en Linux

Situación cuando se atiende la señal:

8.3

. Señale

s

marco main()

pila usuario pila kernel

Info retorno

do_signal

Gestión

CTRL+C

60

Tratamiento de las señales

Captura de la señalSolución propuesta en Linux

1. Añadir nuevo marco a la pila de usuarioIncluir los parámetros de la función que atiende la señal

Copiar los parámetros de retorno almacenados en la pila de kernel

Poner como dirección de retorno, la dirección de la llamada al sistema sigreturn

8.3

. Señale

s

1. Modificar la pila de usuario

marco main()

pila usuario pila kernel

Info retorno

do_signal

parámetros func

Info retorno

Info retornoInfo retorno

parámetros funcinfo retornoparámetros funcinfo retornosigreturn()

61

Tratamiento de las señales

Captura de la señalSolución propuesta en Linux

1. Añadir nuevo marco a la pila de usuario

2. Modificar la pila de kernelPoner como dirección de retorno a modo usuario, la dirección de la función que gestiona la señal

8.3

. Señale

s

2. Modificar la dirección de retorno de la pila de kernel

pila kernel

Info retorno

do_signal

parámetros funcparámetros funcinfo retorno

marco main()

pila usuario

parámetros funcinfo retornosigreturn()

dirección func

62

Tratamiento de las señales

Captura de la señalSolución propuesta en Linux

1. Añadir nuevo marco a la pila de usuario

2. Modificar la pila de kernel

3. Ejecutar la función gestora de la señalSe ejecuta el código de usuario

Al finalizar, la dirección de retorno apunta a la llamada al sistema sigreturn

8.3

. Señale

s

3. Ejecutar la función que atiende la señal

marco main()

pila usuario

parámetros funcinfo retornosigreturn()

void funcion(){printf(“hola mundo”);}main(){signal(SIGINT,funcion); while(1);}

void funcion(){printf(“hola mundo”);}main(){signal(SIGINT,funcion); while(1);}

Código de usuarioCódigo de usuario

63

Tratamiento de las señales

Captura de la señalSolución propuesta en Linux

1. Añadir nuevo marco a la pila de usuario

2. Modificar la pila de kernel

3. Ejecutar la función gestora de la señal

4. Ejecutar la llamada al sistemaCopia la información de retorno almacenada en la pila de usuario

Vuelve a modo usuario

8.3

. Señale

s

3. Ejecutar la función que atiende la señal

marco main()

pila usuario

parámetros funcinfo retornosigreturn()

pila kernel

sys_sigreturn

info retornoinfo retorno

info retorno

info retorno info retorno

64

Tratamiento de las señales

Captura de la señalSolución propuesta en Linux

1. Añadir nuevo marco a la pila de usuario

2. Modificar la pila de kernel

3. Ejecutar la función gestora de la señal

4. Ejecutar la llamada al sistemaCopia la información de retorno almacenada en la pila de usuario

Vuelve a modo usuario

8.3

. Señale

s

3. Ejecutar la función que atiende la señal

marco main()

pila usuario

void funcion(){printf(“hola mundo”);}main(){signal(SIGINT,funcion); while(1);}

void funcion(){printf(“hola mundo”);}main(){signal(SIGINT,funcion); while(1);}

Código de usuarioCódigo de usuario