Bug 1575883 - Handle SIGXCPU in Gecko. r=kinetik,glandium

This allows installing a SIGXCPU handler, which will simply set an atomic to
true when reached.

Another function allows querying this atomic.

Finally, another function allows demoting the current thread from real-time
priority.

This is per-process currently, as there is only one audio callback thread that
is set to RT scheduling per process, servicing all HTMLMediaElements and MSGs.
Whenever any of those go over the soft limit, the thread is demoted.

Differential Revision: https://phabricator.services.mozilla.com/D43404

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Paul Adenot 2019-10-11 16:02:36 +00:00
Родитель 2196bcaba6
Коммит bb8066315b
4 изменённых файлов: 118 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,22 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_UNDERRUNHANDLER_H_
#define MOZILLA_UNDERRUNHANDLER_H_
namespace mozilla {
// Install an handler on SIGXPCU for the calling thread, that calls
// `UnderrunHandler` when the soft real-time limit has been reached. If a
// handler was already in place, this does nothing. No-op if not on Linux
// Desktop.
void InstallSoftRealTimeLimitHandler();
// Query whether or not the soft-real-time limit has been reached. Always
// false when not on Linux desktop. Can be called from any thread.
bool SoftRealTimeLimitReached();
// Set the calling thread to a normal scheduling class.
void DemoteThreadFromRealTime();
} // namespace mozilla
#endif // MOZILLA_UNDERRUNHANDLER_H_

Просмотреть файл

@ -0,0 +1,77 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <csignal>
#include <cerrno>
#include <pthread.h>
#include <mozilla/Sprintf.h>
#include <mozilla/Atomics.h>
#include "audio_thread_priority.h"
namespace mozilla {
Atomic<bool, MemoryOrdering::ReleaseAcquire> gRealtimeLimitReached;
void UnderrunHandler(int signum) { gRealtimeLimitReached = true; }
bool SoftRealTimeLimitReached() { return gRealtimeLimitReached; }
void InstallSoftRealTimeLimitHandler() {
struct sigaction action, previous;
action.sa_handler = UnderrunHandler;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
int rv = sigaction(SIGXCPU, &action, &previous);
if (rv != 0) {
char buf[256];
SprintfLiteral(buf, "sigaction(SIGXCPU, ...): %s", strerror(errno));
NS_WARNING(buf);
return;
}
void* previous_handler = previous.sa_flags == SA_SIGINFO
? reinterpret_cast<void*>(previous.sa_sigaction)
: reinterpret_cast<void*>(previous.sa_handler);
MOZ_ASSERT(previous_handler != UnderrunHandler,
"Only install the SIGXCPU handler once per process.");
if (previous_handler != SIG_DFL && previous_handler != UnderrunHandler) {
NS_WARNING(
"SIGXCPU handler was already set by something else, dropping real-time "
"priority.");
rv = sigaction(SIGXCPU, &previous, nullptr);
if (rv != 0) {
NS_WARNING("Could not restore previous handler for SIGXCPU.");
}
gRealtimeLimitReached = true;
return;
}
gRealtimeLimitReached = false;
}
void DemoteThreadFromRealTime() {
atp_thread_info* info = atp_get_current_thread_info();
if (!info) {
NS_WARNING("Could not get current thread info when demoting thread.");
return;
}
int rv = atp_demote_thread_from_real_time(info);
if (rv) {
NS_WARNING("Could not demote thread from real-time.");
return;
}
rv = atp_free_thread_info(info);
if (rv) {
NS_WARNING("Could not free atp_thread_info struct");
}
gRealtimeLimitReached = false;
}
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,14 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
namespace mozilla {
bool SoftRealTimeLimitReached() { return false; }
void InstallSoftRealTimeLimitHandler() {}
void DemoteThreadFromRealTime() {}
} // namespace mozilla

Просмотреть файл

@ -302,6 +302,11 @@ UNIFIED_SOURCES += [
'XiphExtradata.cpp',
]
if CONFIG['OS_TARGET'] == 'Linux':
UNIFIED_SOURCES += [ 'UnderrunHandlerLinux.cpp' ]
else:
UNIFIED_SOURCES += [ 'UnderrunHandlerNoop.cpp']
if CONFIG['OS_TARGET'] == 'WINNT':
EXPORTS.mozilla.audio += [
'AudioNotificationReceiver.h',