Leer-copiar-actualizar

format_list_bulleted Contenido keyboard_arrow_down
ImprimirCitar

En informática, leer-copiar-actualizar (RCU) es un mecanismo de sincronización que evita el uso de primitivas de bloqueo mientras varios subprocesos leen y actualizan simultáneamente elementos que son vinculados a través de punteros y que pertenecen a estructuras de datos compartidas (por ejemplo, listas vinculadas, árboles, tablas hash).

Siempre que un subproceso inserte o elimine elementos de estructuras de datos en la memoria compartida, se garantiza que todos los lectores verán y recorrerán la estructura anterior o la nueva, evitando así incoherencias (por ejemplo, desreferenciar punteros nulos).

Se utiliza cuando el rendimiento de las lecturas es crucial y es un ejemplo de compensación de espacio-tiempo, lo que permite operaciones rápidas a costa de más espacio. Esto hace que todos los lectores procedan como si no hubiera sincronización de por medio, por lo que serán rápidos, pero también dificultarán las actualizaciones.

Nombre y resumen

El nombre proviene de la forma en que RCU se usa para actualizar una estructura vinculada en su lugar. Un hilo que desee hacer esto utiliza los siguientes pasos:

  • crear una nueva estructura,
  • copiar los datos de la antigua estructura en la nueva, y guardar un puntero a la antigua estructura,
  • modificar el nuevo, copiado, estructura,
  • actualizar el puntero global para referirse a la nueva estructura,
  • dormir hasta que el núcleo del sistema operativo determine que no quedan lectores usando la vieja estructura, por ejemplo, en el núcleo Linux, utilizando synchronize_rcu(),
  • una vez despertada por el núcleo, trate la vieja estructura.

Entonces, la estructura se lee al mismo tiempo que un subproceso copia para hacer una actualización, de ahí el nombre "leer- copiar actualización". La abreviatura "RCU" fue una de las muchas contribuciones de la comunidad Linux. Otros nombres para técnicas similares incluyen serialización pasiva y MP diferido por programadores VM/XA y generaciones por programadores K42 y Tornado.

Descripción detallada

Procedimiento de inserción actualizado. Un hilo asigna una estructura con tres campos, luego establece el puntero global gptr apuntar a esta estructura.

Una propiedad clave de RCU es que los lectores pueden acceder a una estructura de datos incluso cuando está en proceso de actualización: los actualizadores de RCU no pueden bloquear a los lectores ni obligarlos a volver a intentar acceder. Esta descripción general comienza mostrando cómo los datos se pueden insertar y eliminar de forma segura de las estructuras vinculadas a pesar de los lectores simultáneos. El primer diagrama de la derecha muestra un procedimiento de inserción de cuatro estados, con el tiempo avanzando de izquierda a derecha.

El primer estado muestra un puntero global llamado gptr que inicialmente es NULL, de color rojo para indicar que se puede acceder por un lector en cualquier momento, lo que requiere que los actualizadores se encarguen. La asignación de memoria para una nueva estructura pasa al segundo estado. Esta estructura tiene un estado indeterminado (indicado por los signos de interrogación) pero es inaccesible para los lectores (indicado por el color verde). Debido a que la estructura es inaccesible para los lectores, el actualizador puede realizar cualquier operación deseada sin temor a interrumpir a los lectores simultáneos. Al inicializar esta nueva estructura, se pasa al tercer estado, que muestra los valores inicializados de los campos de la estructura. Asignar una referencia a esta nueva estructura a gptr transiciones al cuarto y último estado. En este estado, la estructura es accesible para los lectores y, por lo tanto, está coloreada en rojo. La primitiva rcu_assign_pointer se usa para llevar a cabo esta asignación y garantiza que la asignación sea atómica en el sentido de que los lectores simultáneos verán un NULL puntero o un puntero válido a la nueva estructura, pero no una mezcla de los dos valores. Las propiedades adicionales de rcu_assign_pointer se describen más adelante en este artículo.

