Introducción.
Como veíamos en el artículo de los cambios de contexto, un thread puede ser desalojado de la CPU por varios motivos. Lógicamente llegará un punto en el que tendrá que ser de nuevo alojado para poder continuar con su ejecución. Normalmente las CPUs suelen ser un recurso escaso por lo que fácilmente puede darse el caso que dos o más threads deseen ejecutarse a la vez y no dispongamos de suficientes CPUs libres. Cuando esto sucede el thread de menos prioridad queda a la espera en una dispatch queue, también llamada run queue. Cuando el thread que ocupa la cpu termina, el primero esperando en la queue pasa a ser ejecutado. Hasta aquí es más o menos sencillo, pero puede darse la situación que un thread de más prioridad que el que esta esperando y menor que el que esta ocupando la CPU desee ejecutarse también por lo que tendrá que ser insertado en la posición de la cola que le corresponda, en este caso delante del thread que teníamos esperando. ¿ Fácil verrdad ?, bueno pues así es como NO funciona OpenSolaris, digamos que sería el modelo de un kernel Linux 2.4.x, sin embargo lo he planteado para que se entienda el problema que debemos resolver.Dispatch Queues en Solaris.
La implementación de las colas de ejecución en OpenSolaris es algo más compleja que el modelo anterior, básicamente porque este plantea dos grabes problemas, el primero es que con una sola cola en un sistema multiprocesador habría númerosos interbloqueos en ella, además la necesidad de reordenarla continuamente a medida que nuevos threads con prioridades distintas se ponen en estado runnable es un gran gasto de recursos. Para solventar ambos problemas OpenSolaris crea un set de dispatch queues por cada núcleo de procesador que tenemos. En cada set hay una cola por cada una de las prioridades globales. La excepción son los threads de la scheduling class real time, para estos solo hay un set de colas para todos los procesadores.Jugando con kmdb
Primero vamos a obtener información acerca de las cpus disponibles en nuestro equipo> ::cpuinfo ID ADDR FLG NRUN BSPL PRI RNRN KRNRN SWITCH THREAD PROC 0 3000121a000 1b 0 0 -1 no no t-0 2a10041dcc0 (idle) 1 3000121e000 1b 0 0 -1 no no t-0 2a1004a5cc0 (idle) 2 30001224000 1b 0 0 59 no no t-0 30010cc9c80 sshd 3 0000180c000 1b 0 0 59 no no t-0 300267d9c60 mdb 16 30001228000 1b 0 0 49 no no t-0 30029c3b2c0 oracle 17 3000122c000 1b 0 0 49 no no t-2 30010cd0340 oracle 18 30001232000 1b 0 0 0 no no t-1 30012caf620 oracle 19 30001236000 1b 0 0 165 no no t-0 2a10079fcc0 schedComo vemos nuestro sistema tenemos 8 procesadores, el dcm cpuinfo nos da información acerca de que thread se esta ejecutando y con que prioridad. El campo ADDR apunta a la estructura cpu_t de cada procesador.
> 3000122c000 ::print cpu_t ! grep disp
cpu_disp = 0x60001a35980
cpu_dispthread = 0x30018c53900
cpu_disp_flags = 0
cpu_dispatch_pri = 0x3b
Si volcamos esa estructura vemos que tiene varios campos relacionados con las
dispatch queues, el puntero cpu_disp es la dirección de memoria de la
estructura disp_t con la información más importante de las colas, otro campos
interesantes son cpu_dispthread y cpu_dispatch_pri , que son el thread que se
esta ejecutando actualmente y su prioridad respectivamente.
> 0x60001a35980 ::print disp_t
{
disp_lock = 0
disp_npri = 0xaa
disp_q = 0x60003914000
disp_q_limit = 0x60003914ff0
disp_qactmap = 0x6000296c828
disp_maxrunpri = 0xffff
disp_max_unbound_pri = 0xffff
disp_nrunnable = 0
disp_cpu = 0x3000122c000
Si volcamos la dirección de memoria de la estructura disp_t vemos
más información interesante, disp_q es un puntero a la
dirección de memoria donde está el primer registro del set de
colas, el array esta ordenado de más prioridad a menos.
> 0x60003914000 ::print dispq_t
{
dq_first = 0
dq_last = 0
dq_sruncnt = 0
}
dq_first apunta al primer thread de esta cola, dq_last al último y dq_sruncnt
al total de ellos.> ::cpuinfo ID ADDR FLG NRUN BSPL PRI RNRN KRNRN SWITCH THREAD PROC 0 fec220e8 1b 4 0 59 no no t-1 d49e9c00 mdb > fec220e8 ::walk cpu_dispq d8835600 d8f82a00
Por favor envía cualquier comentario a roger.jordan gmail com