Skip to content
Snippets Groups Projects
Commit 3ab3a6bb authored by Glauber Costa's avatar Glauber Costa Committed by Pekka Enberg
Browse files

general infrastructure for boot time calculation


I am proposing a mechanism here that will allow us to have a better idea about
how much time do we spend booting, and also how much time each of the pieces
contribute to. For that, we need to be able to get time stamps really early, in
places where tracepoints may not be available, and a clock most definitely
won't.

With my proposal, one should be able to register events. After the system
boots, we will calculate the total time since the first event, as well as the
delta since the last event. If the first event is early enough, that should
produce a very good picture about our boot time.

Signed-off-by: default avatarGlauber Costa <glommer@cloudius-systems.com>
Reviewed-by: default avatarNadav Har'El <nyh@cloudius-systems.com>
Signed-off-by: default avatarPekka Enberg <penberg@cloudius-systems.com>
parent 2df3c029
No related branches found
No related tags found
No related merge requests found
...@@ -309,6 +309,11 @@ inline u64 rdtsc() ...@@ -309,6 +309,11 @@ inline u64 rdtsc()
return lo | (u64(hi) << 32); return lo | (u64(hi) << 32);
} }
inline u64 ticks()
{
return rdtsc();
}
struct fpu_state { struct fpu_state {
char x[512]; char x[512];
char extra[]; char extra[];
......
...@@ -598,6 +598,7 @@ objects += core/run.o ...@@ -598,6 +598,7 @@ objects += core/run.o
objects += core/shutdown.o objects += core/shutdown.o
objects += core/version.o objects += core/version.o
objects += core/waitqueue.o objects += core/waitqueue.o
objects += core/chart.o
include $(src)/fs/build.mk include $(src)/fs/build.mk
include $(src)/libc/build.mk include $(src)/libc/build.mk
......
#include "arch.hh"
#include <osv/debug.hh>
#include <osv/sched.hh>
#include "drivers/clock.hh"
#include <osv/barrier.hh>
#include <osv/boot.hh>
double boot_time_chart::to_msec(u64 time)
{
return (double)clock::get()->processor_to_nano(time) / 1000000;
}
void boot_time_chart::print_one_time(int index)
{
auto field = arrays[index].stamp;
auto last = arrays[index - 1].stamp;
auto initial = arrays[0].stamp;
printf("\t%s: %.2fms, (+%.2fms)\n", arrays[index].str, to_msec(field - initial), to_msec(field - last));
}
void boot_time_chart::event(const char *str)
{
arrays[_event].str = str;
arrays[_event++].stamp = processor::ticks();
}
void boot_time_chart::print_chart()
{
if (clock::get()->processor_to_nano(10000) == 0) {
debug("Skipping bootchart: please run this with a clocksource that can do ticks/nanoseconds conversion.\n");
return;
}
int events = _event;
for (auto i = 1; i < events; ++i) {
print_one_time(i);
}
}
#ifndef BOOT_HH
#define BOOT_HH
class time_element {
public:
const char *str;
u64 stamp;
};
class boot_time_chart {
public:
void event(const char *str);
void print_chart();
time_element arrays[16];
private:
int _event = 0;
void print_one_time(int index);
double to_msec(u64 time);
};
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment