Implementar semáforos Linux código fuente del núcleo de un blog antes del

  
introducción de la sincronización del kernel Linux para bloqueos de giro que utilizan bloqueos de giro para proteger los recursos compartidos, ha presentado hoy otro mecanismo de sincronización del kernel de Linux y mdash; — semáforo . Use semáforos en el núcleo es muy ampliamente utilizado para proteger una variedad de recursos compartidos. mecanismo de semáforos y bloqueos de giro aplicación no es lo mismo, la utilidad no es lo mismo. En primer lugar, bloqueos de giro y semáforos se utilizan para representar los contadores para permitir el acceso simultáneo número máximo de procesos a los recursos compartidos, pero el valor de recuento de acciones spinlock es 1, lo que significa que cada vez que hay solamente un proceso que se ejecuta en el área de código compartido; señal capacidad se le permitió compartir recuento es mayor que 1, es decir, se permite el recurso compartido para acceder simultáneamente a una pluralidad de diferentes procesos, por supuesto, el contador de semáforos es también establece en 1, este caso también se conoce semáforo mutex. En segundo lugar, bloqueo de bucle corto plazo utiliza para proteger los recursos compartidos para completar la operación, durante el uso, no permita que el proceso para dormir y el proceso de cambio, que se utiliza semáforo para compartir recursos temporalmente no se puede obtener, si la adquisición falla proceso de dormir no puede ser interrumpido, sólo para despertar el proceso por la liberación de los recursos. Por último, bloqueos de giro que puede ser utilizado en la rutina de servicio de interrupción; semáforo no se puede utilizar la rutina de servicio de interrupción, no se permite la rutina de servicio de interrupción debido a que el proceso del sueño. conocimiento básico del semáforo ha sido explicar terminado, vamos a ver a implementar semáforos en el núcleo interior, el documento explica la versión del kernel es linux-2.6.24. 1
estructura de datos struct {semáforo atomic_t contar; int durmientes; wait_queue_head_t esperar;}; estructura de datos utilizando semáforos semáforo estructura, que comprende tres miembros de datos: un recuento de valor de cuenta es compartida, durmientes actualmente a la espera de entrar en un semáforo del sueño el número de proceso, esperar una cola semáforo de espera actual. 2 semáforo para ser inicializado antes de usar semáforos para usar, de hecho, basta con establecer la cantidad de acciones y esperar cola, el número de inicio del sueño del proceso es 0. Clave para explicar el uso y la aplicación de este semáforo. API operaciones de semáforo:
estática en línea nula abajo (estructura de semáforo * SEM) //Obtener el semáforo, de obtener no se dormir vacío en línea estática (struct semáforo * SEM) //liberar el semáforo, y espera despertar el primer proceso en el semáforo de colas utilizado como sigue:
abajo (sem); ... crítico sección ... hasta (sem); el número de núcleos para asegurar el proceso está accediendo área crítica de menos de o igual a inicializar el intercambio contar el valor, para obtener el proceso de semáforos fallado no se interrumpirá el sueño, esperar en la cola de espera del semáforo. Cuando un proceso libera el semáforo se despierta esperando el primer proceso en la cola. 3 Semáforo aplicación 3.1 abajo (SEM) primera función de búsqueda definida:
estática en línea nula abajo (struct semáforo * SEM) {might_sleep (); __asm__ __volatile __ (" # atómica abajo operación \\ n \\ t " LOCK_PREFIX " decl% 0 \\ n \\ t " /* --sem- > contar * /" jns 2f \\ n " " \\ tlea% 0, %% eax \\ n \\ t " " llamar __down_failed \\ n " " 2: ": " + m " (SEM > contar) :: " memoria ", " ax ");} que contiene un número de código de montaje,% 0 representa SEM > contar. Ese primer gt SEM y, recuento de menos 1, LOCK_PREFIX representa la ejecución de esta instrucción de cierre del bus, para garantizar una operación de reducción es atómica. Después menos 1 si es mayor que o igual a 0 a 2 realice el numeral, se salta directamente a la cola función __down_failed y la función devuelve con éxito la obtención de la semáforo; Guardar o después de 1 SEM > recuento es menor que el orden de ejecución 0 __down_failed función más adelante. Luego, busquen en la definición de la función __down_failed:
ENTRADA (__ down_failed) CFI_STARTPROC MARCO pushl% EDX CFI_ADJUST_CFA_OFFSET 4 CFI_REL_OFFSET EDX, 0% ecx pushl CFI_ADJUST_CFA_OFFSET 4 CFI_REL_OFFSET ecx, 0 llamada __down popl% ecx CFI_ADJUST_CFA_OFFSET -4 CFI_RESTORE ecx popl% EDX CFI_ADJUST_CFA_OFFSET -4 CFI_RESTORE EDX endFrame ret CFI_ENDPROC FIN (__ down_failed) pushl popl y para guardar y restaurar registros, instrucciones de prefijo de CFI para el ajuste de alineación de instrucciones. La función de enfoque __down, definición de la función siguiente aspecto:
fastcall vacío __down __sched (struct semáforo * SEM) {struct task_struct * tsk = corriente; DECLARE_WAITQUEUE (esperar, tsk); unsigned long flags; tsk- > estado = TASK_UNINTERRUPTIBLE; spin_lock_irqsave (&SEM > wait.lock, banderas); add_wait_queue_exclusive_locked (&SEM > esperar, &esperar); SEM > traviesas ++; for (;;) {traviesas int = sem - > durmientes; /* * Añadir " todos los demás " en ella no son * de juego, porque poseemos el spinlock en * el wait_queue_head * /if (atomic_add_negative (traviesas - 1, &! .. SEM > count)) {SEM > durmientes = 0; break;} SEM > durmientes = 1; /* nosotros - véase más arriba * -1 /spin_unlock_irqrestore (&SEM > wait.lock, banderas); horario (); spin_lock_irqsave (&SEM > wait.lock, banderas); tsk- > STATE = TASK_UNINTERRUPTIBLE;} remove_wait_queue _locked (&SEM > esperar, &esperar); wake_up_locked (&SEM > esperar); spin_unlock_irqrestore (&SEM > wait.lock, banderas); tsk- > STATE = TASK_RUNNING;}
Copyright © Conocimiento de Windows All Rights Reserved