Sistemas Operativos

Plan your projects and define important tasks and actions

Comienza Ya. Es Gratis
ó regístrate con tu dirección de correo electrónico
Sistemas Operativos por Mind Map: Sistemas Operativos

1. Memoria

1.1. Auxiliar

1.1.1. También conocida como almacenamiento secundario, es el conjunto de dispositivos y soportes de almacenamiento de datos que conforman el subsistema de memoria de la computadora, junto con la memoria primaria o principal. Puede denominarse periférico de almacenamiento o “memoria periférica”, en contraposición a la ‘memoria central’, porque en ocasiones puede considerarse como periférico de Entrada/Salida. La memoria secundaria es un tipo de almacenamiento masivo y permanente (no volátil) con mayor capacidad para almacenar datos e información que la memoria primaria que es volátil, aunque la memoria secundaria es de menor velocidad.

1.1.1.1. Tipos de tecnología de memoria o almacenamiento

1.1.1.1.1. Almacenamiento óptico En los discos ópticos la información se guarda de una forma secuencial en una espiral que comienza en el centro del disco. Además de la capacidad, estos discos presentan ventajas como la fiabilidad, resistencia a los arañazos, la suciedad y a los efectos de los campos magnéticos. Ejemplos: CD CD-ROM: disco compacto de memoria de sólo lectura CD-R: disco compacto grabable CD-RW: disco compacto regrabable DVD, discos de capacidad de 4,5 hasta 9,4 GB de escritura y múltiples lecturas: DVD±R DVD-R DVD+R DVD±RW: discos de capacidad de 4,5 hasta 9,4GB de múltiples escritura y múltiples lecturas: DVD-RW DVD+RW BD: tecnología de disco de alta densidad, desarrollada por Sony. Ganó la contienda, por ser el nuevo estándar contra su competidor el HD-DVD (DVD de Alta Definición).

1.1.1.1.2. Almacenamiento magneto - óptico                                  Algunos dispositivos combinan la tecnología magnética y óptica, es decir, son dispositivos de almacenamiento híbridos y cuyos soportes son discos magneto-ópticos. Ejemplos: Disco Zip Floptical Minidisc

1.1.1.1.3. Almacenamiento de estado sólido                                                                                                         El dispositivo o unidad de estado sólido (en inglés: Solid-State Drive, SSD) es un dispositivo de almacenamiento de datos que usa memoria no volátil, como la memoria flash, para almacenar datos e información, en lugar de los platos o discos magnéticos giratorios de los dispositivos de discos rígidos convencionales (en inglés, Hard Disk Drive, HDD). Técnicamente no son discos, y a veces se confunde la "D" como disk en vez del término drive (unidad o dispositivo). En comparación con los discos rígidos tradicionales, los dispositivos de estado sólido son menos sensibles a los golpes (más resistentes a los golpes o caídas), son prácticamente inaudibles o silenciosos y tienen un menor tiempo de acceso y de latencia. Los SSD hacen uso de la misma interfaz que los HDD y son fácilmente intercambiables sin tener que recurrir a adaptadores o tarjetas de expansión para compatibilizarlos con el equipo. Ejemplos: Memoria USB. Tarjetas de memoria: Secure Digital (SD), MiniSD, microSD, Memory Stick (MS), MultiMediaCard (MMC), CompactFlash (CF), SmartMedia (SM).

1.2. Virtual

1.2.1. La memoria virtual es una técnica de gestión de la memoria que permite que el sistema operativo disponga, tanto para el software de usuario como para sí mismo, de mayor cantidad de memoria que esté disponible físicamente. La mayoría de los ordenadores tienen cuatro tipos de memoria: registros en la CPU, la memoria caché (tanto dentro como fuera del CPU), la memoria RAM y el disco duro. En ese orden, van de menor capacidad y mayor velocidad a mayor capacidad y menor velocidad.

1.2.1.1. IMPORTANCIA DE LA MEMORIA                                                                                                           Si nos quedamos sin memoria no podremos ejecutar más programas y los que estamos ejecutando tendrán problemas para trabajar con más datos. Además, el uso de memoria virtual puede hacer que tu equipo funcione más lento si es necesario ir por datos al disco duro. Es siempre un compromiso entre la velocidad y la cantidad de datos que el sistema es capaz de procesar. Jamás una configuración de más memoria virtual podrá ser mejor que una ampliación de memoria RAM. Es más, lo ideal sería tener un equipo que no necesitase tener esta característica activada.

