/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/system_wrappers/source/thread_posix.h"

#include <algorithm>

#include <errno.h>
#include <unistd.h>
#ifdef WEBRTC_LINUX
#include <linux/unistd.h>
#include <sched.h>
#include <sys/types.h>
#endif

#include "webrtc/base/checks.h"
#include "webrtc/base/platform_thread.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/event_wrapper.h"
#include "webrtc/system_wrappers/interface/sleep.h"
#include "webrtc/system_wrappers/interface/trace.h"

namespace webrtc {
namespace {
struct ThreadAttributes {
  ThreadAttributes() { pthread_attr_init(&attr); }
  ~ThreadAttributes() { pthread_attr_destroy(&attr); }
  pthread_attr_t* operator&() { return &attr; }
  pthread_attr_t attr;
};
}  // namespace

int ConvertToSystemPriority(ThreadPriority priority, int min_prio,
                            int max_prio) {
  RTC_DCHECK(max_prio - min_prio > 2);
  const int top_prio = max_prio - 1;
  const int low_prio = min_prio + 1;

  switch (priority) {
    case kLowPriority:
      return low_prio;
    case kNormalPriority:
      // The -1 ensures that the kHighPriority is always greater or equal to
      // kNormalPriority.
      return (low_prio + top_prio - 1) / 2;
    case kHighPriority:
      return std::max(top_prio - 2, low_prio);
    case kHighestPriority:
      return std::max(top_prio - 1, low_prio);
    case kRealtimePriority:
      return top_prio;
  }
  RTC_DCHECK(false);
  return low_prio;
}

// static
void* ThreadPosix::StartThread(void* param) {
  static_cast<ThreadPosix*>(param)->Run();
  return 0;
}

ThreadPosix::ThreadPosix(ThreadRunFunction func, void* obj,
                         const char* thread_name)
    : run_function_(func),
      obj_(obj),
      stop_event_(false, false),
      name_(thread_name ? thread_name : "webrtc"),
      thread_(0) {
  RTC_DCHECK(name_.length() < 64);
}

uint32_t ThreadWrapper::GetThreadId() {
  return rtc::CurrentThreadId();
}

ThreadPosix::~ThreadPosix() {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
}

// TODO(pbos): Make Start void, calling code really doesn't support failures
// here.
bool ThreadPosix::Start() {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  RTC_DCHECK(!thread_) << "Thread already started?";

  ThreadAttributes attr;
  // Set the stack stack size to 1M.
  pthread_attr_setstacksize(&attr, 1024 * 1024);
  RTC_CHECK_EQ(0, pthread_create(&thread_, &attr, &StartThread, this));
  return true;
}

bool ThreadPosix::Stop() {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  if (!thread_)
    return true;

  stop_event_.Set();
  RTC_CHECK_EQ(0, pthread_join(thread_, nullptr));
  thread_ = 0;

  return true;
}

bool ThreadPosix::SetPriority(ThreadPriority priority) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  if (!thread_)
    return false;
#if defined(WEBRTC_CHROMIUM_BUILD) && defined(WEBRTC_LINUX)
  // TODO(tommi): Switch to the same mechanism as Chromium uses for
  // changing thread priorities.
  return true;
#else
#ifdef WEBRTC_THREAD_RR
  const int policy = SCHED_RR;
#else
  const int policy = SCHED_FIFO;
#endif
  const int min_prio = sched_get_priority_min(policy);
  const int max_prio = sched_get_priority_max(policy);
  if (min_prio == -1 || max_prio == -1) {
    WEBRTC_TRACE(kTraceError, kTraceUtility, -1,
                 "unable to retreive min or max priority for threads");
    return false;
  }

  if (max_prio - min_prio <= 2)
    return false;

  sched_param param;
  param.sched_priority = ConvertToSystemPriority(priority, min_prio, max_prio);
  if (pthread_setschedparam(thread_, policy, &param) != 0) {
    WEBRTC_TRACE(
        kTraceError, kTraceUtility, -1, "unable to set thread priority");
    return false;
  }

  return true;
#endif  // defined(WEBRTC_CHROMIUM_BUILD) && defined(WEBRTC_LINUX)
}

void ThreadPosix::Run() {
  if (!name_.empty()) {
    // Setting the thread name may fail (harmlessly) if running inside a
    // sandbox. Ignore failures if they happen.
    rtc::SetCurrentThreadName(name_.substr(0, 63).c_str());
  }

  // It's a requirement that for successful thread creation that the run
  // function be called at least once (see RunFunctionIsCalled unit test),
  // so to fullfill that requirement, we use a |do| loop and not |while|.
  do {
    if (!run_function_(obj_))
      break;
  } while (!stop_event_.Wait(0));
}

}  // namespace webrtc
