qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 5/5] thread-pool: convert to use lock guards


From: Eric Blake
Subject: Re: [Qemu-devel] [PATCH 5/5] thread-pool: convert to use lock guards
Date: Fri, 8 Dec 2017 13:50:52 -0600
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0

On 12/08/2017 09:13 AM, Stefan Hajnoczi wrote:
> On Fri, Dec 08, 2017 at 11:55:53AM +0100, Paolo Bonzini wrote:
>> @@ -88,9 +88,9 @@ static void *worker_thread(void *opaque)
>>  
>>          do {
>>              pool->idle_threads++;
>> -            qemu_mutex_unlock(&pool->lock);
>> +            qemu_lock_guard_unlock(&pool_guard);
>>              ret = qemu_sem_timedwait(&pool->sem, 10000);
>> -            qemu_mutex_lock(&pool->lock);
>> +            qemu_lock_guard_lock(&pool_guard);
> 
> Or:
> 
>   QEMU_WITHOUT_LOCK_GUARD(pool_guard) {
>       ret = qemu_sem_timedwait(&pool->sem, 10000);
>   }
> 
> Seems funny but I like it. :)
> 
> Unfortunately it's tricky to come up with good semantics.  A 'return'
> statement inside QEMU_WITHOUT_LOCK_GUARD() should leave the lock
> unlocked.  But a 'break' statement may need to reacquire the lock...

But isn't that what happens already?

QEMU_WITH_LOCK_GUARD(guard) { // 1
  do {
    QEMU_WITHOUT_LOCK_GUARD(guard) {// 2
      if (cond1) {
        break;
      } else if (cond2) {
        goto endlock;
      } else {
        return;
      }
    } // 3
  } while (cond3);
} // 4
endlock:
  ; // 5

Point 2 introduces a new scope which says to unlock the guard at entry,
and to relock the guard at all exits from the scope.  If cond1 is true,
and we break, control flows to point 3, (because of we provided the
scope via a for loop - so the break exits only the lock guard!), and
relocks the guard, so the bulk of the do/while loop that is not
sub-scoped by the WITHOUT_LOCK_GUARD remains locked.  If cond2 is true,
then we leave the WITHOUT_LOCK_GUARD scope (and temporarily lock the
guard), then immediately leave the WITH_LOCK_GUARD scope (and unlock the
guard again) - the cleanup handlers ensure that unwinding out of
multiple scopes performs all of the proper cleanups, as we skip to point
5.  The same is true if cond2 is false and we return from the function -
the lock is temporarily restored then released.

Or did you want semantics where you can return with the lock still
locked in spite of the outer loop, and/or an optimization to avoid the
contention on temporarily re-locking/unlocking a loop when jumping out
of two nested scopes?

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]