]> 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(unsigned cpu, void *)
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(unsigned, void *)
86 {
87   ++ipi_cnt;
88 }
89
90 PRIVATE static
91 void
92 Jdb_kern_info_bench::do_ipi_bench(unsigned my_cpu, void *_partner)
93 {
94   Unsigned64 time;
95   unsigned partner = (unsigned long)_partner;
96   enum {
97     Runs2  = 3,
98     Warmup = 4,
99     Rounds = (1 << Runs2) + Warmup,
100   };
101   unsigned i;
102
103   ipi_cnt = 0;
104   Mem::barrier();
105
106   for (i = 0; i < Warmup; ++i)
107     Jdb::remote_work_ipi(my_cpu, partner, empty_func, 0, true);
108
109   time = get_time_now();
110   for (i = 0; i < (1 << Runs2); i++)
111     Jdb::remote_work_ipi(my_cpu, partner, empty_func, 0, true);
112
113   printf(" %2u:%8lld", partner, (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 (unsigned u = 0; u < Config::Max_num_cpus; ++u)
129     if (Cpu::online(u))
130       {
131         printf("l%2u: ", u);
132
133         for (unsigned v = 0; v < Config::Max_num_cpus; ++v)
134           if (Cpu::online(v))
135             {
136               if (u == v)
137                 printf(" %2u:%8s", u, "X");
138               else
139                 {
140                   ipi_bench_spin_done = 0;
141
142                   // v is waiting for IPIs
143                   if (v != 0)
144                     Jdb::remote_work(v, wait_for_ipi, 0, false);
145
146                   // u is doing benchmark
147                   if (u == 0)
148                     do_ipi_bench(0, (void *)v);
149                   else
150                     Jdb::remote_work(u, do_ipi_bench, (void *)v, false);
151
152                   // v is waiting for IPIs
153                   if (v == 0)
154                     wait_for_ipi(0, 0);
155
156                   Mem::barrier();
157
158                   while (!ipi_bench_spin_done)
159                     Proc::pause();
160                 }
161             }
162         printf("\n");
163       }
164 }