Лучший способ получить абсолютное время?

В настоящее время я пытаюсь получить абсолютное время для использования с pthread_mutex_timedlock, Я знаю, что мне нужно добавить timeval от gettimeofday к timespec а затем добавить мое произвольное количество времени.

Ниже работает, но он может переполниться при умножении на такие большие числа.

Есть ли лучший способ сделать это (мне дают время в миллисекундах):

struct timespec ts;
struct timeval now;
gettimeofday(&now, nullptr);

ts.tv_sec = now.tv_sec + milliseconds / 1000;
ts.tv_nsec = now.tv_usec * 1000000000 * (milliseconds % 1000);

ts.tv_sec += ts.tv_nsec / (1000000000);
ts.tv_nsec %= (1000000000);

Выше я добавляю время, данное с текущим временем, чтобы получить абсолютное время.

Мой альтернативный код:

void timeval_to_timespec(struct timeval* tv, struct timespec* ts)
{
ts->tv_sec = tv->tv_sec;
ts->tv_nsec = tv->tv_usec * 1000;
}

struct timespec add_timespec(struct timespec* a, struct timespec* b)
{
struct timespec result = {a->tv_sec + b->tv_sec, b->tv_nsec + b->tv_nsec};
if(result.tv_nsec >= 1000000000)
{
result.tv_nsec -= 1000000000;
++result.tv_sec;
}
return result;
}

//Convert the milliseconds to timespec.
ts.tv_sec = milliseconds / 1000;
ts.tv_nsec = (milliseconds - (ts.tv_sec * 1000)) * 1000000;

//Convert the current time(timeval) to timespec.
timeval_to_timespec(&now, &spec_now);

ts = add_timespec(&ts, &spec_now); //add the milliseconds to the current time.

Мне интересно, есть ли лучший способ сделать выше. Я бы предпочел не использовать свой альтернативный код, но предыдущий код не кажется слишком безопасным, и я не люблю модуль.

Идеи?

1

Решение

Ваш первый подход на самом деле разумен, за исключением того, что вы допустили некоторые опечатки и ошибки с константами.

Как насчет этого подхода:

ts.tv_sec = now.tv_sec + milliseconds / 1000;
ts.tv_nsec = now.tv_usec * 1000 // 1000 ns per us, not a million!
+ (milliseconds % 1000) * 1000000 // a million ns per ms.
ts.tv_sec += ts.tv_nsec / 1000000000;
ts.tv_nsec %= 1000000000;

Нет опасности того, что второе дополнение переполнит 32-битное int, потому что now.tv_usec * 1000 не более 999 999 000, и (milliseconds % 1000) * 1000000 не более 999 000 000, поэтому сумма не более 1 998 999 000 (а количество секунд, переносимых двумя последними строками, всегда равно 0 или 1).

1

Другие решения


По вопросам рекламы [email protected]