¿Cómo se implementa la suspensión a nivel del sistema operativo?

6 minutos de lectura

avatar de usuario
FatDaemon

solo me interesa como sleep(time in ms) se implementa en una biblioteca C o básicamente en el nivel del sistema operativo…

Estoy adivinando…

  1. Puede ser que, en función de la velocidad del procesador, haga un ciclo de nops (no estoy seguro de si el tiempo de suspensión será preciso) …
  2. Cualquier registro especial en el procesador, donde escribe algún valor y el procesador simplemente se detiene por un tiempo específico (esto sería muy ineficiente ya que el procesador no puede ejecutar ni siquiera otros programas).

¿Alguna pista? ¿Probablemente el código fuente de la biblioteca C puede explicar? No soy demasiado particular acerca de cómo “C” lo está implementando … Solo me pregunto en general cómo se implementa la función “dormir ()”.

avatar de usuario
miguel rebabas

Sleep() se implementa a nivel del sistema operativo. El procesador no gira cuando una tarea/subproceso/proceso está inactivo. Ese subproceso en particular se coloca en una cola pendiente (el subproceso no está listo para ejecutarse) hasta que expire el tiempo, momento en el cual el subproceso se colocará en la cola lista para ejecutarse.

Mientras tanto, se ejecutarán otros subprocesos que estén listos para ejecutarse.

Solo si no hay subprocesos listos para ejecutarse, el sistema operativo entrará en el subproceso inactivo, que generalmente emite instrucciones para apagar (o poner en un estado de bajo consumo de todos modos) el procesador hasta que se produzca una interrupción de hardware.

Solo para un sistema muy simple (como el más simple de los sistemas embebidos), podría Sleep() en realidad se implementará como nada más que un ciclo de espera ocupado.

Cualquier libro de texto del sistema operativo, como “Sistemas operativos modernos” de Tanenbaum cubrirá esto con gran detalle, prácticamente cualquiera de ellos (incluso uno viejo, barato y usado).

  • ahhh… así que no está garantizado que se despierte después del tiempo de espera… Depende del programador o básicamente de otras tareas en el sistema…??

    – FatDaemon

    12 de noviembre de 2009 a las 0:43

  • La rapidez con la que la tarea se volverá a ejecutar después de que expire el tiempo de espera depende del programador. El sistema puede garantizar que se ejecutará tan pronto como expire el tiempo de espera, pero creo que la mayoría simplemente lo colocará en el lugar apropiado en la cola lista para ejecutar (que podría estar al frente si la prioridad del subproceso es mayor que cualquier otro), y se ejecutará la próxima vez que se programe.

    – Michael Burr

    12 de noviembre de 2009 a las 0:46

  • Muchos procesadores integrados tienen una instrucción de suspensión dedicada

    – mocj

    12 de noviembre de 2009 a las 2:20

  • @mocj: sí, al volver a leer, lo que dije sobre el subproceso inactivo no fue tan claro como pretendía sobre detener el procesador. Espero que sea un poco mejor ahora.

    – Michael Burr

    12 de noviembre de 2009 a las 6:01

  • esto pasa por alto una explicación muy importante: ¿por qué el programador del sistema operativo tiene tiempo de CPU para manipular la cola en primer lugar? Opción 1: porque se despierta en cada tic del kernel para actualizar su lógica. Opción 2: porque ha configurado un temporizador en la CPU que activa la CPU y el sistema operativo después del período decidido de tiempo de suspensión. (núcleos sin cosquillas)

    – v.oddou

    26 de marzo de 2013 a las 2:48

La respuesta a su pregunta depende completamente del sistema operativo y de la implementación.

Una forma sencilla de pensarlo: cuando llamas sleep(), el sistema operativo calcula el tiempo de activación y luego coloca su proceso en una cola de prioridad en algún lugar. Entonces simplemente no programa su proceso para obtener un tiempo de ejecución hasta que sea suficiente verdadero ha pasado tiempo para que se saque de la cola.

En un sistema operativo típico, la suspensión llama al núcleo, que configura el proceso para que espere hasta que transcurra la cantidad de tiempo especificada, y luego busca otro proceso para ejecutar. En ausencia de algo mejor que hacer, ejecutará el ‘proceso inactivo’. Una vez que transcurra el tiempo, el programador notará que el proceso de suspensión está listo y lo programará nuevamente.

  • Absolutamente y debe tenerse en cuenta que el proceso inactivo es un proceso que ejecuta la instrucción HLT. En las CPU modernas, se vuelve muy complejo y, según el período de tiempo de suspensión, bajará a los modos CN. (C0 despierto, C1 sueño corto,… C7 sueño largo)

    – v.oddou

    26 de marzo de 2013 a las 2:51

No hace ningún bucle while, de lo contrario, el sistema no podrá hacer nada, no responderá al mouse, al teclado, a la red, etc.

Por lo general, lo que hacen la mayoría de los sistemas operativos es agregar el retraso a la marca de tiempo actual para obtener la marca de tiempo cuando se reanudará la tarea que solicitó el retraso (suponiendo que no haya una tarea de mayor prioridad ejecutándose en ese momento) y agregar el [wakeupTimestamp, task pointer] a una lista que se ordena de forma ascendente por la marca de tiempo. Después de eso, el sistema operativo realiza un cambio de contexto y ejecuta la siguiente tarea disponible. Periódicamente, el sistema compara la marca de tiempo más antigua en la lista de espera con la marca de tiempo actual y, si la fecha límite ha vencido, mueve la tarea inactiva a la cola de tareas “listas”.

Sleep bloquea su tarea/hilo por el valor de tiempo transcurrido. Su tarea se vuelve inejecutable durante ese período o hasta que suceda algo más interesante (como una señal), lo que ocurra primero.

No es raro que el modo de suspensión llame a select() y no pase ningún descriptor para esperar y un valor de tiempo de espera igual a su período de suspensión.

El sistema puede implementar esto configurando un temporizador para que caduque después de que transcurra el tiempo y luego esperando en un semáforo que será señalado cuando expire ese temporizador. Por lo tanto, está bloqueado en ese semáforo.

avatar de usuario
ss ana

uso de la CPU: 0%
requisitos:
create_gate (Configurar los controladores de IRQ)
pic_mask_clear (Habilitar interrupciones específicas)
rtc_poll (Configurar RTC)
rtc_irq
smp_wake_up

; In\   RAX = Time in millisecond
; Out\  All registers preserved
sleep:
    push rcx
    push rax

    mov rcx, [rtc_irq.up_time]
    add rax, rcx
.os_delay_loop:
    hlt
    cmp qword [rtc_irq.up_time], rax
    jle .os_delay_loop

    pop rax
    pop rcx
    ret

smp_wake_up

; In\   Nothing
; Out\  Nohting
smp_wakeup_all:
    push rdi
    push rax

    mov rdi, [os_LocalAPICAddress]
    xor eax, eax
    mov [rdi+0x0310], eax   ; Write to the high bits first
    mov eax, 0x000C0080 ; Execute interrupt 0x80
    mov [rdi+0x0300], eax   ; Then write to the low bits

    pop rax
    pop rdi
    ret

rtc_irq:

; UIP (0), RTC@32.768KHz (010), Rate@1024Hz (0110)
; In\   Nothing
; Out\  Nothing
rtc_irq:
    inc qword[.up_time]
    call smp_wakup_all
    ret
.up_time:       dq 0

uso:

mov rax, 1000 (millisecond)
call sleep

está bien

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad