En Off, un shuttle es un contexto hardware extensible. Inicialmente contiene tan sólo un conjunto de registros de propósito general (incluyendo un contador de programa y un puntero a pila). Posteriormente puede extenderse de forma segura para incluir otras partes del contexto no presentes inicialmente: identificadores de espacios de direcciones, niveles de privilegio, mapas de permisos de E/S, etc. A estas extensiones las denominamos propiedades.
Por ejemplo, en la figura 3.10 tendríamos las propiedades
``A'', ``B'' y ``C'', donde ``A'' y ``B'' corresponden con tipos de
recurso que implementan ciertos módulos dentro del
kernel y ``C''
corresponde con un tipo de recurso implementado o suministrado por una
entidad de nivel de aplicación. Como puede verse en dicha figura, la
asociación de shuttles a recursos se produce únicamente a través del
nombre de éstos, manteniendo la modularidad del sistema en cuanto a la
interrelación de Shuttles y gestores de recursos se refiere: los
shuttles sólo saben qué recursos necesitan (por ejemplo, el de la
parte izquierda de la figura necesita ``i'' de tipo ``A'', ``j'' de
tipo ``B'' y ``k'' de tipo ``C''), y su implementación está
completamente aislada de la implementación de estos tipos de recurso.
Discutiremos más sobre las propiedades en el apartado 3.3.3.
Off no implementa tareas ni otras abstracciones equivalentes.
Naturalmente, un Shuttle necesita en la mayoría de los casos--aunque no siempre--algunos recursos además de los registros para poder ejecutar. Ahora bien, dado que estos recursos no necesitan estar contenidos en ninguna abstracción que pudiera actuar de contenedor de recursos los shuttles no necesitan estar contenidos en otra abstracción, al contrario que en otros sistemas donde los ``threads de kernel'' se consideran siempre incluidos en una tarea que incorpora los recursos necesarios.

Figure 3.10: Los Shuttles de Off y los recursos utilizados.
Esta es una de las diferencias entre los shuttles de Off
(figura 3.10) y los threads de otros sistemas
(figura 3.11). En Off, los Shuttles sólo
saben qué recursos necesitan para ejecutar y no se ocupan en
absoluto del mantenimiento del estado de los mismos; tampoco de la
implementación de sus operaciones (de esto se encarga el implementador
o gestor de dicho tipo de recurso). Complementariamente, los recursos
empleados por los shuttles no están asignados o contenidos en ningún
Shuttle. Al contrario, en sistemas como Mach los threads están
contenidos en tareas que a su vez contienen los recursos necesarios
para la ejecución de aquellos. Así, en la figura 3.11
vemos cómo las líneas que unen los threads con las implementaciones de
los recursos utilizados representan la interrelación entre ambos, con
lo que tenemos menos modularidad en la implementación del
kernel. Una
situación como la que representa la figura 3.11 en la
que distintos threads dentro de una misma tarea de Mach tienen
distintos conjuntos de recursos (el de la izquierda de la figura
utiliza tres, y el de la derecha sólo dos) no es realmente
implementable dado que todos los threads de la misma tarea deben
compartir todos los recursos disponibles dentro de la tarea.
Hay una importante diferencia entre la asociación de un Shuttle a un recurso y el esquema utilizado por otros sistemas para el mismo propósito: los shuttles no conocen ni cuantos recursos diferentes hay ni como están estos implementados (lo que también supone que el conjunto de recursos a emplear por un shuttle no está preestablecido y puede alterarse a voluntad).
La asociación de recursos a las abstracciones empleadas para modelar
la ``computación activa'' o el flujo de control de las aplicaciones ya
existía en cierta medida en algunos sistemas desde hace algún tiempo.
Así, Ra [7] permite que sus ``threads'' (llamados
Isibas en Ra) se asocien a espacios de direcciones de tal modo que un
Isiba puede cambiar de dominio de protección a lo largo de su vida.
Sprite [127] emplea un conjunto de módulos dentro del
kernel de tal modo que el estado de uno de sus procesos está
compartimentado: cada módulo (p.ej.: el sistema de ficheros) mantiene
una parte del estado del proceso con independencia del estado
mantenido por otros módulos. Esta arquitectura modular facilita la
construcción de sistemas de migración de procesos al
modularizar
el empaquetamiento del estado de dichos procesos
[54].
En Off se ha empleado este modelo de asociación a recursos de forma intensiva, generalizándose éste mediante la introducción de propiedades que permiten a los shuttles asociarse a todos y cada uno de los recursos necesitados.
De este modo, cada gestor de recursos puede implementar los recursos que suministra del modo que desee y los cambios o adaptaciones en dicha implementación no afectan en absoluto al sistema de Shuttles de Off. Esto no ocurre con tareas y threads, donde ambas conocen en mayor o menor medida qué gestores están implementando qué servicios e incluso, muchas veces, cómo los están implementando.

Figure 3.11: Tareas, threads y recursos utilizados en sistemas tradicionales.
Esta simple abstracción, el Shuttle, también permite a la aplicación
implementar la migración y replicación (de las abstracciones
construidas sobre los shuttles) de un modo sencillo mediante las
funciones freeze y melt, como se indicó en el capítulo
anterior. Si los recursos necesarios para la ejecución de los shuttles
mantienen su disponibilidad en otros nodos y/o son capaces de migrar y
replicarse no hay ningún obstáculo a la distribución y migración de
abstracciones construidas sobre los Shuttles. Nótese que los recursos
del sistema están disponibles en toda la red, por lo que la única
limitación la impondrán los recursos lógicos implementados por
aplicaciones sobre el
kernel.
Por último, un breve comentario sobre sistemas heterogéneos. Los shuttles de Off no tratan de solucionar el problema de la heterogeneidad. En este sentido no incorporan técnica alguna para su operación en sistemas heterogéneos. Si se desea que un mismo shuttle pueda ejecutar en distintas arquitecturas basta con emplear una máquina virtual o alguna otra técnica conocida.
Como vimos en el apartado 2.4.2, los sistemas heterogéneos están contemplados en el diseño de Off aunque es cierto que la solución al problema de la operación distribuida en dichos sistemas la aportan principalmente las aplicaciones del sistema.