stringtranslate.com

Programador de cogidas cerebrales

La ubicación de los programadores de procesos en una estructura simplificada del kernel de Linux

Brain Fuck Scheduler ( BFS ) es un programador de procesos diseñado para el núcleo Linux en agosto de 2009 basado en la programación de fecha límite virtual más temprana elegible (EEVDF), [2] como una alternativa al Completely Fair Scheduler (CFS) y al programador O(1) . [3] BFS fue creado por Con Kolivas . [4]

El objetivo de BFS, en comparación con otros planificadores, es proporcionar un planificador con un algoritmo más simple , que no requiera el ajuste de heurísticas o parámetros de ajuste para adaptar el rendimiento a un tipo específico de carga de trabajo computacional . Kolivas afirmó que estos parámetros ajustables eran difíciles de entender para el usuario promedio, especialmente en términos de interacciones de múltiples parámetros entre sí, y afirmó que el uso de dichos parámetros de ajuste a menudo podría resultar en un rendimiento mejorado en un tipo específico de cálculo objetivo, a costa de un peor rendimiento en el caso general. [4] Se ha informado que BFS mejora la capacidad de respuesta en computadoras de escritorio Linux con menos de 16 núcleos . [5]

Poco después de su introducción, el nuevo programador fue noticia dentro de la comunidad Linux, apareciendo en Slashdot , con reseñas en Linux Magazine y Linux Pro Magazine . [3] [6] [7] Aunque ha habido diversas revisiones sobre el rendimiento y la capacidad de respuesta mejorados, Con Kolivas no tenía la intención de que BFS se integrara en el núcleo principal. [4]

Diseño teórico y eficiencia

En 2009, se introdujo BFS y originalmente había utilizado una estructura de datos de lista doblemente enlazada , [8] [9] pero la estructura de datos se trata como una cola . La inserción de tareas es ⁠ ⁠ . [9] : ln 119–120  La búsqueda de tareas para la siguiente tarea a ejecutar es ⁠ ⁠ el peor de los casos. [9] : ln 209  Utiliza una única cola de ejecución global que utilizan todas las CPU. Las tareas con prioridades de programación más altas se ejecutan primero. [9] : ln 4146–4161  Las tareas se ordenan (o distribuyen) y se eligen según la fórmula de fecha límite virtual en todas las políticas, excepto en las clases de prioridad de tiempo real e isócrona.

El comportamiento de ejecución sigue siendo una variación ponderada del Programador Round-Robin, especialmente cuando las tareas tienen la misma prioridad por debajo de la política Isócrona. [9] : ln 1193–1195, 334–335  El intervalo round robin ajustable por el usuario ( porción de tiempo ) es de 6 milisegundos de forma predeterminada, que se eligió como el jitter mínimo justo por debajo de lo detectable por los humanos. [9] : ln 306  Kolivas afirmó que cualquier cosa por debajo de los 6 ms era inútil y cualquier cosa por encima de los 300 ms para la porción de tiempo round robin es inútil en términos de rendimiento. [9] : ln 314–320  Este importante ajuste puede adaptar el programador round robin como un compromiso entre el rendimiento y la latencia. [9] : ln 229–320  Todas las tareas obtienen la misma porción de tiempo con la excepción del FIFO en tiempo real, que se supone que tiene una porción de tiempo infinita. [9] : en 1646, 1212–1218, 4062, 3910 

Kolivas explicó la razón por la que eligió la cola de ejecución única de lista doblemente enlazada en lugar de la cola de ejecución múltiple (round robin [10] : par. 3  ) con la matriz de prioridad [11] [10] por CPU que se usó en su programador RDSL para facilitar la equidad entre el escenario de múltiples CPU y eliminar la complejidad de que cada cola de ejecución en un escenario de múltiples colas de ejecución tenía que mantener sus propias latencias y equidad [de tareas]. [9] : ln 81–92  Afirmó que las latencias deterministas estaban garantizadas con BFS en su iteración posterior de MuQSS. [12] : ln 471–472  También reconoció un posible problema de contención de bloqueo (relacionado con la alteración, eliminación y creación de datos de nodos de tareas) [12] : ln 126–144  con el aumento de CPU y la sobrecarga de la siguiente tarea para la búsqueda de ejecución. [12] : En 472–478  MuQSS intentó resolver esos problemas.

