Lines Matching +full:no +full:- +full:pc +full:- +full:write

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"
26 #include "trace/trace-root.h"
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()
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()
107 cpu->cpu_index = UNASSIGNED_CPU_INDEX; in cpu_list_remove()
116 if (cpu->cpu_index == index) { in qemu_get_cpu()
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()
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()
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()
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()
227 /* Can release mutex, no one will enter another exclusive 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()
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()
275 * while holding it; no need to check pending_cpus again. in cpu_exec_start()
277 qatomic_set(&cpu->running, false); in cpu_exec_start()
280 qatomic_set(&cpu->running, true); in cpu_exec_start()
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()
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()
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()
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()
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
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
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()
435 return -ENOENT; in cpu_breakpoint_remove()
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()
452 QTAILQ_FOREACH_SAFE(bp, &cpu->breakpoints, entry, next) { in cpu_breakpoint_remove_all()
453 if (bp->flags & mask) { in cpu_breakpoint_remove_all()