NBLog.h revision 11d8dfcc063425ae7d59229f54b6752fd8987c10
111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten/* 211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten * Copyright (C) 2013 The Android Open Source Project 311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten * 411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten * you may not use this file except in compliance with the License. 611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten * You may obtain a copy of the License at 711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten * 811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten * 1011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten * Unless required by applicable law or agreed to in writing, software 1111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 1211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten * See the License for the specific language governing permissions and 1411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten * limitations under the License. 1511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten */ 1611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 1711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// Non-blocking event logger intended for safe communication between processes via shared memory 1811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 1911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten#ifndef ANDROID_MEDIA_NBLOG_H 2011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten#define ANDROID_MEDIA_NBLOG_H 2111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 2211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten#include <binder/IMemory.h> 2311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten#include <utils/Mutex.h> 2411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten#include <media/nbaio/roundup.h> 2511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 2611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastennamespace android { 2711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 2811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenclass NBLog { 2911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 3011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenpublic: 3111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 3211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenclass Writer; 3311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenclass Reader; 3411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 3511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenprivate: 3611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 3711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenenum Event { 3811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten EVENT_RESERVED, 3911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten EVENT_STRING, // ASCII string, not NUL-terminated 4011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten EVENT_TIMESTAMP, // clock_gettime(CLOCK_MONOTONIC) 4111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}; 4211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 4311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// --------------------------------------------------------------------------- 4411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 4511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// representation of a single log entry in private memory 4611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenstruct Entry { 4711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten Entry(Event event, const void *data, size_t length) 4811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten : mEvent(event), mLength(length), mData(data) { } 4911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten /*virtual*/ ~Entry() { } 5011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 5111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten int readAt(size_t offset) const; 5211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 5311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenprivate: 5411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten friend class Writer; 5511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten Event mEvent; // event type 5611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten size_t mLength; // length of additional data, 0 <= mLength <= 255 5711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten const void *mData; // event type-specific data 5811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}; 5911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 6011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// representation of a single log entry in shared memory 6111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// byte[0] mEvent 6211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// byte[1] mLength 6311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// byte[2] mData[0] 6411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// ... 6511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// byte[2+i] mData[i] 6611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// ... 6711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// byte[2+mLength-1] mData[mLength-1] 6811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// byte[2+mLength] duplicate copy of mLength to permit reverse scan 6911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// byte[3+mLength] start of next log entry 7011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 7111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// located in shared memory 7211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenstruct Shared { 7311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten Shared() : mRear(0) { } 7411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten /*virtual*/ ~Shared() { } 7511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 7611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten volatile int32_t mRear; // index one byte past the end of most recent Entry 7711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten char mBuffer[0]; // circular buffer for entries 7811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}; 7911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 8011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenpublic: 8111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 8211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// --------------------------------------------------------------------------- 8311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 8411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// FIXME Timeline was intended to wrap Writer and Reader, but isn't actually used yet. 8511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// For now it is just a namespace for sharedSize(). 8611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenclass Timeline : public RefBase { 8711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenpublic: 8811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten#if 0 8911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten Timeline(size_t size, void *shared = NULL); 9011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten virtual ~Timeline(); 9111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten#endif 9211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 9311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten static size_t sharedSize(size_t size); 9411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 9511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten#if 0 9611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenprivate: 9711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten friend class Writer; 9811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten friend class Reader; 9911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 10011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten const size_t mSize; // circular buffer size in bytes, must be a power of 2 10111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten bool mOwn; // whether I own the memory at mShared 10211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten Shared* const mShared; // pointer to shared memory 10311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten#endif 10411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}; 10511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 10611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// --------------------------------------------------------------------------- 10711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 10811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// Writer is thread-safe with respect to Reader, but not with respect to multiple threads 10911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// calling Writer methods. If you need multi-thread safety for writing, use LockedWriter. 11011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenclass Writer : public RefBase { 11111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenpublic: 11211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten Writer(); // dummy nop implementation without shared memory 11311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten Writer(size_t size, void *shared); 11411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten Writer(size_t size, const sp<IMemory>& iMemory); 11511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten virtual ~Writer() { } 11611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 11711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten virtual void log(const char *string); 11811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten virtual void logf(const char *fmt, ...); 11911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten virtual void logvf(const char *fmt, va_list ap); 12011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten virtual void logTimestamp(); 12111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten virtual void logTimestamp(const struct timespec& ts); 12211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 12311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten virtual bool isEnabled() const; 12411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 12511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten // return value for all of these is the previous isEnabled() 12611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten virtual bool setEnabled(bool enabled); // but won't enable if no shared memory 12711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten bool enable() { return setEnabled(true); } 12811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten bool disable() { return setEnabled(false); } 12911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 13011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten sp<IMemory> getIMemory() const { return mIMemory; } 13111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 13211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenprivate: 13311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten void log(Event event, const void *data, size_t length); 13411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten void log(const Entry *entry, bool trusted = false); 13511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 13611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten const size_t mSize; // circular buffer size in bytes, must be a power of 2 13711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten Shared* const mShared; // raw pointer to shared memory 13811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten const sp<IMemory> mIMemory; // ref-counted version 13911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten int32_t mRear; // my private copy of mShared->mRear 14011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten bool mEnabled; // whether to actually log 14111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}; 14211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 14311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// --------------------------------------------------------------------------- 14411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 14511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// Similar to Writer, but safe for multiple threads to call concurrently 14611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenclass LockedWriter : public Writer { 14711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenpublic: 14811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten LockedWriter(); 14911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten LockedWriter(size_t size, void *shared); 15011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 15111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten virtual void log(const char *string); 15211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten virtual void logf(const char *fmt, ...); 15311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten virtual void logvf(const char *fmt, va_list ap); 15411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten virtual void logTimestamp(); 15511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten virtual void logTimestamp(const struct timespec& ts); 15611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 15711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten virtual bool isEnabled() const; 15811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten virtual bool setEnabled(bool enabled); 15911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 16011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenprivate: 16111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten mutable Mutex mLock; 16211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}; 16311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 16411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// --------------------------------------------------------------------------- 16511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 16611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenclass Reader : public RefBase { 16711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenpublic: 16811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten Reader(size_t size, const void *shared); 16911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten Reader(size_t size, const sp<IMemory>& iMemory); 17011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten virtual ~Reader() { } 17111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 17211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten void dump(int fd, size_t indent = 0); 17311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten bool isIMemory(const sp<IMemory>& iMemory) const; 17411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 17511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenprivate: 17611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten const size_t mSize; // circular buffer size in bytes, must be a power of 2 17711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten const Shared* const mShared; // raw pointer to shared memory 17811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten const sp<IMemory> mIMemory; // ref-counted version 17911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten int32_t mFront; // index of oldest acknowledged Entry 18011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 18111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten static const size_t kSquashTimestamp = 5; // squash this many or more adjacent timestamps 18211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}; 18311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 18411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}; // class NBLog 18511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 18611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten} // namespace android 18711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten 18811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten#endif // ANDROID_MEDIA_NBLOG_H 189