Kolivas luego cambió el diseño a una lista de omisión en la versión v0.480 de BFS en 2016. [13] Esta vez esto alteró la eficiencia del programador. Señaló ⁠ ⁠ inserción de tareas, ⁠ ⁠ búsqueda de tareas; ⁠ ⁠ , con ⁠ ⁠ , para la eliminación de tareas. [13] : ln 4 

Fecha límite virtual

La fórmula de fecha límite virtual es un tiempo límite futuro que es el intervalo de tiempo round robin escalado basado en el nivel nice desplazado por el tiempo actual (en unidades niffy o jiffies de nanosegundos , un contador de tiempo interno del núcleo). [9] : ln 4023, 4063  La fecha límite virtual solo sugiere el orden pero no garantiza que una tarea se ejecutará exactamente en el niffy programado futuro. [9] : ln 161–163 

Primero se crea una tabla de búsqueda de proporciones a priori. [9] : ln 8042–8044  Se basa en una secuencia recursiva. Aumenta un 10% en cada nivel de nice. [9] : ln 161  Sigue un patrón parabólico si se grafica, y las tareas niced se distribuyen como una función cuadrada móvil de 0 a 39 (que corresponde de la prioridad nice más alta a la más baja) como el dominio y de 128 a 5089 como el rango. [9] : ln 177–179, 120, 184–185  La parte móvil proviene de la variable t en la fórmula de fecha límite virtual que Kolivas insinuó.

g(0) = 128g(i) = INT( g(i-1)*11/10 )

La función de mapeo de nice a índice f(n) de la tarea se mapea de nice −20...19 a índice 0...39 para usarse como entrada en la tabla de búsqueda de relación de prioridades. Esta función de mapeo es la macro en sched.h en el encabezado del kernel. La implementación interna del kernel difiere levemente con un rango entre 100 y 140 de prioridad estática, pero los usuarios la verán como −20...19 nice.TASK_USER_PRIO()

La fecha límite virtual se basa en esta fórmula exacta: [9] : ln 4063, 4036, 4033, 1180 

T = 6N = 1<<20d(n,t) = t + g(f(n)) * T * (N/128)

Alternativamente,

[14]

donde d(n,t) es la fecha límite virtual en u64 nanosegundos enteros como una función de nice n y t que es el tiempo actual en niffies, g(i) es la búsqueda en la tabla de relación de prioridades como una función de índice, f(n) es la función de mapeo nice-a-índice de la tarea, T es el intervalo de tiempo round robin en milisegundos, N es una constante de 1 milisegundo en términos de nanosegundos como una aproximación de reducción de latencia del factor de conversión de pero Kolivas usa una constante de base 2 N con aproximadamente esa escala. [9] : ln 1173–1174  Valores más pequeños de d significan que la fecha límite virtual es anterior correspondiente a valores nice negativos. Valores más grandes de d indican que la fecha límite virtual se retrasa más tarde correspondiente a valores nice positivos. Usa esta fórmula siempre que el intervalo de tiempo expira. [9] : ln 5087 

128 en base 2 corresponde a 100 en base 10 y posiblemente a un "pseudo 100". [9] : ln 3415  115 en base 2 corresponde a 90 en base 10. Kolivas usa 128 para " desplazamientos rápidos ", [9] : ln 3846, 1648, 3525  como en la división es desplazamiento a la derecha en base 2.

Políticas de programación

