mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
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:
parent
2196bcaba6
commit
bb8066315b
22
dom/media/UnderrunHandler.h
Normal file
22
dom/media/UnderrunHandler.h
Normal file
@ -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_
|
77
dom/media/UnderrunHandlerLinux.cpp
Normal file
77
dom/media/UnderrunHandlerLinux.cpp
Normal file
@ -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
|
14
dom/media/UnderrunHandlerNoop.cpp
Normal file
14
dom/media/UnderrunHandlerNoop.cpp
Normal file
@ -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',
|
||||
|
Loading…
Reference in New Issue
Block a user