Basic binary event-log helpers
EventLog can be used from SurfaceFlinger to log jank statistics events to the binary event log. Change-Id: If0fbbe7d7111f10957697166d37fd0c3418109bb
This commit is contained in:
parent
ae772278fe
commit
85cce376cb
@ -18,6 +18,8 @@ LOCAL_SRC_FILES:= \
|
|||||||
DisplayHardware/HWComposer.cpp \
|
DisplayHardware/HWComposer.cpp \
|
||||||
DisplayHardware/PowerHAL.cpp \
|
DisplayHardware/PowerHAL.cpp \
|
||||||
DisplayHardware/VirtualDisplaySurface.cpp \
|
DisplayHardware/VirtualDisplaySurface.cpp \
|
||||||
|
EventLog/EventLogTags.logtags \
|
||||||
|
EventLog/EventLog.cpp
|
||||||
|
|
||||||
LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\"
|
LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\"
|
||||||
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
|
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
|
||||||
|
128
services/surfaceflinger/EventLog/EventLog.cpp
Normal file
128
services/surfaceflinger/EventLog/EventLog.cpp
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <cutils/log.h>
|
||||||
|
#include <utils/String8.h>
|
||||||
|
|
||||||
|
#include "EventLog.h"
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
namespace android {
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ANDROID_SINGLETON_STATIC_INSTANCE(EventLog)
|
||||||
|
|
||||||
|
|
||||||
|
EventLog::EventLog() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventLog::doLogJank(const String8& window, int32_t value) {
|
||||||
|
EventLog::TagBuffer buffer(LOGTAG_SF_JANK);
|
||||||
|
buffer.startList(2);
|
||||||
|
buffer.writeString8(window);
|
||||||
|
buffer.writeInt32(value);
|
||||||
|
buffer.endList();
|
||||||
|
buffer.log();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventLog::logJank(const String8& window, int32_t value) {
|
||||||
|
EventLog::getInstance().doLogJank(window, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
EventLog::TagBuffer::TagBuffer(int32_t tag)
|
||||||
|
: mPos(0), mTag(tag), mOverflow(false) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventLog::TagBuffer::log() {
|
||||||
|
if (mOverflow) {
|
||||||
|
ALOGW("couldn't log to binary event log: overflow.");
|
||||||
|
} else if (android_bWriteLog(mTag, mStorage, mPos) < 0) {
|
||||||
|
ALOGE("couldn't log to EventLog: %s", strerror(errno));
|
||||||
|
}
|
||||||
|
// purge the buffer
|
||||||
|
mPos = 0;
|
||||||
|
mOverflow = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventLog::TagBuffer::startList(int8_t count) {
|
||||||
|
if (mOverflow) return;
|
||||||
|
const size_t needed = 1 + sizeof(count);
|
||||||
|
if (mPos + needed > STORAGE_MAX_SIZE) {
|
||||||
|
mOverflow = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mStorage[mPos + 0] = EVENT_TYPE_LIST;
|
||||||
|
mStorage[mPos + 1] = count;
|
||||||
|
mPos += needed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventLog::TagBuffer::endList() {
|
||||||
|
if (mOverflow) return;
|
||||||
|
const size_t needed = 1;
|
||||||
|
if (mPos + needed > STORAGE_MAX_SIZE) {
|
||||||
|
mOverflow = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mStorage[mPos + 0] = '\n';
|
||||||
|
mPos += needed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventLog::TagBuffer::writeInt32(int32_t value) {
|
||||||
|
if (mOverflow) return;
|
||||||
|
const size_t needed = 1 + sizeof(value);
|
||||||
|
if (mPos + needed > STORAGE_MAX_SIZE) {
|
||||||
|
mOverflow = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mStorage[mPos + 0] = EVENT_TYPE_INT;
|
||||||
|
memcpy(&mStorage[mPos + 1], &value, sizeof(value));
|
||||||
|
mPos += needed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventLog::TagBuffer::writeInt64(int64_t value) {
|
||||||
|
if (mOverflow) return;
|
||||||
|
const size_t needed = 1 + sizeof(value);
|
||||||
|
if (mPos + needed > STORAGE_MAX_SIZE) {
|
||||||
|
mOverflow = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mStorage[mPos + 0] = EVENT_TYPE_LONG;
|
||||||
|
memcpy(&mStorage[mPos + 1], &value, sizeof(value));
|
||||||
|
mPos += needed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventLog::TagBuffer::writeString8(const String8& value) {
|
||||||
|
if (mOverflow) return;
|
||||||
|
const int32_t stringLen = value.length();
|
||||||
|
const size_t needed = 1 + sizeof(int32_t) + stringLen;
|
||||||
|
if (mPos + needed > STORAGE_MAX_SIZE) {
|
||||||
|
mOverflow = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mStorage[mPos + 0] = EVENT_TYPE_STRING;
|
||||||
|
memcpy(&mStorage[mPos + 1], &stringLen, sizeof(int32_t));
|
||||||
|
memcpy(&mStorage[mPos + 5], value.string(), stringLen);
|
||||||
|
mPos += needed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
}// namespace android
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
83
services/surfaceflinger/EventLog/EventLog.h
Normal file
83
services/surfaceflinger/EventLog/EventLog.h
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <utils/Errors.h>
|
||||||
|
#include <utils/Singleton.h>
|
||||||
|
|
||||||
|
#ifndef ANDROID_SF_EVENTLOG_H
|
||||||
|
#define ANDROID_SF_EVENTLOG_H
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
namespace android {
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class String8;
|
||||||
|
|
||||||
|
class EventLog : public Singleton<EventLog> {
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void logJank(const String8& window, int32_t value);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
EventLog();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*
|
||||||
|
* EventLogBuffer is a helper class to construct an in-memory event log
|
||||||
|
* tag. In this version the buffer is not dynamic, so write operation can
|
||||||
|
* fail if there is not enough space in the temporary buffer.
|
||||||
|
* Once constructed, the buffer can be logger by calling the log()
|
||||||
|
* method.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class TagBuffer {
|
||||||
|
enum { STORAGE_MAX_SIZE = 128 };
|
||||||
|
int32_t mPos;
|
||||||
|
int32_t mTag;
|
||||||
|
bool mOverflow;
|
||||||
|
char mStorage[STORAGE_MAX_SIZE];
|
||||||
|
public:
|
||||||
|
TagBuffer(int32_t tag);
|
||||||
|
|
||||||
|
// starts list of items
|
||||||
|
void startList(int8_t count);
|
||||||
|
// terminates the list
|
||||||
|
void endList();
|
||||||
|
// write a 32-bit integer
|
||||||
|
void writeInt32(int32_t value);
|
||||||
|
// write a 64-bit integer
|
||||||
|
void writeInt64(int64_t value);
|
||||||
|
// write a C string
|
||||||
|
void writeString8(const String8& value);
|
||||||
|
|
||||||
|
// outputs the the buffer to the log
|
||||||
|
void log();
|
||||||
|
};
|
||||||
|
|
||||||
|
friend class Singleton<EventLog>;
|
||||||
|
EventLog(const EventLog&);
|
||||||
|
EventLog& operator =(const EventLog&);
|
||||||
|
|
||||||
|
enum { LOGTAG_SF_JANK = 60100 };
|
||||||
|
void doLogJank(const String8& window, int32_t value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
}// namespace android
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#endif /* ANDROID_SF_EVENTLOG_H */
|
38
services/surfaceflinger/EventLog/EventLogTags.logtags
Normal file
38
services/surfaceflinger/EventLog/EventLogTags.logtags
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# The entries in this file map a sparse set of log tag numbers to tag names.
|
||||||
|
# This is installed on the device, in /system/etc, and parsed by logcat.
|
||||||
|
#
|
||||||
|
# Tag numbers are decimal integers, from 0 to 2^31. (Let's leave the
|
||||||
|
# negative values alone for now.)
|
||||||
|
#
|
||||||
|
# Tag names are one or more ASCII letters and numbers or underscores, i.e.
|
||||||
|
# "[A-Z][a-z][0-9]_". Do not include spaces or punctuation (the former
|
||||||
|
# impacts log readability, the latter makes regex searches more annoying).
|
||||||
|
#
|
||||||
|
# Tag numbers and names are separated by whitespace. Blank lines and lines
|
||||||
|
# starting with '#' are ignored.
|
||||||
|
#
|
||||||
|
# Optionally, after the tag names can be put a description for the value(s)
|
||||||
|
# of the tag. Description are in the format
|
||||||
|
# (<name>|data type[|data unit])
|
||||||
|
# Multiple values are separated by commas.
|
||||||
|
#
|
||||||
|
# The data type is a number from the following values:
|
||||||
|
# 1: int
|
||||||
|
# 2: long
|
||||||
|
# 3: string
|
||||||
|
# 4: list
|
||||||
|
#
|
||||||
|
# The data unit is a number taken from the following list:
|
||||||
|
# 1: Number of objects
|
||||||
|
# 2: Number of bytes
|
||||||
|
# 3: Number of milliseconds
|
||||||
|
# 4: Number of allocations
|
||||||
|
# 5: Id
|
||||||
|
# 6: Percent
|
||||||
|
# Default value for data of type int/long is 2 (bytes).
|
||||||
|
|
||||||
|
# surfaceflinger
|
||||||
|
60100 sf_jank (window|3),(value|1)
|
||||||
|
|
||||||
|
# NOTE - the range 1000000-2000000 is reserved for partners and others who
|
||||||
|
# want to define their own log tags without conflicting with the core platform.
|
Loading…
Reference in New Issue
Block a user