BFS utiliza políticas de programación para determinar qué cantidad de CPU pueden utilizar las tareas. BFS utiliza 4 niveles de programación (llamados políticas de programación o clases de programación) ordenados de mejor a peor, lo que determina cómo se seleccionan las tareas [9] : ln 4146–4161,  y las que están en la parte superior se ejecutan primero.

Cada tarea tiene un valor especial llamado prioridad. En la edición v0.462 (usada en el conjunto de parches del kernel -ck 4.0), hay un total de 103 "colas de prioridad" (también conocidas como prioridad) o valores permitidos que puede tomar. No se utilizó ninguna estructura de datos especial real como cola de prioridad, sino solo la cola de ejecución de lista doblemente enlazada. El valor de prioridad más bajo significa que es más importante y se ejecuta primero.

Política en tiempo real

La política de tiempo real fue diseñada para tareas en tiempo real . Esta política implica que las tareas en ejecución no pueden ser interrumpidas (es decir, precluidas) por tareas con menor prioridad o niveles de política de menor prioridad. Las clases de prioridad consideradas bajo la política de tiempo real por el programador son aquellas marcadas como SCHED_RR y SCHED_FIFO. [9] : ln 351, 1150  El programador trata el round robin en tiempo real (SCHED_RR) y el FIFO en tiempo real (SCHED_FIFO) de manera diferente. [9] : ln 3881–3934 

El diseño estableció las primeras 100 colas de prioridad estáticas. [9] : ln 189 

La tarea que se elegirá para su ejecución se basa en la disponibilidad de la tarea del valor más bajo de prioridad de las 100 colas y la programación FIFO. [9] : ln 4146–4161 

En las bifurcaciones , la prioridad del proceso se degradará a la política normal. [9] : ln 2708 

En caso de uso sin privilegios (es decir, por parte de un usuario no root) de sched_setscheduler llamado con una solicitud de clase de política en tiempo real, el programador degradará la tarea a la política isócrona. [9] : ln 350–359, 5023–5025 

Política isócrona

La política isócrona fue diseñada para un rendimiento casi en tiempo real para usuarios no root . [9] : ln 325 

El diseño estableció una cola de prioridad que, de manera predeterminada, se ejecutaba como tareas en pseudotiempo real, pero que se podía ajustar como un grado de tiempo real. [9] : ln 1201, 346–348 

El comportamiento de la política puede permitir que una tarea se degrade a la política normal [9] : ln 336  cuando excede un porcentaje de manejo de recursos ajustable (70% por defecto [9] : ln 343, 432  ) de 5 segundos escalado al número de CPU en línea y la resolución del temporizador más 1 tic. [9] : ln 343, 3844–3859, 1167, 338  [12] : ln 1678, 4770–4783, 734  La fórmula fue alterada en MuQSS debido al diseño de cola de ejecución múltiple. Las fórmulas exactas son:

donde T es el número total de ticks isócronos, F es la frecuencia del temporizador, n es el número de CPU en línea, R es el porcentaje de manejo de recursos ajustable no en decimal sino como un número entero. La frecuencia del temporizador está establecida en 250 de manera predeterminada y es editable en el núcleo, pero generalmente se ajusta a 100 Hz para servidores y 1000 Hz para escritorios interactivos. 250 es el valor equilibrado. Establecer R en 100 hizo que las tareas se comportaran como tiempo real y 0 hizo que no fuera pseudo-tiempo real y cualquier cosa en el medio fuera pseudo-tiempo real. [9] : ln 346–348 

Se eligió la tarea que tenía una fecha límite virtual más temprana para su ejecución, pero cuando existen múltiples tareas isócronas, se programan como round robin, lo que permite que las tareas ejecuten el valor round robin ajustable (con 6 ms como valor predeterminado) una después de la otra con una probabilidad justa y equitativa sin considerar el nivel agradable. [9] : ln 334 

Este comportamiento de la política isócrona es exclusivo de BFS y MuQSS y no puede implementarse en otros programadores de CPU. [9] : ln 324, 8484–8485  [12] : ln 1287–1288 

