// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Description: Linux specific functionality. Other Linux-derivatives layer on
// top of this translation unit.

#include "base/threading/platform_thread.h"

#include <errno.h>
#include <pthread.h>
#include <sched.h>
#include <stddef.h>
#include <sys/prctl.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#include <atomic>
#include <cstdint>
#include <optional>

#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/feature_list.h"
#include "base/files/file_util.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/metrics/field_trial_params.h"
#include "base/no_destructor.h"
#include "base/notreached.h"
#include "base/process/internal_linux.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/threading/platform_thread_internal_posix.h"
#include "base/threading/thread_id_name_manager.h"
#include "base/threading/thread_type_delegate.h"
#include "build/build_config.h"

namespace base {

namespace {

ThreadTypeDelegate* g_thread_type_delegate = nullptr;

const FilePath::CharType kCgroupDirectory[] =
    FILE_PATH_LITERAL("/sys/fs/cgroup");

FilePath ThreadTypeToCgroupDirectory(const FilePath& cgroup_filepath,
                                     ThreadType thread_type) {
  switch (thread_type) {
    case ThreadType::kBackground:
    case ThreadType::kUtility:
      return cgroup_filepath.Append(FILE_PATH_LITERAL("non-urgent"));
    case ThreadType::kDefault:
      return cgroup_filepath;
    case ThreadType::kPresentation:
    case ThreadType::kAudioProcessing:
    case ThreadType::kRealtimeAudio:
      return cgroup_filepath.Append(FILE_PATH_LITERAL("urgent"));
  }
  NOTREACHED();
}

void SetThreadCgroup(PlatformThreadId thread_id,
                     const FilePath& cgroup_directory) {
  FilePath tasks_filepath = cgroup_directory.Append(FILE_PATH_LITERAL("tasks"));
  std::string tid = NumberToString(thread_id.raw());
  if (!WriteFile(tasks_filepath, as_byte_span(tid))) {
    DVLOG(1) << "Failed to add " << tid << " to " << tasks_filepath.value();
  }
}

void SetThreadCgroupForThreadType(PlatformThreadId thread_id,
                                  const FilePath& cgroup_filepath,
                                  ThreadType thread_type) {
  // Append "chrome" suffix.
  FilePath cgroup_directory = ThreadTypeToCgroupDirectory(
      cgroup_filepath.Append(FILE_PATH_LITERAL("chrome")), thread_type);

  // Silently ignore request if cgroup directory doesn't exist.
  if (!DirectoryExists(cgroup_directory)) {
    return;
  }

  SetThreadCgroup(thread_id, cgroup_directory);
}

}  // namespace

namespace internal {

const ThreadTypeToNiceValuePairForTest kThreadTypeToNiceValueMapForTest[7] = {
    {ThreadType::kRealtimeAudio, -10}, {ThreadType::kPresentation, -8},
    {ThreadType::kDefault, 0},         {ThreadType::kUtility, 2},
    {ThreadType::kBackground, 10},
};

bool CanSetThreadTypeToRealtimeAudio() {
  // Check if root
  if (geteuid() == 0) {
    return true;
  }

  // A non-zero soft-limit on RLIMIT_RTPRIO is required to be allowed to invoke
  // pthread_setschedparam in SetCurrentThreadTypeForPlatform().
  struct rlimit rlim;
  return getrlimit(RLIMIT_RTPRIO, &rlim) != 0 && rlim.rlim_cur != 0;
}

void SetCurrentThreadTypeImpl(ThreadType thread_type,
                              MessagePumpType pump_type_hint) {
  const PlatformThreadId thread_id = PlatformThread::CurrentId();

  if (g_thread_type_delegate &&
      g_thread_type_delegate->HandleThreadTypeChange(thread_id, thread_type)) {
    return;
  }

  internal::SetThreadType(getpid(), thread_id, thread_type);
}

std::optional<ThreadType> GetCurrentEffectiveThreadTypeForPlatformForTest() {
  int maybe_sched_rr = 0;
  struct sched_param maybe_realtime_prio = {0};
  if (pthread_getschedparam(pthread_self(), &maybe_sched_rr,
                            &maybe_realtime_prio) == 0 &&
      maybe_sched_rr == SCHED_RR &&
      maybe_realtime_prio.sched_priority ==
          PlatformThreadLinux::kRealTimeAudioPrio.sched_priority) {
    return std::make_optional(ThreadType::kRealtimeAudio);
  }
  return std::nullopt;
}

PlatformPriorityOverride SetThreadTypeOverride(
    PlatformThreadHandle thread_handle,
    ThreadType thread_type) {
  if (!thread_handle.is_equal(PlatformThread::CurrentHandle()) ||
      g_thread_type_delegate) {
    return false;
  }
  internal::SetThreadType(getpid(), PlatformThread::CurrentId(), thread_type);
  return true;
}

void RemoveThreadTypeOverride(
    PlatformThreadHandle thread_handle,
    const PlatformPriorityOverride& priority_override_handle,
    ThreadType initial_thread_type) {
  if (!priority_override_handle) {
    return;
  }
  DCHECK(thread_handle.is_equal(PlatformThread::CurrentHandle()));
  internal::SetThreadType(getpid(), PlatformThread::CurrentId(),
                          initial_thread_type);
}

}  // namespace internal

// Determine if thread_id is a background thread by looking up whether
// it is in the urgent or non-urgent cpuset.
bool PlatformThreadLinux::IsThreadBackgroundedForTest(
    PlatformThreadId thread_id) {
  FilePath cgroup_filepath(kCgroupDirectory);

  FilePath urgent_cgroup_directory =
      cgroup_filepath.Append(FILE_PATH_LITERAL("cpuset"))
          .Append(FILE_PATH_LITERAL("chrome"))
          .Append(FILE_PATH_LITERAL("urgent"));
  FilePath non_urgent_cgroup_directory =
      cgroup_filepath.Append(FILE_PATH_LITERAL("cpuset"))
          .Append(FILE_PATH_LITERAL("chrome"))
          .Append(FILE_PATH_LITERAL("non-urgent"));

  // Silently ignore request if cgroup directory doesn't exist.
  if (!DirectoryExists(urgent_cgroup_directory) ||
      !DirectoryExists(non_urgent_cgroup_directory)) {
    return false;
  }

  FilePath urgent_tasks_filepath =
      urgent_cgroup_directory.Append(FILE_PATH_LITERAL("tasks"));
  FilePath non_urgent_tasks_filepath =
      non_urgent_cgroup_directory.Append(FILE_PATH_LITERAL("tasks"));

  std::string tid = NumberToString(thread_id.raw());
  // Check if thread_id is in the urgent cpuset
  std::string urgent_tasks;
  if (!ReadFileToString(urgent_tasks_filepath, &urgent_tasks)) {
    return false;
  }
  if (urgent_tasks.find(tid) != std::string::npos) {
    return false;
  }

  // Check if thread_id is in the non-urgent cpuset
  std::string non_urgent_tasks;
  if (!ReadFileToString(non_urgent_tasks_filepath, &non_urgent_tasks)) {
    return false;
  }
  if (non_urgent_tasks.find(tid) != std::string::npos) {
    return true;
  }

  return false;
}

void PlatformThreadBase::SetName(const std::string& name) {
  SetNameCommon(name);

  // On linux we can get the thread names to show up in the debugger by setting
  // the process name for the LWP.  We don't want to do this for the main
  // thread because that would rename the process, causing tools like killall
  // to stop working.
  if (PlatformThread::CurrentId().raw() == getpid()) {
    return;
  }

  // http://0pointer.de/blog/projects/name-your-threads.html
  // Set the name for the LWP (which gets truncated to 15 characters).
  // Note that glibc also has a 'pthread_setname_np' api, but it may not be
  // available everywhere and it's only benefit over using prctl directly is
  // that it can set the name of threads other than the current thread.
  int err = prctl(PR_SET_NAME, name.c_str());
  // We expect EPERM failures in sandboxed processes, just ignore those.
  if (err < 0 && errno != EPERM) {
    DPLOG(ERROR) << "prctl(PR_SET_NAME)";
  }
}

// static
void PlatformThreadLinux::SetThreadTypeDelegate(ThreadTypeDelegate* delegate) {
  // A component cannot override a delegate set by another component, thus
  // disallow setting a delegate when one already exists.
  DCHECK(!g_thread_type_delegate || !delegate);

  g_thread_type_delegate = delegate;
}

// static
void PlatformThreadLinux::SetThreadCgroupsForThreadType(
    PlatformThreadId thread_id,
    ThreadType thread_type) {
  FilePath cgroup_filepath(kCgroupDirectory);
  SetThreadCgroupForThreadType(
      thread_id, cgroup_filepath.Append(FILE_PATH_LITERAL("cpuset")),
      thread_type);
  SetThreadCgroupForThreadType(
      thread_id, cgroup_filepath.Append(FILE_PATH_LITERAL("schedtune")),
      thread_type);
}

// static
void PlatformThreadLinux::SetThreadType(ProcessId process_id,
                                        PlatformThreadId thread_id,
                                        ThreadType thread_type) {
  internal::SetThreadType(process_id, thread_id, thread_type);
}

namespace internal {
void SetThreadTypeLinux(ProcessId process_id,
                        PlatformThreadId thread_id,
                        ThreadType thread_type) {
  PlatformThreadLinux::SetThreadCgroupsForThreadType(thread_id, thread_type);

  // Some scheduler syscalls require thread ID of 0 for current thread.
  // This prevents us from requiring to translate the NS TID to
  // global TID.
  PlatformThreadId syscall_tid = thread_id;
  if (thread_id == PlatformThreadLinux::CurrentId()) {
    syscall_tid = kInvalidThreadId;
  }

  if (thread_type == ThreadType::kRealtimeAudio) {
    if (sched_setscheduler(syscall_tid.raw(), SCHED_RR,
                           &PlatformThreadLinux::kRealTimeAudioPrio) == 0) {
      return;
    }
    // If failed to set to RT, fallback to setpriority to set nice value.
    DPLOG(ERROR) << "Failed to set realtime priority for thread " << thread_id;
  }

  SetThreadNiceFromType(thread_id, thread_type);
}

int ThreadTypeToNiceValue(const ThreadType thread_type) {
  switch (thread_type) {
    case ThreadType::kBackground:
      return 10;
    case ThreadType::kUtility:
      return 2;
    case ThreadType::kDefault:
      return 0;
    case ThreadType::kPresentation:
    case ThreadType::kAudioProcessing:
      return -8;
    case ThreadType::kRealtimeAudio:
      return -10;
  }
}

}  // namespace internal

}  // namespace base
