@@ -151,31 +151,69 @@ void ::SMP::init_task()
151151 /* do nothing */
152152}
153153
154- void ::SMP::add_task (smp_task_func task, smp_done_func done)
154+ void ::SMP::add_task (smp_task_func task, smp_done_func done, int cpu )
155155{
156156#ifdef INCLUDEOS_SINGLE_THREADED
157+ assert (cpu == -1 || cpu == 0 );
157158 task (); done ();
158159#else
159- lock (smp.tlock );
160- smp.tasks .emplace_back (std::move (task), std::move (done));
161- unlock (smp.tlock );
160+ if (cpu == -1 )
161+ {
162+ lock (smp.tlock );
163+ smp.tasks .emplace_back (std::move (task), std::move (done));
164+ unlock (smp.tlock );
165+ }
166+ else {
167+ lock (smp_local[cpu].tlock );
168+ smp_local[cpu].tasks .emplace_back (std::move (task), std::move (done));
169+ unlock (smp_local[cpu].tlock );
170+ }
162171#endif
163172}
164- void ::SMP::add_task (smp_task_func task)
173+ void ::SMP::add_task (smp_task_func task, int cpu )
165174{
166175#ifdef INCLUDEOS_SINGLE_THREADED
176+ assert (cpu == -1 || cpu == 0 );
167177 task ();
168178#else
169- lock (smp.tlock );
170- smp.tasks .emplace_back (std::move (task), nullptr );
171- unlock (smp.tlock );
179+ if (cpu == -1 )
180+ {
181+ lock (smp.tlock );
182+ smp.tasks .emplace_back (std::move (task), nullptr );
183+ unlock (smp.tlock );
184+ }
185+ else {
186+ lock (smp_local[cpu].tlock );
187+ smp_local[cpu].tasks .emplace_back (std::move (task), nullptr );
188+ unlock (smp_local[cpu].tlock );
189+ }
172190#endif
173191}
174- void ::SMP::signal ()
192+ void ::SMP::add_bsp_task (smp_done_func task)
193+ {
194+ #ifdef INCLUDEOS_SINGLE_THREADED
195+ task ();
196+ #else
197+ lock (smp.flock );
198+ smp.completed .push_back (std::move (task));
199+ unlock (smp.flock );
200+ x86::APIC::get ().send_bsp_intr ();
201+ #endif
202+ }
203+
204+ void ::SMP::signal (int cpu)
175205{
176206#ifndef INCLUDEOS_SINGLE_THREADED
177207 // broadcast that there is work to do
178- x86::APIC::get ().bcast_ipi (0x20 );
208+ // -1: Broadcast to everyone except BSP
209+ if (cpu == -1 )
210+ x86::APIC::get ().bcast_ipi (0x20 );
211+ // 1-xx: Unicast specific vCPU
212+ else if (cpu != 0 )
213+ x86::APIC::get ().send_ipi (cpu, 0x20 );
214+ // 0: BSP unicast
215+ else
216+ x86::APIC::get ().send_bsp_intr ();
179217#endif
180218}
181219
0 commit comments