Política normal

La política normal fue diseñada para el uso habitual y es la política predeterminada. Las tareas recién creadas suelen marcarse como normales. [9] : ln 502 

El diseño establece una cola de prioridades y las tareas se eligen para ejecutarse primero en función de la fecha límite virtual más temprana.

Política de prioridad de inactividad

La prioridad inactiva fue diseñada para procesos en segundo plano, como programas distribuidos y transcodificadores, de modo que los procesos en primer plano o aquellos por encima de esta política de programación puedan ejecutarse sin interrupciones. [9] : ln 363–368 

El diseño estableció una cola de prioridad y las tareas se pueden promover a la política normal automáticamente para evitar la retención indefinida de recursos . [9] : ln 368 

La siguiente tarea ejecutada con prioridad inactiva con otras que residen en la misma política de prioridad se selecciona por la fecha límite virtual más temprana. [9] : ln 4160–4161 

Derecho preferente de compra

La preempción puede ocurrir cuando una tarea recién lista con una política de prioridad más alta (es decir, mayor prio) tiene una fecha límite virtual anterior a la tarea que se está ejecutando actualmente, la cual será desprogramada y puesta al final de la cola. [9] : ln 169–175  Desprogramado significa que su fecha límite virtual se actualiza. [9] : ln 165–166  El tiempo de la tarea se vuelve a llenar al quantum máximo de round robin cuando ha usado todo su tiempo. [9] : ln 4057–4062, 5856  Si el programador encontró la tarea con el mayor prio con la fecha límite virtual más temprana, se ejecutará en lugar de la tarea menos importante que se está ejecutando actualmente solo si todas las CPU lógicas (incluidos los núcleos hiperprocesados ​​/ subprocesos SMT) están ocupados. El programador retrasará la preempción tanto como sea posible si hay CPU lógicas sin usar.

Si una tarea está marcada con una política de prioridad inactiva, no puede preemitir en absoluto ni siquiera otras tareas marcadas con una política inactiva, sino que utiliza la multitarea cooperativa . [9] : ln 2341–2344 

Ubicación de tareas, múltiples núcleos

Cuando el programador descubre una tarea de activación en un sistema que no es unicore, deberá determinar en qué CPU lógica ejecutar la tarea. El programador favorece primero a la mayoría de los núcleos hiperprocesados ​​inactivos (o subprocesos SMT inactivos ) en la misma CPU en la que se ejecutó la tarea, [9] : ln 261  luego el otro núcleo inactivo de una CPU multinúcleo, [9] : ln 262  luego las otras CPU en el mismo nodo NUMA, [9] : ln 267, 263–266, 255–258  luego todos los núcleos hiperprocesados ​​ocupados / subprocesos SMT / CPU lógicas que se van a interrumpido en el mismo nodo NUMA , [9] : ln 265–267  luego el otro nodo NUMA (remoto) [9] : ln 268–270  y se clasifica en una lista de preferencias. [9] : ln 255–274  Este escaneo especial existe para minimizar la sobrecarga de latencia resultante de la migración de la tarea. [9] : ln 245, 268–272 

El orden de preempción es similar al párrafo anterior. El orden de preempción es el núcleo hiperprocesado / unidades SMT en el mismo multinúcleo primero, luego el otro núcleo en el multinúcleo, luego la otra CPU en el mismo nodo NUMA. [9] : ln 265–267  Cuando comienza a escanear en busca de una tarea para preemptar en el otro nodo NUMA remoto, la preempción es simplemente cualquier hilo ocupado con una prioridad menor o igual o una fecha límite virtual posterior asumiendo que todas las CPU lógicas (incluidos los hilos de núcleo hiperprocesado / SMT) en la máquina están ocupados. [9] : ln 270  El programador tendrá que escanear en busca de una tarea adecuada con una política de prioridad menor o tal vez igual (con una fecha límite virtual posterior si es necesario) para preemptar y evitar CPU lógicas con una tarea con una política de prioridad más alta que no puede preemptar. La preempción local tiene un rango más alto que el escaneo de una unidad NUMA remota inactiva. [9] : ln 265–269 

