]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/jdb/jdb_kern_info-bench.cpp
Update
[l4.git] / kernel / fiasco / src / jdb / jdb_kern_info-bench.cpp
1 INTERFACE:
2
3 #include "jdb.h"
4
5 class Jdb_kern_info_bench : public Jdb_kern_info_module
6 {
7 private:
8   static Unsigned64 get_time_now();
9   static void show_arch();
10 };
11
12 //---------------------------------------------------------------------------
13 IMPLEMENTATION:
14
15 static Jdb_kern_info_bench k_a INIT_PRIORITY(JDB_MODULE_INIT_PRIO+1);
16
17 PUBLIC
18 Jdb_kern_info_bench::Jdb_kern_info_bench()
19   : Jdb_kern_info_module('b', "Benchmark privileged instructions")
20 {
21   Jdb_kern_info::register_subcmd(this);
22 }
23
24 PUBLIC
25 void
26 Jdb_kern_info_bench::show()
27 {
28   do_mp_benchmark();
29   show_arch();
30 }
31
32 //---------------------------------------------------------------------------
33 IMPLEMENTATION [!mp]:
34
35 PRIVATE
36 void
37 Jdb_kern_info_bench::do_mp_benchmark()
38 {}
39
40 //---------------------------------------------------------------------------
41 IMPLEMENTATION [mp && (ia32 || amd64)]:
42
43 #include "idt.h"
44
45 PRIVATE static inline
46 void
47 Jdb_kern_info_bench::stop_timer()
48 {
49   Timer_tick::set_vectors_stop();
50 }
51
52 //---------------------------------------------------------------------------
53 IMPLEMENTATION [mp && !(ia32 || amd64)]:
54
55 PRIVATE static inline
56 void
57 Jdb_kern_info_bench::stop_timer()
58 {}
59
60 //---------------------------------------------------------------------------
61 IMPLEMENTATION [mp]:
62
63 #include "ipi.h"
64
65 static int volatile ipi_bench_spin_done;
66 static int ipi_cnt;
67
68 PRIVATE static
69 void
70 Jdb_kern_info_bench::wait_for_ipi(Cpu_number cpu)
71 {
72   Jdb::restore_irqs(cpu);
73   stop_timer();
74   Proc::sti();
75
76   while (!ipi_bench_spin_done)
77     Proc::pause();
78
79   Proc::cli();
80   Jdb::save_disable_irqs(cpu);
81 }
82
83 PRIVATE static
84 void
85 Jdb_kern_info_bench::empty_func(Cpu_number, void *)
86 {
87   ++ipi_cnt;
88 }
89
90 PRIVATE static
91 void
92 Jdb_kern_info_bench::do_ipi_bench(Cpu_number my_cpu, Cpu_number partner)
93 {
94   Unsigned64 time;
95   enum {
96     Runs2  = 3,
97     Warmup = 4,
98     Rounds = (1 << Runs2) + Warmup,
99   };
100   unsigned i;
101
102   ipi_cnt = 0;
103   Mem::barrier();
104
105   for (i = 0; i < Warmup; ++i)
106     Jdb::remote_work_ipi(my_cpu, partner, empty_func, 0, true);
107
108   time = get_time_now();
109   for (i = 0; i < (1 << Runs2); i++)
110     Jdb::remote_work_ipi(my_cpu, partner, empty_func, 0, true);
111
112   printf(" %2u:%8llu", cxx::int_value<Cpu_number>(partner),
113          (get_time_now() - time) >> Runs2);
114
115   if (ipi_cnt != Rounds)
116     printf("\nCounter mismatch: cnt=%d v %d\n", ipi_cnt, Rounds);
117
118   ipi_bench_spin_done = 1;
119   Mem::barrier();
120 }
121
122 PRIVATE
123 void
124 Jdb_kern_info_bench::do_mp_benchmark()
125 {
126   // IPI bench matrix
127   printf("IPI round-trips:\n");
128   for (Cpu_number u = Cpu_number::first(); u < Config::max_num_cpus(); ++u)
129     if (Cpu::online(u))
130       {
131         printf("l%2u: ", cxx::int_value<Cpu_number>(u));
132
133         for (Cpu_number v = Cpu_number::first(); v < Config::max_num_cpus(); ++v)
134           if (Cpu::online(v))
135             {
136               if (u == v)
137                 printf(" %2u:%8s", cxx::int_value<Cpu_number>(u), "X");
138               else
139                 {
140                   ipi_bench_spin_done = 0;
141
142                   // v is waiting for IPIs
143                   if (v != Cpu_number::boot_cpu())
144                     Jdb::remote_work(v, wait_for_ipi, false);
145
146                   // u is doing benchmark
147                   if (u == Cpu_number::boot_cpu())
148                     do_ipi_bench(Cpu_number::boot_cpu(), v);
149                   else
150                     Jdb::remote_work(u, [this, v](Cpu_number cpu){ do_ipi_bench(cpu, v); }, false);
151
152                   // v is waiting for IPIs
153                   if (v == Cpu_number::boot_cpu())
154                     wait_for_ipi(Cpu_number::boot_cpu());
155
156                   Mem::barrier();
157
158                   while (!ipi_bench_spin_done)
159                     Proc::pause();
160                 }
161             }
162         printf("\n");
163       }
164 }