1.3. Real

1.3.1. La memoria real o principal es en donde son ejecutados los programas y procesos de una computadora y es el espacio real que existe en memoria para que se ejecuten los procesos. Por lo general esta memoria es de mayor costo que la memoria secundaria, pero el acceso a la información contenida en ella es de más rápido acceso

1.3.1.1. Multiprogramación y uso de memoria Esta organización facilita la programación de una aplicación al dividirla en dos o más procesos. Además ofrece la capacidad de tener más de un proceso a la vez en memoria así puede ofrecer servicios a varios usuarios a la vez.

1.3.1.2. Multiprogramación y uso de memoria Esta organización facilita la programación de una aplicación al dividirla en dos o más procesos. Además ofrece la capacidad de tener más de un proceso a la vez en memoria así puede ofrecer servicios a varios usuarios a la vez. El esquema de multiprogramación incrementa el aprovechamiento del CPU, dado que a diferencia de la monoprogramación en donde solo un proceso reside en memoria a la vez limitando el uso del procesador a las llamadas que requiera dicho proceso, desperdiciando un promedio del 80% del tiempo del procesador. En cambio la multiprogramación, al tener varios procesos en la memoria principal y dividiéndose el tiempo de uso del procesador, logra reducir drásticamente el desperdicio del procesador.

1.3.1.3. Multiprogramación con particiones fijas Para poder implementar la multiprogramación, se puede hacer uso de particiones fijas o variables en la memoria. En el caso de las particiones fijas, la memoria se puede organizar dividiéndose en diversas partes, las cuales pueden variar en tamaño. Esta partición la puede hacer el usuario en forma manual, al iniciar una sesión con la máquina.

2. Administración de memoria

2.1. La memoria se puede definir como los circuitos que permiten almacenar y recuperar la informacion, donde la unidad de almacenamiento es el bit (binary digit) aunque normalmente la consideramos estructurada en bytes u octetos (8 bits). Aunque el byte es la unidad de direccionamiento, solemos hablar de palabras, que se refiere a la longitud de los registros del microprocesador. Así hablamos de microprocesadores de 16 bits, de 32 bits

2.2. Particionada

2.2.1. Las particiones pueden ser del mismo o de distinto tamaño, pero generalmente serán de distinto tamaño. Si las particiones son del mismo tamaño, la ubicación de un proceso en la memoria es trivial, ya que mientras haya una partición libre, puede cargarse un proceso en esa partición. Cuando todas las particiones están ocupadas por procesos que no están listos para ejecutarse, uno de esos procesos debe sacarse y hacer sitio para un nuevo proceso.                                                                                       El particionamiento fijo consiste en la asignación estática de la memoria particionada, que es una forma de hacer posible la multiprogramación, dividiendo la memoria física disponible en varias particiones, cada una de las cuales puede ser asignada a diferentes procesos.

2.3. Simple

2.3.1. Un programa se divide en varios bloques o segmentos que pueden almacenarse en direcciones que no tienen que ser necesariamente adyacentes, por lo que es más compleja pero más eficiente que la asignación continua. El tamaño de los programas está limitado por la cantidad de memoria principal, pero se puede superar este límite con técnicas de “recubrimientos”, con las siguientes características: Si una sección particular del programa ya no es necesaria, se carga otra sección desde el almacenamiento secundario ocupando las áreas de memoria liberadas por la sección que ya no se necesita. La administración manual por programa del recubrimiento es complicada y dificulta el desarrollo y el mantenimiento.

2.4. Paginada

2.4.1. los sistemas de paginación de memoria dividen los programas en pequeñas partes o páginas. Del mismo modo, la memoria es dividida en trozos del mismo tamaño que las páginas llamados marcos de página. De esta forma, la cantidad de memoria desperdiciada por un proceso es el final de su última página, lo que minimiza la fragmentación interna y evita la externa.En un momento cualquiera, la memoria se encuentra ocupada con páginas de diferentes procesos, mientras que algunos marcos están disponibles para su uso. El sistema operativo mantiene una lista de estos últimos marcos, y una tabla por cada proceso, donde consta en qué marco se encuentra cada página del proceso. De esta forma, las páginas de un proceso pueden no estar contiguamente ubicadas en memoria, y pueden intercalarse con las páginas de otros procesos.

