On 10/02/2015 11:41, Kevin Wolf wrote: > + ret = qemu_coroutine_switch(self, co, COROUTINE_ENTER); > + > + qemu_co_queue_run_restart(co); > + > + switch (ret) { > + case COROUTINE_YIELD: > + return; > + case COROUTINE_TERMINATE: > + trace_qemu_coroutine_terminate(co); > + coroutine_delete(co); > + return; > + default:
Say you have: co1 co2 ------------------------------------------------------------------------ 1 qemu_co_mutex_lock(&m); 2 qemu_coroutine_yield(); 3 qemu_co_mutex_lock(&m); 4 qemu_co_mutex_unlock(&m); 5 qemu_coroutine_yield(); Then you have: 1 mutex->locked = true; 2 coroutine_swap(co1, leader, COROUTINE_YIELD); 3 while (mutex->locked) { qemu_co_queue_wait(&mutex->queue); '--> QTAILQ_INSERT_TAIL(&queue->entries, self, co_queue_next); qemu_coroutine_yield(); '--> coroutine_swap(co2, leader, COROUTINE_YIELD); } 4 mutex->locked = false; qemu_co_queue_next(&mutex->queue); '--> qemu_co_queue_do_restart(queue, true); '--> QTAILQ_REMOVE(&queue->entries, next, co_queue_next); QTAILQ_INSERT_TAIL(&self->co_queue_wakeup, next, co_queue_next); 5 coroutine_swap(co1, leader, COROUTINE_YIELD); And co2 is never reentered until co1 terminates. Right? Paolo