Cuando una tarea es interrumpida involuntariamente en el momento en que la CPU se ralentiza como resultado del escalado de frecuencia de la CPU mediado por el núcleo (también conocido como gobernador de frecuencia de la CPU), la tarea se marca especialmente como "pegajosa", excepto aquellas marcadas como política de tiempo real. [9] : ln 2085  Marcado como pegajoso indica que la tarea aún tiene tiempo sin usar y la tarea está restringida a la ejecución en la misma CPU. [9] : ln 233–243  La tarea se marcará como pegajosa siempre que el gobernador de escalado de la CPU haya escalado la CPU a una velocidad más lenta. [9] : ln 2082–2107, 8840–8848  La tarea pegajosa inactiva volverá a ejecutarse a la velocidad completa de Ghz por casualidad o se reprogramará para ejecutarse en la mejor CPU inactiva que no sea la misma CPU en la que se ejecutó la tarea. [9] : ln 2082–2086, 239–242, 2068–2079  No es deseable migrar la tarea a otros lugares, sino dejarla inactiva debido a la mayor latencia provocada por la sobrecarga al migrar la tarea a otra CPU o nodo NUMA. [9] : ln 228, 245  Esta característica persistente se eliminó en la última iteración de BFS (v0.512) correspondiente al conjunto de parches 4.8-ck1 de Kolivas y no existía en MuQSS.

herramienta de programación

Un usuario privilegiado puede cambiar la política de prioridad de un proceso con el programa schedtool [9] : ln 326, 373  o lo hace el propio programa. [9] : ln 336  La clase de prioridad se puede manipular a nivel de código con una llamada al sistema como sched_setscheduler solo disponible para root, [15] que utiliza schedtool. [16]

Puntos de referencia

En un estudio contemporáneo, [5] el autor comparó el BFS con el CFS utilizando el kernel de Linux v3.6.2 y varios puntos finales basados ​​en el rendimiento. El propósito de este estudio fue evaluar el Completely Fair Scheduler (CFS) en el kernel de Linux original y el BFS en el kernel correspondiente parcheado con el conjunto de parches ck1. Se utilizaron siete máquinas diferentes para ver si existían diferencias y hasta qué punto escalaban utilizando métricas basadas en el rendimiento. La cantidad de CPU lógicas varió de 1 a 16. Estos puntos finales nunca fueron factores en los objetivos de diseño primarios del BFS. Los resultados fueron alentadores.

Los núcleos parcheados con el conjunto de parches ck1, incluido el BFS, superaron al núcleo estándar que utiliza el CFS en casi todos los puntos de referencia basados ​​en el rendimiento probados. [5] Se podrían realizar estudios adicionales con un conjunto de pruebas más grande, pero en función del pequeño conjunto de pruebas de 7 PC evaluado, estos aumentos en la cola de procesos, la eficiencia/velocidad son, en general, independientes del tipo de CPU (mono, dual, quad, hyperthreaded, etc.), la arquitectura de la CPU (32 bits y 64 bits) y la multiplicidad de la CPU (mono o dual socket).

Además, en varias CPU "modernas", como Intel Core 2 Duo y Core i7 , que representan estaciones de trabajo y computadoras portátiles comunes, BFS superó consistentemente a CFS en el kernel original en todos los puntos de referencia. Las ganancias de eficiencia y velocidad fueron entre pequeñas y moderadas.

Adopción

BFS es el programador predeterminado para las siguientes distribuciones de Linux de escritorio:

Además, BFS se ha añadido a una rama experimental del repositorio de desarrollo de Android de Google . [21] No se incluyó en la versión Froyo después de que las pruebas a ciegas no mostraran una experiencia de usuario mejorada. [22]

