2012-04-24 3 views
2

Я пишу библиотеку потоков, и при планировании потоков мне нужно знать, как долго они были готовы. Каждый экземпляр Thread имеет timeval _timeInReady поля, и когда я нажимаю экземпляр в готовую очередь я называю эту функцию:gettimeofday возвращает отрицательное значение

void Thread::startTiming() { 
    gettimeofday(&_timeInReady, NULL); 
} 

Когда я хочу, чтобы проверить текущее _timeInReady значения я называю:

double Thread::getTimeInReady() const { 
    return TIME(_timeInReady.tv_sec,_timeInReady.tv_usec); 
} 

Где TIME равно #define TIME(a,b) ((a*1000000) + b) Так что я получаю общее время в микросекундах.

Моя проблема в том, что по какой-то причине я получаю сумасшедшие отрицательные значения (например, -10293843), когда я проверяю это поле через некоторое время.

Любые идеи? Благодаря!

+0

Что именно вы наблюдаете, что заставляет вас думать, что у вас есть отрицательные числа? Если это заявление печати, пожалуйста, покажите его. Если это проверка отладчика, сообщите нам об этом подробнее. –

+0

Это был отладчик, затмение – yotamoo

ответ

4

Вы должны вернуть результат в виде 64-разрядного целого числа без знака, как вы хотите результат целое число микросекунд, а не дробное второе (что означало бы возвращение double):

unsigned long long Thread::getTimeInReady() const 
{ 
    return (unsigned long long)_timeInReady.tv_sec * 1000000ULL + 
     (unsigned long long)_timeInReady.tv_usec; 
} 

Ваша система может иметь uint64_t который является более кратким, чем unsigned long long, или вы могли бы typedef его.

1

На моем компьютере все tv_sec, tv_usec и 1000000 подписаны 32-разрядными количествами. Подписано 32-битное значение переполнения, когда его попросят удерживать число больше 2^31 или около того.

В результате, это выражение:

((x.tv_sec*1000000) + x.tv_usec) 

будет переполнение в 2^31/10^6 секунд, или около 2147 секунд. Пока ваша программа работает только с интервалами времени менее 35 минут, вы должны быть в порядке.

Если вы хотите, чтобы представить значения> = 35 минут, попробуйте заменить ваш #define с этим:

#define TIME(a,b) ((a*1000000ull) + b) 

Через стандартных промо-акций, это изменение приведет все ваши математике должны быть выполнены с unsigned long long значениями ,

Возможно, вы можете изменить свой double на uint64_t. Это зависит от вас.