Procedimiento de eliminación actualizado

Este procedimiento demuestra cómo se pueden insertar nuevos datos en una estructura de datos vinculados aunque los lectores estén recorriendo simultáneamente la estructura de datos antes, durante y después de la inserción. El segundo diagrama a la derecha muestra un procedimiento de eliminación de cuatro estados, nuevamente con el tiempo avanzando de izquierda a derecha.

El primer estado muestra una lista enlazada que contiene los elementos A, B y C. Los tres elementos están coloreados en rojo para indicar que un lector de RCU puede hacer referencia a cualquiera de ellos en cualquier momento. El uso de list_del_rcu para eliminar el elemento B de esta lista pasa al segundo estado. Tenga en cuenta que el enlace del elemento B al C se deja intacto para permitir a los lectores que actualmente hacen referencia al elemento B recorrer el resto del lista. Los lectores que accedan al enlace desde el elemento A obtendrán una referencia al elemento B o elemento C, pero de cualquier manera, cada lector verá un valor válido y correcto lista enlazada formateada. El elemento B ahora está coloreado en amarillo para indicar que, si bien los lectores preexistentes aún pueden tener una referencia al elemento B, los nuevos lectores no tienen forma de obtener una referencia. Una operación de espera de lectores pasa al tercer estado. Tenga en cuenta que esta operación de espera de lectores solo necesita esperar lectores preexistentes, pero no lectores nuevos. El elemento B ahora está coloreado en verde para indicar que los lectores ya no pueden hacer referencia a él. Por lo tanto, ahora es seguro que el actualizador libere el elemento B, pasando así al cuarto y último estado.

Es importante reiterar que en el segundo estado diferentes lectores pueden ver dos versiones diferentes de la lista, ya sea con o sin el elemento B. En otras palabras, RCU proporciona coordinación en el espacio (diferentes versiones de la lista) así como en el tiempo (diferentes estados en los procedimientos de borrado). Esto contrasta marcadamente con las primitivas de sincronización más tradicionales, como el bloqueo o las transacciones que se coordinan en el tiempo, pero no en el espacio.

Este procedimiento demuestra cómo se pueden eliminar los datos antiguos de una estructura de datos vinculados aunque los lectores estén recorriendo simultáneamente la estructura de datos antes, durante y después de la eliminación. Dada la inserción y eliminación, se puede implementar una amplia variedad de estructuras de datos usando RCU.

Los lectores de RCU se ejecutan dentro de las secciones críticas del lado de lectura, que normalmente están delimitadas por rcu_read_lock y rcu_read_unlock. Se dice que cualquier declaración que no esté dentro de una sección crítica del lado de lectura de RCU está en un estado inactivo, y no se permite que tales declaraciones contengan referencias a estructuras de datos protegidas por RCU, ni la espera- Se requiere una operación para lectores para esperar subprocesos en estados inactivos. Cualquier período de tiempo durante el cual cada subproceso reside al menos una vez en un estado inactivo se denomina período de gracia. Por definición, cualquier sección crítica del lado de lectura de RCU existente al comienzo de un período de gracia determinado debe completarse antes del final de ese período de gracia, lo que constituye la garantía fundamental proporcionada por RCU. Además, la operación de espera de lectores debe esperar a que transcurra al menos un período de gracia. Resulta que esta garantía se puede proporcionar con gastos generales del lado de lectura extremadamente pequeños; de hecho, en el caso límite que realmente se realiza mediante compilaciones de kernel de Linux de clase de servidor, el gasto general del lado de lectura es exactamente cero.

