From f99498ee4de7123e2fd71778c6877be44fbd1506 Mon Sep 17 00:00:00 2001 From: Eino-Ville Talvala Date: Fri, 25 Sep 2015 16:52:55 -0700 Subject: CameraService: Use SCHED_FIFO for request queue thread in HFR - Move SchedulingPolicyService from audioservice to mediautils - When starting up a high speed stream config, set request queue thread to SCHED_FIFO using SchedulingPolicyService Bug: 24227252 Change-Id: I224b59142bd111caf563779f55cddd62385b9bac --- media/utils/Android.mk | 2 + media/utils/ISchedulingPolicyService.cpp | 80 ++++++++++++++++++++++ media/utils/ISchedulingPolicyService.h | 45 ++++++++++++ media/utils/SchedulingPolicyService.cpp | 62 +++++++++++++++++ .../include/mediautils/SchedulingPolicyService.h | 31 +++++++++ services/audioflinger/Android.mk | 15 +--- services/audioflinger/ISchedulingPolicyService.cpp | 80 ---------------------- services/audioflinger/ISchedulingPolicyService.h | 45 ------------ services/audioflinger/SchedulingPolicyService.cpp | 62 ----------------- services/audioflinger/SchedulingPolicyService.h | 31 --------- services/audioflinger/Threads.cpp | 2 +- services/camera/libcameraservice/Android.mk | 2 +- .../libcameraservice/device3/Camera3Device.cpp | 16 +++++ .../libcameraservice/device3/Camera3Device.h | 2 + 14 files changed, 242 insertions(+), 233 deletions(-) create mode 100644 media/utils/ISchedulingPolicyService.cpp create mode 100644 media/utils/ISchedulingPolicyService.h create mode 100644 media/utils/SchedulingPolicyService.cpp create mode 100644 media/utils/include/mediautils/SchedulingPolicyService.h delete mode 100644 services/audioflinger/ISchedulingPolicyService.cpp delete mode 100644 services/audioflinger/ISchedulingPolicyService.h delete mode 100644 services/audioflinger/SchedulingPolicyService.cpp delete mode 100644 services/audioflinger/SchedulingPolicyService.h diff --git a/media/utils/Android.mk b/media/utils/Android.mk index dfadbc8..54d22b1 100644 --- a/media/utils/Android.mk +++ b/media/utils/Android.mk @@ -18,6 +18,8 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES := \ BatteryNotifier.cpp \ + ISchedulingPolicyService.cpp \ + SchedulingPolicyService.cpp LOCAL_SHARED_LIBRARIES := \ libbinder \ diff --git a/media/utils/ISchedulingPolicyService.cpp b/media/utils/ISchedulingPolicyService.cpp new file mode 100644 index 0000000..f55bc02 --- /dev/null +++ b/media/utils/ISchedulingPolicyService.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "ISchedulingPolicyService" +//#define LOG_NDEBUG 0 + +#include +#include "ISchedulingPolicyService.h" + +namespace android { + +// Keep in sync with frameworks/base/core/java/android/os/ISchedulingPolicyService.aidl +enum { + REQUEST_PRIORITY_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION, +}; + +// ---------------------------------------------------------------------- + +class BpSchedulingPolicyService : public BpInterface +{ +public: + BpSchedulingPolicyService(const sp& impl) + : BpInterface(impl) + { + } + + virtual int requestPriority(int32_t pid, int32_t tid, int32_t prio, bool asynchronous) + { + Parcel data, reply; + data.writeInterfaceToken(ISchedulingPolicyService::getInterfaceDescriptor()); + data.writeInt32(pid); + data.writeInt32(tid); + data.writeInt32(prio); + uint32_t flags = asynchronous ? IBinder::FLAG_ONEWAY : 0; + status_t status = remote()->transact(REQUEST_PRIORITY_TRANSACTION, data, &reply, flags); + if (status != NO_ERROR) { + return status; + } + if (asynchronous) { + return NO_ERROR; + } + // fail on exception: force binder reconnection + if (reply.readExceptionCode() != 0) { + return DEAD_OBJECT; + } + return reply.readInt32(); + } +}; + +IMPLEMENT_META_INTERFACE(SchedulingPolicyService, "android.os.ISchedulingPolicyService"); + +// ---------------------------------------------------------------------- + +status_t BnSchedulingPolicyService::onTransact( + uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) +{ + switch (code) { + case REQUEST_PRIORITY_TRANSACTION: + // Not reached + return NO_ERROR; + break; + default: + return BBinder::onTransact(code, data, reply, flags); + } +} + +} // namespace android diff --git a/media/utils/ISchedulingPolicyService.h b/media/utils/ISchedulingPolicyService.h new file mode 100644 index 0000000..b94b191 --- /dev/null +++ b/media/utils/ISchedulingPolicyService.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_ISCHEDULING_POLICY_SERVICE_H +#define ANDROID_ISCHEDULING_POLICY_SERVICE_H + +#include + +namespace android { + +class ISchedulingPolicyService : public IInterface +{ +public: + DECLARE_META_INTERFACE(SchedulingPolicyService); + + virtual int requestPriority(/*pid_t*/int32_t pid, /*pid_t*/int32_t tid, + int32_t prio, bool asynchronous) = 0; + +}; + +class BnSchedulingPolicyService : public BnInterface +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +} // namespace android + +#endif // ANDROID_ISCHEDULING_POLICY_SERVICE_H diff --git a/media/utils/SchedulingPolicyService.cpp b/media/utils/SchedulingPolicyService.cpp new file mode 100644 index 0000000..17ee9bc --- /dev/null +++ b/media/utils/SchedulingPolicyService.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "SchedulingPolicyService" +//#define LOG_NDEBUG 0 + +#include +#include +#include "ISchedulingPolicyService.h" +#include "mediautils/SchedulingPolicyService.h" + +namespace android { + +static sp sSchedulingPolicyService; +static const String16 _scheduling_policy("scheduling_policy"); +static Mutex sMutex; + +int requestPriority(pid_t pid, pid_t tid, int32_t prio, bool asynchronous) +{ + // FIXME merge duplicated code related to service lookup, caching, and error recovery + int ret; + for (;;) { + sMutex.lock(); + sp sps = sSchedulingPolicyService; + sMutex.unlock(); + if (sps == 0) { + sp binder = defaultServiceManager()->checkService(_scheduling_policy); + if (binder == 0) { + sleep(1); + continue; + } + sps = interface_cast(binder); + sMutex.lock(); + sSchedulingPolicyService = sps; + sMutex.unlock(); + } + ret = sps->requestPriority(pid, tid, prio, asynchronous); + if (ret != DEAD_OBJECT) { + break; + } + ALOGW("SchedulingPolicyService died"); + sMutex.lock(); + sSchedulingPolicyService.clear(); + sMutex.unlock(); + } + return ret; +} + +} // namespace android diff --git a/media/utils/include/mediautils/SchedulingPolicyService.h b/media/utils/include/mediautils/SchedulingPolicyService.h new file mode 100644 index 0000000..a9870d4 --- /dev/null +++ b/media/utils/include/mediautils/SchedulingPolicyService.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ANDROID_SCHEDULING_POLICY_SERVICE_H +#define _ANDROID_SCHEDULING_POLICY_SERVICE_H + +namespace android { + +// Request elevated priority for thread tid, whose thread group leader must be pid. +// The priority parameter is currently restricted to either 1 or 2. +// The asynchronous parameter should be 'true' to return immediately, +// after the request is enqueued but not necessarily executed. +// The default value 'false' means to return after request has been enqueued and executed. +int requestPriority(pid_t pid, pid_t tid, int32_t prio, bool asynchronous = false); + +} // namespace android + +#endif // _ANDROID_SCHEDULING_POLICY_SERVICE_H diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk index debcdf9..9b4ba79 100644 --- a/services/audioflinger/Android.mk +++ b/services/audioflinger/Android.mk @@ -3,17 +3,6 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := \ - ISchedulingPolicyService.cpp \ - SchedulingPolicyService.cpp - -# FIXME Move this library to frameworks/native -LOCAL_MODULE := libscheduling_policy - -include $(BUILD_STATIC_LIBRARY) - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ ServiceUtilities.cpp # FIXME Move this library to frameworks/native @@ -64,10 +53,10 @@ LOCAL_SHARED_LIBRARIES := \ libeffects \ libpowermanager \ libserviceutility \ - libsonic + libsonic \ + libmediautils LOCAL_STATIC_LIBRARIES := \ - libscheduling_policy \ libcpustats \ libmedia_helper diff --git a/services/audioflinger/ISchedulingPolicyService.cpp b/services/audioflinger/ISchedulingPolicyService.cpp deleted file mode 100644 index f55bc02..0000000 --- a/services/audioflinger/ISchedulingPolicyService.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "ISchedulingPolicyService" -//#define LOG_NDEBUG 0 - -#include -#include "ISchedulingPolicyService.h" - -namespace android { - -// Keep in sync with frameworks/base/core/java/android/os/ISchedulingPolicyService.aidl -enum { - REQUEST_PRIORITY_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION, -}; - -// ---------------------------------------------------------------------- - -class BpSchedulingPolicyService : public BpInterface -{ -public: - BpSchedulingPolicyService(const sp& impl) - : BpInterface(impl) - { - } - - virtual int requestPriority(int32_t pid, int32_t tid, int32_t prio, bool asynchronous) - { - Parcel data, reply; - data.writeInterfaceToken(ISchedulingPolicyService::getInterfaceDescriptor()); - data.writeInt32(pid); - data.writeInt32(tid); - data.writeInt32(prio); - uint32_t flags = asynchronous ? IBinder::FLAG_ONEWAY : 0; - status_t status = remote()->transact(REQUEST_PRIORITY_TRANSACTION, data, &reply, flags); - if (status != NO_ERROR) { - return status; - } - if (asynchronous) { - return NO_ERROR; - } - // fail on exception: force binder reconnection - if (reply.readExceptionCode() != 0) { - return DEAD_OBJECT; - } - return reply.readInt32(); - } -}; - -IMPLEMENT_META_INTERFACE(SchedulingPolicyService, "android.os.ISchedulingPolicyService"); - -// ---------------------------------------------------------------------- - -status_t BnSchedulingPolicyService::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) -{ - switch (code) { - case REQUEST_PRIORITY_TRANSACTION: - // Not reached - return NO_ERROR; - break; - default: - return BBinder::onTransact(code, data, reply, flags); - } -} - -} // namespace android diff --git a/services/audioflinger/ISchedulingPolicyService.h b/services/audioflinger/ISchedulingPolicyService.h deleted file mode 100644 index b94b191..0000000 --- a/services/audioflinger/ISchedulingPolicyService.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_ISCHEDULING_POLICY_SERVICE_H -#define ANDROID_ISCHEDULING_POLICY_SERVICE_H - -#include - -namespace android { - -class ISchedulingPolicyService : public IInterface -{ -public: - DECLARE_META_INTERFACE(SchedulingPolicyService); - - virtual int requestPriority(/*pid_t*/int32_t pid, /*pid_t*/int32_t tid, - int32_t prio, bool asynchronous) = 0; - -}; - -class BnSchedulingPolicyService : public BnInterface -{ -public: - virtual status_t onTransact( uint32_t code, - const Parcel& data, - Parcel* reply, - uint32_t flags = 0); -}; - -} // namespace android - -#endif // ANDROID_ISCHEDULING_POLICY_SERVICE_H diff --git a/services/audioflinger/SchedulingPolicyService.cpp b/services/audioflinger/SchedulingPolicyService.cpp deleted file mode 100644 index 70a3f1a..0000000 --- a/services/audioflinger/SchedulingPolicyService.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "SchedulingPolicyService" -//#define LOG_NDEBUG 0 - -#include -#include -#include "ISchedulingPolicyService.h" -#include "SchedulingPolicyService.h" - -namespace android { - -static sp sSchedulingPolicyService; -static const String16 _scheduling_policy("scheduling_policy"); -static Mutex sMutex; - -int requestPriority(pid_t pid, pid_t tid, int32_t prio, bool asynchronous) -{ - // FIXME merge duplicated code related to service lookup, caching, and error recovery - int ret; - for (;;) { - sMutex.lock(); - sp sps = sSchedulingPolicyService; - sMutex.unlock(); - if (sps == 0) { - sp binder = defaultServiceManager()->checkService(_scheduling_policy); - if (binder == 0) { - sleep(1); - continue; - } - sps = interface_cast(binder); - sMutex.lock(); - sSchedulingPolicyService = sps; - sMutex.unlock(); - } - ret = sps->requestPriority(pid, tid, prio, asynchronous); - if (ret != DEAD_OBJECT) { - break; - } - ALOGW("SchedulingPolicyService died"); - sMutex.lock(); - sSchedulingPolicyService.clear(); - sMutex.unlock(); - } - return ret; -} - -} // namespace android diff --git a/services/audioflinger/SchedulingPolicyService.h b/services/audioflinger/SchedulingPolicyService.h deleted file mode 100644 index a9870d4..0000000 --- a/services/audioflinger/SchedulingPolicyService.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _ANDROID_SCHEDULING_POLICY_SERVICE_H -#define _ANDROID_SCHEDULING_POLICY_SERVICE_H - -namespace android { - -// Request elevated priority for thread tid, whose thread group leader must be pid. -// The priority parameter is currently restricted to either 1 or 2. -// The asynchronous parameter should be 'true' to return immediately, -// after the request is enqueued but not necessarily executed. -// The default value 'false' means to return after request has been enqueued and executed. -int requestPriority(pid_t pid, pid_t tid, int32_t prio, bool asynchronous = false); - -} // namespace android - -#endif // _ANDROID_SCHEDULING_POLICY_SERVICE_H diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index 5bd9149..f586291 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -60,7 +60,7 @@ #include "FastMixer.h" #include "FastCapture.h" #include "ServiceUtilities.h" -#include "SchedulingPolicyService.h" +#include "mediautils/SchedulingPolicyService.h" #ifdef ADD_BATTERY_DATA #include diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk index e8ef24e..45900c4 100644 --- a/services/camera/libcameraservice/Android.mk +++ b/services/camera/libcameraservice/Android.mk @@ -53,7 +53,7 @@ LOCAL_SRC_FILES:= \ device3/StatusTracker.cpp \ gui/RingBufferConsumer.cpp \ utils/CameraTraces.cpp \ - utils/AutoConditionLock.cpp \ + utils/AutoConditionLock.cpp LOCAL_SHARED_LIBRARIES:= \ libui \ diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp index 433a745..1a3a770 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.cpp +++ b/services/camera/libcameraservice/device3/Camera3Device.cpp @@ -44,6 +44,7 @@ #include #include "utils/CameraTraces.h" +#include "mediautils/SchedulingPolicyService.h" #include "device3/Camera3Device.h" #include "device3/Camera3OutputStream.h" #include "device3/Camera3InputStream.h" @@ -1766,6 +1767,21 @@ status_t Camera3Device::configureStreamsLocked() { // across configure_streams() calls mRequestThread->configurationComplete(); + // Boost priority of request thread for high speed recording to SCHED_FIFO + if (mIsConstrainedHighSpeedConfiguration) { + pid_t requestThreadTid = mRequestThread->getTid(); + res = requestPriority(getpid(), requestThreadTid, + kConstrainedHighSpeedThreadPriority, true); + if (res != OK) { + ALOGW("Can't set realtime priority for request processing thread: %s (%d)", + strerror(-res), res); + } else { + ALOGD("Set real time priority for request queue thread (tid %d)", requestThreadTid); + } + } else { + // TODO: Set/restore normal priority for normal use cases + } + // Update device state mNeedConfig = false; diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h index 9d3c533..402cb1d 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.h +++ b/services/camera/libcameraservice/device3/Camera3Device.h @@ -161,6 +161,8 @@ class Camera3Device : static const nsecs_t kActiveTimeout = 500000000; // 500 ms static const size_t kInFlightWarnLimit = 20; static const size_t kInFlightWarnLimitHighSpeed = 256; // batch size 32 * pipe depth 8 + // SCHED_FIFO priority for request submission thread in HFR mode + static const int kConstrainedHighSpeedThreadPriority = 3; struct RequestTrigger; // minimal jpeg buffer size: 256KB + blob header -- cgit v1.1