полгода назад тот же вопрос меня мучил. нарыла в какой-то статье реализацию счётчика, маленько переделала под свои нужны. примерно вот так вышло (выкусываю куски кода, ибо весь он сильно объёмный и там не просто счётчики, а отдельный поток с организацией дилеев реализован для моих хардварных нужд):
// это инициализация
#ifndef __linux__
::QueryPerformanceFrequency(&frequency);
simplistic_synchronize(ref_point);
#endif
// это использование
#ifdef __linux__
// pt - типа boost::posix_time::ptime
pt = microsec_clock::universal_time(); // это из boost - там под линём всё OK с таймерами
#else
pt = get_total_microseconds(); // под вендой начинаем извращаться через QueryPerformanceCounter
#endif
детали реализации счётчика под венду:
это файл для счётчика под венду (идея в замерах по счётчику и периодической синхронизации его с системным временем для устранения набежавшей погрешности). взято хоть убей не помню откуда, возможно, что-то я ещё переделывала потом - уже плохо помню чего там было, но код работает:
typedef ptime time_type; // это boost::posix_time::ptime
struct reference_point
{
FILETIME file_time;
LARGE_INTEGER counter;
};
reference_point ref_point;
LARGE_INTEGER frequency;
mutex mtx;
void simplistic_synchronize(reference_point& ref_point)
{
FILETIME ft0 = { 0, 0 },
ft1 = { 0, 0 };
LARGE_INTEGER li;
//
// Spin waiting for a change in system time. Get the matching
// performance counter value for that time.
//
::GetSystemTimeAsFileTime(&ft0);
do
{
::GetSystemTimeAsFileTime(&ft1);
::QueryPerformanceCounter(&li);
}
while ((ft0.dwHighDateTime == ft1.dwHighDateTime) &&
(ft0.dwLowDateTime == ft1.dwLowDateTime));
ref_point.file_time = ft1;
ref_point.counter = li;
}
void get_time(LARGE_INTEGER frequency, const reference_point&
reference, FILETIME& current_time)
{
LARGE_INTEGER li;
::QueryPerformanceCounter(&li);
//
// Calculate performance counter ticks elapsed
//
LARGE_INTEGER ticks_elapsed;
ticks_elapsed.QuadPart = li.QuadPart -
reference.counter.QuadPart;
//
// Translate to 100-nanoseconds intervals (FILETIME
// resolution) and add to
// reference FILETIME to get current FILETIME.
//
ULARGE_INTEGER filetime_ticks,
filetime_ref_as_ul;
filetime_ticks.QuadPart =
(ULONGLONG)((((double)ticks_elapsed.QuadPart/(double)
frequency.QuadPart)*10000000.0)+0.5);
filetime_ref_as_ul.HighPart = reference.file_time.dwHighDateTime;
filetime_ref_as_ul.LowPart = reference.file_time.dwLowDateTime;
filetime_ref_as_ul.QuadPart += filetime_ticks.QuadPart;
//
// Copy to result
//
current_time.dwHighDateTime = filetime_ref_as_ul.HighPart;
current_time.dwLowDateTime = filetime_ref_as_ul.LowPart;
}
time_type create_time(FILETIME& ft) {
// offset is difference (in 100-nanoseconds) from
// 1970-Jan-01 to 1601-Jan-01
boost::uint64_t c1 = 27111902;
boost::uint64_t c2 = 3577643008UL; // 'UL' removes compiler warnings
const boost::uint64_t OFFSET = (c1 << 32) + c2;
boost::uint64_t filetime = ft.dwHighDateTime;
filetime = filetime << 32;
filetime += ft.dwLowDateTime;
filetime -= OFFSET;
// filetime now holds 100-nanoseconds since 1970-Jan-01
// microseconds -- static casts supress warnings
boost::uint32_t sub_sec = static_cast<boost::uint32_t>((filetime % 10000000) / 10);
std::time_t t = static_cast<time_t>(filetime / 10000000); // seconds since epoch
std::tm *curr_ptr = 0;
curr_ptr = std::gmtime(&t);//, &curr);
ptime::date_type d(curr_ptr->tm_year + 1900,
curr_ptr->tm_mon + 1,
curr_ptr->tm_mday);
//The following line will adjusts the fractional second tick in terms
//of the current time system. For example, if the time system
//doesn't support fractional seconds then res_adjust returns 0
//and all the fractional seconds return 0.
int adjust = static_cast<int>(ptime::time_duration_type::rep_type::res_adjust()/1000000);
ptime::time_duration_type td(curr_ptr->tm_hour,
curr_ptr->tm_min,
curr_ptr->tm_sec,
sub_sec * adjust);
return time_type(d,td);
}
time_type get_total_microseconds(void)
{
FILETIME ft;
{
mutex::scoped_lock l(mtx);
get_time(frequency, ref_point, ft);
}
return create_time(ft);
}
P.S. я тут быстро из кода навыдирала кусочков и комменты маленько добавила, могла чего-нить забыть. но в общем, я думаю, идея понятна.