Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 04491e1d authored by Ravneet Dhanjal's avatar Ravneet Dhanjal Committed by Android (Google) Code Review
Browse files

Merge "cameraserver: Set abort message for watchdog" into udc-dev

parents 9e7da98b 3c78274b
Loading
Loading
Loading
Loading
+22 −8
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#define LOG_TAG "CameraServiceWatchdog"

#include "CameraServiceWatchdog.h"
#include "android/set_abort_message.h"
#include "utils/CameraServiceProxyWrapper.h"

namespace android {
@@ -36,12 +37,15 @@ bool CameraServiceWatchdog::threadLoop()
    {
        AutoMutex _l(mWatchdogLock);

        for (auto it = tidToCycleCounterMap.begin(); it != tidToCycleCounterMap.end(); it++) {
        for (auto it = mTidMap.begin(); it != mTidMap.end(); it++) {
            uint32_t currentThreadId = it->first;

            tidToCycleCounterMap[currentThreadId]++;
            mTidMap[currentThreadId].cycles++;

            if (tidToCycleCounterMap[currentThreadId] >= mMaxCycles) {
            if (mTidMap[currentThreadId].cycles >= mMaxCycles) {
                std::string abortMessage = getAbortMessage(getpid(), currentThreadId,
                        mTidMap[currentThreadId].functionName);
                android_set_abort_message(abortMessage.c_str());
                ALOGW("CameraServiceWatchdog triggering abort for pid: %d tid: %d", getpid(),
                        currentThreadId);
                mCameraServiceProxyWrapper->logClose(mCameraId, 0 /*latencyMs*/,
@@ -56,13 +60,20 @@ bool CameraServiceWatchdog::threadLoop()
    return true;
}

std::string CameraServiceWatchdog::getAbortMessage(int pid, int tid, std::string functionName) {
    std::string res = "CameraServiceWatchdog triggering abort during "
            + functionName + " | pid: " + std::to_string(pid)
            + " tid: " + std::to_string(tid);
    return res;
}

void CameraServiceWatchdog::requestExit()
{
    Thread::requestExit();

    AutoMutex _l(mWatchdogLock);

    tidToCycleCounterMap.clear();
    mTidMap.clear();

    if (mPause) {
        mPause = false;
@@ -85,18 +96,21 @@ void CameraServiceWatchdog::stop(uint32_t tid)
{
    AutoMutex _l(mWatchdogLock);

    tidToCycleCounterMap.erase(tid);
    mTidMap.erase(tid);

    if (tidToCycleCounterMap.empty()) {
    if (mTidMap.empty()) {
        mPause = true;
    }
}

void CameraServiceWatchdog::start(uint32_t tid)
void CameraServiceWatchdog::start(uint32_t tid, const char* functionName)
{
    AutoMutex _l(mWatchdogLock);

    tidToCycleCounterMap[tid] = 0;
    MonitoredFunction monitoredFunction = {};
    monitoredFunction.cycles = 0;
    monitoredFunction.functionName = functionName;
    mTidMap[tid] = monitoredFunction;

    if (mPause) {
        mPause = false;
+20 −10
Original line number Diff line number Diff line
@@ -40,9 +40,9 @@
#include "utils/CameraServiceProxyWrapper.h"

// Used to wrap the call of interest in start and stop calls
#define WATCH(toMonitor) watchThread([&]() { return toMonitor;}, gettid())
#define WATCH(toMonitor) watchThread([&]() { return toMonitor;}, gettid(), __FUNCTION__)
#define WATCH_CUSTOM_TIMER(toMonitor, cycles, cycleLength) \
        watchThread([&]() { return toMonitor;}, gettid(), cycles, cycleLength);
        watchThread([&]() { return toMonitor;}, gettid(), __FUNCTION__, cycles, cycleLength);

// Default cycles and cycle length values used to calculate permitted elapsed time
const static size_t   kMaxCycles     = 100;
@@ -52,6 +52,11 @@ namespace android {

class CameraServiceWatchdog : public Thread {

struct MonitoredFunction {
    uint32_t cycles;
    std::string functionName;
};

public:
    explicit CameraServiceWatchdog(const String8 &cameraId,
            std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper) :
@@ -75,7 +80,8 @@ public:

    /** Used to wrap monitored calls in start and stop functions using custom timer values */
    template<typename T>
    auto watchThread(T func, uint32_t tid, uint32_t cycles, uint32_t cycleLength) {
    auto watchThread(T func, uint32_t tid, const char* functionName, uint32_t cycles,
            uint32_t cycleLength) {
        decltype(func()) res;

        if (cycles != mMaxCycles || cycleLength != mCycleLengthMs) {
@@ -91,17 +97,17 @@ public:
            status_t status = tempWatchdog->run("CameraServiceWatchdog");
            if (status != OK) {
                ALOGE("Unable to watch thread: %s (%d)", strerror(-status), status);
                res = watchThread(func, tid);
                res = watchThread(func, tid, functionName);
                return res;
            }

            res = tempWatchdog->watchThread(func, tid);
            res = tempWatchdog->watchThread(func, tid, functionName);
            tempWatchdog->requestExit();
            tempWatchdog.clear();
        } else {
            // If custom timer values are equivalent to set class timer values, use
            // current thread
            res = watchThread(func, tid);
            res = watchThread(func, tid, functionName);
        }

        return res;
@@ -109,12 +115,12 @@ public:

    /** Used to wrap monitored calls in start and stop functions using class timer values */
    template<typename T>
    auto watchThread(T func, uint32_t tid) {
    auto watchThread(T func, uint32_t tid, const char* functionName) {
        decltype(func()) res;
        AutoMutex _l(mEnabledLock);

        if (mEnabled) {
            start(tid);
            start(tid, functionName);
            res = func();
            stop(tid);
        } else {
@@ -130,7 +136,7 @@ private:
     * Start adds a cycle counter for the calling thread. When threadloop is blocked/paused,
     * start() unblocks and starts the watchdog
     */
    void start(uint32_t tid);
    void start(uint32_t tid, const char* functionName);

    /**
     * If there are no calls left to be monitored, stop blocks/pauses threadloop
@@ -138,6 +144,8 @@ private:
     */
    void stop(uint32_t tid);

    std::string getAbortMessage(int pid, int tid, std::string functionName);

    virtual bool    threadLoop();

    Mutex           mWatchdogLock;      // Lock for condition variable
@@ -151,7 +159,9 @@ private:

    std::shared_ptr<CameraServiceProxyWrapper> mCameraServiceProxyWrapper;

    std::unordered_map<uint32_t, uint32_t> tidToCycleCounterMap; // Thread Id to cycle counter map
    std::unordered_map<uint32_t, MonitoredFunction> mTidMap; // Thread Id to MonitoredFunction type
                                                             // which retrieves the num of cycles
                                                             // and name of the function
};

}   // namespace android