La garantía fundamental de RCU se puede utilizar dividiendo las actualizaciones en fases de eliminación y recuperación. La fase de eliminación elimina las referencias a los elementos de datos dentro de una estructura de datos (posiblemente reemplazándolos con referencias a nuevas versiones de estos elementos de datos) y puede ejecutarse simultáneamente con las secciones críticas del lado de lectura de RCU. La razón por la que es seguro ejecutar la fase de eliminación al mismo tiempo que los lectores de RCU es que la semántica de las CPU modernas garantiza que los lectores verán la versión antigua o la nueva de la estructura de datos en lugar de una referencia parcialmente actualizada. Una vez que ha transcurrido un período de gracia, ya no puede haber lectores que hagan referencia a la versión anterior, por lo que es seguro que la fase de recuperación libere (recuperar) los elementos de datos que componían esa versión anterior.

Dividir una actualización en fases de eliminación y recuperación permite al actualizador realizar la fase de eliminación inmediatamente y posponer la fase de recuperación hasta que todos los lectores activos durante la fase de eliminación hayan finalizado, en otras palabras, hasta que haya transcurrido un período de gracia.

Entonces, la secuencia típica de actualización de RCU es algo como lo siguiente:

  1. Velar por que todos los lectores que accedan a estructuras de datos protegidas por la UCR realicen sus referencias dentro de una sección crítica de la UCR.
  2. Eliminar los punteros a una estructura de datos, para que los lectores posteriores no puedan obtener una referencia a ella.
  3. Esperar un período de gracia para salir adelante, de modo que todos los lectores anteriores (que todavía podrían tener punteros a la estructura de datos eliminados en el paso anterior) habrán completado sus secciones críticas de la UCR.
  4. En este punto, no puede haber lectores que todavía tengan referencias a la estructura de datos, por lo que ahora puede ser reclamado con seguridad (por ejemplo, liberado).

En el procedimiento anterior (que coincide con el diagrama anterior), el actualizador realiza tanto el paso de eliminación como el de recuperación, pero a menudo es útil que un subproceso completamente diferente realice la recuperación. El conteo de referencias se puede usar para permitir que el lector realice la eliminación, por lo que, incluso si el mismo hilo realiza tanto el paso de actualización (paso (2) anterior) como el paso de recuperación (paso (4) anterior), a menudo es útil pensar en ellos. por separado.

RCU es quizás el algoritmo de no bloqueo más común para una estructura de datos compartida. RCU es completamente libre de espera para cualquier número de lectores. Las implementaciones de RCU de un solo escritor también están libres de bloqueo para el escritor. Algunas implementaciones de RCU de varios escritores no tienen bloqueos. Otras implementaciones de múltiples escritores de RCU serializan escritores con un bloqueo.

Usos

A principios de 2008, había casi 2000 usos de la API RCU dentro del kernel de Linux, incluidas las pilas de protocolos de red y el sistema de administración de memoria. Hasta marzo de 2014, hubo más de 9000 usos. Desde 2006, los investigadores han aplicado RCU y técnicas similares a una serie de problemas, incluida la gestión de metadatos utilizados en el análisis dinámico, la gestión de la vida útil de los objetos agrupados, la gestión de la vida útil de los objetos en el sistema operativo de investigación K42 y la optimización de las implementaciones de memoria transaccional de software. Dragonfly BSD utiliza una técnica similar a RCU que se asemeja más a la implementación Sleepable RCU (SRCU) de Linux.

Ventajas y desventajas

La capacidad de esperar hasta que todos los lectores hayan terminado permite a los lectores de RCU usar una sincronización mucho más liviana; en algunos casos, absolutamente ninguna sincronización. Por el contrario, en los esquemas más convencionales basados en bloqueos, los lectores deben usar una sincronización de gran peso para evitar que un actualizador elimine la estructura de datos debajo de ellos. El motivo es que los actualizadores basados en bloqueos normalmente actualizan los datos en su lugar y, por lo tanto, deben excluir a los lectores. Por el contrario, los actualizadores basados en RCU suelen aprovechar el hecho de que las escrituras en punteros alineados únicos son atómicas en las CPU modernas, lo que permite la inserción, eliminación y reemplazo atómicos de datos en una estructura vinculada sin interrumpir a los lectores. Los lectores RCU simultáneos pueden continuar accediendo a las versiones anteriores y pueden prescindir de las instrucciones atómicas de lectura, modificación y escritura, las barreras de memoria y las fallas de caché que son tan costosas en los sistemas informáticos SMP modernos, incluso en ausencia de contención de bloqueo. La naturaleza liviana de las primitivas del lado de lectura de RCU brinda ventajas adicionales más allá del excelente rendimiento, escalabilidad y respuesta en tiempo real. Por ejemplo, brindan inmunidad a la mayoría de las condiciones de interbloqueo y bloqueo dinámico.

