Sistemas operativos modernos
Algunas diferencias de hardware, como el tamaño de la RAM, pueden manejarse haciendo que el sistema operativo determine ese valor durante el arranque y lo guarde en una variable. Los asignadores de memoria, por ejemplo, pueden usar la variable de tamaño de RAM para determi nar qué tamaño deben tener el caché de bloques, las tablas de páginas, etc. Incluso tablas estáti cas como la tabla de procesos pueden dimensionarse con base en el total de memoria disponible. Sin embargo, otras diferencias, como el uso de un chip de CPU distinto, no pueden resol verse teniendo un solo binario que determine en tiempo de ejecución qué CPU está en ejecu ción. Una forma de atacar el problema de un origen y múltiples destinos es utilizar compilación condicional. En los archivos fuente se definen ciertas efiquetas en tiempo de compilación para las disfintas configuraciones, y se utilizan para delimitar código que depende de la CPU, la lon gitud de palabra, la MMU, etc. Por ejemplo, imaginemos un sistema operativo que debe ejecu tarse en los chips Pentium y UltraSPARC, que necesitan código de inicialización distinto. Podría escribirse el procedimiento init como se ilustra en la figura 12-5a. Dependiendo del valor de la constante CPU, que se define en el archivo de encabezado config.h, se efectúa un fipo de inicia lización o el otro. Puesto que el binario sólo contiene el código requerido para la máquina de destino, no se pierde eficiencia. #include "config.h" #include "config.h" initO # if (WORD_ LENGTH ==32 ) { typedef Int Register ; #lf( CPU == PENTIUM) #endif /* Inicialización para Pentium aquí V #endif #if( WORD_ LENGTH == 64) typedef long Register; #if( GPU == ULTRASPARC) #endif /* Inicialización para UltraSPARC aquí */ #endif Register RO, R1, R2, R3; (a) (b) } Figura 12-5. a) Compilación condicional que depende de la CPU. b) Compilación condicional que depende de la longitud de palabra (dada por la constante WORD_ LENGThf). Como segundo ejemplo, supongamos que se necesita un tipo de datos Register, que debe ocupar 32 bits en el Penfium y 64 bits en el UltraSPARC. Esto podría manejarse con el códi go condicional de la figura 12-5b (suponiendo que según el compilador los int son de 32 bits y los long son de 64 bits). Una vez que se ha efectuado esta definición (quizá en un archivo de encabezado que se incluye en todas partes), el programador tan sólo declara que las variables son de tipo Register, sabiendo que tendrán la longitud correcta. Claro que el archivo de configuración, config.h, debe definirse en forma correcta. Para el Pentium podría ser algo como lo siguiente: #defineCPU PENT IUM #de fineWORD LENGTH 32
RkJQdWJsaXNoZXIy MjI4NDcx