+ if (thread->sched_mode == TH_MODE_REALTIME)
+ priority = BASEPRI_RTQUEUES;
+ else {
+ if (thread->importance > MAXPRI)
+ priority = MAXPRI;
+ else
+ if (thread->importance < -MAXPRI)
+ priority = -MAXPRI;
+ else
+ priority = thread->importance;
+
+ priority += thread->task_priority;
+
+ if (priority > thread->max_priority)
+ priority = thread->max_priority;
+ else
+ if (priority < MINPRI)
+ priority = MINPRI;
+#if CONFIG_EMBEDDED
+ /* No one can have a base priority less than MAXPRI_THROTTLE */
+ if (priority < MAXPRI_THROTTLE)
+ priority = MAXPRI_THROTTLE;
+#endif /* CONFIG_EMBEDDED */
+ }
+
+ set_priority(thread, priority);
+}
+
+#if CONFIG_EMBEDDED
+static void
+thread_throttle(
+ thread_t thread,
+ integer_t task_priority)
+{
+ if ((!(thread->sched_flags & TH_SFLAG_THROTTLED)
+ || (thread->sched_flags & TH_SFLAG_PENDING_THROTTLE_PROMOTION))
+ && (task_priority <= MAXPRI_THROTTLE)) {
+
+ /* Kill a promotion if it was in flight */
+ thread->sched_flags &= ~TH_SFLAG_PENDING_THROTTLE_PROMOTION;
+
+ if (!(thread->sched_flags & TH_SFLAG_THROTTLED)) {
+ /*
+ * Set the pending bit so that we can switch runqueues
+ * (potentially) at a later time safely
+ */
+ thread->sched_flags |= TH_SFLAG_PENDING_THROTTLE_DEMOTION;
+ }
+ }
+ else if (((thread->sched_flags & TH_SFLAG_THROTTLED)
+ || (thread->sched_flags & TH_SFLAG_PENDING_THROTTLE_DEMOTION))
+ && (task_priority > MAXPRI_THROTTLE)) {
+
+ /* Kill a demotion if it was in flight */
+ thread->sched_flags &= ~TH_SFLAG_PENDING_THROTTLE_DEMOTION;
+
+ if (thread->sched_flags & TH_SFLAG_THROTTLED) {
+ thread->sched_flags |= TH_SFLAG_PENDING_THROTTLE_PROMOTION;
+ }
+ }
+}
+#endif
+
+void
+thread_task_priority(
+ thread_t thread,
+ integer_t priority,
+ integer_t max_priority)
+{
+ spl_t s;
+
+ assert(thread != THREAD_NULL);
+
+ s = splsched();
+ thread_lock(thread);
+
+#if CONFIG_EMBEDDED
+ thread_throttle(thread, priority);
+#endif
+
+ thread->task_priority = priority;
+ thread->max_priority = max_priority;
+
+ thread_recompute_priority(thread);
+
+ thread_unlock(thread);
+ splx(s);
+}
+
+void
+thread_policy_reset(
+ thread_t thread)
+{
+ spl_t s;
+
+ s = splsched();
+ thread_lock(thread);
+
+ if (!(thread->sched_flags & TH_SFLAG_DEMOTED_MASK)) {
+ sched_mode_t oldmode = thread->sched_mode;
+
+ thread->sched_mode = SCHED(initial_thread_sched_mode)(thread->task);
+
+ if ((oldmode != TH_MODE_TIMESHARE) && (thread->sched_mode == TH_MODE_TIMESHARE)) {
+
+ if ((thread->state & (TH_RUN|TH_IDLE)) == TH_RUN)
+ sched_share_incr();
+ }
+ }
+ else {
+ thread->sched_mode = thread->saved_mode;
+ thread->saved_mode = TH_MODE_NONE;
+ thread->sched_flags &= ~TH_SFLAG_DEMOTED_MASK;
+ }
+
+ thread->importance = 0;
+
+ thread_recompute_priority(thread);
+
+ thread_unlock(thread);
+ splx(s);