Introducción
En los distintos unix cada proceso tiene definida una prioridad, en base a esta se decide cual de ellos se debe ejecutar primero y cual debe esperar a que una cpu se encuentre libre. Con los sistemas multithread cada uno de los hilos de un proceso puede tener una prioridad distinta, además esta es dinámica, es decir durante su vida puede variar en función de varios parámetros, como pueda ser la carga el sistema, como interactúe con otros hilos, ...
Las Scheduling Classes en Opensolaris
Cuando un threads es creado en Solaris se asigna a una scheduling class, para que nos entendemos esta define el rango de prioridades en el que fluctuará durante su vida. Existen 6 rangos distintos.
Las estructuras para el uso de las distintas clases se cargan de forma dinámica cuando son requeridas. Con mdb podemos ver las que hay actualmente cargadas.
Mirando dentro del kernel
Podemos jugar un poco con kmbd para ver las distintas estructuras del kernel. Con el dcm ::class podemos ver actualmente las distintas prioridades que tenemos cargadas en el kernel
root@myhost:~# mdb -k Loading modules: [ unix genunix specfs dtrace uppc pcplusmp scsi_vhci ufs ip hook neti sctp arp usba md lofs zfs random nfs ipc ptm crypto logindmux sppp ] > ::class SLOT NAME INIT FCN CLASS FCN 0 SYS sys_init sys_classfuncs 1 TS ts_init ts_classfuncs 2 FX fx_init fx_classfuncs 3 0 0 4 0 0 5 0 0 6 0 0 7 0 0 8 0 0 9 0 0
Ahora vamos a jugar un poco, el proceso 475 es la shell de mi consola, al ser un proceso de usuario no relacionado con las X su scheduling class es TS.
> ::ps S PID PPID PGID SID UID FLAGS ADDR NAME R 0 0 0 0 0 0x00000001 fec205d0 sched R 3 0 0 0 0 0x00020001 d5286308 fsflush R 2 0 0 0 0 0x00020001 d5286b88 pageout R 1 0 0 0 0 0x4a004000 d5287408 init R 1559 1 1559 1559 0 0x42000000 d527e890 nscd R 700 1 700 700 0 0x42000000 d94bd140 devfsadm R 681 1 637 637 0 0x4a004000 d526a030 gksu R 682 681 637 637 0 0x4a004000 d94c1038 gnome-terminal R 1768 682 1768 1768 0 0x4a014000 d94bc040 bash R 1784 1768 1784 1768 0 0x4a004000 d94ba348 more R 745 682 745 745 0 0x4a014000 d94bc8c0 bash R 686 682 686 686 0 0x4a014000 d94bd9c0 bash R 1785 686 1785 686 0 0x4a004000 d94babc8 mdb R 685 682 637 637 0 0x5a006000 d94bf340 gnome-pty-helper R 671 1 567 567 0 0x4a004000 d94be240 mixer_applet2 R 670 1 567 567 0 0x4a004000 d94beac0 clock-applet R 667 1 667 667 0 0x42000000 d94c0440 gnome-screensave R 664 1 639 639 0 0x4a004000 d94bfbc0 mapping-daemon R 659 1 567 567 0 0x4a004000 d94c3238 trashapplet
La columna ADDR indica la dirección de memoria de la estructura del proceso, usando un walker podemos ver los distintos threads de este, en nuestro caso solo tenemos 1.
> d94bc8c0 ::walk thread d9a01c00
La dirección de memoria que nos devuelve correspone a la estructura del thread, podéis ver una descripción completa de dicha estructura en el fichero /usr/include/sys/thread.h, en este caso solo nos interesa el campo t_cldata, este es un puntero a la estructura de la scheduling class del thread.
> d9a01c00 ::print kthread_t ! grep t_cldata
t_cldata = 0xd95dea88
Con la dirección de memoria obtenida podemos hacer un volcado de la estructura
de la clase TS.
> 0xd95dea88 ::print tsproc_t
{
ts_timeleft = 0xb
ts_dispwait = 0x8b
ts_cpupri = 0x3b
ts_uprilim = 0
ts_upri = 0
ts_umdpri = 0x3b
ts_scpri = 0x6c17
ts_nice = '\024'
ts_boost = '\0'
ts_flags = 0x2
ts_tp = 0xd9a01c00
ts_next = 0xd531df38
ts_prev = ts_plisthead+0x268
ts_caps = {
csc_cputime = 0
}
}
De los distintos campos podemos destacar:
Aquí hay que aclarar que el usuario solo puede modificar uno de los valores de la formula que establece la prioridad final del thread, los demás son controlados por el kernel.
Con el comando priocntl vamos a cambiar la scheduling class de nuestro proceso a Real Time:
#priocntl -s -c RT -i pid 745
Volvemos a repetir la operación anterior, ahora el campo t_cldata apunta a la estructura de la clase Real Time.
> d9a01c00 ::print kthread_t ! grep t_cldata
t_cldata = 0xd8f9f8c0
> 0xd8f9f8c0 ::print rtproc_t
{
rt_pquantum = 0x64
rt_timeleft = 0x63
rt_pri = 0
rt_flags = 0
rt_tqsignal = 0
rt_tp = 0xd9a01c00
rt_next = 0xd516dcc0
rt_prev = rt_plisthead
}
La linea de comandos
Por suerte no hace falta bucear por el kernel para ver los distintos valores mas significativos asignados a las scheduling classes, aunque como ejercicio didáctico es divertido :)
Con el comando dispadmin los podemos ver y modificar, aunque no es aconsejable hacer cambios salvo que sepamos muy bien lo que estamos haciendo
root@myhost:~# dispadmin -l
CONFIGURED CLASSES
==================
SYS (System Class)
TS (Time Sharing)
FX (Fixed Priority)
RT (Real Time)
root@myhost:~# dispadmin -c TS -g
# Time Sharing Dispatcher Configuration
RES=1000
# ts_quantum ts_tqexp ts_slpret ts_maxwait ts_lwait PRIORITY LEVEL
200 0 50 0 50 # 0
200 0 50 0 50 # 1
200 0 50 0 50 # 2
200 0 50 0 50 # 3
200 0 50 0 50 # 4
200 0 50 0 50 # 5
200 0 50 0 50 # 6
200 0 50 0 50 # 7
200 0 50 0 50 # 8
200 0 50 0 50 # 9
160 0 51 0 51 # 10
160 1 51 0 51 # 11
160 2 51 0 51 # 12
160 3 51 0 51 # 13
160 4 51 0 51 # 14
160 5 51 0 51 # 15
160 6 51 0 51 # 16
160 7 51 0 51 # 17
160 8 51 0 51 # 18
160 9 51 0 51 # 19
120 10 52 0 52 # 20
120 11 52 0 52 # 21
120 12 52 0 52 # 22
120 13 52 0 52 # 23
120 14 52 0 52 # 24
120 15 52 0 52 # 25
120 16 52 0 52 # 26
120 17 52 0 52 # 27
120 18 52 0 52 # 28
120 19 52 0 52 # 29
80 20 53 0 53 # 30
80 21 53 0 53 # 31
80 22 53 0 53 # 32
80 23 53 0 53 # 33
80 24 53 0 53 # 34
80 25 54 0 54 # 35
80 26 54 0 54 # 36
80 27 54 0 54 # 37
80 28 54 0 54 # 38
80 29 54 0 54 # 39
40 30 55 0 55 # 40
40 31 55 0 55 # 41
40 32 55 0 55 # 42
40 33 55 0 55 # 43
40 34 55 0 55 # 44
40 35 56 0 56 # 45
40 36 57 0 57 # 46
40 37 58 0 58 # 47
40 38 58 0 58 # 48
40 39 58 0 59 # 49
40 40 58 0 59 # 50
40 41 58 0 59 # 51
40 42 58 0 59 # 52
40 43 58 0 59 # 53
40 44 58 0 59 # 54
40 45 58 0 59 # 55
40 46 58 0 59 # 56
40 47 58 0 59 # 57
40 48 58 0 59 # 58
20 49 59 32000 59 # 59
Finalmente, como ya hemos visto, con el comando priocntl podemos asignar un
proceso a una Scheduling class determinada.
root@myhost:~# priocntl -s -c RT -i pid 745
root@myhost:~# priocntl -d -i pid 745
REAL TIME PROCESSES:
PID RTPRI TQNTM TQSIG
745 0 1000 0
Por favor envía cualquier comentario a roger.jordan gmail com