return 0;
smp->data.type = SMP_T_SINT;
- smp->data.u.sint = smp->strm->task->calls ? smp->strm->task->cpu_time / smp->strm->task->calls : 0;
+ smp->data.u.sint = smp->strm->task->calls ? smp->strm->cpu_time / smp->strm->task->calls : 0;
return 1;
}
return 0;
smp->data.type = SMP_T_SINT;
- smp->data.u.sint = smp->strm->task->cpu_time;
+ smp->data.u.sint = smp->strm->cpu_time;
return 1;
}
return 0;
smp->data.type = SMP_T_SINT;
- smp->data.u.sint = smp->strm->task->calls ? smp->strm->task->lat_time / smp->strm->task->calls : 0;
+ smp->data.u.sint = smp->strm->task->calls ? smp->strm->lat_time / smp->strm->task->calls : 0;
return 1;
}
return 0;
smp->data.type = SMP_T_SINT;
- smp->data.u.sint = smp->strm->task->lat_time;
+ smp->data.u.sint = smp->strm->lat_time;
return 1;
}
s->buffer_wait.target = s;
s->buffer_wait.wakeup_cb = stream_buf_available;
+ s->lat_time = s->cpu_time = 0;
s->call_rate.curr_tick = s->call_rate.curr_ctr = s->call_rate.prev_ctr = 0;
s->pcli_next_pid = 0;
s->pcli_flags = 0;
}
}
+/* if the current task's wake_date was set, it's being profiled, thus we may
+ * report latencies and CPU usages in logs, so it's desirable to update the
+ * latency when entering process_stream().
+ */
+static void stream_cond_update_cpu_latency(struct stream *s)
+{
+ uint32_t lat = th_ctx->sched_call_date - th_ctx->sched_wake_date;
+
+ s->lat_time += lat;
+}
+
/* if the current task's wake_date was set, it's being profiled, thus we may
* report latencies and CPU usages in logs, so it's desirable to do that before
* logging in order to report accurate CPU usage. In this case we count that
return;
cpu = (uint32_t)now_mono_time() - th_ctx->sched_call_date;
- s->task->cpu_time += cpu;
+ s->cpu_time += cpu;
HA_ATOMIC_ADD(&th_ctx->sched_profile_entry->cpu_time, cpu);
th_ctx->sched_wake_date = 0;
}
+/* this functions is called directly by the scheduler for tasks whose
+ * ->process points to process_stream(), and is used to keep latencies
+ * and CPU usage measurements accurate.
+ */
+void stream_update_timings(struct task *t, uint64_t lat, uint64_t cpu)
+{
+ struct stream *s = t->context;
+ s->lat_time += lat;
+ s->cpu_time += cpu;
+}
+
+
/* This macro is very specific to the function below. See the comments in
* process_stream() below to understand the logic and the tests.
*/
DBG_TRACE_ENTER(STRM_EV_STRM_PROC, s);
activity[tid].stream_calls++;
+ stream_cond_update_cpu_latency(s);
req = &s->req;
res = &s->res;
}
else if ((tmpctx = sc_appctx(scf)) != NULL) {
chunk_appendf(&trash,
- " app0=%p st0=%d st1=%d applet=%s tid=%d nice=%d calls=%u rate=%u cpu=%llu lat=%llu\n",
+ " app0=%p st0=%d st1=%d applet=%s tid=%d nice=%d calls=%u rate=%u\n",
tmpctx,
tmpctx->st0,
tmpctx->st1,
tmpctx->applet->name,
tmpctx->t->tid,
- tmpctx->t->nice, tmpctx->t->calls, read_freq_ctr(&tmpctx->call_rate),
- (unsigned long long)tmpctx->t->cpu_time, (unsigned long long)tmpctx->t->lat_time);
+ tmpctx->t->nice, tmpctx->t->calls, read_freq_ctr(&tmpctx->call_rate));
}
scb = strm->scb;
}
else if ((tmpctx = sc_appctx(scb)) != NULL) {
chunk_appendf(&trash,
- " app1=%p st0=%d st1=%d applet=%s tid=%d nice=%d calls=%u rate=%u cpu=%llu lat=%llu\n",
+ " app1=%p st0=%d st1=%d applet=%s tid=%d nice=%d calls=%u rate=%u\n",
tmpctx,
tmpctx->st0,
tmpctx->st1,
tmpctx->applet->name,
tmpctx->t->tid,
- tmpctx->t->nice, tmpctx->t->calls, read_freq_ctr(&tmpctx->call_rate),
- (unsigned long long)tmpctx->t->cpu_time, (unsigned long long)tmpctx->t->lat_time);
+ tmpctx->t->nice, tmpctx->t->calls, read_freq_ctr(&tmpctx->call_rate));
}
chunk_appendf(&trash,
curr_strm->task->state, curr_strm->stream_epoch,
human_time(now.tv_sec - curr_strm->logs.tv_accept.tv_sec, 1),
curr_strm->task->calls, read_freq_ctr(&curr_strm->call_rate),
- (unsigned long long)curr_strm->task->cpu_time, (unsigned long long)curr_strm->task->lat_time);
+ (unsigned long long)curr_strm->cpu_time, (unsigned long long)curr_strm->lat_time);
chunk_appendf(&trash,
" rq[f=%06xh,i=%u,an=%02xh,rx=%s",
#include <haproxy/tools.h>
extern struct task *process_stream(struct task *t, void *context, unsigned int state);
+extern void stream_update_timings(struct task *t, uint64_t lat, uint64_t cpu);
DECLARE_POOL(pool_head_task, "task", sizeof(struct task));
DECLARE_POOL(pool_head_tasklet, "tasklet", sizeof(struct tasklet));
uint32_t now_ns = now_mono_time();
uint32_t lat = now_ns - t->wake_date;
- t->lat_time += lat;
t->wake_date = 0;
th_ctx->sched_call_date = now_ns;
profile_entry = sched_activity_entry(sched_activity, t->process);
if (unlikely(th_ctx->sched_wake_date)) {
uint32_t cpu = (uint32_t)now_mono_time() - th_ctx->sched_call_date;
- if (t)
- t->cpu_time += cpu;
HA_ATOMIC_ADD(&profile_entry->cpu_time, cpu);
}