Home | History | Annotate | Download | only in runtime
      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 <log/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, int32_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, Thread::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   ArtMethod* m = self->GetCurrentMethod(&pc);
     82   const char* filename;
     83   int32_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 == nullptr) {
     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