1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "monitor.h" 18 #include "thread.h" 19 20 #include <fcntl.h> 21 #include <sys/stat.h> 22 #include <sys/types.h> 23 24 #include "cutils/log.h" 25 26 #define EVENT_LOG_TAG_dvm_lock_sample 20003 27 28 namespace art { 29 30 static void Set4LE(uint8_t* buf, uint32_t val) { 31 *buf++ = (uint8_t)(val); 32 *buf++ = (uint8_t)(val >> 8); 33 *buf++ = (uint8_t)(val >> 16); 34 *buf = (uint8_t)(val >> 24); 35 } 36 37 static char* EventLogWriteInt(char* dst, int value) { 38 *dst++ = EVENT_TYPE_INT; 39 Set4LE(reinterpret_cast<uint8_t*>(dst), value); 40 return dst + 4; 41 } 42 43 static char* EventLogWriteString(char* dst, const char* value, size_t len) { 44 *dst++ = EVENT_TYPE_STRING; 45 len = len < 32 ? len : 32; 46 Set4LE(reinterpret_cast<uint8_t*>(dst), len); 47 dst += 4; 48 memcpy(dst, value, len); 49 return dst + len; 50 } 51 52 void Monitor::LogContentionEvent(Thread* self, uint32_t wait_ms, uint32_t sample_percent, 53 const char* owner_filename, uint32_t owner_line_number) { 54 // Emit the event list length, 1 byte. 55 char eventBuffer[174]; 56 char* cp = eventBuffer; 57 *cp++ = 9; 58 59 // Emit the process name, <= 37 bytes. 60 int fd = open("/proc/self/cmdline", O_RDONLY); 61 char procName[33]; 62 memset(procName, 0, sizeof(procName)); 63 read(fd, procName, sizeof(procName) - 1); 64 close(fd); 65 size_t len = strlen(procName); 66 cp = EventLogWriteString(cp, procName, len); 67 68 // Emit the sensitive thread ("main thread") status, 5 bytes. 69 cp = EventLogWriteInt(cp, Monitor::IsSensitiveThread()); 70 71 // Emit self thread name string, <= 37 bytes. 72 std::string thread_name; 73 self->GetThreadName(thread_name); 74 cp = EventLogWriteString(cp, thread_name.c_str(), thread_name.size()); 75 76 // Emit the wait time, 5 bytes. 77 cp = EventLogWriteInt(cp, wait_ms); 78 79 // Emit the source code file name, <= 37 bytes. 80 uint32_t pc; 81 mirror::ArtMethod* m = self->GetCurrentMethod(&pc); 82 const char* filename; 83 uint32_t line_number; 84 TranslateLocation(m, pc, &filename, &line_number); 85 cp = EventLogWriteString(cp, filename, strlen(filename)); 86 87 // Emit the source code line number, 5 bytes. 88 cp = EventLogWriteInt(cp, line_number); 89 90 // Emit the lock owner source code file name, <= 37 bytes. 91 if (owner_filename == NULL) { 92 owner_filename = ""; 93 } else if (strcmp(filename, owner_filename) == 0) { 94 // Common case, so save on log space. 95 owner_filename = "-"; 96 } 97 cp = EventLogWriteString(cp, owner_filename, strlen(owner_filename)); 98 99 // Emit the source code line number, 5 bytes. 100 cp = EventLogWriteInt(cp, owner_line_number); 101 102 // Emit the sample percentage, 5 bytes. 103 cp = EventLogWriteInt(cp, sample_percent); 104 105 CHECK_LE((size_t)(cp - eventBuffer), sizeof(eventBuffer)); 106 android_btWriteLog(EVENT_LOG_TAG_dvm_lock_sample, EVENT_TYPE_LIST, eventBuffer, 107 (size_t)(cp - eventBuffer)); 108 } 109 110 } // namespace art 111