El MCP (Master Control Program) es el sistema operativo de los modelos Burroughs B5000/B5500/B5700 y B6500 y sucesores , incluidos los sistemas Unisys Clearpath/MCP .
MCP se escribió originalmente en 1961 en ESPOL (lenguaje orientado a problemas de sistemas ejecutivos). En la década de 1970, MCP se convirtió en NEWP , que era una forma de ESPOL mejor estructurada, más robusta y más segura.
El MCP fue líder en muchas áreas, entre ellas: el primer sistema operativo en gestionar múltiples procesadores, la primera implementación comercial de memoria virtual y el primer sistema operativo escrito exclusivamente en un lenguaje de alto nivel .
En 1961, el MCP fue el primer sistema operativo escrito exclusivamente en un lenguaje de alto nivel (HLL). El Burroughs Large System ( B5000 [2] y sus sucesores) fue único en el sentido de que fue diseñado con la expectativa de que todo el software, incluido el software del sistema, se escribiera en un HLL en lugar de en lenguaje ensamblador , lo que fue un enfoque único e innovador en 1961.
A diferencia de IBM, que se enfrentó a la competencia de hardware después de la salida de Gene Amdahl , el software de Burroughs solo se ejecutó en hardware de Burroughs debido a la falta de hardware de terceros compatible. Por esta razón, Burroughs fue libre de distribuir el código fuente de todo el software que vendió, incluido el MCP, que fue diseñado con esta apertura en mente. Por ejemplo, la actualización requería que el usuario volviera a compilar el software del sistema y aplicara los parches locales necesarios. En ese momento, esta era una práctica común y era necesaria ya que no era inusual que los clientes (especialmente los grandes, como la Reserva Federal ) modificaran el programa para ajustarlo a sus necesidades específicas. [3] Como resultado, se formó un Grupo de usuarios de Burroughs, que celebraba reuniones anuales y permitía a los usuarios intercambiar sus propias extensiones al sistema operativo y otras partes del paquete de software del sistema. Muchas de estas extensiones se han abierto camino en el código del sistema operativo base a lo largo de los años y ahora están disponibles para todos los clientes. Como tal, el MCP podría considerarse uno de los primeros proyectos de código abierto .
Burroughs no fue el primer fabricante en distribuir código fuente y se introdujo tardíamente en la informática electrónica (en comparación con sus rivales tradicionales NCR, IBM y Univac). Ahora que MCP se ejecuta en hardware comercial, algunos elementos del paquete de software basado en MCP ya no están disponibles en formato fuente por parte de Unisys.
El MCP fue el primer sistema operativo comercial que proporcionó memoria virtual , que ha sido compatible con la arquitectura de sistemas grandes de Burroughs desde su inicio. Este esquema es único en la industria, ya que almacena y recupera objetos definidos por el compilador en lugar de páginas de memoria de tamaño fijo, como consecuencia de su arquitectura general no basada en von Neumann y basada en pila uniforme.
Donald Knuth también tuvo influencia durante este período, convirtiéndose en consultor de Burroughs Corporation, uniéndose al Departamento de Planificación de Productos de 1960 a 1968. Se refiere a "un programa de control" (presumiblemente el MCP entonces en desarrollo) en su libro 'Algoritmos fundamentales' en la sección 2.5 sobre la asignación dinámica de almacenamiento , Knuth se atribuye el mérito de "El método de "etiqueta de límite", introducido en la Sección 2.5, fue diseñado por el autor en 1962 para su uso en un programa de control para la computadora B5000". [4] : 460
Unisys dejó de producir el hardware a principios de la década de 2010 y ahora el sistema operativo se ejecuta bajo emulación. [5]
El MCP proporciona un sistema de archivos con estructuras de directorios jerárquicas. En las primeras implementaciones de MCP, los nodos de directorio se representaban mediante archivos separados con entradas de directorio, como lo hacían otros sistemas. Sin embargo, desde aproximadamente 1970, MCP utiliza internamente un directorio "FLAT" que enumera todas las rutas de archivo en un volumen. Esto se debe a que abrir archivos visitando y abriendo cada directorio en una ruta de archivo era ineficiente y para un entorno de producción se descubrió que era mejor mantener todos los archivos en un solo directorio, aunque mantuvieran el esquema de nombres jerárquico. Desde el punto de vista programático, esto no hace ninguna diferencia. La única diferencia visible para los usuarios es que un archivo de entidad puede tener el mismo nombre que un directorio. Por ejemplo, "A/B" y "A/B/C" pueden existir ambos; "B" puede ser tanto un nodo en un archivo como un directorio.
Los archivos se almacenan en volúmenes con nombre, por ejemplo, "este/es/un/nombredearchivo en myvol", donde "myvol" es el nombre del volumen. Esto es independiente del dispositivo, ya que el disco que contiene "myvol" se puede mover o copiar a diferentes unidades de disco físicas. Los discos también se pueden concatenar para que se pueda instalar un solo volumen en varias unidades, así como duplicarlos para recuperar datos confidenciales. Para mayor flexibilidad, cada programa puede realizar sustituciones de volúmenes; un nombre de volumen se puede sustituir por un nombre alternativo principal y secundario. Esto se conoce como FAMILIA del proceso. Por ejemplo, la asignación "FAMILIA DISCO = USERPACK DE LO CONTRARIO SYSPACK" almacena archivos designados lógicamente en el volumen DISCO en el volumen USERPACK y buscará archivos primero en el volumen USERPACK. Si esa búsqueda no tiene éxito, se realiza otra búsqueda del archivo en el volumen SYSPACK. DISCO es el nombre de volumen predeterminado si no se especifica ninguno.
Cada archivo del sistema tiene un conjunto de atributos de archivo. Estos atributos registran todo tipo de metadatos sobre un archivo, principalmente su nombre y su tipo (que le indica al sistema cómo manejar un archivo, como el código de tipo de archivo de cuatro caracteres más limitado en Macintosh ). Otros atributos incluyen el tamaño de registro del archivo (si es fijo para aplicaciones comerciales), el tamaño de bloque (en múltiplos de registros que le indica al MCP cuántos registros leer y escribir en una única E/S física) y un tamaño de área en múltiplos de bloques, que indica el tamaño de las áreas de disco que se asignarán a medida que el archivo se expande.
El tipo de archivo indica si el archivo contiene datos de caracteres, código fuente escrito en idiomas específicos, datos binarios o archivos de código.
Los archivos están protegidos por los mecanismos de acceso de seguridad habituales, como público o privado, o un archivo puede tener un archivo de protección donde el propietario puede especificar reglas de seguridad complejas.
Otro mecanismo de seguridad es que los archivos de código solo pueden ser creados por compiladores de confianza. Los programadores malintencionados no pueden crear un programa y llamarlo compilador; un programa solo puede ser convertido en compilador por un operador con privilegios suficientes con el comando 'mc' make compiler operator.
El MCP implementa un sistema de archivos con registro en diario , que proporciona tolerancia a fallos en caso de falla del disco, pérdida de energía, etc. No es posible corromper el sistema de archivos (excepto por el sistema operativo u otro software de sistema confiable con acceso directo a sus capas inferiores) [ cita requerida ] .
El sistema de archivos no distingue entre mayúsculas y minúsculas y no las conserva, a menos que se agreguen comillas alrededor del nombre, en cuyo caso distingue entre mayúsculas y minúsculas y las conserva.
Los procesos de MCP se denominan " Trabajos " y " Tareas ". Un Trabajo contiene una o más tareas. Las tareas dentro de un trabajo pueden ejecutarse de manera secuencial o en paralelo. La lógica se puede implementar en el nivel de Trabajo, generalmente en el lenguaje de control de trabajos de MCP WFL, para controlar el flujo de un trabajo. Una vez que se completan todas las tareas de un trabajo, el trabajo en sí se completa.
Un proceso MCP pasa por un ciclo de vida desde el momento en que ingresa al sistema hasta que sale. El estado inicial de un trabajo es "En cola". Hay un período de tiempo mientras el trabajo reside en una de varias colas de trabajos definidas por el usuario. El siguiente estado es "Programado" cuando el trabajo pasa de una cola a la memoria. Las tareas dentro de un trabajo no esperan en la cola, sino que pasan directamente al estado "Programado" cuando se inician. Una vez que se inicia un trabajo o una tarea, puede pasar de "Activo", "En espera" y "Programado" a medida que avanza. Una vez que un trabajo o una tarea se completa, pasa al estado "Completado".
Los procesos en ejecución son aquellos que utilizan un recurso del procesador y están marcados como "en ejecución". Los procesos que están listos para ser asignados a un procesador, cuando no hay ningún procesador libre, se colocan en la cola de listos. A los procesos se les puede asignar una prioridad "Declarada" o "Visible", generalmente 50 como valor predeterminado, pero puede ser de 0 a 99 para los procesos de usuario. A los procesos del sistema se les pueden asignar los valores más altos. Tenga en cuenta que esta prioridad numérica es secundaria a una prioridad general, que se basa en el tipo de tarea. Los procesos que son parte directa del sistema operativo, llamados Ejecutores independientes, tienen la prioridad más alta independientemente del valor de prioridad numérica. A continuación vienen los procesos que utilizan un bloqueo MCP, luego los sistemas de control de mensajes como CANDE . Luego los procesos discontinuados. Luego los trabajos de lenguaje de flujo de trabajo. Finalmente vienen los procesos de usuario. En un nivel inferior, hay una prioridad Fina destinada a elevar la prioridad de las tareas que no utilizan su porción de procesador completa. Esto permite que una tarea vinculada a IO obtenga tiempo de procesador por delante de una tarea vinculada a procesador en la misma prioridad declarada.
Los procesos que esperan otros recursos, como la lectura de un archivo, esperan en la estructura de datos EVENT . Por lo tanto, todos los procesos que esperan en un solo recurso esperan en un solo evento. Cuando el recurso está disponible, se produce el evento, que despierta a todos los procesos que lo esperan. Los procesos pueden esperar varios eventos hasta que se produzca cualquiera de ellos, incluido un tiempo de espera. Los eventos son totalmente programables por el usuario, es decir, los usuarios pueden escribir sistemas que utilicen el sistema de eventos generalizados proporcionado por el MCP.
Los procesos que han finalizado se marcan como completados.
En términos operativos, el estado de todas las tareas del sistema se muestra al operador. Todos los procesos en ejecución y listos se muestran como tareas "activas" (dado que el sistema implementa la multitarea preventiva , el cambio de listo a en ejecución y viceversa es tan rápido que no tiene sentido distinguir las tareas listas de las que se están ejecutando porque todas ellas obtendrán una porción del procesador en un segundo). Todas las tareas activas se pueden mostrar con el comando "A".
Las tareas finalizadas se muestran como tareas completadas con el motivo de la finalización, EOT para el "fin de tarea" normal y DSed con un motivo de un fallo del proceso. A todos los procesos se les asigna un número mixto y los operadores pueden utilizar este número para identificar un proceso a controlar. Uno de estos comandos es el comando DS (que significa Delete from Schedule, Discontinue o Deep Six, en honor a la influencia del personal de la Marina en los primeros proyectos informáticos, según con quién hable). Las tareas finalizadas por el operador se enumeran en las entradas completas como O-DS.
Las tareas también pueden finalizar debido a fallas del programa, marcadas como F-DS o P-DS, por fallas como índice no válido , desbordamiento numérico , etc. El operador puede enumerar las entradas completadas con el comando 'C'.
Las tareas que esperan un recurso se enumeran en las entradas de espera y el motivo de la espera. Todas las tareas en espera se pueden enumerar con el comando 'W'. También se enumera el motivo de la espera y se puede ver más información sobre una tarea con el comando 'Y'. Puede ser que una tarea esté esperando la entrada del operador, que se envía a una tarea mediante el comando accept 'AX' (tenga en cuenta que la entrada del operador es muy diferente de la entrada del usuario, que se ingresaría desde un dispositivo de red con una interfaz gráfica de usuario).
Las tareas que esperan la entrada de un usuario o la lectura de un archivo normalmente no se enumeran como entradas en espera para la atención del operador. Otro motivo por el que una tarea puede estar en espera es que esté esperando un archivo. Cuando un proceso abre un archivo y este no está presente, la tarea se coloca en las entradas en espera, lo que indica que está esperando un archivo determinado. Un operador (o el usuario propietario del proceso) tiene la oportunidad de copiar el archivo al lugar esperado o de redirigir la tarea para que lea el archivo desde otro lugar, o incluso el archivo puede ser creado por un proceso independiente que aún no se ha completado.
Si el operador no puede proporcionar el recurso, puede finalizar la tarea como último recurso. Esto es diferente de otros sistemas, que finalizan automáticamente una tarea cuando un recurso, como un archivo, no está disponible. El MCP proporciona este nivel de recuperabilidad de tareas por parte del operador. Otros sistemas obligan a los programadores a agregar código para verificar la presencia de archivos antes de acceder a ellos y, por lo tanto, se debe escribir código adicional en cada caso para proporcionar recuperabilidad o sincronización de procesos. Dicho código se puede escribir en un programa MCP cuando no es deseable que una tarea espere, pero debido a la recuperabilidad a nivel del operador, esto no es forzado y, por lo tanto, hace que la programación sea mucho más sencilla.
Además de la capacidad de reasignar dinámicamente las solicitudes de archivos (o bases de datos) a otros archivos (o bases de datos), antes o durante la ejecución del programa, existen varios mecanismos disponibles para permitir a los programadores detectar errores y recuperarse de ellos. Una forma, una sentencia "ON", ha existido durante muchos años. Se pueden enumerar errores específicos (por ejemplo, dividir por cero) o se puede utilizar la sentencia "anyfault" para todo. La sentencia o bloque que sigue a la sentencia "ON" es reconocida por el compilador como código de manejo de errores. Durante la ejecución, si ocurre un error recuperable en el ámbito de la sentencia "on", la pila se reduce y el control se transfiere a la sentencia que la sigue.
Un problema con la lógica de manejo detrás de la declaración ON era que solo se invocaría en caso de fallas del programa, no en caso de terminaciones del programa por otras causas. Con el tiempo, aumentó la necesidad de un manejo garantizado de las terminaciones anormales. En particular, se necesitaba un mecanismo que permitiera a los programas invocar complementos escritos por clientes o terceros sin ningún riesgo en caso de que el complemento se comportara mal. Además de los mecanismos generales de complementos, la nueva forma de vinculación dinámica de bibliotecas (Bibliotecas de conexión) permite a los programas importar y exportar funciones y datos, y por lo tanto un programa ejecuta el código proporcionado por otro.
Para lograr una protección tan mejorada, a mediados de los años 90 se introdujo un nuevo mecanismo. En un intento desacertado de lograr compatibilidad, se le dio el nombre de la construcción del lenguaje C++ propuesta en ese momento con el mismo nombre. Como la sintaxis y el comportamiento de ambos difieren en gran medida, la elección del mismo nombre solo ha provocado confusión y malentendidos.
Sintácticamente, las instrucciones "try" se parecen a las instrucciones "if": "try", seguido de una instrucción o bloque, seguido de "else" y otra instrucción o bloque. Pueden añadirse otras cláusulas "else" a la primera. Durante la ejecución, si se produce alguna terminación recuperable en el código que sigue a la cláusula "try", la pila se recorta si es necesario y el control se bifurca al código que sigue a la primera cláusula "else". Además, se establecen atributos para permitir que el programa determine qué ha sucedido y dónde (incluido el número de línea específico).
La mayoría de los eventos que darían como resultado la finalización de una tarea son recuperables. Esto incluye desbordamiento de pila, acceso a matriz fuera de límites, exceso o defecto de flujo de enteros, etc. El operador (o usuario) DS no es recuperable excepto por tareas privilegiadas que utilicen una forma INSEGURA de try.
De esta forma, MCP proporciona un entorno muy tolerante a fallos, no el volcado de núcleo de fallos y fallos de otros sistemas.
Al igual que los atributos de archivo, las tareas también tienen atributos, como la prioridad de la tarea (que se asigna en el momento de la compilación o de la ejecución, o se puede cambiar mientras la tarea se está ejecutando), el tiempo de procesamiento, el tiempo de espera, el estado, etc. Se puede acceder a estos atributos de tarea mediante programación, al igual que a los atributos de archivo de los archivos. La tarea principal está disponible mediante programación como un atributo de tarea que es del tipo tarea. Por ejemplo, 'myself.initiator.name' proporciona el nombre del proceso que inició el proceso actual.
GETSPACE
y FORGETSPACE
son los dos procedimientos principales que manejan la asignación y desasignación de memoria. La memoria debe asignarse al inicio del proceso y siempre que se ingresa a un bloque que usa matrices, archivos, etc. GETSPACE
y FORGETSPACE
no solo manejan espacio de memoria, también asignan o desasignan el espacio de disco donde se pueden superponer datos que no residen en la memoria. La memoria puede ser SAVE (es decir, residente en memoria), OVERLAYABLE (es decir, memoria virtual) o STICKY (es decir, residente en memoria, pero movible). Se los llama, por ejemplo, HARDWAREINTERRUPT
cuando un proceso direcciona una matriz no inicializada o por FILEOPEN
.
HARDWAREINTERRUPT
maneja interrupciones de hardware y puede llamar a GETSPACE
, IO_FINISH
o similares.
BLOCKEXIT
es llamado por una tarea que sale de un bloque. BLOCKEXIT puede a su vez llamar a FILECLOSE
, FORGETSPACE
o similar mientras limpia y libera recursos declarados y utilizados dentro de ese bloque.
J_EDGAR_HOOVER es el principal guardián de seguridad del sistema, al que se llama al iniciar un proceso, abrir un archivo, iniciar sesión el usuario, etc.
GEORGE
es el procedimiento que decide qué proceso es el siguiente en recibir recursos de la CPU y, por lo tanto, es uno de los pocos procesos que utiliza la instrucción MoveStack.
Una tarea pasa por varios estados, comenzando con NASCENT. En DELIVERY se produce el evento BIRTH y el estado de la tarea cambia a ALIVE. Cuando se invoca PROCESSKILL, el estado cambia a DISEASED. Cuando se produce DEATH, la tarea se coloca en la estructura de cola de la MORGUE, después de lo cual todos los recursos restantes se liberan al sistema mediante un proceso llamado PROCESSKILL.
Mientras la tarea está VIVA, las funciones MCP se ejecutan sobre ese proceso en particular, por lo que los recursos de la CPU se cargan automáticamente a la tarea que causa la sobrecarga de MCP. Además, gran parte del trabajo de MCP se realiza con los derechos de seguridad de esa pila en particular. Solo antes de BIRTH y después de DEATH es necesario que el MCP esté funcionando en otra pila. Si no hay ninguna disponible, el sistema mantiene una pila inactiva.
Las bibliotecas MCP proporcionan una forma de compartir datos y código entre procesos. El artículo sobre los grandes sistemas de Burroughs analiza la forma en que los procesos dependientes podrían ejecutarse de forma asincrónica para que muchos procesos pudieran compartir datos comunes (con los mecanismos para proporcionar actualizaciones sincronizadas). Esa familia de procesos relacionados tenía que escribirse como una sola unidad de programa, procesando procedimientos en niveles lex superiores como procesos asincrónicos, que aún podían acceder a variables globales y otras variables en niveles lex inferiores.
Las bibliotecas invirtieron completamente este escenario con las siguientes ventajas:
El mecanismo de la biblioteca era tan limpio y radical que gran parte del software del sistema sufrió importantes reescrituras que dieron como resultado sistemas mejor estructurados y mejoras en el rendimiento.
Las bibliotecas se introdujeron en los sistemas MCP a principios de los años 1980, desarrolladas por Roy Guck y otros en Burroughs . Son muy similares a los monitores de CAR Hoare y proporcionan la oportunidad de exclusión mutua controlada y sincronización entre procesos de cliente, utilizando eventos MCP y la técnica de bloqueo Dahm. Las bibliotecas ofrecen puntos de entrada procedimentales al cliente, que se comprueban para una interfaz compatible (se comprueban todos los parámetros y tipos de retorno de los procedimientos importados) antes de vincular al cliente a la biblioteca. La biblioteca y su cliente pueden estar escritos en diferentes lenguajes. La ventaja es que toda la sincronización se proporciona en la biblioteca y el código del cliente no necesita preocuparse en absoluto por este nivel de programación. Esto da como resultado un código robusto ya que los clientes no pueden socavar el código de sincronización en la biblioteca. (Algunos llamarían a esto una " Iniciativa de Computación Confiable ").
Las bibliotecas son formas más sofisticadas de bibliotecas en otros sistemas, como las DLL . Las bibliotecas MCP pueden ser "compartidas por todos", "compartidas por la unidad de ejecución" o "privadas". El caso privado es el más cercano a las bibliotecas en otros sistemas: para cada cliente se invoca una copia separada de la biblioteca y no hay intercambio de datos entre procesos.
Es más interesante que todos compartan los servicios. Cuando se inicia un cliente, puede ejecutarse durante un tiempo hasta que necesite los servicios de la biblioteca. Tras la primera referencia a un punto de entrada de la biblioteca, se inicia el enlace. Si ya se está ejecutando una instancia de la biblioteca, el cliente se vincula a esa instancia de la biblioteca. Todos los clientes comparten la misma instancia.
El mecanismo compartido por rununit es un mecanismo de uso compartido entre estos dos esquemas de uso compartido. Fue diseñado específicamente para COBOL, donde una rununit se define como el programa cliente de inicio original y todas las bibliotecas a las que se ha vinculado. Cada rununit obtiene una instancia de la biblioteca y las diferentes rununits obtienen una instancia diferente. Esta es la única implementación dinámica de rununits COBOL.
Si esta fuera la primera invocación de la biblioteca, la biblioteca ejecutaría su programa principal (bloque externo en un programa ALGOL) para inicializar su entorno global. Una vez que se completara la inicialización, ejecutaría un congelamiento, en cuyo punto todos los puntos de entrada exportados estarían disponibles para los clientes. En este punto, se decía que la pila de la biblioteca estaba congelada ya que nada más se ejecutaría en esta pila hasta que la biblioteca se descongelara, en cuyo caso se ejecutaría el código de limpieza y terminación. Cuando un cliente llama a una rutina en una biblioteca, esa rutina se ejecuta sobre la pila del cliente, almacenando allí sus variables locales y temporales. Esto permite que muchos clientes ejecuten la misma rutina al mismo tiempo, siendo sincronizados por la rutina de la biblioteca, que accede a los datos en el entorno global de la pila de la biblioteca.
La congelación también podía adoptar tres formas: temporal, permanente y controlada. Temporal significaba que una vez que el número de clientes bajaba a cero, la biblioteca se descongelaba y se terminaba. Permanente significaba que la biblioteca permanecía disponible para otros clientes incluso si el número de clientes bajaba a cero: un operador podía descongelar las bibliotecas permanentes con un comando THAW. Una congelación controlada significaba que la biblioteca seguía funcionando, de modo que podía ejecutar funciones de monitoreo y realizar funciones de inicialización y limpieza de datos para cada cliente vinculado.
También se podía acceder a las bibliotecas "por título" y "por función". En "por título", el cliente especificaba el nombre de archivo de la biblioteca. "Por función" era un método indirecto en el que un cliente simplemente especificaba el nombre de la función de la biblioteca, por ejemplo "system_support", y la ubicación real de la biblioteca se encontraba en una tabla previamente configurada por un operador con comandos "SL" (biblioteca del sistema), por ejemplo "SL system_support = *system/library/support". La actitud tolerante a errores de MCP también funciona aquí: si un cliente intenta acceder a una biblioteca que no está presente, el cliente se coloca en las tareas "en espera" y la biblioteca podría estar presente o la solicitud redirigida.
Las bibliotecas también se pueden actualizar sobre la marcha. Todo lo que se necesita hacer es "SL" (activar la biblioteca) en la nueva versión. Los clientes en ejecución seguirán usando la versión anterior hasta que finalicen y los nuevos clientes serán redirigidos a la nueva versión.
Las bibliotecas de funciones también implementaron una característica de seguridad muy importante: las clases de enlace. Todas las bibliotecas normales tienen una clase de enlace cero. Las bibliotecas utilizadas por el MCP u otros módulos privilegiados del sistema pueden no ser utilizables desde programas normales. Se accede a ellas mediante funciones y se fuerza su uso en la clase de enlace uno. Un cliente en la clase de enlace cero no puede vincularse a puntos de entrada de la clase de enlace uno. Una biblioteca con la clase de enlace uno que necesite ofrecer puntos de entrada a programas normales puede hacerlo si se la designa como "confiable". Puede ofrecer puntos de entrada seleccionados en la clase de enlace cero.
Todo el sistema de base de datos está implementado con bibliotecas que brindan un acceso muy eficiente y personalizado a bases de datos compartidas entre muchos clientes. Lo mismo sucede con todas las funciones de red y los elementos intrínsecos del sistema.
A mediados de los años 1990 se puso a disposición un nuevo tipo de biblioteca: las bibliotecas de conexión. Se trata de programas por derecho propio que pueden ejecutarse de forma independiente, así como importar y exportar datos y funciones a otros programas en matrices de bloques de estructura. Por ejemplo, el componente de red del sistema operativo está disponible como una biblioteca de conexión, lo que permite que otros programas utilicen sus servicios exportando e importando funciones. Tras la vinculación, cada cliente obtiene un bloque de estructura dedicado para mantener la información de estado. Un programa que utiliza la red puede importar una función de escritura de red y exportar una función de lectura de red. Por lo tanto, si abre una conexión de red (por ejemplo, utilizando TCP ), cuando llegan datos para que los lea, el componente de red puede llamar directamente a su función para consumirlos, sin tener que copiar primero los datos a un búfer y hacer un cambio de contexto. Del mismo modo, puede escribir datos en la red llamando directamente a una función de escritura de red.
Las bibliotecas de conexión permiten un grado significativo de control sobre los vínculos. Cada lado de un vínculo puede aprobar opcionalmente un vínculo y puede cortar el vínculo según lo desee. El estado se puede mantener fácilmente por vínculo y también de manera global.
Otra técnica para la comunicación entre procesos (IPC) son los archivos de puerto. Son como las tuberías de Unix , excepto que se generalizan para ser multidireccionales y bidireccionales. Dado que son un orden de magnitud más lentos que otras técnicas de IPC, como las bibliotecas, es mejor utilizar otras técnicas en las que la IPC se realiza entre diferentes procesos en la misma máquina.
Por lo tanto, el uso más ventajoso de los archivos de puerto es para la IPC distribuida. Los archivos de puerto se introdujeron con BNA (Burroughs Network Architecture), pero con la llegada de tecnologías de red estándar como OSI y TCP / IP , los archivos de puerto también se pueden utilizar con estas redes.
Un servidor que escucha conexiones entrantes declara un archivo de puerto (un archivo con el atributo KIND igual a PORT). Cada conexión que se realiza desde un cliente crea un subarchivo con un índice, por lo que cada archivo de puerto representa varias conexiones a diferentes clientes de la red.
Un proceso de servidor recibe solicitudes de clientes desde cualquier parte de la red mediante la emisión de una lectura en el archivo de puerto (subarchivo = 0 para leer desde cualquier subarchivo). Emite una respuesta al cliente que emitió la solicitud escribiendo en el subarchivo particular desde el que se leyó la solicitud.
El MCP también proporciona un entorno de operador sofisticado pero simple. Para instalaciones grandes, es posible que se requiera que muchos operadores pongan a disposición recursos físicos, como impresoras (carga de papel, cartuchos de tóner, etc.). Los entornos de gama baja para oficinas pequeñas o usuarios individuales pueden requerir un entorno sin operadores (especialmente la implementación de la computadora portátil).
Los sistemas grandes tienen terminales de operaciones dedicadas llamadas ODT (Operator Display Terminals), que normalmente se guardan en un entorno seguro. En el caso de los sistemas pequeños, las máquinas se pueden controlar desde cualquier terminal (siempre que el terminal y el usuario tengan los privilegios suficientes) mediante el programa MARC (Menu Assisted Resource Control). Los comandos del operador también pueden ser utilizados por usuarios familiarizados con ellos.
Los comandos de operador son en su mayoría de dos letras (como en Unix) y algunos son de una sola letra. Esto significa que la interfaz de operador debe aprenderse, pero es muy eficiente para operadores experimentados que manejan un gran sistema mainframe día tras día. Los comandos no distinguen entre mayúsculas y minúsculas.
Las tareas se introducen en el programa 'mix' y se identifican mediante números de mix, al igual que las bibliotecas. Para ejecutar un programa, los operadores pueden utilizar el comando 'EX' o 'RUN' seguido del nombre de archivo del programa. Los ODT se ejecutan normalmente con ADM (Modo de visualización automática), que es una visualización personalizable del estado del sistema que suele configurarse para mostrar las entradas de mix activas, en espera y completadas, así como mensajes del sistema al operador para notificaciones o situaciones que requieren la acción del operador.
La lista completa de estas pantallas se da mediante 'A' (activo), 'W' (en espera), 'C' (completado) y 'MSG' (comandos de mensaje).
Si una tarea queda en espera de la acción de algún operador, el operador puede averiguar qué necesita la tarea ingresando su número de combinación seguido del comando 'Y'. (Observe el estilo orientado a objetos de los comandos, seleccionando primero el objeto, seguido del comando). Por ejemplo, '3456Y'.
Un operador puede forzar una tarea en las entradas en espera con el comando de detención '3456ST' y activarla nuevamente con OK: '3456OK'. El comando OK también se puede utilizar cuando un operador ha puesto un recurso a disposición de una tarea, aunque con más frecuencia, el MCP detectará que los recursos se han vuelto disponibles, CAUSARÁ el EVENTO que los procesos han estado esperando sin más intervención del operador. Para pasar información textual de un operador a un programa, se puede utilizar el comando de aceptación '3456AX MORE INFO'. Los programas pueden pasar información a los operadores utilizando el mecanismo DISPLAY, que hace que los mensajes DISPLAY se agreguen a la pantalla MSG.
Además de las tareas y los procesos, los operadores también tienen control sobre los archivos. Los archivos se pueden listar con el comando FILE, copiar con COPY, eliminar con REMOVE y cambiar de nombre.
El entorno operativo del MCP es potente, pero simple y generalmente sólo requiere una fracción del número de operadores de otros sistemas.
Una parte importante del entorno de operaciones es el lenguaje de flujo de trabajo de alto nivel .
Todas las acciones del sistema se registran, por ejemplo, todos los mensajes que se muestran al operador y todas las acciones del operador. Todas las acciones significativas del programa se registran opcionalmente en un registro del sistema y un registro del programa, por ejemplo, BOJ para el comienzo de un trabajo WFL, BOT para el comienzo de una tarea dentro de un trabajo WFL, EOT y EOJ para el final de tareas y trabajos. Además, se pueden registrar todas las aperturas y cierres de archivos y bases de datos. El registro de muchos eventos contribuye a una aparente lentitud del entorno operativo MCP en comparación con sistemas como Unix, ya que todo se registra con escrituras físicas forzadas en el registro del programa después de cada registro, que es lo que sistemas como Unix no hacen, aunque también guardan muchas cosas en los registros del sistema.
Los registros se pueden utilizar con fines forenses para averiguar por qué los programas o sistemas pueden haber fallado, o para detectar intentos de comprometer la seguridad del sistema. Los registros del sistema se cierran automáticamente después de un período que el sistema puede configurar y se abre uno nuevo. Los registros del sistema contienen una gran cantidad de información, que se puede filtrar y analizar con programas como LOGANALYZER.
DUMPANALYZER analiza los volcados de memoria que se escribieron originalmente en cinta. Como todos los compiladores agregaron LINEINFO a los archivos de código, DUMPANALYZER puede identificar exactamente qué instrucción fuente se estaba ejecutando en el momento del error.
Además, un volcado de programa normal, en el que sólo se volcó un programa, contiene información sobre el número de secuencia del código fuente y los nombres de las variables.
Los dos analizadores son herramientas de diagnóstico importantes para todo tipo de propósitos.
Además de las numerosas innovaciones técnicas en el diseño del MCP, los sistemas de gran tamaño de Burroughs tenían muchas innovaciones de gestión que ahora utiliza la comunidad de Internet en general. El software del sistema se envió a los clientes junto con el código fuente y todas las herramientas de edición y compilación necesarias para generar nuevas versiones del MCP para los clientes. Muchos clientes desarrollaron conocimientos especializados sobre el funcionamiento interno del MCP y, a menudo, los clientes enviaban los "parches" (fragmentos de código fuente con números de secuencia) como sugerencias de nuevas funciones mejoradas o correcciones de fallas (FTR, informes de problemas de campo). Muchos de los parches sugeridos fueron incluidos por los desarrolladores de sistemas e integrados en la siguiente versión del lanzamiento del MCP. Incluir una comunidad de expertos voluntarios y autoproclamados en el trabajo técnico general es una práctica generalizada en la actualidad y es la esencia de la innovación abierta . Esta innovación de gestión del desarrollo de la comunidad se remonta a la década de 1970.
Unisys MCP ha tenido varias generaciones de compiladores en su historia que admiten una amplia variedad de lenguajes de programación , incluidos:
Otros productos incluyen:
Anteriormente existían compiladores para ESPOL , COBOL(68), Fortran(66), APL y PL/I .
No hay ningún ensamblador en el sistema operativo Unisys MCP.
El MCP fue el primer sistema operativo desarrollado exclusivamente en un lenguaje de alto nivel. A lo largo de sus 50 años de historia, ha tenido muchas primicias en una implementación comercial, incluyendo memoria virtual, multiprocesamiento simétrico y un lenguaje de control de trabajos de alto nivel (WFL). Desde hace mucho tiempo cuenta con muchas funciones que recién ahora [ ¿cuándo? ] aparecen en otros sistemas operativos generalizados y, junto con la arquitectura de sistemas grandes de Burroughs, el MCP proporciona un entorno de procesamiento de transacciones y multitarea de alto rendimiento y muy seguro [ palabras confusas ] .