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

Commit 70aca464 authored by Glenn Kasten's avatar Glenn Kasten Committed by Android (Google) Code Review
Browse files

Merge "Add RecordThread media.log and deferred deallocation"

parents 0312b69e 481fb67a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -441,7 +441,7 @@ void NBLog::Reader::dump(int fd, size_t indent)

bool NBLog::Reader::isIMemory(const sp<IMemory>& iMemory) const
{
    return iMemory.get() == mIMemory.get();
    return iMemory != 0 && mIMemory != 0 && iMemory->pointer() == mIMemory->pointer();
}

}   // namespace android
+49 −12
Original line number Diff line number Diff line
@@ -213,6 +213,18 @@ AudioFlinger::~AudioFlinger()
        audio_hw_device_close(mAudioHwDevs.valueAt(i)->hwDevice());
        delete mAudioHwDevs.valueAt(i);
    }

    // Tell media.log service about any old writers that still need to be unregistered
    sp<IBinder> binder = defaultServiceManager()->getService(String16("media.log"));
    if (binder != 0) {
        sp<IMediaLogService> mediaLogService(interface_cast<IMediaLogService>(binder));
        for (size_t count = mUnregisteredWriters.size(); count > 0; count--) {
            sp<IMemory> iMemory(mUnregisteredWriters.top()->getIMemory());
            mUnregisteredWriters.pop();
            mediaLogService->unregisterWriter(iMemory);
        }
    }

}

static const char * const audio_interfaces[] = {
@@ -406,16 +418,44 @@ sp<AudioFlinger::Client> AudioFlinger::registerPid_l(pid_t pid)

sp<NBLog::Writer> AudioFlinger::newWriter_l(size_t size, const char *name)
{
    // If there is no memory allocated for logs, return a dummy writer that does nothing
    if (mLogMemoryDealer == 0) {
        return new NBLog::Writer();
    }
    sp<IMemory> shared = mLogMemoryDealer->allocate(NBLog::Timeline::sharedSize(size));
    sp<NBLog::Writer> writer = new NBLog::Writer(size, shared);
    sp<IBinder> binder = defaultServiceManager()->getService(String16("media.log"));
    if (binder != 0) {
        interface_cast<IMediaLogService>(binder)->registerWriter(shared, size, name);
    // Similarly if we can't contact the media.log service, also return a dummy writer
    if (binder == 0) {
        return new NBLog::Writer();
    }
    sp<IMediaLogService> mediaLogService(interface_cast<IMediaLogService>(binder));
    sp<IMemory> shared = mLogMemoryDealer->allocate(NBLog::Timeline::sharedSize(size));
    // If allocation fails, consult the vector of previously unregistered writers
    // and garbage-collect one or more them until an allocation succeeds
    if (shared == 0) {
        Mutex::Autolock _l(mUnregisteredWritersLock);
        for (size_t count = mUnregisteredWriters.size(); count > 0; count--) {
            {
                // Pick the oldest stale writer to garbage-collect
                sp<IMemory> iMemory(mUnregisteredWriters[0]->getIMemory());
                mUnregisteredWriters.removeAt(0);
                mediaLogService->unregisterWriter(iMemory);
                // Now the media.log remote reference to IMemory is gone.  When our last local
                // reference to IMemory also drops to zero at end of this block,
                // the IMemory destructor will deallocate the region from mLogMemoryDealer.
            }
            // Re-attempt the allocation
            shared = mLogMemoryDealer->allocate(NBLog::Timeline::sharedSize(size));
            if (shared != 0) {
                goto success;
            }
        }
        // Even after garbage-collecting all old writers, there is still not enough memory,
        // so return a dummy writer
        return new NBLog::Writer();
    }
    return writer;
success:
    mediaLogService->registerWriter(shared, size, name);
    return new NBLog::Writer(size, shared);
}

void AudioFlinger::unregisterWriter(const sp<NBLog::Writer>& writer)
@@ -427,13 +467,10 @@ void AudioFlinger::unregisterWriter(const sp<NBLog::Writer>& writer)
    if (iMemory == 0) {
        return;
    }
    sp<IBinder> binder = defaultServiceManager()->getService(String16("media.log"));
    if (binder != 0) {
        interface_cast<IMediaLogService>(binder)->unregisterWriter(iMemory);
        // Now the media.log remote reference to IMemory is gone.
        // When our last local reference to IMemory also drops to zero,
        // the IMemory destructor will deallocate the region from mMemoryDealer.
    }
    // Rather than removing the writer immediately, append it to a queue of old writers to
    // be garbage-collected later.  This allows us to continue to view old logs for a while.
    Mutex::Autolock _l(mUnregisteredWritersLock);
    mUnregisteredWriters.push(writer);
}

// IAudioFlinger interface
+5 −1
Original line number Diff line number Diff line
@@ -235,8 +235,12 @@ public:
    sp<NBLog::Writer>   newWriter_l(size_t size, const char *name);
    void                unregisterWriter(const sp<NBLog::Writer>& writer);
private:
    static const size_t kLogMemorySize = 10 * 1024;
    static const size_t kLogMemorySize = 40 * 1024;
    sp<MemoryDealer>    mLogMemoryDealer;   // == 0 when NBLog is disabled
    // When a log writer is unregistered, it is done lazily so that media.log can continue to see it
    // for as long as possible.  The memory is only freed when it is needed for another log writer.
    Vector< sp<NBLog::Writer> > mUnregisteredWriters;
    Mutex               mUnregisteredWritersLock;
public:

    class SyncEvent;
+2 −0
Original line number Diff line number Diff line
@@ -4404,6 +4404,7 @@ AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger,
#endif
{
    snprintf(mName, kNameLength, "AudioIn_%X", id);
    mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mName);

    readInputParameters();
}
@@ -4411,6 +4412,7 @@ AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger,

AudioFlinger::RecordThread::~RecordThread()
{
    mAudioFlinger->unregisterWriter(mNBLogWriter);
    delete[] mRsmpInBuffer;
    delete mResampler;
    delete[] mRsmpOutBuffer;