Un seqlock (abreviatura de sequence lock ) es un mecanismo de bloqueo especial utilizado en Linux para permitir escrituras rápidas de variables compartidas entre dos rutinas paralelas del sistema operativo . La semántica se estabilizó a partir de la versión 2.5.59 y están presentes en la serie de kernel estable 2.6.x. Los seqlocks fueron desarrollados por Stephen Hemminger y originalmente llamados frlocks, basándose en trabajos anteriores de Andrea Arcangeli. La primera implementación fue en el código de tiempo x86-64 donde era necesario sincronizar con el espacio de usuario donde no era posible usar un bloqueo real.
Es un mecanismo consistente entre lectores y escritores que evita el problema de la falta de escritura . Un seqlock consiste en un almacenamiento para guardar un número de secuencia además de un bloqueo. El bloqueo sirve para soportar la sincronización entre dos escritores y el contador sirve para indicar la consistencia en los lectores. Además de actualizar los datos compartidos, el escritor incrementa el número de secuencia, tanto después de adquirir el bloqueo como antes de liberarlo. Los lectores leen el número de secuencia antes y después de leer los datos compartidos. Si el número de secuencia es impar en cualquiera de las ocasiones, un escritor había tomado el bloqueo mientras se leían los datos y es posible que haya cambiado. Si los números de secuencia son diferentes, un escritor ha cambiado los datos mientras se leían. En cualquier caso, los lectores simplemente vuelven a intentarlo (usando un bucle) hasta que leen el mismo número de secuencia par antes y después.
El lector nunca se bloquea, pero puede tener que volver a intentarlo si hay una escritura en curso; esto acelera a los lectores en el caso de que los datos no se hayan modificado, ya que no tienen que adquirir el bloqueo como lo harían con un bloqueo de lectura-escritura tradicional. Además, los escritores no esperan a los lectores, mientras que con los bloqueos de lectura-escritura tradicionales sí lo hacen, lo que lleva a una posible escasez de recursos en una situación en la que hay varios lectores (porque el escritor debe esperar a que no haya lectores). Debido a estos dos factores, los bloqueos de secuencia son más eficientes que los bloqueos de lectura-escritura tradicionales para la situación en la que hay muchos lectores y pocos escritores. El inconveniente es que si hay demasiada actividad de escritura o el lector es demasiado lento, pueden bloquearse en vivo (y los lectores pueden quedarse sin recursos).
La técnica no funcionará con datos que contengan punteros, porque cualquier escritor podría invalidar un puntero que un lector ya haya seguido. La actualización del bloque de memoria al que se apunta está bien utilizando seqlocks, pero no se permite actualizar el puntero en sí . En un caso en el que los punteros en sí deben actualizarse o modificarse, se prefiere utilizar la sincronización de lectura-copia-actualización .
Esto se aplicó por primera vez a la actualización del contador de tiempo del sistema. Cada interrupción de tiempo actualiza la hora del día; puede haber muchos lectores de la hora para uso interno del sistema operativo y aplicaciones, pero las escrituras son relativamente poco frecuentes y solo ocurren una a la vez. El código del contador de tiempo BSD, por ejemplo, parece utilizar una técnica similar.
Un problema sutil del uso de seqlocks para un contador de tiempo es que es imposible recorrerlo con un depurador. La lógica de reintento se activará todo el tiempo porque el depurador es lo suficientemente lento como para hacer que la carrera de lectura ocurra siempre.