Por supuesto, RCU también tiene desventajas. Por ejemplo, RCU es una técnica especializada que funciona mejor en situaciones con lecturas en su mayoría y pocas actualizaciones, pero a menudo es menos aplicable a cargas de trabajo de solo actualización. Para otro ejemplo, aunque el hecho de que los lectores y actualizadores de RCU puedan ejecutarse simultáneamente es lo que permite la naturaleza liviana de las primitivas del lado de lectura de RCU, es posible que algunos algoritmos no sean aptos para la concurrencia de lectura/actualización.

A pesar de más de una década de experiencia con RCU, el alcance exacto de su aplicabilidad sigue siendo un tema de investigación.

Patentes

La técnica está cubierta por una patente de software de EE. UU. U.S. Patente 5.442.758, emitida el 15 de agosto de 1995 y cedida a Sequent Computer Systems, así como por U.S. Patente 5.608.893 (caducada el 30 de marzo de 2009), EE. UU. Patente 5,727,209 (caducada el 05-04-2010), EE.UU. Patente 6.219.690 (caducada el 18 de mayo de 2009) y U.S. Patente 6.886.162 (caducada el 25 de mayo de 2009). La patente estadounidense ahora vencida U.S. La patente 4.809.168 cubre una técnica estrechamente relacionada. RCU también es el tema de un reclamo en la demanda SCO v. IBM.

Interfaz RCU de muestra

RCU está disponible en varios sistemas operativos y se agregó al kernel de Linux en octubre de 2002. También están disponibles implementaciones a nivel de usuario, como liburcu.

La implementación de RCU en la versión 2.6 del kernel de Linux se encuentra entre las implementaciones de RCU más conocidas y se usará como inspiración para la API de RCU en el resto de este artículo. La API central (interfaz de programación de aplicaciones) es bastante pequeña:

  • rcu_read_lock(): Marca una estructura de datos protegida por la UCR para que no se reclame durante toda la duración de esa sección crítica.
  • rcu_read_unlock(): Usado por un lector para informar a la reclamadora de que el lector está saliendo de una sección crítica de la UCR. Tenga en cuenta que las secciones críticas del lado derecho de la UCR pueden ser anidadas y/o superpuestas.
  • synchronize_rcu(): Se han completado bloques hasta que se hayan completado todas las secciones críticas de la UCR anteriores. Note que synchronize_rcu voluntad no necesariamente esperar a que se completen las secciones críticas posteriores de la UCR. Por ejemplo, considere la siguiente secuencia de eventos:
CPU 0 CPU 1 CPU 2
- Sí. ------- ---------------
1. rcu_read_lock()
2. entra sincronizar_rcu()
3. rcu_read_lock()
4. rcu_read_unlock()
5. salidas synchronize_rcu()
6. rcu_read_unlock()
Desde synchronize_rcu es la API que debe averiguar cuándo se hacen los lectores, su implementación es clave para la UCR. Para que la UCR sea útil en todas las situaciones, pero las más intensas, synchronize_rcuEs demasiado pequeño.
Alternativamente, en lugar de bloquear, synchronize_rcu puede registrar un callback a ser invocado después de que todas las secciones críticas de la UCR en curso hayan finalizado. Esta variante de callback se llama call_rcu en el núcleo Linux.
  • rcu_assign_pointer(): El actualizador utiliza esta función para asignar un nuevo valor a un puntero protegido por RCU, con el fin de comunicar con seguridad el cambio de valor del actualizador al lector. Esta función devuelve el nuevo valor, y también ejecuta las instrucciones de barrera de memoria necesarias para una arquitectura CPU dada. Tal vez más importante, sirve para documentar qué punteros están protegidos por la UCR.
  • rcu_dereference(): El lector utiliza rcu_dereference para buscar un puntero protegido por la UCR, que devuelve un valor que puede ser degradado con seguridad. También ejecuta cualquier directiva requerida por el compilador o la CPU, por ejemplo, un molde volátil para gcc, una carga de memoria_order_consume para C/C++11 o la instrucción de memoria-barrier requerida por la antigua CPU DE DEC Alpha. El valor devuelto por rcu_dereference es válido sólo dentro de la sección crítica de la UCR de cierre. Como con rcu_assign_pointer, una función importante rcu_dereference es documentar qué punteros están protegidos por la UCR.
RCU API comunicaciones entre el lector, el actualizador y la recuperación

El diagrama de la derecha muestra cómo cada API se comunica entre el lector, el actualizador y el reclamador.

La infraestructura RCU observa la secuencia de tiempo de las invocaciones rcu_read_lock, rcu_read_unlock, synchronize_rcu y call_rcu en orden para determinar cuándo (1) las invocaciones de synchronize_rcu pueden volver a sus llamantes y (2) las devoluciones de llamada de call_rcu pueden invocarse. Las implementaciones eficientes de la infraestructura RCU hacen un uso intensivo del procesamiento por lotes para amortizar sus gastos generales en muchos usos de las API correspondientes.

Implementación sencilla

RCU tiene un "juguete" extremadamente simple; implementaciones que pueden ayudar a comprender RCU. Esta sección presenta uno de esos "juguetes" implementación que funciona en un entorno no preventivo.

vacío rcu_read_lock()vacío) {} }vacío rcu_read_unlock()vacío) {} }vacío call_rcu()vacío ()*callback) ()vacío *), vacío *arg){} // añadir callback/arg par a una lista}vacío synchronize_rcu()vacío){} int cpu, Ncpus = 0; para each_cpu()cpu) schedule_current_task_to()cpu); para cada uno entrada dentro el call_rcu lista entrada-callback ()entrada-arg);}

En el ejemplo de código, rcu_assign_pointer y rcu_dereference se pueden ignorar sin perder mucho. Sin embargo, son necesarios para suprimir la optimización dañina del compilador y para evitar que las CPU reordenen los accesos.

#define rcu_assign_pointer(p, v) ({  smp_wmb(); /* Ordene escritos anteriores. */  ACCES_ONCE(p) = (v); })#define rcu_dereference(p) ({ tipo de(p) _value = ACCESS_ONCE(p);  smp_read_barrier_depends(); /* nop en la mayoría de las arquitecturas */  (_value); })

Tenga en cuenta que rcu_read_lock y rcu_read_unlock no hacen nada. Esta es la gran fortaleza de la RCU clásica en un kernel no preventivo: la sobrecarga del lado de lectura es precisamente cero, ya que smp_read_barrier_depends() es una macro vacía en todas las CPU excepto en DEC Alpha; tales barreras de memoria no son necesarias en las CPU modernas. La macro ACCESS_ONCE() es una conversión volátil que no genera código adicional en la mayoría de los casos. Y no hay forma de que rcu_read_lock pueda participar en un ciclo de interbloqueo, hacer que un proceso en tiempo real pierda su fecha límite de programación, precipitar la inversión de prioridad o resultar en una alta contención de bloqueo. Sin embargo, en esta implementación de RCU de juguete, el bloqueo dentro de una sección crítica del lado de lectura de RCU es ilegal, al igual que el bloqueo mientras se mantiene un spinlock puro.

La implementación de synchronize_rcu mueve la llamada desynchronize_cpu a cada CPU, bloqueando así hasta que todas las CPU hayan podido realizar el cambio de contexto. Recuerde que este es un entorno no preventivo y que el bloqueo dentro de una sección crítica del lado de lectura de RCU es ilegal, lo que implica que no puede haber puntos de preferencia dentro de una sección crítica del lado de lectura de RCU. Por lo tanto, si una CPU determinada ejecuta un cambio de contexto (para programar otro proceso), sabemos que esta CPU debe haber completado todas las secciones críticas del lado de lectura de RCU anteriores. Una vez que todas las CPU hayan ejecutado un cambio de contexto, todas las secciones críticas del lado de lectura de la RCU anteriores se habrán completado.

Analogía con el bloqueo lector-escritor

Aunque RCU se puede usar de muchas maneras diferentes, un uso muy común de RCU es análogo al bloqueo de lector-escritor. La siguiente pantalla de código lado a lado muestra qué tan estrechamente relacionados pueden estar el bloqueo lector-escritor y la RCU.

 /* lector-escritor bloqueo */ * UCR */ 1 struct el {} 1 struct el {} 2 struct list_head lp; 2 struct list_head lp; 3 largo clave; 3 largo clave; 4 spinlock_t mutex; 4 spinlock_t mutex; 5 int datos; 5 int datos; 6 * Otros campos de datos */ 6 * Otros campos de datos */ 7 }; 7 }; 8 DEFINE_RWLOCK()listmutex); 8 DEFINE_SPINLOCK()listmutex); 9 LIST_HEAD()cabeza); 9 LIST_HEAD()cabeza); 1 int búsqueda()largo clave, int *resultado) 1 int búsqueda()largo clave, int *resultado) 2 {} 2 {} 3 struct el *p; 3 struct el *p; 4 4 5 read_lock()"listmutex); 5 rcu_read_lock(); 6 list_for_each_entry()p, "cabeza, lp) {} 6 list_for_each_entry_rcu()p, "cabeza, lp) {} 7 si ()p-clave == clave) {} 7 si ()p-clave == clave) {} 8 *resultado = p-datos; 8 *resultado = p-datos; 9 read_unlock()"listmutex); 9 rcu_read_unlock();10 retorno 1; 10 retorno 1;11 } 11 }12 } 12 }13 read_unlock()"listmutex); 13 rcu_read_unlock();14 retorno 0; 14 retorno 0;15 } 15 } 1 int Borrador()largo clave) 1 int Borrador()largo clave) 2 {} 2 {} 3 struct el *p; 3 struct el *p; 4 4 5 Write_lock()"listmutex); 5 spin_lock()"listmutex); 6 list_for_each_entry()p, "cabeza, lp) {} 6 list_for_each_entry()p, "cabeza, lp) {} 7 si ()p-clave == clave) {} 7 si ()p-clave == clave) {} 8 list_del()"p-lp); 8 list_del_rcu()"p-lp); 9 Write_unlock()"listmutex); 9 spin_unlock()"listmutex); 10 synchronize_rcu();10 kfree()p); 11 kfree()p);11 retorno 1; 12 retorno 1;12 } 13 }13 } 14 }14 Write_unlock()"listmutex); 15 spin_unlock()"listmutex);15 retorno 0; 16 retorno 0;16 } 17 }

Las diferencias entre los dos enfoques son bastante pequeñas. El bloqueo del lado de lectura se mueve a rcu_read_lock y rcu_read_unlock, el bloqueo del lado de actualización se mueve de un bloqueo de lectura y escritura a un bloqueo de giro simple, y un synchronize_rcu precede a kfree.

Sin embargo, existe un problema potencial: las secciones críticas del lado de lectura y del lado de actualización ahora pueden ejecutarse simultáneamente. En muchos casos, esto no será un problema, pero es necesario verificar cuidadosamente de todos modos. Por ejemplo, si varias actualizaciones de listas independientes deben verse como una única actualización atómica, la conversión a RCU requerirá un cuidado especial.