MuQSS

BFS se ha retirado en favor de MuQSS , conocido formalmente como Multiple Queue Skiplist Scheduler , una implementación reescrita del mismo concepto. [23] [24] El autor principal abandonó [25] el trabajo en MuQSS a fines de agosto de 2021.

Diseño teórico y eficiencia

MuQSS utiliza una lista de omisión estática bidireccional de 8 niveles y las tareas se ordenan por prioridad estática [colas] (en referencia a la política de programación) y una fecha límite virtual. [12] : ln 519, 525, 537, 588, 608  Se eligió 8 para ajustar la matriz en la línea de caché. [12] : ln 523  Se eligió el diseño de estructura de datos doblemente enlazada para acelerar la eliminación de tareas. Eliminar una tarea toma solo O(1) con una lista de omisión doble en comparación con el diseño original de William Pugh que toma el peor caso. [12] : ln 458 

La inserción de tareas es ⁠ ⁠ . [12] : ln 458  La siguiente tarea para la búsqueda de ejecución es ⁠ ⁠ , donde k es el número de CPU. [12] : ln 589–590, 603, 5125  La siguiente tarea para la ejecución es ⁠ ⁠ por cola de ejecución, [12] : ln 5124  pero el programador examina todas las demás colas de ejecución para mantener la equidad de tareas entre las CPU, para la latencia o el equilibrio (para maximizar el uso de la CPU y la coherencia de la memoria caché en el mismo nodo NUMA sobre aquellos que acceden a través de nodos NUMA), por lo que en última instancia ⁠ ⁠ . [12] : ln 591–593, 497–501, 633–656  El número máximo de tareas que puede manejar son 64k tareas por cola de ejecución por CPU. [12] : ln 521  Utiliza múltiples colas de ejecución de tareas en algunas configuraciones, una cola de ejecución por CPU, mientras que su predecesor BFS solo usaba una cola de ejecución de tareas para todas las CPU.

Las tareas se ordenan como un gradiente en la lista de omisión de manera que la prioridad de la política en tiempo real viene primero y la prioridad de la política inactiva viene al final. [12] : ln 2356–2358  La política de prioridad normal e inactiva todavía se ordena por fecha límite virtual que usa valores agradables . [12] : ln 2353  Las tareas de política en tiempo real e isócrona se ejecutan en orden FIFO ignorando los valores agradables. [12] : ln 2350–2351  Las nuevas tareas con la misma clave se colocan en orden FIFO, lo que significa que las tareas más nuevas se colocan al final de la lista (es decir, el nodo superior verticalmente), y las tareas en el nivel 0 o en la parte inferior delantera se ejecutan primero antes que las más cercanas a la parte superior verticalmente y las más alejadas del nodo principal. [12] : ln 2351–2352, 590  La clave utilizada para la ordenación insertada es la prioridad estática [12] : ln 2345, 2365   o la fecha límite virtual. [12] : ln 2363 

El usuario puede elegir compartir colas de ejecución entre núcleos múltiples o tener una cola de ejecución por CPU lógica. [12] : ln 947–1006  La especulación del diseño de colas de ejecución compartidas fue reducir la latencia con una compensación de rendimiento. [12] : ln 947–1006 

Un nuevo comportamiento introducido por MuQSS fue el uso del temporizador de alta resolución para una precisión inferior a milisegundos cuando se agotaban los intervalos de tiempo, lo que daba como resultado la reprogramación de tareas. [12] : ln 618–630, 3829–3851, 3854–3865, 5316 

Véase también

