*/
int next_timer_expiry(void);
+/* Pings the scheduler to verify that tasks continue running.
+ * Returns 1 if the scheduler made progress since last call,
+ * 0 if it looks stuck.
+ */
+int is_sched_alive(void);
+
/*
* Delete every tasks before running the master polling loop
*/
*/
__decl_aligned_rwlock(wq_lock);
+/* used to detect if the scheduler looks stuck (for warnings) */
+static THREAD_LOCAL int sched_stuck;
+
/* Flags the task <t> for immediate destruction and puts it into its first
* thread's shared tasklet list if not yet queued/running. This will bypass
* the priority scheduling and make the task show up as fast as possible in
else {
done++;
th_ctx->current = NULL;
+ sched_stuck = 0; // scheduler is not stuck (don't warn)
/* signal barrier to prevent thread dump helpers
* from dumping a task currently being freed.
*/
task_unlink_wq(t);
__task_free(t);
th_ctx->current = NULL;
+ sched_stuck = 0; // scheduler is not stuck (don't warn)
__ha_barrier_store();
/* We don't want max_processed to be decremented if
* we're just freeing a destroyed task, we should only
}
th_ctx->current = NULL;
+ sched_stuck = 0; // scheduler is not stuck (don't warn)
__ha_barrier_store();
/* stats are only registered for non-zero wake dates */
activity[tid].long_rq++;
}
+/* Pings the scheduler to verify that tasks continue running.
+ * Returns 1 if the scheduler made progress since last call,
+ * 0 if it looks stuck.
+ */
+int is_sched_alive(void)
+{
+ if (sched_stuck)
+ return 0;
+
+ /* next time we'll know if any progress was made */
+ sched_stuck = 1;
+ return 1;
+}
+
/*
* Delete every tasks before running the master polling loop
*/