07-2-sincronizacion

6
  Estudio de un S.O. Sincronización. Semáforos del núcleo. JuanCarlos PerezCortes

Upload: kiring84

Post on 05-Oct-2015

213 views

Category:

Documents


0 download

DESCRIPTION

tema asignatura eso

TRANSCRIPT

  • Estudio de un S.O. Sincronizacin. Semforos del ncleo. JuanCarlos PerezCortes

  • Table of ContentsTema 7. Sincronizacin......................................................................................................................................1

    7.1 Introduccin.......................................................................................................................................17.2 Estructuras de datos...........................................................................................................................17.3 Implementacin de los semforos......................................................................................................27.4 Operaciones en ensamblador: up() y down().....................................................................................37.5 Operaciones en C: __up() y __down()...............................................................................................37.6 Otras versiones de semforos de __down().......................................................................................4

    Estudio de un S.O. Sincronizacin. Semforos del ncleo.

    i

  • Tema 7. SincronizacinSemforos del ncleo

    Juan Carlos Prez y Sergio Sez Juan Carlos Prez

    Sergio [email protected]@disca.upv.es

    7.1 IntroduccinUn semforo es una herramienta para la programacin concurrente. Con los semforos se pueden construirsecciones crticas para proteger datos compartidos, o utilizarlos como mecanismo de sincronizacin.

    En muchas ocasiones, incluso con un solo procesador, puede haber varios hilos de ejecucin ejecutandocdigo del ncleo y modificando o consultando las variables del ncleo (v.g. cuando llega una interrupcin yestamos sirviendo una llamada al sistema u otra interrupcin).

    Si un hilo debe de esperar a otro por breve periodo de tiempo se pueden utilizar mecanismos de espera activo(v.g. spinlocks o read/write locks), pero si la espera puede ser prolongada, el proceso que debe esperar debersuspenderse y abandonar la CPU. En estos casos se pueden utilizar semforos.

    Se van a estudiar los semforos que se utilizan para sincronizar procesos entro del ncleo.

    Un semforo es una estructura de datos que se compone bsicamente de:

    contador: Para contabilizar el nmero de procesos que pueden entrar en la seccin crtica. cola de espera: Para bloquear a los procesos que no han podido adquirir el semforo.

    Sobre un semforo se pueden realizar dos operaciones:

    1. P, wait, down: De forma atmica, se decrementa el contador y, si el resultado es negativo, entoncesse suspende el proceso y se inserta en la cola de espera.

    2. V, signal, up: De forma atmica, se incrementa el contador y, si el resultado es menor o igual a 0,entonces se despierta a uno de los procesos de la cola de espera.

    7.2 Estructuras de datosUn semforo est representado por la estructura struct semaphore[include/asmi386/semaphore.h#L44]. Dichaestructura contiene los campos:

    count (atomic_t): es un contador atmico. Cuando es positivo el semforo est libre y se puedeadquirir, indicando su valor cuntos procesos pueden adquirirlo concurrentemente. Si su valor es ceroo negativo, el semforo est cerrado y cualquier intento de adquirirlo bloquear al proceso invocante.

    Tema 7. Sincronizacin 1

  • Si el valor es negativo (normalmente 1) indicar que hay algn proceso durmiendo en la cola deespera.

    sleepers: Indica que hay un proceso o ms durmiendo en la cola de espera. Su valor en ese casotiende a ser 1, pero temporalmente puede tener valores superiores. No indica el nmero de procesosque hay durmiendo en la cola.

    wait (wait_queue_head_t): Es la cola de espera asociada al semforo.

    Los semforos se pueden inicializar de diversas formas:

    Con la macro __SEMAPHORE_INITIALIZER(name, count)[include/asmi386/semaphore.h#L61] sepuede inicializar una variable de tipo semforo durante su declaracin, o declararla e inicializarla conla macro __DECLARE_SEMAPHORE_GENERIC(name, count)[include/asmi386/semaphore.h#L68].Ambas macros reciben el nombre de la variable semforo en name y la cuenta inicial del semforoen count.

    Para el caso especial de semforos binarios (mutexes) se utilizan las macros__MUTEX_INITIALIZER[include/asmi386/semaphore.h#L65],DECLARE_MUTEX[include/asmi386/semaphore.h#L71] yDECLARE_MUTEX_LOCKED[include/asmi386/semaphore.h#L72]. Estas dos ltimas declaran una variable detipo mutex incialmente abierto o cerrado respectivamente.

    Para inicializar semforos cuyas variables ya se han declarado, se pueden utilizar las funcionessema_init(sem,val)[include/asmi386/semaphore.h#L74],init_MUTEX(sem)[include/asmi386/semaphore.h#L90] oinit_MUTEX_LOCKED(sem)[include/asmi386/semaphore.h#L95]

    7.3 Implementacin de los semforosLa implementacin de los semforos del ncleo de Linux est organizada en tres niveles:

    1. El primer nivel est implementado en ensamblador (y adems, no demasiado claro) con el objetivo dehacerlo lo ms eficiente posible. En este nivel se maneja el caso ms frecuente: que se intenteadquirir un semforo que est libre o que se libere un semforo que no tiene ningn procesoesperando en la cola. Las funciones que lo implementan son up()[include/asmi386/semaphore.h#L200] ydown()[include/asmi386/semaphore.h#L110]. Existen algunas variantes comodown_interruptible()[include/asmi386/semaphore.h#L138], que permite que el proceso bloqueadoreciba seales que lo puedan despertar, y down_trylock()[include/asmi386/semaphore.h#L169], queintenta adquirir el semforo, pero si no lo consigue no se bloquea.

    2. El nivel intermedio simplemente almacena los registros que utilizan las funciones del tercer nivel enla pila e invoca a dichas funciones. Las funcones que lo implementan son __up_wakeup()[arch/i386/kernel/semaphore.c#L220] y__down_failed()[arch/i386/kernel/semaphore.c#L180]. Las variantes en este caso son__down_failed_interruptible()[arch/i386/kernel/semaphore.c#L194] y__down_failed_trylock()[arch/i386/kernel/semaphore.c#L207].

    3. El tercer nivel es el que realiza el trabajo en los casos ms desfavorables. Est implementado en lasfunciones __up()[arch/i386/kernel/semaphore.c#L50] y __down()[arch/i386/kernel/semaphore.c#L57]. Las variantesson __down_interruptible()[arch/i386/kernel/semaphore.c#L90] y__down_trylock()[arch/i386/kernel/semaphore.c#L140].

    Estudio de un S.O. Sincronizacin. Semforos del ncleo.

    7.3 Implementacin de los semforos 2

  • 7.4 Operaciones en ensamblador: up() y down()El primer nivel se lleva a cabo en ensamblador, intentando optimizar el caso ms frecuente. El cdigo deestas funciones es un poco extrao para optimizar el uso de la cache y la ejecucin en procesadoressegmentados.

    up()[include/asmi386/semaphore.h#L200]: Incrementa el contador count del semforo de forma atmica.El contador es el primer campo de la estructura que compone un semforo. Para que la operacin deincremento sea atmica en el caso multiprocesador, se utiliza el prefijo lock, que bloquea el uso delbus de memoria durante la ejecucin de la siguiente instruccin. Si el valor resultante es 0 o inferior,eso significa que el valor era negativo y que, por lo tanto, hay algn proceso durmiendo en la cola yhay que despertarlo invocando al segundo nivel, __up_wakeup()[arch/i386/kernel/semaphore.c#L220], queacabar invocando a la funcin del tercer nivel: __up()[arch/i386/kernel/semaphore.c#L50].

    down()[include/asmi386/semaphore.h#L110]: Decrementa el contador count del semforo de formaatmica. Si el valor resultante es negativo, el semforo estaba cerrado ( 0) y por lo tanto hay quedormir al proceso invocante. Para ello se invoca a la funcin del segundo nivel,__down_failed()[arch/i386/kernel/semaphore.c#L180], que acabar invocando a la funcin del tercernivel: __down()[arch/i386/kernel/semaphore.c#L57].

    7.5 Operaciones en C: __up() y __down()__up()[arch/i386/kernel/semaphore.c#L50]: Es muy simple y despierta a uno de los procesos que est en la cola deespera en modo exclusivo. Como se puede observar en la funcin __down() en la cola de espera delsemforo slo hay procesos en modo exclusivo.

    __down()[arch/i386/kernel/semaphore.c#L57]: Es la funcin que contiene la mayor parte de la lgica del semforo.Su objetivo es dormir al proceso invocante si el contador count del semforo es negativo. Para ello realizalas siguientes acciones:

    Declara una estructura wait para insertar el proceso actual en la cola de espera del semforo. [#5960] Se cambia el estado de la tarea actual a TASK_UNINTERRUPTIBLE e inserta el proceso en modo

    exclusivo en la cola de espera del semforo. [#612] Adquiere el cerrojo sobre los semforos. [#64] Incrementa el campo sleepers del semforo. [#65]

    Comienza un bucle infinito del que slo saldr cuando el contador count del semforo no seanegativo. [#6683]

    Le suma al contador count del semforo, la variable sleepers menos 1, devolviendo cierto si elvalor es negativo. Esto se lleva a cabo de forma atmica. Si el resultado no es negativo, el procesoactual debe salir del bucle puesto que no se debe bloquear. [#736]

    Si count sigue siendo negativo, pone sleepers a 1. [#77] Libera el cerrojo sobre los semforos e invoca al planificador. [#7880] Cuando lo despierten, se pone en estado TASK_UNINTERRUPTIBLE, vuelve adquirir el cerrojo de

    los semforos y vuelve a ejecutar el bucle para comprobar si se puede despertar. [#8182] Al salir del bucle, se libera el cerrojo, se elimina al proceso de la cola de espera y se lo pone en

    estado TASK_RUNNING. [#846]

    Estudio de un S.O. Sincronizacin. Semforos del ncleo.

    7.4 Operaciones en ensamblador: up() y down() 3

  • Despierta a otro proceso, que se volver a dormir, para que arregle el valor de los campossleepers y count. [#87]Los campos sleepers y count deben valer 1 y 1 respectivamentecuando hay algn proceso durmiendo en la cola.

    Algunos casos posibles:

    Un proceso invoca a __down() cuando no hay ningn proceso en la cola. El contadorsleepers valdr 0 y count debera valer 1.

    Un proceso invoca a __down() cuando ya hay algn proceso en la cola. El contadorsleepers valdr 1 y count debera valer 2.

    Un proceso acaba de ser despertado y debe adquirir el semforo. El contador sleepers valdr 1 ycount debera valer 0.

    Un proceso acaba de ser despertado y debe volverse a dormir. El contador sleepers valdr 0 ycount debera valer 0.

    7.6 Otras versiones de semforos de __down() La funcin __down_interruptible()[arch/i386/kernel/semaphore.c#L90] es muy similar a __down(),

    salvo que al principio del bucle se comprueba si el proceso a recibido alguna seal. En este caso, sesale del bucle incrementando el contador count para informar de que este proceso no debecontabilizarse, y se devuelve el error correspondiente.

    La funcin down_trylock() no se debe no se debe bloquear si el proceso no puede adquirir elsemforo. Por lo tanto, lo nico que intenta la funcin__down_trylock()[arch/i386/kernel/semaphore.c#L90] es poner los campos del semforo con el valoradecuado. Se debe recordar que si se ha invocado a __down_trylock() el proceso ha fallado aladquirir el semforo.

    Estudio de un S.O. Sincronizacin. Semforos del ncleo.

    7.6 Otras versiones de semforos de __down() 4

    Table of ContentsTema 7. Sincronizacin7.1 Introduccin7.2 Estructuras de datos7.3 Implementacin de los semforos7.4 Operaciones en ensamblador: up() y down()7.5 Operaciones en C: __up() y __down()7.6 Otras versiones de semforos de __down()