/*
 * 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 "object.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((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((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->GetName()->ToModifiedUtf8());
  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.
  const char* filename;
  uint32_t line_number;
  self->GetCurrentLocation(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
