Я использую ALSA в асинхронном режиме с обратными вызовами (snd_async_add_pcm_handler ()). Каждый обратный вызов ALSA вызывается из обработчика сигнала SIGIO. Каждый обратный вызов вызывает мою функцию getCurrentTimeMs () :
// Return current milliseconds (don't care - local time or UTC).
long long getCurrentTimeMs(void)
{
std::cout << "+"; std::cout.flush();
long long ret = 0;
#define Z
#ifdef Z
struct timespec ts;
clock_gettime( CLOCK_MONOTONIC, &ts);
ret = ts.tv_sec * 1000;
ret += ts.tv_nsec / 1000000;
#else
boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();
std::cout << "."; std::cout.flush();
boost::posix_time::ptime epoch_start(boost::gregorian::date(1970,1,1));
std::cout << "."; std::cout.flush();
boost::posix_time::time_duration dur = now - epoch_start;
std::cout << "."; std::cout.flush();
ret = dur.total_milliseconds();
#endif
std::cout << "-"; std::cout.flush();
return ret;
}
Обработчик сигнала может быть вызван до завершения предыдущего обработчика;
Мне нужно текущее время в мс для измерения точной частоты дискретизации.
Если я комментирую # определение Z , используется повышение. В «режиме повышения» приложение зависает через непредсказуемое время от начала воспроизведения звука. strace Показать приложение зависает на этом:
write(1, "+"..., 1) = 1
gettimeofday({1332627252, 660534}, NULL) = 0
futex(0xb68dba4c, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
Но 0xb68dba4c происходило только 2 ... 3 раза во всем журнале трассировки. futex (0xb68dba4c ... - это не то, что происходит при каждом вызове getCurrentTimeMs (). Но когда это происходит, все зависает, и это происходит только после этого gettimeofday ; я вижу " +. "на консоли, а затем возникает futex . Но до этого приложение может воспроизводить тонны звука, вызывая getCurrentTimeMs () для каждого обратного вызова 50 раз в секунду. Такая загадка ...
С # определить Z мой код используется. В этом случае приложение прекрасно работает - проигрывает гигабайты WAV-файлов без зависаний.
Приложение имеет 2 потока, работающих через boost :: threadpool, и оба используют getCurrentTimeMs () ; допустим, у меня есть некоторые тупиковые ошибки; но я понятия не имею, как # определяет Z может повлиять на это.
EDIT:
На мой вопрос ответили таким образом, и я принимаю этот ответ:
1) http://permalink.gmane.org/gmane.linux.alsa.devel/96282
2) http://answerpot.com/showthread.php?3448138-ALSA+async+callback+re-enter+and+DEADLOCK.