diff options
author | Glenn Kasten <gkasten@google.com> | 2013-01-14 14:53:13 -0800 |
---|---|---|
committer | Glenn Kasten <gkasten@google.com> | 2013-01-25 15:01:24 -0800 |
commit | 10eb4b33545a58e4b09249c30c100bc7b992250a (patch) | |
tree | 412dc200ac801d561fd2df61c462c2d8485fcb9e /include | |
parent | bb9c2e1155d0a844f04aec981b44a9e562522fde (diff) | |
download | frameworks_av-10eb4b33545a58e4b09249c30c100bc7b992250a.zip frameworks_av-10eb4b33545a58e4b09249c30c100bc7b992250a.tar.gz frameworks_av-10eb4b33545a58e4b09249c30c100bc7b992250a.tar.bz2 |
Add non-blocking event logger NBLog
Change-Id: I6c136cf3d7f46a8af84c69ecfc199dab394c10dc
Diffstat (limited to 'include')
-rw-r--r-- | include/media/nbaio/NBLog.h | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/include/media/nbaio/NBLog.h b/include/media/nbaio/NBLog.h new file mode 100644 index 0000000..8fc417f --- /dev/null +++ b/include/media/nbaio/NBLog.h @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2013 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. + */ + +// Non-blocking event logger intended for safe communication between processes via shared memory + +#ifndef ANDROID_MEDIA_NBLOG_H +#define ANDROID_MEDIA_NBLOG_H + +#include <binder/IMemory.h> +#include <utils/Mutex.h> +#include <media/nbaio/roundup.h> + +namespace android { + +class NBLog { + +public: + +class Writer; +class Reader; + +private: + +enum Event { + EVENT_RESERVED, + EVENT_STRING, // ASCII string, not NUL-terminated + EVENT_TIMESTAMP, // clock_gettime(CLOCK_MONOTONIC) +}; + +// --------------------------------------------------------------------------- + +// representation of a single log entry in private memory +struct Entry { + Entry(Event event, const void *data, size_t length) + : mEvent(event), mLength(length), mData(data) { } + /*virtual*/ ~Entry() { } + + int readAt(size_t offset) const; + +private: + friend class Writer; + Event mEvent; // event type + size_t mLength; // length of additional data, 0 <= mLength <= 255 + const void *mData; // event type-specific data +}; + +// representation of a single log entry in shared memory +// byte[0] mEvent +// byte[1] mLength +// byte[2] mData[0] +// ... +// byte[2+i] mData[i] +// ... +// byte[2+mLength-1] mData[mLength-1] +// byte[2+mLength] duplicate copy of mLength to permit reverse scan +// byte[3+mLength] start of next log entry + +// located in shared memory +struct Shared { + Shared() : mRear(0) { } + /*virtual*/ ~Shared() { } + + volatile int32_t mRear; // index one byte past the end of most recent Entry + char mBuffer[0]; // circular buffer for entries +}; + +public: + +// --------------------------------------------------------------------------- + +// FIXME Timeline was intended to wrap Writer and Reader, but isn't actually used yet. +// For now it is just a namespace for sharedSize(). +class Timeline : public RefBase { +public: +#if 0 + Timeline(size_t size, void *shared = NULL); + virtual ~Timeline(); +#endif + + static size_t sharedSize(size_t size); + +#if 0 +private: + friend class Writer; + friend class Reader; + + const size_t mSize; // circular buffer size in bytes, must be a power of 2 + bool mOwn; // whether I own the memory at mShared + Shared* const mShared; // pointer to shared memory +#endif +}; + +// --------------------------------------------------------------------------- + +// Writer is thread-safe with respect to Reader, but not with respect to multiple threads +// calling Writer methods. If you need multi-thread safety for writing, use LockedWriter. +class Writer : public RefBase { +public: + Writer(); // dummy nop implementation without shared memory + Writer(size_t size, void *shared); + Writer(size_t size, const sp<IMemory>& iMemory); + virtual ~Writer() { } + + virtual void log(const char *string); + virtual void logf(const char *fmt, ...); + virtual void logvf(const char *fmt, va_list ap); + virtual void logTimestamp(); + virtual void logTimestamp(const struct timespec& ts); + + virtual bool isEnabled() const; + + // return value for all of these is the previous isEnabled() + virtual bool setEnabled(bool enabled); // but won't enable if no shared memory + bool enable() { return setEnabled(true); } + bool disable() { return setEnabled(false); } + + sp<IMemory> getIMemory() const { return mIMemory; } + +private: + void log(Event event, const void *data, size_t length); + void log(const Entry *entry, bool trusted = false); + + const size_t mSize; // circular buffer size in bytes, must be a power of 2 + Shared* const mShared; // raw pointer to shared memory + const sp<IMemory> mIMemory; // ref-counted version + int32_t mRear; // my private copy of mShared->mRear + bool mEnabled; // whether to actually log +}; + +// --------------------------------------------------------------------------- + +// Similar to Writer, but safe for multiple threads to call concurrently +class LockedWriter : public Writer { +public: + LockedWriter(); + LockedWriter(size_t size, void *shared); + + virtual void log(const char *string); + virtual void logf(const char *fmt, ...); + virtual void logvf(const char *fmt, va_list ap); + virtual void logTimestamp(); + virtual void logTimestamp(const struct timespec& ts); + + virtual bool isEnabled() const; + virtual bool setEnabled(bool enabled); + +private: + mutable Mutex mLock; +}; + +// --------------------------------------------------------------------------- + +class Reader : public RefBase { +public: + Reader(size_t size, const void *shared); + Reader(size_t size, const sp<IMemory>& iMemory); + virtual ~Reader() { } + + void dump(int fd, size_t indent = 0); + bool isIMemory(const sp<IMemory>& iMemory) const; + +private: + const size_t mSize; // circular buffer size in bytes, must be a power of 2 + const Shared* const mShared; // raw pointer to shared memory + const sp<IMemory> mIMemory; // ref-counted version + int32_t mFront; // index of oldest acknowledged Entry + + static const size_t kSquashTimestamp = 5; // squash this many or more adjacent timestamps +}; + +}; // class NBLog + +} // namespace android + +#endif // ANDROID_MEDIA_NBLOG_H |