// Copyright 2020 The Bazel Authors. All rights reserved.
//
// 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.

// POSIX support for Starlark CPU profiler.

#include <arpa/inet.h>  // for htonl
#include <errno.h>
#include <fcntl.h>
#include <jni.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

namespace cpu_profiler {

// static native boolean supported();
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_devtools_build_lib_syntax_CpuProfiler_supported(JNIEnv *env,
                                                                jclass clazz) {
  return true;
}

static int fd;  // the write end of the profile event pipe

pid_t gettid(void) {
#ifdef __linux__
  return (pid_t)syscall(SYS_gettid);
#else  // darwin
  return (pid_t)syscall(SYS_thread_selfid);
#endif
}

// SIGPROF handler.
// Warning: asynchronous! See signal-safety(7) for the programming discipline.
void onsigprof(int sig) {
  int old_errno = errno;

  if (fd == 0) {
    const char *msg = "startTimer called before createPipe\n";
    write(2, msg, strlen(msg));
    abort();
  }

  // Send an event containing the int32be-encoded OS thread ID.
  pid_t tid = gettid();
  uint32_t tid_be = htonl(tid);
  int r = write(fd, (void *)&tid_be, sizeof tid_be);
  if (r < 0) {
    if (errno == EAGAIN || errno == EWOULDBLOCK) {
      // The Java router thread cannot keep up.
      //
      // A busy 12-core machine receives 12 * 100Hz = 1200 signals per second,
      // and thus writes 4.8KB/s to the pipe. The default pipe buffer
      // size on Linux is 64KiB, sufficient to buffer ~14s of data.
      // (It is a quarter of that on Mac OS X.)
      //
      // Rather than block in write(2), causing the JVM to deadlock,
      // we print an error and discard the event.
      const char *msg =
          "Starlark profile event router thread cannot keep up; discarding "
          "events\n";
      write(2, msg, strlen(msg));
    } else {
      // We shouldn't use perror in a signal handler.
      // Strictly, we shouldn't use strerror either,
      // but for all errors returned by write it merely
      // returns a constant.
      char buf[1024] = "write: ";
      strncat(buf, strerror(errno), sizeof buf - strlen(buf) - 1);
      strncat(buf, "\n", sizeof buf - strlen(buf) - 1);
      write(2, buf, strlen(buf));
      abort();
    }
  }

  errno = old_errno;
}

// static native jint gettid();
extern "C" JNIEXPORT jint JNICALL
Java_com_google_devtools_build_lib_syntax_CpuProfiler_gettid(JNIEnv *env,
                                                             jclass clazz) {
  return gettid();
}

// makeFD: return new FileDescriptor(fd)
//
// This would be easy to do in Java, but for the field being private.
// Java really does everything it can to make system programming hateful.
static jobject makeFD(JNIEnv *env, int fd) {
  jclass fdclass = env->FindClass("java/io/FileDescriptor");
  if (fdclass == NULL) return NULL;  // exception

  jmethodID init = env->GetMethodID(fdclass, "<init>", "()V");
  if (init == NULL) return NULL;  // exception
  jobject fdobj = env->NewObject(fdclass, init);

  jfieldID fd_field = env->GetFieldID(fdclass, "fd", "I");
  if (fd_field == NULL) return NULL;  // exception
  env->SetIntField(fdobj, fd_field, fd);

  return fdobj;
}

// static native FileDescriptor createPipe();
extern "C" JNIEXPORT jobject JNICALL
Java_com_google_devtools_build_lib_syntax_CpuProfiler_createPipe(JNIEnv *env,
                                                                 jclass clazz) {
  // Create a pipe for profile events from the handler to Java.
  // The default pipe size is 64KiB on Linux and 16KiB on Mac OS X.
  int pipefds[2];
  if (pipe(pipefds) < 0) {
    perror("pipe");
    abort();
  }
  fd = pipefds[1];

  // Make the write end non-blocking so that the signal
  // handler can detect overflow (rather than deadlock).
  fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);

  // Return the read end of the event pipe,
  // wrapped by a java FileDescriptor.
  return makeFD(env, pipefds[0]);
}

// static native boolean startTimer(long period_micros);
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_devtools_build_lib_syntax_CpuProfiler_startTimer(
    JNIEnv *env, jclass clazz, jlong period_micros) {
  // Install the signal handler.
  // Use sigaction(2) not signal(2) so that we can correctly
  // restore the previous handler if necessary.
  struct sigaction oldact = {}, act = {};
  act.sa_handler = onsigprof;
  act.sa_flags = SA_RESTART;  // the JVM doesn't expect EINTR
  if (sigaction(SIGPROF, &act, &oldact) < 0) {
    perror("sigaction");
    abort();
  }

  // Is a handler already in effect?
  // Check for 3-arg and 1-arg forms.
  typedef void (*sighandler_t)(int);  // don't rely on this GNU extension
  if ((oldact.sa_flags & SA_SIGINFO) != 0
          ? (reinterpret_cast<sighandler_t>(oldact.sa_sigaction) != SIG_IGN)
          : (oldact.sa_handler != SIG_IGN)) {
    // Someone else is profiling this JVM.
    // Restore their handler and fail.
    (void)sigaction(SIGPROF, &oldact, nullptr);
    return false;
  }

  // Start the CPU interval timer.
  struct timeval period = {
      .tv_sec = 0,
      .tv_usec = static_cast<suseconds_t>(period_micros),
  };
  struct itimerval timer = {.it_interval = period, .it_value = period};
  if (setitimer(ITIMER_PROF, &timer, nullptr) < 0) {
    perror("setitimer");
    abort();
  }

  return true;
}

// static native void stopTimer();
extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_syntax_CpuProfiler_stopTimer(JNIEnv *env,
                                                                jclass clazz) {
  // Disarm the CPU interval timer.
  struct itimerval timer = {};
  if (setitimer(ITIMER_PROF, &timer, nullptr) < 0) {
    perror("setitimer");
    abort();
  }

  // Uninstall signal handler.
  signal(SIGPROF, SIG_IGN);
}

}  // namespace cpu_profiler
