+#if CONFIG_EMBEDDED
+static void
+thread_throttle(
+ thread_t thread,
+ integer_t task_priority)
+{
+ if (!(thread->sched_flags & TH_SFLAG_THROTTLED) &&
+ (task_priority <= MAXPRI_THROTTLE)) {
+
+ if (!((thread->sched_mode == TH_MODE_REALTIME) ||
+ (thread->saved_mode == TH_MODE_REALTIME))) {
+ return;
+ }
+
+ /* Demote to timeshare if throttling */
+ if (thread->sched_mode == TH_MODE_REALTIME)
+ {
+ thread->saved_mode = TH_MODE_REALTIME;
+
+ if (thread->sched_mode == TH_MODE_TIMESHARE) {
+ if ((thread->state & (TH_RUN|TH_IDLE)) == TH_RUN)
+ sched_share_incr();
+ }
+ }
+
+ /* TH_SFLAG_FAILSAFE and TH_SFLAG_THROTTLED are mutually exclusive,
+ * since a throttled thread is not realtime during the throttle
+ * and doesn't need the failsafe repromotion. We therefore clear
+ * the former and set the latter flags here.
+ */
+ thread->sched_flags &= ~TH_SFLAG_FAILSAFE;
+ thread->sched_flags |= TH_SFLAG_THROTTLED;
+
+ if (SCHED(supports_timeshare_mode)())
+ thread->sched_mode = TH_MODE_TIMESHARE;
+ else
+ thread->sched_mode = TH_MODE_FIXED;
+ }
+ else if ((thread->sched_flags & TH_SFLAG_THROTTLED) &&
+ (task_priority > MAXPRI_THROTTLE)) {
+
+ /* Promote back to real time if unthrottling */
+ if (!(thread->saved_mode == TH_MODE_TIMESHARE)) {
+
+ thread->sched_mode = thread->saved_mode;
+
+ if (thread->sched_mode == TH_MODE_TIMESHARE) {
+ if ((thread->state & (TH_RUN|TH_IDLE)) == TH_RUN)
+ sched_share_decr();
+ }
+
+ thread->saved_mode = TH_MODE_NONE;
+ }
+
+ thread->sched_flags &= ~TH_SFLAG_THROTTLED;
+ }
+}
+#endif
+