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

Reply via email to