diff options
Diffstat (limited to 'runtime/monitor_android.cc')
-rw-r--r-- | runtime/monitor_android.cc | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/runtime/monitor_android.cc b/runtime/monitor_android.cc new file mode 100644 index 0000000000..9265cd649d --- /dev/null +++ b/runtime/monitor_android.cc @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2008 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 "monitor.h" +#include "thread.h" + +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include "cutils/log.h" + +#define EVENT_LOG_TAG_dvm_lock_sample 20003 + +namespace art { + +static void Set4LE(uint8_t* buf, uint32_t val) { + *buf++ = (uint8_t)(val); + *buf++ = (uint8_t)(val >> 8); + *buf++ = (uint8_t)(val >> 16); + *buf = (uint8_t)(val >> 24); +} + +static char* EventLogWriteInt(char* dst, int value) { + *dst++ = EVENT_TYPE_INT; + Set4LE(reinterpret_cast<uint8_t*>(dst), value); + return dst + 4; +} + +static char* EventLogWriteString(char* dst, const char* value, size_t len) { + *dst++ = EVENT_TYPE_STRING; + len = len < 32 ? len : 32; + Set4LE(reinterpret_cast<uint8_t*>(dst), len); + dst += 4; + memcpy(dst, value, len); + return dst + len; +} + +void Monitor::LogContentionEvent(Thread* self, uint32_t wait_ms, uint32_t sample_percent, + const char* owner_filename, uint32_t owner_line_number) { + // Emit the event list length, 1 byte. + char eventBuffer[174]; + char* cp = eventBuffer; + *cp++ = 9; + + // Emit the process name, <= 37 bytes. + int fd = open("/proc/self/cmdline", O_RDONLY); + char procName[33]; + memset(procName, 0, sizeof(procName)); + read(fd, procName, sizeof(procName) - 1); + close(fd); + size_t len = strlen(procName); + cp = EventLogWriteString(cp, procName, len); + + // Emit the sensitive thread ("main thread") status, 5 bytes. + cp = EventLogWriteInt(cp, Monitor::IsSensitiveThread()); + + // Emit self thread name string, <= 37 bytes. + std::string thread_name; + self->GetThreadName(thread_name); + cp = EventLogWriteString(cp, thread_name.c_str(), thread_name.size()); + + // Emit the wait time, 5 bytes. + cp = EventLogWriteInt(cp, wait_ms); + + // Emit the source code file name, <= 37 bytes. + uint32_t pc; + mirror::AbstractMethod* m = self->GetCurrentMethod(&pc); + const char* filename; + uint32_t line_number; + TranslateLocation(m, pc, filename, line_number); + cp = EventLogWriteString(cp, filename, strlen(filename)); + + // Emit the source code line number, 5 bytes. + cp = EventLogWriteInt(cp, line_number); + + // Emit the lock owner source code file name, <= 37 bytes. + if (owner_filename == NULL) { + owner_filename = ""; + } else if (strcmp(filename, owner_filename) == 0) { + // Common case, so save on log space. + owner_filename = "-"; + } + cp = EventLogWriteString(cp, owner_filename, strlen(owner_filename)); + + // Emit the source code line number, 5 bytes. + cp = EventLogWriteInt(cp, owner_line_number); + + // Emit the sample percentage, 5 bytes. + cp = EventLogWriteInt(cp, sample_percent); + + CHECK_LE((size_t)(cp - eventBuffer), sizeof(eventBuffer)); + android_btWriteLog(EVENT_LOG_TAG_dvm_lock_sample, EVENT_TYPE_LIST, eventBuffer, + (size_t)(cp - eventBuffer)); +} + +} // namespace art |