2.5. Segmentacion

2.5.1. La segmentación es una técnica de gestión de memoria que pretende acercarse más al punto de vista del usuario. Los programas se desarrollan, generalmente, en torno a un núcleo central (principal) desde el que se bifurca a otras partes (rutinas) o se accede a zonas de datos (tablas, pilas, etc).   Desde este punto de vista, un programa es un conjunto de componentes lógicos de tamaño variable o un conjunto de segmentos, es decir, el espacio lógico de direcciones se considera como un conjunto de segmentos, cada uno definido por un identificador, y consistente de un punto de inicio y el tamaño asignado.

2.6. Relocalizable

2.6.1. Con este esquema de asignación de memoria, el administrador de memoria relocaliza los programas para reunir los bloques vacios y compactarlos, para hacer un bloque de memoria lo bastante grande para aceptar algunas o todas las tareas en espera de entrar. La compactibilidad no es una tarea sencilla. Primero, todos los programas en memoria se deben relocalizar, de manera que queden contiguos; luego hay que ajustar cada dirección y cada referencia a una dirección en todo programa para tomar en consideración la nueva localización del programa en memoria.

3. Conceptos

3.1. Overlays                                                          Para que un proceso pueda ser mayor que la cantidad de memoria que se le ha asignado, a veces se emplea una técnica llamada superposiciones (Overlays). Lo que busca es mantener en la memoria sólo las instrucciones y datos que se necesitan en cualquier momento dado. Si se requieren otras instrucciones, se cargan en un espacio que antes estaba ocupado por instrucciones que ya no se necesitan.

3.2. Swapping                                                                                                                                       Es un mecanismo o modo de interrelacionar la memoria principal (la que contiene el Programa en ejecución, los datos de proceso inmediato y los resultados intermedios) con la secundaria, de tal modo que se produce un intercambio de programas entre ambas cuyo resultado es la simulación de un sistema multitarea o la potenciación de memoria central a base de recursos de la memoria secundaria.

3.3. Carga y enlace dinámico                                                                                                             Su función principal es proteger  la carga en memoria de un modulo hasta que el programa lo llame,como también tenemos el "Enlace dinámico"  que es otro caso de carga dinámica , es aquel en el cual la biblioteca de código se enlazada cuando un determinado programa se ejecuta en posición contraria a  un enlace estático que se produce en un tiempo de proceso de compilación. Este tipo de enlace tiene grandes ventajas , por ejemplo: hace que el programa sea mas liviano y puede evitar las duplicaciones de código.

4. El Procesador

4.1. Diagramas de estado

4.1.1. Diagrama de estados simplificado Activo: el proceso está empleando la CPU, por tanto, está ejecutándose. Pueden haber tantos procesos activos como procesadores haya disponibles. Por tanto, si el sistema dispone de un único procesador, únicamente puede haber un proceso activo a la vez.                                     Preparado: el proceso no está ejecutándose pero es candidato a pasar a estado activo. Es el planificador el que, en base a un criterio de planificación, decide qué proceso selecciona de la lista de procesos preparados para pasar a estado activo.                                                             Bloqueado: el proceso está pendiente de un evento externo que le ha hecho bloquear, tales como una operación de lectura/escritura, la espera de finalización de un proceso hijo, una señal o una operación sobre un semáforo. El dispositivo/hecho externo "avisa" al S.O. cuando ha terminado la acción que realizaba mediante una INTERRUPCIÓN, dejando el S.O. lo que está haciendo para atender a esta última. Tras esto, el S.O. comprueba cuales son los procesos que fueron bloqueados por ese evento externo, cambiándolos al estado de preparado.

4.1.2. Diagrama de Estados Ampliado En espera / Preparación: Estado por el que pasan los procesos antes de pasar a estar preparados por primera vez. Los procesos, cuando comienzan a existir, no están preparados para comenzar a ejecutar instrucciones hasta que el sistema no ha llevado a cabo una serie de actividades. Una vez que el proceso está completamente cargado, ya se puede producir la primera transición al estado preparado.                                       Terminado: La transición de activo a este estado ocurre cuando el proceso realiza una llamada al sistema solicitando su propia terminación. En estas circunstancias, hay estructuras de datos correspondientes al proceso que no pueden ser liberadas hasta que el proceso padre del que está terminando recoja el código de terminación del mismo. Hasta que esto ocurra, estas estructuras se mantendrán y el proceso seguirá existiendo en estado terminado.                                                             Transición: cuando se completa la operación que mantiene a un proceso en estado bloqueado termina, el proceso puede haber perdido parte de los recursos que necesita para proseguir su ejecución.

