#define TASK_F_USR1 0x00010000 /* preserved user flag 1, application-specific, def:0 */
#define TASK_F_UEVT1 0x00020000 /* one-shot user event type 1, application specific, def:0 */
#define TASK_F_UEVT2 0x00040000 /* one-shot user event type 2, application specific, def:0 */
-/* unused: 0x80000..0x80000000 */
+#define TASK_F_WANTS_TIME 0x00080000 /* task/tasklet wants th_ctx->sched_call_date to be set */
+/* unused: 0x100000..0x80000000 */
/* These flags are persistent across scheduler calls */
#define TASK_PERSISTENT (TASK_SELF_WAKING | TASK_KILLED | \
- TASK_HEAVY | TASK_F_TASKLET | TASK_F_USR1)
+ TASK_HEAVY | TASK_F_TASKLET | TASK_F_USR1 | \
+ TASK_F_WANTS_TIME)
/* This function is used to report state in debugging tools. Please reflect
* below any single-bit flag addition above in the same order via the
(int)!MT_LIST_ISEMPTY(&th_ctx->shared_tasklet_list));
}
+/* returns the most recent known date of the task's call from the scheduler */
+static inline uint64_t task_mono_time(void)
+{
+ return th_ctx->sched_call_date;
+}
+
/* puts the task <t> in run queue with reason flags <f>, and returns <t> */
/* This will put the task in the local runqueue if the task is only runnable
* by the current thread, in the global runqueue otherwies. With DEBUG_TASK,
t->calls++;
th_ctx->sched_wake_date = t->wake_date;
- if (th_ctx->sched_wake_date) {
- uint32_t now_ns = now_mono_time();
- uint32_t lat = now_ns - th_ctx->sched_wake_date;
+ if (th_ctx->sched_wake_date || (t->state & TASK_F_WANTS_TIME)) {
+ /* take the most accurate clock we have, either
+ * mono_time() or last now_ns (monotonic but only
+ * incremented once per poll loop).
+ */
+ th_ctx->sched_call_date = now_mono_time();
+ if (unlikely(!th_ctx->sched_call_date))
+ th_ctx->sched_call_date = now_ns;
+ }
+ if (th_ctx->sched_wake_date) {
t->wake_date = 0;
- th_ctx->sched_call_date = now_ns;
profile_entry = sched_activity_entry(sched_activity, t->process, t->caller);
th_ctx->sched_profile_entry = profile_entry;
- HA_ATOMIC_ADD(&profile_entry->lat_time, lat);
+ HA_ATOMIC_ADD(&profile_entry->lat_time, (uint32_t)(th_ctx->sched_call_date - th_ctx->sched_wake_date));
HA_ATOMIC_INC(&profile_entry->calls);
}
+
__ha_barrier_store();
th_ctx->current = t;