Цитата:
Сообщение от falabella
Просьба немного изменилась.
Вот код. Его надо адаптировать под делфи, а выделенную части надо переделать на получение не просто тика, а на зависимость от частоты процессора (т,е. t = 1/f, f - количество тиков в секунду, частоту получить через rdtsc). Особенность моего задания именно в том, что мне нужно получать временные задержки основываясь именно на частоте процессора. Чем больше частота, тем выше точность задржки. Вот в чем суть! Надесь, что сейчас вопрос более понятен.
Код:
#include <windows.h>
#include <iostream>
#include <conio.h>
using namespace std;
class ExactTimer
{
public:
typedef void (*CallbackProc)(void);
ExactTimer()
{
Callback = NULL;
StartThreadHandle = NULL;
RepeatOnce = false;
Milliseconds = 1000;
}
~ExactTimer()
{
Stop();
}
void Start()
{
Stop();
StartThreadHandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(StartThread),(void*)this,NULL,0);
}
void Stop()
{
if (StartThreadHandle != NULL)
{
TerminateThread(StartThreadHandle, 0);
CloseHandle(StartThreadHandle);
StartThreadHandle = NULL;
}
}
void SetMilliseconds(long milliseconds)
{
Milliseconds = milliseconds;
}
long GetMilliseconds() const
{
return Milliseconds;
}
void SetCallbackProcedure(CallbackProc callback)
{
Callback = callback;
}
void SetRepeatOnce(bool repeatOnce)
{
RepeatOnce = repeatOnce;
}
protected:
CallbackProc Callback;
bool RepeatOnce;
bool Repeat;
long Milliseconds;
HANDLE StartThreadHandle;
static DWORD WINAPI StartThread(void *pExactTimer)
{
ExactTimer exactTimer = *((ExactTimer*)pExactTimer);
LARGE_INTEGER liFrequency, liStartTime, liCurrent;
QueryPerformanceFrequency(&liFrequency);
__int64 llWaitTime = ((liFrequency.QuadPart / 1000) * exactTimer.Milliseconds);
while (true)
{
QueryPerformanceCounter(&liStartTime);
QueryPerformanceCounter(&liCurrent);
while ((liCurrent.QuadPart - liStartTime.QuadPart) < llWaitTime)
QueryPerformanceCounter(&liCurrent);
if (exactTimer.Callback != NULL)
exactTimer.Callback();
if (exactTimer.RepeatOnce)
exactTimer.Stop();
}
return 0;
}
};
void PrintTheEnd()
{
cout << " THE END " << endl;
}
int main()
{
ExactTimer t;
t.SetRepeatOnce(false);
t.SetMilliseconds(100);
t.SetCallbackProcedure(PrintTheEnd);
t.Start();
_getch();
t.Stop();
_getch();
return 0;
}
|
Ну, собственно, весь интересный код лежит в функции ExactTimer exactTimer, остальное - шелуха вокруг. Собственно, как я понимаю, эта функция запускается как отдельный поток. Фактически,она и выполняет расчет времени ожидания в зависимости от частоты проца.
Т.е. тело потока будет выглядеть как-то так:
Код:
var
AWaitTime : Int64;
ACurTime, AStartTime : Int64;
CPUFrq : Int64;
begin
QueryPerformanceFrequency(CPUFreq);
AWaitTime := CPUFreq / 1000 * Miliseconds;
QueryPerformanceCounter(AStartTime);
QueryPerformanceCounter(ACurTime);
While Not Terminated Do
Begin
If (ACurTime - AStartTime) > AWaitTime Then
Begin
AStartTime := ACurTime;
If Assigned(FCallBack) Then FCallBack;
End;
QueryPerformanceCounter(ACurTime);
End;
end;