4.2. Diagrama Trabajos y Procesos

4.2.1. Son representaciones gráficas de toda una secuencia de actividades que se siguen dentro de un proceso o procedimiento. Además posee información importante para el análisis del problema, tal como distancia recorrida, tiempo requerido y cantidad considerada. Son considerados en la actualidad por la mayoría de las empresas como uno de los principales instrumentos para la realización de cualquier método o sistema. Algunos de estos se desarrollan de manera esquemática y otros, siguiendo los pasos y símbolos de los diagramas de flujo que describen de forma más detallada, y además expresan también condiciones que tengan los procesos, si éstos poseen.

5. Modulo asignacion del procesador

5.1. La Asignación estática de memoria consiste en el proceso de asignar memoria en tiempo de compilacion antes de que el programa asociado sea ejecutado, a diferencia de la asignacion dinamica o la automatica donde la memoria se asigna a medida que se necesita en tiempo de ejuecucion .

5.1.1. Asignación automática de memoria Las variables automáticas son variables locales a un bloque de sentencias (subrutina, función o procedimiento). Pueden ser asignadas automáticamente en la pila de datos cuando se entra en el bloque de código. Cuando se sale del bloque, las variables son automáticamente desasignadas.3 Las variables automáticas tendrán un valor sin definir cuando son declaradas, por tanto es buena práctica de programación inicializarlas con un valor válido antes de usarlas.

5.1.2. Asignación dinámica de memoria En ciencia de la computación, asignación dinámica de la memoria es la asignación de almacenamiento de memoria para utilización por parte de un programa de computador durante el tiempo de ejecución de ese programa. Es una manera de distribuir la propiedad de recursos de memoria limitada entre muchas piezas de código y datos. Un objeto asignado dinámicamente permanece asignado hasta que es desasignado explícitamente, o por el programador o por un recolector de basura; esto es notablemente diferente de la asignación automática de memoria y de la asignación estática de memoria (la de las variables estáticas). Se dice que tal objeto tiene tiempo de vida dinámico.

5.1.2.1. Soluciones para los problemas de asignación La tarea de satisfacer una petición de asignación, la cual conlleva encontrar un bloque de memoria sin usar de cierto tamaño en el heap, es un problema complicado. Se han propuesto una amplia variedad de soluciones, incluyendo listas de bloques libres, Paginación, y Asignación buddy de memoria. El problema principal para la mayoría de algoritmos de asignación de memoria dinámica es evitar la fragmentación interna y externa mientras se mantiene la eficiencia del algoritmo. También, la mayoría de algoritmos en uso tienen el problema de que un número grande de pequeñas asignaciones pueden causar el desaprovechamiento del espacio debido a la recolección de metadatos; así la mayoría de los programadores intentan evitar esto, a veces usando una estrategia llamada chunking.

5.1.3. Asignación de bloques de tamaño fijo                                                                                                 Una aplicación de esta técnica conlleva que un módulo de programa (por ejemplo función o subrutina) declara datos estáticos de forma local, de forma que estos datos son inaccesibles desde otros módulos a menos que se les pasen referenciados como parámetros o que les sean devueltos por la función. Se mantiene una copia simple de los datos estáticos, accesible a través de llamadas a la función en la cual han sido declarados. El uso de variables estáticas dentro de una clase en la programación orientada a objetos permite que una copia individual de tales datos se comparta entre todos los objetos de esa clase. Las constantes conocidas en tiempo de compilación, como literales de tipo cadena, se asignan normalmente de forma estática. En programación orientada a objetos, el método usual para las tablas de clases también es la asignación estática de memoria.

5.1.4. Asignación automática de memoria Las variables automáticas son variables locales a un bloque de sentencias (subrutina, función o procedimiento). Pueden ser asignadas automáticamente en la pila de datos cuando se entra en el bloque de código. Cuando se sale del bloque, las variables son automáticamente desasignadas.3 Las variables automáticas tendrán un valor sin definir cuando son declaradas, por tanto es buena práctica de programación inicializarlas con un valor válido antes de usarlas.

