Camera: Bump the thread priority during stream configuration and open
Bump the scheduling priority of two critical performance paths
that include stream configuration and camera device open.
Flag: com.android.internal.camera.flags.realtime_priority_bump
Bug: 336628522
Test: Camera CTS,
Manual using camera application
Change-Id: I8ac10099e74bfae91bcc3b5caadc2276510c97e3
diff --git a/services/camera/libcameraservice/utils/Utils.cpp b/services/camera/libcameraservice/utils/Utils.cpp
index c8f5e86..34c0ed8 100644
--- a/services/camera/libcameraservice/utils/Utils.cpp
+++ b/services/camera/libcameraservice/utils/Utils.cpp
@@ -14,14 +14,17 @@
* limitations under the License.
*/
+#define LOG_TAG "Camera3-Utils"
+
#include "Utils.h"
#include <android-base/properties.h>
#include <com_android_internal_camera_flags.h>
-
+#include <utils/Errors.h>
+#include <utils/Log.h>
namespace android {
-using namespace com::android::internal::camera::flags;
+namespace flags = com::android::internal::camera::flags;
constexpr const char *LEGACY_VNDK_VERSION_PROP = "ro.vndk.version";
constexpr const char *BOARD_API_LEVEL_PROP = "ro.board.api_level";
@@ -52,4 +55,37 @@
return __ANDROID_API_V__ + vndkVersion;
}
-} // namespace android
+RunThreadWithRealtimePriority::RunThreadWithRealtimePriority(int tid)
+ : mTid(tid), mPreviousPolicy(sched_getscheduler(tid)) {
+ if (flags::realtime_priority_bump()) {
+ auto res = sched_getparam(mTid, &mPreviousParams);
+ if (res != OK) {
+ ALOGE("Can't retrieve thread scheduler parameters: %s (%d)", strerror(-res), res);
+ return;
+ }
+
+ struct sched_param param = {0};
+ param.sched_priority = kRequestThreadPriority;
+
+ res = sched_setscheduler(mTid, SCHED_FIFO, ¶m);
+ if (res != OK) {
+ ALOGW("Can't set realtime priority for thread: %s (%d)", strerror(-res), res);
+ } else {
+ ALOGD("Set real time priority for thread (tid %d)", mTid);
+ mPolicyBumped = true;
+ }
+ }
+}
+
+RunThreadWithRealtimePriority::~RunThreadWithRealtimePriority() {
+ if (mPolicyBumped && flags::realtime_priority_bump()) {
+ auto res = sched_setscheduler(mTid, mPreviousPolicy, &mPreviousParams);
+ if (res != OK) {
+ ALOGE("Can't set regular priority for thread: %s (%d)", strerror(-res), res);
+ } else {
+ ALOGD("Set regular priority for thread (tid %d)", mTid);
+ }
+ }
+}
+
+} // namespace android
diff --git a/services/camera/libcameraservice/utils/Utils.h b/services/camera/libcameraservice/utils/Utils.h
index f8a107d..4e90871 100644
--- a/services/camera/libcameraservice/utils/Utils.h
+++ b/services/camera/libcameraservice/utils/Utils.h
@@ -17,6 +17,9 @@
#ifndef ANDROID_SERVERS_CAMERA_UTILS_H
#define ANDROID_SERVERS_CAMERA_UTILS_H
+#include <sched.h>
+#include <unistd.h>
+
namespace android {
/**
@@ -28,6 +31,40 @@
*/
int getVNDKVersionFromProp(int defaultVersion);
+/**
+ * An instance of this class will raise the scheduling policy of a given
+ * given thread to real time and keep it this way throughout the lifetime
+ * of the object. The thread scheduling policy will revert back to its original
+ * state after the instances is released. By default the implementation will
+ * raise the priority of the current thread unless clients explicitly specify
+ * another thread id.
+ * Client must avoid:
+ * - Keeping an instance of this class for extended and long running operations.
+ * This is only intended for short/temporarily priority bumps that mitigate
+ * scheduling delays within critical camera paths.
+ * - Allocating instances of this class on the memory heap unless clients have
+ * complete control over the object lifetime. It is preferable to allocate
+ * instances of this class on the stack instead.
+ * - Nesting multiple instances of this class using the same default or same thread id.
+ */
+class RunThreadWithRealtimePriority final {
+ public:
+ RunThreadWithRealtimePriority(int tid = gettid());
+ ~RunThreadWithRealtimePriority();
+
+ RunThreadWithRealtimePriority(const RunThreadWithRealtimePriority&) = delete;
+ RunThreadWithRealtimePriority& operator=(const RunThreadWithRealtimePriority&) = delete;
+
+ // SCHED_FIFO priority for request submission thread in HFR mode
+ static const int kRequestThreadPriority = 1;
+
+ private:
+ int mTid;
+ int mPreviousPolicy;
+ bool mPolicyBumped = false;
+ struct sched_param mPreviousParams;
+};
+
} // namespace android
#endif //ANDROID_SERVERS_CAMERA_UTILS_H