summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cpus-common.c11
-rw-r--r--docs/tcg-exclusive.promela4
-rw-r--r--include/qom/cpu.h4
3 files changed, 11 insertions, 8 deletions
diff --git a/cpus-common.c b/cpus-common.c
index 80aaf9b42d..429652c7fd 100644
--- a/cpus-common.c
+++ b/cpus-common.c
@@ -171,8 +171,7 @@ static inline void exclusive_idle(void)
}
/* Start an exclusive operation.
- Must only be called from outside cpu_exec, takes
- qemu_cpu_list_lock. */
+ Must only be called from outside cpu_exec. */
void start_exclusive(void)
{
CPUState *other_cpu;
@@ -191,11 +190,17 @@ void start_exclusive(void)
while (pending_cpus > 1) {
qemu_cond_wait(&exclusive_cond, &qemu_cpu_list_lock);
}
+
+ /* Can release mutex, no one will enter another exclusive
+ * section until end_exclusive resets pending_cpus to 0.
+ */
+ qemu_mutex_unlock(&qemu_cpu_list_lock);
}
-/* Finish an exclusive operation. Releases qemu_cpu_list_lock. */
+/* Finish an exclusive operation. */
void end_exclusive(void)
{
+ qemu_mutex_lock(&qemu_cpu_list_lock);
pending_cpus = 0;
qemu_cond_broadcast(&exclusive_resume);
qemu_mutex_unlock(&qemu_cpu_list_lock);
diff --git a/docs/tcg-exclusive.promela b/docs/tcg-exclusive.promela
index 8bb0967df6..feac679b9a 100644
--- a/docs/tcg-exclusive.promela
+++ b/docs/tcg-exclusive.promela
@@ -98,9 +98,11 @@ byte has_waiter[N_CPUS];
do \
:: pending_cpus > 1 -> COND_WAIT(exclusive_cond, mutex); \
:: else -> break; \
- od
+ od; \
+ MUTEX_UNLOCK(mutex);
#define end_exclusive() \
+ MUTEX_LOCK(mutex); \
pending_cpus = 0; \
COND_BROADCAST(exclusive_resume); \
MUTEX_UNLOCK(mutex);
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index f8726140f6..934c07afbf 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -846,9 +846,6 @@ void cpu_exec_end(CPUState *cpu);
* cpu_exec are exited immediately. CPUs that call cpu_exec_start
* during the exclusive section go to sleep until this CPU calls
* end_exclusive.
- *
- * Returns with the CPU list lock taken (which nests outside all
- * other locks except the BQL).
*/
void start_exclusive(void);
@@ -856,7 +853,6 @@ void start_exclusive(void);
* end_exclusive:
*
* Concludes an exclusive execution section started by start_exclusive.
- * Releases the CPU list lock.
*/
void end_exclusive(void);