5.1.5. Asignación dinámica de memoria En ciencia de la computación, asignación dinámica de la memoria es la asignación de almacenamiento de memoria para utilización por parte de un programa de computador durante el tiempo de ejecución de ese programa. Es una manera de distribuir la propiedad de recursos de memoria limitada entre muchas piezas de código y datos. Un objeto asignado dinámicamente permanece asignado hasta que es desasignado explícitamente, o por el programador o por un recolector de basura; esto es notablemente diferente de la asignación automática de memoria y de la asignación estática de memoria (la de las variables estáticas). Se dice que tal objeto tiene tiempo de vida dinámico.

5.1.5.1. Soluciones para los problemas de asignación La tarea de satisfacer una petición de asignación, la cual conlleva encontrar un bloque de memoria sin usar de cierto tamaño en el heap, es un problema complicado. Se han propuesto una amplia variedad de soluciones, incluyendo listas de bloques libres, Paginación, y Asignación buddy de memoria. El problema principal para la mayoría de algoritmos de asignación de memoria dinámica es evitar la fragmentación interna y externa mientras se mantiene la eficiencia del algoritmo. También, la mayoría de algoritmos en uso tienen el problema de que un número grande de pequeñas asignaciones pueden causar el desaprovechamiento del espacio debido a la recolección de metadatos; así la mayoría de los programadores intentan evitar esto, a veces usando una estrategia llamada chunking.

6. Sincronizacion de procesos

6.1. La comunicación entre procesos: necesaria si se desea que varios procesos puedan colaborar para realizar una misma tarea. Sincronizacion, funcionamiento y coordinado en la resolución de una tarea encomendada. El SO ofrece mecanismos básicos de comunicación, que permiten transferir cadenas de bytes. Deben ser los procesos que se comunican quienes interpreten el significado de las cadenas transferidas para su labor coordinada. Los mecanismos de comunicación y sincronización son dinámicos. Es decir, cuando se necesita un mecanismo de este estilo, se crea, usa y destruye, de forma que no se establezca de forma definitiva ningún mecanismo de comunicación, ya que ellos podrían producir efectos indeseados. Es decir, la comunicación es algo puntual. Los servicios básicos de comunicación son: crear: el proceso solicita la creación del mecanismo.                                                              enviar o escribir: el proceso emisor envía información al proceso receptor.                                        recibir o leer: el proceso receptor recibe información.                                                                 destruir: el proceso solicita la destrucción del mecanismo de comunicación.

7. Abrazo mortal

7.1. Se entiende como recurso un elemento que un programa o proceso puede utilizar en la computadora donde se está ejecutando. Se engloban bajo el concepto de recurso, tanto los dispositivos hardware (por ejemplo, una impresora), como una cierta cantidad de información (por ejemplo, un registro de un archivo). No obstante, en una computadora pueden existir muchos tipos de recursos, e incluso varios del mismo tipo. Por ello definiremos un recurso como algo que puede ser utilizado por un solo proceso en un instante dado. Para que el proceso pueda utilizar un recurso, deberá realizar la siguiente secuencia de operaciones: · Solicitar el recurso. Si no estuviera disponible el proceso, quedará bloqueado hasta que le pueda ser asignado. · Utilizar el recurso. · Liberar el recurso Modelo En primer lugar vamos a definir lo que entendemos por Abrazo Mortal. Se dice que un conjunto de procesos han alcanzado un estado de Abrazo Mortal si cada uno de ellos espera que ocurra algo que sólo puede ser producido por uno de los procesos del propio conjunto (no necesariamente tiene que ser el mismo suceso). Como todos los procesos están en espera, ninguno de ello será el primero en producir el suceso deseado y por tanto permanecerá esperando indefinidamente. Para formalizar todo lo expuesto hasta el momento, vamos a fijar los principios en que se basa todo sistema informático: · Posee un número finito de recursos. · Existe un número finito de procesos que compiten por los recursos. · Los recursos se pueden dividir en tipos de tal forma que cada uno de ellos esté compuesto por recursos idénticos entre sí. · Los procesos deben realizar las tres acciones expuestas anteriormente sobre los recursos: solicitar, utilizar, liberar. · Un proceso puede pedir tantos recursos como necesite para realizar su trabajo, ya sean del mismo tipo o no, siempre que no excedan del total existente en el sistema. · Las operaciones sobre los recursos se realizarán a través de llamadas al sistema operativo, de manera que si se solicita un recurso que está siendo utilizado, quedará bloqueado en espera de que se libere dicho recurso.

