Lines Matching +full:copy +full:- +full:item

2  * CPU thread main loop - common bits for user and system mode emulation
4 * Copyright (c) 2003-2005 Fabrice Bellard
16 * You should have received a copy of the GNU Lesser General Public
21 #include "qemu/main-loop.h"
22 #include "exec/cpu-common.h"
25 #include "trace/trace-root.h"
66 if (some_cpu->cpu_index >= max_cpu_index) { in cpu_get_free_index()
67 max_cpu_index = some_cpu->cpu_index + 1; in cpu_get_free_index()
86 if (cpu->cpu_index == UNASSIGNED_CPU_INDEX) { in cpu_list_add()
88 cpu->cpu_index = cpu_get_free_index(); in cpu_list_add()
89 assert(cpu->cpu_index != UNASSIGNED_CPU_INDEX); in cpu_list_add()
106 cpu->cpu_index = UNASSIGNED_CPU_INDEX; in cpu_list_remove()
115 if (cpu->cpu_index == index) { in qemu_get_cpu()
135 qemu_mutex_lock(&cpu->work_mutex); in queue_work_on_cpu()
136 QSIMPLEQ_INSERT_TAIL(&cpu->work_list, wi, node); in queue_work_on_cpu()
137 wi->done = false; in queue_work_on_cpu()
138 qemu_mutex_unlock(&cpu->work_mutex); in queue_work_on_cpu()
173 wi->func = func; in async_run_on_cpu()
174 wi->data = data; in async_run_on_cpu()
175 wi->free = true; in async_run_on_cpu()
197 g_assert(!current_cpu->running); in start_exclusive()
199 if (current_cpu->exclusive_context_count) { in start_exclusive()
200 current_cpu->exclusive_context_count++; in start_exclusive()
210 /* Write pending_cpus before reading other_cpu->running. */ in start_exclusive()
214 if (qatomic_read(&other_cpu->running)) { in start_exclusive()
215 other_cpu->has_waiter = true; in start_exclusive()
231 current_cpu->exclusive_context_count = 1; in start_exclusive()
237 current_cpu->exclusive_context_count--; in end_exclusive()
238 if (current_cpu->exclusive_context_count) { in end_exclusive()
251 qatomic_set(&cpu->running, true); in cpu_exec_start()
253 /* Write cpu->running before reading pending_cpus. */ in cpu_exec_start()
256 /* 1. start_exclusive saw cpu->running == true and pending_cpus >= 1. in cpu_exec_start()
257 * After taking the lock we'll see cpu->has_waiter == true and run---not in cpu_exec_start()
261 * 2. start_exclusive saw cpu->running == false but pending_cpus >= 1. in cpu_exec_start()
262 * This includes the case when an exclusive item is running now. in cpu_exec_start()
263 * Then we'll see cpu->has_waiter == false and wait for the item to in cpu_exec_start()
267 * see cpu->running == true, and it will kick the CPU. in cpu_exec_start()
271 if (!cpu->has_waiter) { in cpu_exec_start()
272 /* Not counted in pending_cpus, let the exclusive item in cpu_exec_start()
273 * run. Since we have the lock, just set cpu->running to true in cpu_exec_start()
276 qatomic_set(&cpu->running, false); in cpu_exec_start()
279 qatomic_set(&cpu->running, true); in cpu_exec_start()
291 qatomic_set(&cpu->running, false); in cpu_exec_end()
293 /* Write cpu->running before reading pending_cpus. */ in cpu_exec_end()
296 /* 1. start_exclusive saw cpu->running == true. Then it will increment in cpu_exec_end()
298 * we'll see cpu->has_waiter == true. in cpu_exec_end()
300 * 2. start_exclusive saw cpu->running == false but here pending_cpus >= 1. in cpu_exec_end()
301 * This includes the case when an exclusive item started after setting in cpu_exec_end()
302 * cpu->running to false and before we read pending_cpus. Then we'll see in cpu_exec_end()
303 * cpu->has_waiter == false and not touch pending_cpus. The next call to in cpu_exec_end()
305 * for the item to complete. in cpu_exec_end()
308 * see cpu->running == false, and it can ignore this CPU until the in cpu_exec_end()
313 if (cpu->has_waiter) { in cpu_exec_end()
314 cpu->has_waiter = false; in cpu_exec_end()
315 qatomic_set(&pending_cpus, pending_cpus - 1); in cpu_exec_end()
329 wi->func = func; in async_safe_run_on_cpu()
330 wi->data = data; in async_safe_run_on_cpu()
331 wi->free = true; in async_safe_run_on_cpu()
332 wi->exclusive = true; in async_safe_run_on_cpu()
339 while (!QSIMPLEQ_EMPTY(&cpu->work_list)) { in free_queued_cpu_work()
340 struct qemu_work_item *wi = QSIMPLEQ_FIRST(&cpu->work_list); in free_queued_cpu_work()
341 QSIMPLEQ_REMOVE_HEAD(&cpu->work_list, node); in free_queued_cpu_work()
342 if (wi->free) { in free_queued_cpu_work()
352 qemu_mutex_lock(&cpu->work_mutex); in process_queued_cpu_work()
353 if (QSIMPLEQ_EMPTY(&cpu->work_list)) { in process_queued_cpu_work()
354 qemu_mutex_unlock(&cpu->work_mutex); in process_queued_cpu_work()
357 while (!QSIMPLEQ_EMPTY(&cpu->work_list)) { in process_queued_cpu_work()
358 wi = QSIMPLEQ_FIRST(&cpu->work_list); in process_queued_cpu_work()
359 QSIMPLEQ_REMOVE_HEAD(&cpu->work_list, node); in process_queued_cpu_work()
360 qemu_mutex_unlock(&cpu->work_mutex); in process_queued_cpu_work()
361 if (wi->exclusive) { in process_queued_cpu_work()
370 wi->func(cpu, wi->data); in process_queued_cpu_work()
374 wi->func(cpu, wi->data); in process_queued_cpu_work()
376 qemu_mutex_lock(&cpu->work_mutex); in process_queued_cpu_work()
377 if (wi->free) { in process_queued_cpu_work()
380 qatomic_store_release(&wi->done, true); in process_queued_cpu_work()
383 qemu_mutex_unlock(&cpu->work_mutex); in process_queued_cpu_work()
393 if (cpu->cc->gdb_adjust_breakpoint) { in cpu_breakpoint_insert()
394 pc = cpu->cc->gdb_adjust_breakpoint(cpu, pc); in cpu_breakpoint_insert()
399 bp->pc = pc; in cpu_breakpoint_insert()
400 bp->flags = flags; in cpu_breakpoint_insert()
402 /* keep all GDB-injected breakpoints in front */ in cpu_breakpoint_insert()
404 QTAILQ_INSERT_HEAD(&cpu->breakpoints, bp, entry); in cpu_breakpoint_insert()
406 QTAILQ_INSERT_TAIL(&cpu->breakpoints, bp, entry); in cpu_breakpoint_insert()
413 trace_breakpoint_insert(cpu->cpu_index, pc, flags); in cpu_breakpoint_insert()
422 if (cpu->cc->gdb_adjust_breakpoint) { in cpu_breakpoint_remove()
423 pc = cpu->cc->gdb_adjust_breakpoint(cpu, pc); in cpu_breakpoint_remove()
426 QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) { in cpu_breakpoint_remove()
427 if (bp->pc == pc && bp->flags == flags) { in cpu_breakpoint_remove()
432 return -ENOENT; in cpu_breakpoint_remove()
438 QTAILQ_REMOVE(&cpu->breakpoints, bp, entry); in cpu_breakpoint_remove_by_ref()
440 trace_breakpoint_remove(cpu->cpu_index, bp->pc, bp->flags); in cpu_breakpoint_remove_by_ref()
449 QTAILQ_FOREACH_SAFE(bp, &cpu->breakpoints, entry, next) { in cpu_breakpoint_remove_all()
450 if (bp->flags & mask) { in cpu_breakpoint_remove_all()