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 
     19 #include <fcntl.h>
     20 #include <sys/stat.h>
     21 #include <sys/types.h>
     22 
     23 #include <log/log.h>
     24 #include <log/log_event_list.h>
     25 
     26 #include "art_method.h"
     27 #include "thread.h"
     28 
     29 #define EVENT_LOG_TAG_dvm_lock_sample 20003
     30 
     31 namespace art {
     32 
     33 void Monitor::LogContentionEvent(Thread* self,
     34                                  uint32_t wait_ms,
     35                                  uint32_t sample_percent,
     36                                  ArtMethod* owner_method,
     37                                  uint32_t owner_dex_pc) {
     38   android_log_event_list ctx(EVENT_LOG_TAG_dvm_lock_sample);
     39 
     40   const char* owner_filename;
     41   int32_t owner_line_number;
     42   TranslateLocation(owner_method, owner_dex_pc, &owner_filename, &owner_line_number);
     43 
     44   // Emit the process name, <= 37 bytes.
     45   {
     46     int fd = open("/proc/self/cmdline", O_RDONLY);
     47     char procName[33];
     48     memset(procName, 0, sizeof(procName));
     49     read(fd, procName, sizeof(procName) - 1);
     50     close(fd);
     51     ctx << procName;
     52   }
     53 
     54   // Emit the sensitive thread ("main thread") status. We follow tradition that this corresponds
     55   // to a C++ bool's value, but be explicit.
     56   constexpr uint32_t kIsSensitive = 1u;
     57   constexpr uint32_t kIsNotSensitive = 0u;
     58   ctx << (Thread::IsSensitiveThread() ? kIsSensitive : kIsNotSensitive);
     59 
     60   // Emit self thread name string.
     61   {
     62     std::string thread_name;
     63     self->GetThreadName(thread_name);
     64     ctx << thread_name;
     65   }
     66 
     67   // Emit the wait time.
     68   ctx << wait_ms;
     69 
     70   const char* filename = nullptr;
     71   {
     72     uint32_t pc;
     73     ArtMethod* m = self->GetCurrentMethod(&pc);
     74     int32_t line_number;
     75     TranslateLocation(m, pc, &filename, &line_number);
     76 
     77     // Emit the source code file name.
     78     ctx << filename;
     79 
     80     // Emit the source code line number.
     81     ctx << line_number;
     82 
     83     // Emit the method name.
     84     ctx << ArtMethod::PrettyMethod(m);
     85   }
     86 
     87   // Emit the lock owner source code file name.
     88   if (owner_filename == nullptr) {
     89     owner_filename = "";
     90   } else if (strcmp(filename, owner_filename) == 0) {
     91     // Common case, so save on log space.
     92     owner_filename = "-";
     93   }
     94   ctx << owner_filename;
     95 
     96   // Emit the source code line number.
     97   ctx << owner_line_number;
     98 
     99   // Emit the owner method name.
    100   ctx << ArtMethod::PrettyMethod(owner_method);
    101 
    102   // Emit the sample percentage.
    103   ctx << sample_percent;
    104 
    105   ctx << LOG_ID_EVENTS;
    106 }
    107 
    108 }  // namespace art
    109