El servidor de Shuttles, el de portales y el DMM emplean versiones simplificadas del Slab allocator de Solaris [22] para almacenar las estructuras de datos correspondientes a Shuttles, Portales y DTLBs.
Un Slab en Off es tan sólo un vector capaz de crecer dinámicamente
que sabe agrupar en una serie páginas de memoria virtual del
kernel
estructuras de datos del mismo tamaño. A diferencia de un simple
vector dinámico, un Slab sabe empaquetar los objetos por él asignados
en páginas de memoria, evitando que un objeto atraviese un límite
entre dos páginas, manteniendo en cada página objetos del mismo
tamaño, etc. A pesar de que los Slabs empleados en la implementación
actual son capaces de preinicializar
los objetos que contienen
(véase [22]), la simplicidad de las
estructuras de datos contenidas en ellos hicieron innecesario el
empleo de esta habilidad.
Los servidores combinan el empleo de Slabs y la posibilidad de incluir
alguna información extra en el campo slot de los
identificadores de los objetos del sistema para optimizar la
localización de los objetos que implementan. Cuando se crea un objeto
y se obtiene almacenamiento en el Slab del servidor correspondiente,
el campo slot de su identificador (ver
apartado 2.1.7) se inicializa con el índice de dicho objeto
en el Slab. De este modo, cuando se efectúa una petición al servidor
que implementa el objeto, el servidor extrae del identificador del
objeto el campo slot y lo utiliza como índice en el Slab. En
todos aquellos casos en que el objeto considerado no ha migrado, la
obtención de la estructura de datos a partir del identificador habrá
sido extremadamente rápida: una indexación y una comparación.
Concretamente, los servidores del sistema que implementan recursos
lógicos emplean la función needs mostrada en la
figura 3.4. Dicha función tiene como propósito obtener la
estructura de datos de un recurso lógico a partir de su identificador.
Primero se indexa en el Slab como se mencionó en el párrafo anterior.
Seguidamente se comprueba que el identificador del objeto almacenado
en el Slab corresponde con el del objeto deseado. En caso afirmativo
tenemos el identificador del objeto. En caso negativo deberemos
emplear una tabla hash de relocalización (que básicamente permite
encontrar aquellos objetos que, aun estando en el Slab, no se
encuentran en la posición indicada por el campo slot de su
identificador) y posiblemente sea preciso enviar excepciones a la
aplicación, tal y como se ve en el código de la función.

Figure: Obtención del descriptor de un objeto a partir de su
identificador.
Por último, hay un detalle que conviene considerar. Para evitar que
una aplicación solicitando un excesivo número de shuttles, portales o
DTLBs agote los recursos del sistema, los Slabs empleados emplean
memoria virtual del
kernel que es posible paginar
.
Cuando una aplicación crea un número excesivo de recursos lógicos
sencillamente aumentará la probabilidad de que la escojan para
expulsión de algunas de las páginas que emplea (debido a que también
se consideran suyas las páginas que utiliza el
kernel para almacenar
las estructuras de datos de los recursos suministrados por el
kernel a
la aplicación). Dicho de otro modo, a pesar de que shuttles, portales
y DTLBs están dentro del kernel y no son modificables directamente
por las aplicaciones, la memoria que ocupan estos recursos está
registrada a nombre de las aplicaciones que los crearon (y no está
asignada al kernel, aunque sea éste el único capaz de escribir dicha
memoria). En la figura 3.5 puede verse un ejemplo donde
el parte del Slab empleado para portales está ausente debido al número
excesivo de portales empleado por varias aplicaciones.

Figure 3.5: Los Slabs pueden paginarse.