/*
 * 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::ArtMethod* 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