8. Condiciones de corrida

8.1. REGLA DURA DEL COMPARTIMIENTO DE RECURSOS: “Cada vez que un recurso (hard o soft) es compartido a travez de un hilo de ejecucion, y existe la posibilidad de que un hilo pueda encontrar un estado inconsistente del recurso, debemos explicitamente administrar el acceso al recurso”. La tecnica mas comun para la administracion de acceso es llamada LOCKING o EXCLUSION MUTUA.

8.2. SEMAFOROS Y MUTEXES: La meta de agregar locking a nuestra aplicacion es que las operaciones sobre nuestras estructuras de datos sean atomicas. Para esto tenemos que definir y marcar las secciones criticas (que son las secciones de codigo que pueden ser ejecutadas por solo un thread a la vez). Pero no todas estas secciones criticas son iguales. Por esto el kernel provee diferentes primitivas para diferentes necesidades. En esta contexto usamos mucho la frase “go to sleep”. en los casos donde un proceso llega a un punto dende no puede seguir su flijo de proceso, “se va a dormir” (o se bloquea) cediendo el procesador a alguien mas hasta que en algun punto en el futuro el pueda seguir haciendo su trabajo y se despierte. Por lo general los procesos duermen cuando se quedan esperando que operaciones de I/O se completen. A medida que vamos entrando en las profundidades del kernel veremos bastantes situaciones donde no podemos dormir. Los semaforos son un concepto bien entendido en las ciencias de la computacion. Como nucleo tenemos que un semaforo es un solo entero combinado con un par de funciones que son tipicamente llamadas P (down) y V (up). Cuando un semaforo es usado para exclusion mutua – mantener multiples procesos corriendo con una seccion critica simultaneamente – el valor inicial se setea en 1. Este semaforo puede ser posieido por un solo proceso o hilo en un tiempo determinado (esto es llamado MUTEX).

8.3. SEMAFOROS DE LECTURA/ESCRITURA: Los semaforos proveen exclusion mutua para todos los llamantes, sin importar que es lo que el hilo quiera hacer. La mayoria de las tareas se pueden dividir en 2 tipos: • Lectura de los datos protegidos • Cambios (o escritura) de los datos protegidos Por lo tanto es posible tener muchos lectores concurrentes, mientras nadie trate de hacer ningun cambio. Hacinedo esto optimizamos la performance, ya que las tareas de solo lectura pueden hacer su trabajo en paralelo sin tener que esperar a que otros lectores salgan de la seccion critica. Para esto linux provee un tipo espacial de semaforo llamado rwsem (<linux/rwsem.h>) Y tenemos las funciones para actuar sobre el: Inicializacion void init_rwsem(struct rw_semaphore *sem) Lectura void down_read(struct rw_semaphore *sem) int down_read_trylock(struct rw_semaphore *sem) void up_read(struct rw_semaphore *sem) y las funciones para escritura void down_write(struct rw_semaphore *sem) int down_write_trylock(struct rw_semaphore *sem) void up_write(struct rw_semaphore *sem) void downgrade_write(struct rw_semaphore *sem) Entonces rwsem permite que un escritor o una cantidad ilimitada lectores tenga el semaforo. Los escritores tienen prioridad. Cuando un escritor entra a la seccion critica ningun lector podra acceder. Por esto rwsem es usado cuando el acceso para escritura son por periodos cortos y ocurren casi nunca y tenemos muchos accesos de lectura.

8.4. COMPLETIONS: Un patron comun en la programacion del kernel involucra inicial alguna actividad fuera del hilo actual y luego esperar a que esta actividad se complete. Esta actividad puede ser tanto la creacion de un nuevo hilo de kernel o un proceso de espacio de usuario, un request a algun proceso existent, o alguna accion sobre algun hardware. EN esto casos puede ser tentador usar un semaforo para sincronizar las dos tareas: EJ: struct semaphore sem; init_mutex_locked(&sem); start_external_task(&sem); down(&sem);