|
RDTSC를 이용한 슬립을 구현하면 됩니다.
#define getTick(count){ \
__asm rdtsc; \
__asm lea ebx, count; \
__asm mov dword ptr [ebx], eax; \
__asm mov dword ptr [ebx + 4], edx; \
}
위에 작성한 것은 64비트 자료형를 파라미터로 받아 전원이 들어온 후 지금까지의
CPU 클럭틱을 가지고 오는 매크로 함수죠.
__int64 start, end;
getTick(start);
::Sleep(1000);
getTick(end);
ShowMessage(end - start);
해 보시면 1초간 CPU 속도 만큼을 카운트 한다는걸 알 수 있죠.
(2.8기가 CPU면 2800000000 회를 카운트 합니다)
쓰레드를 하나 만들고
쓰레드의 실행 함수 안에서
__int64 last, current;
getTick(last);
while(쓰레드 생존여부){
while((getTick(current) - last) < 주기); // 이부분이 주기 만큼을 놉니다.
last = current;
// 부가 작업.... 예를들어 이 쓰레드 타이머에 등록된 함수 (콜백함수)를 호출해 준다거나,
// 이 쓰레드를 생성시킨 윈도우(혹은 윈 컨트롤)에 메시지를 던지면 되죠.
}
이렇게 구성된 타이머 쓰레드를 작성하면 됩니다.
여기서 주기라는걸 나노초와 같은 절대 시간에 맞춰주고 싶다면,
현재 CPU 클럭이 어느정도냐를 위에 언급한 예와 같이 (5초동안 구해서 5로 나눈다든지 하면 더 정확하죠)
산출해서, 그걸 필요 단위 시간으로 다시 나눈 클럭 횟수지요.
물론 이렇게만 구현하면, 처음 1초나 5초동안 산출한 CPU 클럭이 절대적으로 확실한 수치는 아니기에
조금씩 차이가 생길 수도 있습니다만, 일단 나노 수준의 빈도는 보장이 되고,
중간 중간에 현재시간을 읽어 보정을 해 주면 보다 정확해 지지요.
|