Referencias

  1. ^ "-ck hacking: versión BFS 0.512, linux-4.8-ck1, MuQSS para linux-4.8". ck-hack.blogspot.com . 2016-10-03 . Consultado el 2016-11-10 .
  2. ^ "El programador de CPU MuQSS [LWN.net]". LWN.net .
  3. ^ ab "Con Kolivas presenta el nuevo planificador BFS » Linux Magazine". Linuxpromagazine.com. 2009-09-02 . Consultado el 2013-10-30 .
  4. ^ abc "Preguntas frecuentes sobre BFS v0.330". Ck.kolivas.org . Consultado el 30 de octubre de 2013 .
  5. ^ abc "Comparación de programadores de CPU" (PDF) . Repo-ck.com . Consultado el 30 de octubre de 2013 .
  6. ^ "Con Kolivas regresa con un programador Linux orientado al escritorio". Slashdot. 6 de septiembre de 2009. Consultado el 30 de octubre de 2013 .
  7. ^ "Ingo Molnar prueba el nuevo programador BF". Linux Magazine. 8 de septiembre de 2009. Consultado el 30 de octubre de 2013 .
  8. ^ "sched-bfs-001.patch". Con Kolivas. 2009-08-13 . Consultado el 2020-10-09 .
  9. ^ abcdefghijklmnopqrstu vwxyz aa ab ac ad ae af ag ah ai aj ak al am an ao ap aq ar as at au av aw ax ay az ba bb bc bd be bf bg bh "4.0-sched-bfs-462.patch". Con Kolivas. 2015-04-16 . Consultado el 29 de enero de 2019 .
  10. ^ ab "El programador de plazos de escalera giratoria". corbet. 2007-03-06 . Consultado el 2019-01-30 .
  11. ^ "sched-rsdl-0.26.patch". Con Kolivas. Archivado desde el original el 26 de julio de 2011. Consultado el 30 de enero de 2019 .
  12. ^ abcdefghijklmnopqrstu v "0001-MultiQueue-Skiplist-Scheduler-version-v0.173.patch". Con Kolivas. 2018-08-27 . Consultado el 2019-01-29 .
  13. ^ ab "4.7-sched-bfs-480.patch". Con Kolivas. 2016-09-02 . Consultado el 2020-10-09 .
  14. ^ La fórmula alternativa se presenta para facilitar la comprensión. Todos los cálculos se realizan con números enteros, por lo que la pérdida de precisión sería importante. Es posible que sea por eso que Kolivas postergó la división por 128 a uno de los números más grandes como múltiplo de 128, lo que no deja resto.
  15. ^ "El programador de Linux". Moshe Bar. 1 de abril de 2000. Consultado el 29 de enero de 2019 .
  16. ^ "schedtool.c". libre. 2017-07-17 . Consultado el 30 de enero de 2019 .
  17. ^ "Sabayon 7 trae el paraíso de Linux". Ostatic.com . Consultado el 30 de octubre de 2013 .
  18. ^ "La edición 2010 ya está disponible para descargar". PCLinuxOS. 2013-10-22 . Consultado el 2013-10-30 .
  19. ^ "Zenwalk 6.4 está listo! - Lanzamientos - Noticias". Zenwalk.org. Archivado desde el original el 23 de octubre de 2013. Consultado el 30 de octubre de 2013 .
  20. ^ "Acerca de GalliumOS - Wiki de GalliumOS". wiki.galliumos.org . Consultado el 8 de junio de 2018 .
  21. ^ [1] Archivado el 22 de septiembre de 2009 en Wayback Machine .
  22. ^ "CyanogenMod 5 para G1/ADP1". Lwn.net . Consultado el 30 de octubre de 2013 .
  23. ^ "ck-hacking: linux-4.8-ck2, MuQSS versión 0.114". ck-hack.blogspot.com . 2016-10-21 . Consultado el 2016-11-10 .
  24. ^ "Con Kolivas anuncia el primer lanzamiento importante de MuQSS, sucesor de BFS - Phoronix".
  25. ^ "5.14 y el futuro de MuQSS y -ck una vez más". ck-hack.blogspot.com . 2021-08-31 . Consultado el 2022-09-20 .

Enlaces externos