/*
 * 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, int32_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, Thread::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;
  ArtMethod* m = self->GetCurrentMethod(&pc);
  const char* filename;
  int32_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 == nullptr) {
    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
