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

Commit 370d6473 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Evict buffers from idle bufferpool" into rvc-dev am: 7a2a0740

Change-Id: Ic2441a222eb92dab6403973f30164666b5925ffa
parents 0dca30c6 7a2a0740
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -117,6 +117,10 @@ void Accessor::createInvalidator() {
    Accessor::Impl::createInvalidator();
}

void Accessor::createEvictor() {
    Accessor::Impl::createEvictor();
}

// Methods from ::android::hardware::media::bufferpool::V2_0::IAccessor follow.
Return<void> Accessor::connect(
        const sp<::android::hardware::media::bufferpool::V2_0::IObserver>& observer,
+2 −0
Original line number Diff line number Diff line
@@ -187,6 +187,8 @@ struct Accessor : public IAccessor {

    static void createInvalidator();

    static void createEvictor();

private:
    class Impl;
    std::shared_ptr<Impl> mImpl;
+90 −1
Original line number Diff line number Diff line
@@ -39,6 +39,9 @@ namespace {

    static constexpr size_t kMinAllocBytesForEviction = 1024*1024*15;
    static constexpr size_t kMinBufferCountForEviction = 25;

    static constexpr nsecs_t kEvictGranularityNs = 1000000000; // 1 sec
    static constexpr nsecs_t kEvictDurationNs = 5000000000; // 5 secs
}

// Buffer structure in bufferpool process
@@ -146,7 +149,7 @@ uint32_t Accessor::Impl::sSeqId = time(nullptr) & kSeqIdMax;

Accessor::Impl::Impl(
        const std::shared_ptr<BufferPoolAllocator> &allocator)
        : mAllocator(allocator) {}
        : mAllocator(allocator), mScheduleEvictTs(0) {}

Accessor::Impl::~Impl() {
}
@@ -184,6 +187,7 @@ ResultStatus Accessor::Impl::connect(
        }
        mBufferPool.processStatusMessages();
        mBufferPool.cleanUp();
        scheduleEvictIfNeeded();
    }
    return status;
}
@@ -198,6 +202,7 @@ ResultStatus Accessor::Impl::close(ConnectionId connectionId) {
    // Since close# will be called after all works are finished, it is OK to
    // evict unused buffers.
    mBufferPool.cleanUp(true);
    scheduleEvictIfNeeded();
    return ResultStatus::OK;
}

@@ -224,6 +229,7 @@ ResultStatus Accessor::Impl::allocate(
        mBufferPool.handleOwnBuffer(connectionId, *bufferId);
    }
    mBufferPool.cleanUp();
    scheduleEvictIfNeeded();
    return status;
}

@@ -249,6 +255,7 @@ ResultStatus Accessor::Impl::fetch(
        }
    }
    mBufferPool.cleanUp();
    scheduleEvictIfNeeded();
    return ResultStatus::CRITICAL_ERROR;
}

@@ -891,6 +898,88 @@ void Accessor::Impl::createInvalidator() {
    }
}

void Accessor::Impl::evictorThread(
        std::map<const std::weak_ptr<Accessor::Impl>, nsecs_t, std::owner_less<>> &accessors,
        std::mutex &mutex,
        std::condition_variable &cv) {
    std::list<const std::weak_ptr<Accessor::Impl>> evictList;
    while (true) {
        int expired = 0;
        int evicted = 0;
        {
            nsecs_t now = systemTime();
            std::unique_lock<std::mutex> lock(mutex);
            if (accessors.size() == 0) {
                cv.wait(lock);
            }
            auto it = accessors.begin();
            while (it != accessors.end()) {
                if (now > (it->second + kEvictDurationNs)) {
                    ++expired;
                    evictList.push_back(it->first);
                    it = accessors.erase(it);
                } else {
                    ++it;
                }
            }
        }
        // evict idle accessors;
        for (auto it = evictList.begin(); it != evictList.end(); ++it) {
            const std::shared_ptr<Accessor::Impl> accessor = it->lock();
            if (accessor) {
                accessor->cleanUp(true);
                ++evicted;
            }
        }
        if (expired > 0) {
            ALOGD("evictor expired: %d, evicted: %d", expired, evicted);
        }
        evictList.clear();
        ::usleep(kEvictGranularityNs / 1000);
    }
}

Accessor::Impl::AccessorEvictor::AccessorEvictor() {
    std::thread evictor(
            evictorThread,
            std::ref(mAccessors),
            std::ref(mMutex),
            std::ref(mCv));
    evictor.detach();
}

void Accessor::Impl::AccessorEvictor::addAccessor(
        const std::weak_ptr<Accessor::Impl> &impl, nsecs_t ts) {
    std::lock_guard<std::mutex> lock(mMutex);
    bool notify = mAccessors.empty();
    auto it = mAccessors.find(impl);
    if (it == mAccessors.end()) {
        mAccessors.emplace(impl, ts);
    } else {
        it->second = ts;
    }
    if (notify) {
        mCv.notify_one();
    }
}

std::unique_ptr<Accessor::Impl::AccessorEvictor> Accessor::Impl::sEvictor;

void Accessor::Impl::createEvictor() {
    if (!sEvictor) {
        sEvictor = std::make_unique<Accessor::Impl::AccessorEvictor>();
    }
}

void Accessor::Impl::scheduleEvictIfNeeded() {
    nsecs_t now = systemTime();

    if (now > (mScheduleEvictTs + kEvictGranularityNs)) {
        mScheduleEvictTs = now;
        sEvictor->addAccessor(shared_from_this(), now);
    }
}

}  // namespace implementation
}  // namespace V2_0
}  // namespace bufferpool
+24 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <map>
#include <set>
#include <condition_variable>
#include <utils/Timers.h>
#include "Accessor.h"

namespace android {
@@ -71,6 +72,8 @@ public:

    static void createInvalidator();

    static void createEvictor();

private:
    // ConnectionId = pid : (timestamp_created + seqId)
    // in order to guarantee uniqueness for each connection
@@ -78,6 +81,8 @@ private:

    const std::shared_ptr<BufferPoolAllocator> mAllocator;

    nsecs_t mScheduleEvictTs;

    /**
     * Buffer pool implementation.
     *
@@ -389,6 +394,25 @@ private:
        std::mutex &mutex,
        std::condition_variable &cv,
        bool &ready);

    struct AccessorEvictor {
        std::map<const std::weak_ptr<Accessor::Impl>, nsecs_t, std::owner_less<>> mAccessors;
        std::mutex mMutex;
        std::condition_variable mCv;

        AccessorEvictor();
        void addAccessor(const std::weak_ptr<Accessor::Impl> &impl, nsecs_t ts);
    };

    static std::unique_ptr<AccessorEvictor> sEvictor;

    static void evictorThread(
        std::map<const std::weak_ptr<Accessor::Impl>, nsecs_t, std::owner_less<>> &accessors,
        std::mutex &mutex,
        std::condition_variable &cv);

    void scheduleEvictIfNeeded();

};

}  // namespace implementation
+1 −0
Original line number Diff line number Diff line
@@ -484,6 +484,7 @@ sp<ClientManager> ClientManager::getInstance() {
        sInstance = new ClientManager();
    }
    Accessor::createInvalidator();
    Accessor::createEvictor();
    return sInstance;
}