// Copyright 2016 Google Inc. 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.

#include "starboard/shared/pthread/thread_create_priority.h"

#include <sched.h>
#include <sys/resource.h>

#include "starboard/log.h"

namespace starboard {
namespace shared {
namespace pthread {

#if SB_HAS(THREAD_PRIORITY_SUPPORT)
// Note that use of sched_setscheduler() has been found to be more reliably
// supported than pthread_setschedparam(), so we are using that.

void SetIdleScheduler() {
  struct sched_param thread_sched_param;
  thread_sched_param.sched_priority = 0;
  int result = sched_setscheduler(0, SCHED_IDLE, &thread_sched_param);
  if (result != 0) {
    SB_NOTREACHED();
  }
}

void SetOtherScheduler() {
  struct sched_param thread_sched_param;
  thread_sched_param.sched_priority = 0;
  int result = sched_setscheduler(0, SCHED_OTHER, &thread_sched_param);
  if (result != 0) {
    SB_NOTREACHED();
  }
}

// Here |priority| is a number between >= 0, where the higher the number, the
// higher the priority.  The actual real time priority setting will be:
//
//     std::min(sched_get_priority_min(SCHED_RR) + priority,
//              sched_get_priority_max(SCHED_RR))
//
// If the desired priority is not supported on this platform, we fall back to
// SCHED_OTHER.
void SetRoundRobinScheduler(int priority) {
  // First determine what the system has setup for the min/max priorities.
  int min_priority = sched_get_priority_min(SCHED_RR);
  int max_priority = sched_get_priority_max(SCHED_RR);

  struct rlimit rlimit_rtprio;
  getrlimit(RLIMIT_RTPRIO, &rlimit_rtprio);

  if (rlimit_rtprio.rlim_cur < min_priority) {
    SB_LOG(WARNING) << "Unable to set real time round-robin thread priority "
                    << "because `ulimit -r` is too low ("
                    << rlimit_rtprio.rlim_cur << " < " << min_priority << ").";

    // Fallback to SCHED_OTHER.
    SetOtherScheduler();
  } else {
    struct sched_param thread_sched_param;
    thread_sched_param.sched_priority =
        std::min(min_priority + priority, max_priority);
    int result = sched_setscheduler(0, SCHED_RR, &thread_sched_param);
    if (result != 0) {
      SB_NOTREACHED();
    }
  }
}

void ThreadSetPriority(SbThreadPriority priority) {
  // Use different schedulers according to priority. This is preferred over
  // using SCHED_RR for all threads because the scheduler time slice is too
  // high (defaults to 100ms) for the desired threading behavior.
  switch (priority) {
    case kSbThreadPriorityLowest:
    case kSbThreadPriorityLow:
      SetIdleScheduler();
      break;
    case kSbThreadNoPriority:
    case kSbThreadPriorityNormal:
      SetOtherScheduler();
      break;
    case kSbThreadPriorityHigh:
      SetRoundRobinScheduler(0);
      break;
    case kSbThreadPriorityHighest:
      SetRoundRobinScheduler(1);
      break;
    case kSbThreadPriorityRealTime:
      SetRoundRobinScheduler(2);
      break;
    default:
      SB_NOTREACHED();
      break;
  }
}

#endif  // SB_HAS(THREAD_PRIORITY_SUPPORT)

}  // namespace pthread
}  // namespace shared
}  // namespace starboard
