Lines Matching +full:cpu +full:- +full:1

2  * CPU thread main loop - common bits for user and system mode emulation
4 * Copyright (c) 2003-2005 Fabrice Bellard
21 #include "qemu/main-loop.h"
22 #include "exec/cpu-common.h"
23 #include "hw/core/cpu.h"
26 #include "trace/trace-root.h"
33 /* >= 1 if a thread is inside start_exclusive/end_exclusive. Written
67 if (some_cpu->cpu_index >= max_cpu_index) { in cpu_get_free_index()
68 max_cpu_index = some_cpu->cpu_index + 1; in cpu_get_free_index()
82 void cpu_list_add(CPUState *cpu) in cpu_list_add() argument
87 if (cpu->cpu_index == UNASSIGNED_CPU_INDEX) { in cpu_list_add()
89 cpu->cpu_index = cpu_get_free_index(); in cpu_list_add()
90 assert(cpu->cpu_index != UNASSIGNED_CPU_INDEX); in cpu_list_add()
94 QTAILQ_INSERT_TAIL_RCU(&cpus_queue, cpu, node); in cpu_list_add()
98 void cpu_list_remove(CPUState *cpu) in cpu_list_remove() argument
101 if (!QTAILQ_IN_USE(cpu, node)) { in cpu_list_remove()
106 QTAILQ_REMOVE_RCU(&cpus_queue, cpu, node); in cpu_list_remove()
107 cpu->cpu_index = UNASSIGNED_CPU_INDEX; in cpu_list_remove()
113 CPUState *cpu; in qemu_get_cpu() local
115 CPU_FOREACH(cpu) { in qemu_get_cpu()
116 if (cpu->cpu_index == index) { in qemu_get_cpu()
117 return cpu; in qemu_get_cpu()
124 /* current CPU in the current thread. It is only valid inside cpu_exec() */
134 static void queue_work_on_cpu(CPUState *cpu, struct qemu_work_item *wi) in queue_work_on_cpu() argument
136 qemu_mutex_lock(&cpu->work_mutex); in queue_work_on_cpu()
137 QSIMPLEQ_INSERT_TAIL(&cpu->work_list, wi, node); in queue_work_on_cpu()
138 wi->done = false; in queue_work_on_cpu()
139 qemu_mutex_unlock(&cpu->work_mutex); in queue_work_on_cpu()
141 qemu_cpu_kick(cpu); in queue_work_on_cpu()
144 void do_run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data, in do_run_on_cpu() argument
149 if (qemu_cpu_is_self(cpu)) { in do_run_on_cpu()
150 func(cpu, data); in do_run_on_cpu()
160 queue_work_on_cpu(cpu, &wi); in do_run_on_cpu()
169 void async_run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data) in async_run_on_cpu() argument
173 wi = g_new0(struct qemu_work_item, 1); in async_run_on_cpu()
174 wi->func = func; in async_run_on_cpu()
175 wi->data = data; in async_run_on_cpu()
176 wi->free = true; in async_run_on_cpu()
178 queue_work_on_cpu(cpu, wi); in async_run_on_cpu()
181 /* Wait for pending exclusive operations to complete. The CPU list lock
198 g_assert(!current_cpu->running); in start_exclusive()
200 if (current_cpu->exclusive_context_count) { in start_exclusive()
201 current_cpu->exclusive_context_count++; in start_exclusive()
209 qatomic_set(&pending_cpus, 1); in start_exclusive()
211 /* Write pending_cpus before reading other_cpu->running. */ in start_exclusive()
215 if (qatomic_read(&other_cpu->running)) { in start_exclusive()
216 other_cpu->has_waiter = true; in start_exclusive()
222 qatomic_set(&pending_cpus, running_cpus + 1); in start_exclusive()
223 while (pending_cpus > 1) { in start_exclusive()
232 current_cpu->exclusive_context_count = 1; in start_exclusive()
238 current_cpu->exclusive_context_count--; in end_exclusive()
239 if (current_cpu->exclusive_context_count) { in end_exclusive()
249 /* Wait for exclusive ops to finish, and begin cpu execution. */
250 void cpu_exec_start(CPUState *cpu) in cpu_exec_start() argument
252 qatomic_set(&cpu->running, true); in cpu_exec_start()
254 /* Write cpu->running before reading pending_cpus. */ in cpu_exec_start()
257 /* 1. start_exclusive saw cpu->running == true and pending_cpus >= 1. in cpu_exec_start()
258 * After taking the lock we'll see cpu->has_waiter == true and run---not in cpu_exec_start()
262 * 2. start_exclusive saw cpu->running == false but pending_cpus >= 1. in cpu_exec_start()
264 * Then we'll see cpu->has_waiter == false and wait for the item to in cpu_exec_start()
268 * see cpu->running == true, and it will kick the CPU. in cpu_exec_start()
272 if (!cpu->has_waiter) { in cpu_exec_start()
274 * run. Since we have the lock, just set cpu->running to true in cpu_exec_start()
277 qatomic_set(&cpu->running, false); in cpu_exec_start()
280 qatomic_set(&cpu->running, true); in cpu_exec_start()
289 /* Mark cpu as not executing, and release pending exclusive ops. */
290 void cpu_exec_end(CPUState *cpu) in cpu_exec_end() argument
292 qatomic_set(&cpu->running, false); in cpu_exec_end()
294 /* Write cpu->running before reading pending_cpus. */ in cpu_exec_end()
297 /* 1. start_exclusive saw cpu->running == true. Then it will increment in cpu_exec_end()
299 * we'll see cpu->has_waiter == true. in cpu_exec_end()
301 * 2. start_exclusive saw cpu->running == false but here pending_cpus >= 1. in cpu_exec_end()
303 * cpu->running to false and before we read pending_cpus. Then we'll see in cpu_exec_end()
304 * cpu->has_waiter == false and not touch pending_cpus. The next call to in cpu_exec_end()
309 * see cpu->running == false, and it can ignore this CPU until the in cpu_exec_end()
314 if (cpu->has_waiter) { in cpu_exec_end()
315 cpu->has_waiter = false; in cpu_exec_end()
316 qatomic_set(&pending_cpus, pending_cpus - 1); in cpu_exec_end()
317 if (pending_cpus == 1) { in cpu_exec_end()
324 void async_safe_run_on_cpu(CPUState *cpu, run_on_cpu_func func, in async_safe_run_on_cpu() argument
329 wi = g_new0(struct qemu_work_item, 1); in async_safe_run_on_cpu()
330 wi->func = func; in async_safe_run_on_cpu()
331 wi->data = data; in async_safe_run_on_cpu()
332 wi->free = true; in async_safe_run_on_cpu()
333 wi->exclusive = true; in async_safe_run_on_cpu()
335 queue_work_on_cpu(cpu, wi); in async_safe_run_on_cpu()
338 void free_queued_cpu_work(CPUState *cpu) in free_queued_cpu_work() argument
340 while (!QSIMPLEQ_EMPTY(&cpu->work_list)) { in free_queued_cpu_work()
341 struct qemu_work_item *wi = QSIMPLEQ_FIRST(&cpu->work_list); in free_queued_cpu_work()
342 QSIMPLEQ_REMOVE_HEAD(&cpu->work_list, node); in free_queued_cpu_work()
343 if (wi->free) { in free_queued_cpu_work()
349 void process_queued_cpu_work(CPUState *cpu) in process_queued_cpu_work() argument
353 qemu_mutex_lock(&cpu->work_mutex); in process_queued_cpu_work()
354 if (QSIMPLEQ_EMPTY(&cpu->work_list)) { in process_queued_cpu_work()
355 qemu_mutex_unlock(&cpu->work_mutex); in process_queued_cpu_work()
358 while (!QSIMPLEQ_EMPTY(&cpu->work_list)) { in process_queued_cpu_work()
359 wi = QSIMPLEQ_FIRST(&cpu->work_list); in process_queued_cpu_work()
360 QSIMPLEQ_REMOVE_HEAD(&cpu->work_list, node); in process_queued_cpu_work()
361 qemu_mutex_unlock(&cpu->work_mutex); in process_queued_cpu_work()
362 if (wi->exclusive) { in process_queued_cpu_work()
364 * 1) start_exclusive() is called with the BQL taken while another in process_queued_cpu_work()
365 * CPU is running; 2) cpu_exec in the other CPU tries to takes the in process_queued_cpu_work()
367 * neither CPU can proceed. in process_queued_cpu_work()
371 wi->func(cpu, wi->data); in process_queued_cpu_work()
375 wi->func(cpu, wi->data); in process_queued_cpu_work()
377 qemu_mutex_lock(&cpu->work_mutex); in process_queued_cpu_work()
378 if (wi->free) { in process_queued_cpu_work()
381 qatomic_store_release(&wi->done, true); in process_queued_cpu_work()
384 qemu_mutex_unlock(&cpu->work_mutex); in process_queued_cpu_work()
389 int cpu_breakpoint_insert(CPUState *cpu, vaddr pc, int flags, in cpu_breakpoint_insert() argument
392 CPUClass *cc = CPU_GET_CLASS(cpu); in cpu_breakpoint_insert()
395 if (cc->gdb_adjust_breakpoint) { in cpu_breakpoint_insert()
396 pc = cc->gdb_adjust_breakpoint(cpu, pc); in cpu_breakpoint_insert()
401 bp->pc = pc; in cpu_breakpoint_insert()
402 bp->flags = flags; in cpu_breakpoint_insert()
404 /* keep all GDB-injected breakpoints in front */ in cpu_breakpoint_insert()
406 QTAILQ_INSERT_HEAD(&cpu->breakpoints, bp, entry); in cpu_breakpoint_insert()
408 QTAILQ_INSERT_TAIL(&cpu->breakpoints, bp, entry); in cpu_breakpoint_insert()
415 trace_breakpoint_insert(cpu->cpu_index, pc, flags); in cpu_breakpoint_insert()
420 int cpu_breakpoint_remove(CPUState *cpu, vaddr pc, int flags) in cpu_breakpoint_remove() argument
422 CPUClass *cc = CPU_GET_CLASS(cpu); in cpu_breakpoint_remove()
425 if (cc->gdb_adjust_breakpoint) { in cpu_breakpoint_remove()
426 pc = cc->gdb_adjust_breakpoint(cpu, pc); in cpu_breakpoint_remove()
429 QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) { in cpu_breakpoint_remove()
430 if (bp->pc == pc && bp->flags == flags) { in cpu_breakpoint_remove()
431 cpu_breakpoint_remove_by_ref(cpu, bp); in cpu_breakpoint_remove()
435 return -ENOENT; in cpu_breakpoint_remove()
439 void cpu_breakpoint_remove_by_ref(CPUState *cpu, CPUBreakpoint *bp) in cpu_breakpoint_remove_by_ref() argument
441 QTAILQ_REMOVE(&cpu->breakpoints, bp, entry); in cpu_breakpoint_remove_by_ref()
443 trace_breakpoint_remove(cpu->cpu_index, bp->pc, bp->flags); in cpu_breakpoint_remove_by_ref()
448 void cpu_breakpoint_remove_all(CPUState *cpu, int mask) in cpu_breakpoint_remove_all() argument
452 QTAILQ_FOREACH_SAFE(bp, &cpu->breakpoints, entry, next) { in cpu_breakpoint_remove_all()
453 if (bp->flags & mask) { in cpu_breakpoint_remove_all()
454 cpu_breakpoint_remove_by_ref(cpu, bp); in cpu_breakpoint_remove_all()