summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorGlenn Kasten <gkasten@google.com>2013-01-14 14:53:13 -0800
committerGlenn Kasten <gkasten@google.com>2013-01-25 15:01:24 -0800
commit10eb4b33545a58e4b09249c30c100bc7b992250a (patch)
tree412dc200ac801d561fd2df61c462c2d8485fcb9e /include
parentbb9c2e1155d0a844f04aec981b44a9e562522fde (diff)
downloadframeworks_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.h188
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