programing

운영체제 수준에서 수면은 어떻게 구현됩니까?

iphone6s 2023. 6. 26. 21:08
반응형

운영체제 수준에서 수면은 어떻게 구현됩니까?

나는 단지 어떻게 하는지에 관심이 있습니다.sleep(time in ms)C 라이브러리에서 구현되거나 기본적으로 OS 레벨에서 구현됩니다.

내 생각엔...

  1. 잠시 동안 nop 루프를 수행하는 프로세서 속도를 기준으로 했을 수도 있습니다(sleeve 시간이 정확할지 확신할 수 없습니다)...
  2. 프로세서에 있는 특수 레지스터로, 사용자가 값을 기록하면 프로세서가 지정된 시간 동안 일시 중지됩니다(이는 프로세서가 다른 프로그램도 실행할 수 없기 때문에 매우 비효율적입니다.

단서는?아마도 C 라이브러리 소스 코드가 설명할 수 있을까요?"C"가 그것을 어떻게 실행하는지에 대해 너무 구체적이지 않습니다...저는 일반적으로 "sleep()" 기능이 어떻게 구현되는지 궁금합니다.

Sleep()OS 수준에서 구현됩니다.작업/스레드/프로세스가 절전 모드일 때 프로세서가 회전하지 않습니다.실행 준비 대기열에 스레드를 배치할 시간이 만료될 때까지 해당 스레드는 보류 대기열에 놓입니다(스레드가 실행 준비가 되지 않음).

그 동안 실행할 준비가 된 다른 스레드가 실행됩니다.

실행할 준비가 된 스레드가 없는 경우에만 OS가 유휴 스레드로 이동합니다. 이 스레드는 일반적으로 하드웨어 중단이 발생할 때까지 프로세서를 종료(또는 저전력 상태로 전환)하라는 명령을 내립니다.

(한 임베디드 매우 시스템의 합니다.Sleep()실제로는 바쁜 대기 루프에 지나지 않습니다.

Tanenbaum의 "Modern Operating Systems"와 같은 모든 운영 체제 교과서는 이 문제를 매우 자세히 다룰 것입니다. 거의 모든 운영 체제(오래되고, 저렴하며, 사용된 것도 있음).

질문에 대한 대답은 운영 체제와 구현에 따라 완전히 다릅니다.

이에 대한 간단한 생각:전화할 때sleep()OS는 웨이크업 시간을 계산한 다음 프로세스를 우선 순위 대기열 어딘가에 고정합니다.그런 다음 프로세스가 대기열에서 팝업되기에 충분한 실시간이 경과할 때까지 프로세스 실행 시간을 예약하지 않습니다.

일반적인 운영 체제에서 절전 모드는 커널로 호출됩니다. 커널은 지정된 시간이 경과할 때까지 대기할 프로세스를 설정한 다음 실행할 다른 프로세스를 찾아냅니다.더 나은 작업이 없으면 '유휴 프로세스'가 실행됩니다.시간이 경과하면 스케줄러는 절전 프로세스가 정상임을 확인하고 다시 예약합니다.

루프하는 동안에는 작업을 수행하지 않습니다. 그렇지 않으면 시스템이 마우스, 키보드, 네트워크 등에 응답하지 않습니다.

일반적으로 대부분의 운영 체제에서 수행하는 작업은 지연을 현재 타임스탬프에 추가하여 지연을 요청한 작업이 다시 시작될 때 타임스탬프를 가져오고(당시 실행 중인 우선 순위가 높은 작업이 없다고 가정) 타임스탬프를 기준으로 오름차순으로 정렬된 목록에 [wakeupTimestamp, task pointer]를 추가합니다.그런 다음 OS가 컨텍스트 전환을 수행하고 사용 가능한 다음 태스크를 실행합니다.시스템은 주기적으로 절전 목록의 초기 타임스탬프를 현재 타임스탬프와 비교하고, 마감 시간이 지난 경우 절전 작업을 "준비" 작업 대기열로 이동합니다.

절전 모드는 전달된 시간 값에 대한 작업/스레드를 차단합니다.해당 기간 동안 또는 다른 흥미로운 일(신호 등)이 발생할 때까지 작업을 실행할 수 없게 됩니다.

절전 모드에서 select()를 호출하고 대기할 설명자를 전달하지 않고 절전 모드 기간과 동일한 시간 초과 값을 전달하는 경우는 드물지 않습니다.

시스템은 타이머를 시간이 경과한 후 만료되도록 설정한 다음 타이머가 만료될 때 신호가 전송될 세마포를 대기하여 이를 구현할 수 있습니다.따라서 그것은 그 세마포에서 차단됩니다.

CPU 사용량: 0%
요구 사항:
create_gate(IRQ 핸들러 설정)
pic_mask_clear(특정 인터럽트 사용)
rtc_poll(RTC 설정)
rtc_irq
smp_sm_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_sm_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

사용법 :

mov rax, 1000 (millisecond)
call sleep

괜찮아요.

언급URL : https://stackoverflow.com/questions/1719071/how-is-sleep-implemented-at-the-os-level

반응형