// 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.

#include "base/threading/platform_thread.h"

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

#include <algorithm>
#include <iterator>
#include <optional>
#include <vector>

#include "base/android/android_info.h"
#include "base/android/jni_android.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/system/sys_info.h"
#include "base/threading/platform_thread_internal_posix.h"
#include "base/threading/thread_id_name_manager.h"
#include "base/trace_event/trace_event.h"

// Must come after all headers that specialize FromJniType() / ToJniType().
#include "base/tasks_jni/ThreadUtils_jni.h"

namespace base {

// Allows fine-grained control of thread priorities on Android.
// Enable with e.g.
// --enable-features=AndroidThreadPriority:presentation/-8/default/-1
BASE_FEATURE(kAndroidThreadPriority, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE_PARAM(int,
                   kBackgroundThreadPriority,
                   &kAndroidThreadPriority,
                   "background",
                   10);
BASE_FEATURE_PARAM(int,
                   kUtilityThreadPriority,
                   &kAndroidThreadPriority,
                   "utility",
                   1);
BASE_FEATURE_PARAM(int,
                   kDefaultThreadPriority,
                   &kAndroidThreadPriority,
                   "default",
                   0);
BASE_FEATURE_PARAM(int,
                   kPresentationThreadPriority,
                   &kAndroidThreadPriority,
                   "presentation",
                   -4);
BASE_FEATURE_PARAM(int,
                   kInteractiveThreadPriority,
                   &kAndroidThreadPriority,
                   "interactive",
                   -4);
BASE_FEATURE_PARAM(bool,
                   kObeySocRestrictions,
                   &kAndroidThreadPriority,
                   "obey_soc_restrictions",
                   true);
// kRealtimeAudio cannot be configured on the command line and should be the
// effective maximum.

// When enabled, do not run threads with a less important ThreadType than
// kDisplayCritical on the big core cluster, for configurations with at least 3
// clusters. This is based on observations that this cluster is both
// power-hungry and contended.
BASE_FEATURE(kRestrictBigCoreThreadAffinity, base::FEATURE_DISABLED_BY_DEFAULT);

namespace {

std::vector<uint64_t>* g_max_frequency_per_processor_override = nullptr;

struct SetAffinityMask {
  // Only set when the current CPU configuration has at least 3 separate
  // clusters.
  std::optional<cpu_set_t> mask;
  size_t count = 0;
  int allowed_count = 0;
};

// Get the CPU affinity mask, given the maximum frequency of all cores, and
// whether the mask should allow to run on the largest core cluster, for
// configurations with at least 3 clusters.
//
// Returns a value where `mask.mask` is not set if the device is not eligible,
// that is it does not have at least 3 different CPU types.
SetAffinityMask GetAffinityMask(const std::vector<uint64_t>& max_frequencies,
                                bool can_run) {
  if (max_frequencies.empty()) {
    return {};
  }

  auto sorted = max_frequencies;
  std::sort(sorted.begin(), sorted.end());
  uint64_t max_frequency = sorted[sorted.size() - 1];
  auto last = std::unique(sorted.begin(), sorted.end());
  ssize_t distinct_count = std::distance(sorted.begin(), last);

  // Don't want to move entirely from big cores on big.LITTLE, only on
  // little-mid-big designs.
  if (distinct_count < 3) {
    return {};
  }

  int allowed_cpus_count = 0;
  cpu_set_t cpu_set;
  // SAFETY: Here and below, these are macros that we don't control, and hence
  // we cannot safely replace. However, CPU_ZERO() is safe, and CPU_SET() has a
  // check internally to not overflow the bitset, which we repeat in the loop to
  // be clearer.
  UNSAFE_BUFFERS(CPU_ZERO(&cpu_set));
  for (size_t i = 0; i < max_frequencies.size(); i++) {
    if (i < CPU_SETSIZE) {
      if (can_run || (max_frequencies[i] < max_frequency)) {
        allowed_cpus_count++;
        UNSAFE_BUFFERS(CPU_SET(i, &cpu_set));
      }
    }
  }

  return {cpu_set, max_frequencies.size(), allowed_cpus_count};
}

}  // namespace

void SetMaxFrequencyPerProcessorOverrideForTesting(
    std::vector<uint64_t>* value) {
  g_max_frequency_per_processor_override = value;
}

bool IsEligibleForBigCoreAffinityChange() {
  if (g_max_frequency_per_processor_override) {
    return GetAffinityMask(*g_max_frequency_per_processor_override, false)
        .mask.has_value();
  }
  static const bool eligible =
      GetAffinityMask(SysInfo::MaxFrequencyPerProcessor(), false)
          .mask.has_value();
  return eligible;
}

void SetCanRunOnBigCore(PlatformThreadId thread_id, bool can_run) {
  TRACE_EVENT("base", __PRETTY_FUNCTION__, "thread_id", thread_id, "can_run",
              can_run);
  SetAffinityMask mask;
  if (g_max_frequency_per_processor_override) {
    mask = GetAffinityMask(*g_max_frequency_per_processor_override, can_run);
  } else {
    static const SetAffinityMask all_cores_mask =
        GetAffinityMask(SysInfo::MaxFrequencyPerProcessor(), true);
    static const SetAffinityMask no_big_cores_mask =
        GetAffinityMask(SysInfo::MaxFrequencyPerProcessor(), false);
    mask = can_run ? all_cores_mask : no_big_cores_mask;
  }

  if (!mask.mask) {
    return;
  }

  TRACE_EVENT("base", "SetAffinity", "count", mask.count, "allowed",
              mask.allowed_count);
  // If the call fails, it's not a correctness issue. However we want to catch
  // the sandbox returning EPERM.
  //
  // For instance, an invalid mask (e.g. one with an empty intersection with the
  // set of possible CPUs) returns EINVAL and does not change the current mask,
  // per sched_setaffinity(2). On more recent kernels, an empty mask resets the
  // affinity.
  int retval =
      sched_setaffinity(thread_id.raw(), sizeof(*mask.mask), &*mask.mask);
  DPCHECK(!retval);
}

namespace internal {

static int GetAdjustedPresentationThreadPriority() {
  // ADPF-equipped Google Pixels seem to have issues with input jank if the
  // kDisplayCriticalThreadPriority value is lowered below -4.
  static bool is_google_soc = SysInfo::SocManufacturer() == "Google";
  const bool allowed_to_lower =
      (!is_google_soc || !kObeySocRestrictions.Get()) &&
      base::FeatureList::IsEnabled(kAndroidThreadPriority);
  const int requested_priority = kPresentationThreadPriority.Get();
  return allowed_to_lower ? requested_priority
                          : std::max(-4, requested_priority);
}

// - kRealtimeAudio corresponds to Android's PRIORITY_AUDIO = -16 value.
// - kPresentation corresponds to Android's PRIORITY_DISPLAY = -4 value.
// - kUtility corresponds to Android's THREAD_PRIORITY_LESS_FAVORABLE = 1 value.
// - kBackground corresponds to Android's PRIORITY_BACKGROUND = 10
//   value. Contrary to the matching Java APi in Android <13, this does not
//   restrict the thread to (subset of) little cores.
const ThreadTypeToNiceValuePairForTest kThreadTypeToNiceValueMapForTest[7] = {
    {ThreadType::kRealtimeAudio, -16}, {ThreadType::kPresentation, -4},
    {ThreadType::kDefault, 0},         {ThreadType::kUtility, 1},
    {ThreadType::kBackground, 10},
};

// If we're not in the AndroidThreadPriorityTrial:
//    - kBackground corresponds to Android's PRIORITY_BACKGROUND = 10 value.
//    - kUtility corresponds to Android's THREAD_PRIORITY_LESS_FAVORABLE = 1
//      value.
//    - kPresentation and kInteractive correspond to Android's
//      PRIORITY_DISPLAY = -4 value.
//    - kRealtimeAudio corresponds to Android's PRIORITY_AUDIO = -16 value.
int ThreadTypeToNiceValue(const ThreadType thread_type) {
  if (base::FeatureList::IsEnabled(kAndroidThreadPriority)) {
    [[unlikely]]
    // Establish weak partial ordering from high to low.
    DCHECK_LE(kUtilityThreadPriority.Get(), kBackgroundThreadPriority.Get());
    DCHECK_LE(kDefaultThreadPriority.Get(), kUtilityThreadPriority.Get());
    DCHECK_LE(GetAdjustedPresentationThreadPriority(),
              kDefaultThreadPriority.Get());
    DCHECK_LE(kInteractiveThreadPriority.Get(),
              GetAdjustedPresentationThreadPriority());
    // Check that -16 is the highest priority in the system.
    DCHECK_LT(-16, kInteractiveThreadPriority.Get());
    switch (thread_type) {
      case ThreadType::kBackground:
        return kBackgroundThreadPriority.Get();
      case ThreadType::kUtility:
        return kUtilityThreadPriority.Get();
      case ThreadType::kDefault:
        return kDefaultThreadPriority.Get();
      case ThreadType::kPresentation:
        return GetAdjustedPresentationThreadPriority();
      case ThreadType::kAudioProcessing:
        return kInteractiveThreadPriority.Get();
      case ThreadType::kRealtimeAudio:
        // Not configurable, should be the effective highest.
        return -16;
    }
  }
  switch (thread_type) {
    case ThreadType::kBackground:
      return 10;
    case ThreadType::kUtility:
      return 1;
    case ThreadType::kDefault:
      return 0;
    case ThreadType::kPresentation:
    case ThreadType::kAudioProcessing:
      return -4;
    case ThreadType::kRealtimeAudio:
      return -16;
  }
}

bool CanSetThreadTypeToRealtimeAudio() {
  return true;
}

void SetCurrentThreadTypeImpl(ThreadType thread_type,
                              MessagePumpType pump_type_hint) {
  // We set the Audio priority through JNI as the Java setThreadPriority will
  // put it into a preferable cgroup, whereas the "normal" C++ call wouldn't.
  // However, with
  // https://android-review.googlesource.com/c/platform/system/core/+/1975808
  // this becomes obsolete and we can avoid this starting in API level 33.
  if (thread_type == ThreadType::kRealtimeAudio &&
      base::android::android_info::sdk_int() <
          base::android::android_info::SDK_VERSION_T) {
    JNIEnv* env = base::android::AttachCurrentThread();
    Java_ThreadUtils_setThreadPriorityAudio(env,
                                            PlatformThread::CurrentId().raw());
  } else if (thread_type == ThreadType::kPresentation &&
             pump_type_hint == MessagePumpType::UI &&
             GetCurrentThreadNiceValue() <=
                 ThreadTypeToNiceValue(ThreadType::kPresentation)) {
    // Recent versions of Android (O+) up the priority of the UI thread
    // automatically.
  } else {
    SetThreadNiceFromType(PlatformThread::CurrentId(), thread_type);
  }

  if (IsEligibleForBigCoreAffinityChange() &&
      base::FeatureList::IsEnabled(kRestrictBigCoreThreadAffinity)) {
    SetCanRunOnBigCore(PlatformThread::CurrentId(),
                       thread_type >= ThreadType::kPresentation);
  }
}

std::optional<ThreadType> GetCurrentEffectiveThreadTypeForPlatformForTest() {
  JNIEnv* env = base::android::AttachCurrentThread();
  if (Java_ThreadUtils_isThreadPriorityAudio(
          env, PlatformThread::CurrentId().raw())) {
    return std::make_optional(ThreadType::kRealtimeAudio);
  }
  return std::nullopt;
}

PlatformPriorityOverride SetThreadTypeOverride(
    PlatformThreadHandle thread_handle,
    ThreadType thread_type) {
  PlatformThreadId thread_id(
      pthread_gettid_np(thread_handle.platform_handle()));
  if (GetThreadNiceValue(thread_id) <= ThreadTypeToNiceValue(thread_type)) {
    return false;
  }
  return SetThreadNiceFromType(thread_id, thread_type);
}

void RemoveThreadTypeOverride(
    PlatformThreadHandle thread_handle,
    const PlatformPriorityOverride& priority_override_handle,
    ThreadType initial_thread_type) {
  if (!priority_override_handle) {
    return;
  }

  PlatformThreadId thread_id(
      pthread_gettid_np(thread_handle.platform_handle()));
  SetThreadNiceFromType(thread_id, initial_thread_type);
}

}  // namespace internal

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

  // Like linux, on android 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;
  }

  // Set the name for the LWP (which gets truncated to 15 characters).
  int err = prctl(PR_SET_NAME, name.c_str());
  if (err < 0 && errno != EPERM) {
    DPLOG(ERROR) << "prctl(PR_SET_NAME)";
  }
}

void InitThreading() {}

void TerminateOnThread() {
  base::android::DetachFromVM();
}

size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes) {
#if !defined(ADDRESS_SANITIZER)
  return 0;
#else
  // AddressSanitizer bloats the stack approximately 2x. Default stack size of
  // 1Mb is not enough for some tests (see http://crbug.com/263749 for example).
  return 2 * (1 << 20);  // 2Mb
#endif
}

}  // namespace base

DEFINE_JNI(ThreadUtils)
