Я использую 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;
}
Если я комментирую #define Z, используется ускорение. В «ускоренном режиме» приложение зависает через непредсказуемое время от начала воспроизведения звука. Приложение strace show зависает на этом:
write(1, "+"..., 1) = 1 gettimeofday({1332627252, 660534}, NULL) = 0 futex(0xb68dba4c, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
Но 0xb68dba4c встречается всего 2...3 раза во всем журнале трассировки. futex(0xb68dba4c ... — это не то, что происходит при каждом вызове getCurrentTimeMs(). Но когда это происходит, все зависает, и это происходит только после этого gettimeofday; i см. "+" на консоли, а затем происходит этот фьютекс. Но до этого приложение может воспроизводить тонны звука, вызывая getCurrentTimeMs() при каждом обратном вызове 50 раз в секунду. , Такая загадка...
В #define Z используется мой код. В этом случае приложение работает отлично - проигрывает гигабайты WAV-файлов без зависаний.
Приложение имеет 2 потока, запущенных через boost::threadpool, и оба используют метод getCurrentTimeMs(); давайте предположим, что у меня есть некоторые ошибки взаимоблокировки; но я понятия не имею, как #define Z может повлиять на это.
EDIT: На мой вопрос дан такой ответ, и я принимаю этот ответ:
1) http://permalink.gmane.org/gmane.linux.alsa.devel/96282
2) http://answerpot.com/showthread.php?3448138-ALSA+асинхронный+обратныйвызов+повторныйввод+и+DEADLOCK.