Además, la presencia de synchronize_rcu significa que la versión RCU de delete ahora puede bloquear. Si esto es un problema, call_rcu podría usarse como call_rcu (kfree, p) en lugar de synchronize_rcu. Esto es especialmente útil en combinación con el recuento de referencia.

Historia

Las técnicas y los mecanismos que se asemejan a RCU se han inventado de forma independiente varias veces:

  1. H. T. Kung y Q. Lehman describieron el uso de recolectores de basura para implementar acceso similar a RCU a un árbol de búsqueda binario.
  2. Udi Manber y Richard Ladner extendieron el trabajo de Kung y Lehman a entornos no recolectados por el aplazamiento de la regeneración hasta que todos los hilos que se ejecutan en el tiempo de eliminación hayan terminado, lo que funciona en entornos que no tienen hilos de larga vida.
  3. Richard Rashid y otros. describió un buffer de aspecto perezoso de traducción (TLB) que aplazaba la recuperación del espacio de dirección virtual hasta que todas las CPU desaparecieron su TLB, que es similar en espíritu a algunas implementaciones de RCU.
  4. James P. Hennessy, Damian L. Osisek, and Joseph W. Seigh, II were granted US Patent 4,809,168 in 1989 (since lapsed). Esta patente describe un mecanismo similar a la UCR que aparentemente se utilizó en VM/XA sobre los mainframes IBM.
  5. William Pugh describió un mecanismo similar a la UCR que dependía del establecimiento de banderas explícito por los lectores.
  6. Aju John propuso una implementación similar a la UCR cuando los actualizadores simplemente esperen un período fijo de tiempo, bajo la suposición de que los lectores se completarían dentro de ese tiempo fijo, como podría ser apropiado en un sistema duro en tiempo real. Van Jacobson propuso un esquema similar en 1993 (comunicación verbal).
  7. J. Slingwine and P. E. McKenney received US Patent 5,442,758 in August 1995, which describes RCU as implemented in DYNIX/ptx and later in the Linux kernel.
  8. B. Gamsa, O. Krieger, J. Appavoo y M. Stumm describieron un mecanismo similar a RCU utilizado en el sistema operativo de investigación de la Universidad de Toronto Tornado y los sistemas de investigación de IBM Research K42 estrechamente relacionados.
  9. Rusty Russell y Phil Rumpf describieron técnicas similares a RCU para manejar la descarga de módulos del kernel de Linux.
  10. D. Sarma agregó RCU a la versión 2.5.43 del kernel de Linux en octubre de 2002.
  11. Robert Colvin et al. verificaron formalmente un algoritmo de conjunto concurrente perezoso que se asemeja a RCU.
  12. M. Desnoyers et al. publicaron una descripción de la UCR del espacio-usuario.
  13. A. Gotsman et al. derived formal semantics for RCU based on separation logic.
  14. Ilan Frenkel, Roman Geller, Yoram Ramberg y Yoram Snir recibieron la patente de EE.UU. 7,099,932 en 2006. Esta patente describe un mecanismo similar a la UCR para recuperar y almacenar la calidad de la información de gestión de políticas de servicio utilizando un servicio de directorios de manera que ejecute la consistencia de lectura/escritura y permita la concurrencia de lectura/escritura.

Contenido relacionado

SAVIA

49°17′38″N 8°38′22″E / 49.2938038°N 8.639581°E / 49.2938038; 8.639581 SAP SE es una empresa de software multinacional alemana con sede en...

Ejecución especulativa

La ejecución especulativa es una técnica de optimización en la que un sistema informático realiza alguna tarea que puede no ser necesaria. El trabajo se...

Interfaz de nivel de llamada

La interfaz de nivel de llamada es una interfaz de programación de aplicaciones y un estándar de software para incrustar código de lenguaje de consulta...
Más resultados...
Tamaño del texto:
undoredo
format_boldformat_italicformat_underlinedstrikethrough_ssuperscriptsubscriptlink
save