[PATCH] thread-win32: replace CRITICAL_SECTION with SRWLOCK

Paolo Bonzini posted 1 patch 2 days, 11 hours ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260330141818.286412-1-pbonzini@redhat.com
Maintainers: Stefan Weil <sw@weilnetz.de>
util/qemu-thread-win32.c | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
[PATCH] thread-win32: replace CRITICAL_SECTION with SRWLOCK
Posted by Paolo Bonzini 2 days, 11 hours ago
SRWLOCK is a much cheaper primitive than CRITICAL_SECTION, which
basically exists only as a legacy API.  The SRWLOCK is a single word
in memory and it is cheaper to just initialize it always.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 util/qemu-thread-win32.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c
index 272afc33856..3037732a6fe 100644
--- a/util/qemu-thread-win32.c
+++ b/util/qemu-thread-win32.c
@@ -242,7 +242,7 @@ struct QemuThreadData {
     /* Only used for joinable threads. */
     bool              exited;
     void             *ret;
-    CRITICAL_SECTION  cs;
+    SRWLOCK           lock;
 };
 
 static bool atexit_registered;
@@ -295,9 +295,9 @@ void qemu_thread_exit(void *arg)
     notifier_list_notify(&data->exit, NULL);
     if (data->mode == QEMU_THREAD_JOINABLE) {
         data->ret = arg;
-        EnterCriticalSection(&data->cs);
+        AcquireSRWLockExclusive(&data->lock);
         data->exited = true;
-        LeaveCriticalSection(&data->cs);
+        ReleaseSRWLockExclusive(&data->lock);
     } else {
         g_free(data);
     }
@@ -328,7 +328,6 @@ void *qemu_thread_join(QemuThread *thread)
         CloseHandle(handle);
     }
     ret = data->ret;
-    DeleteCriticalSection(&data->cs);
     g_free(data);
     return ret;
 }
@@ -357,6 +356,7 @@ void qemu_thread_create(QemuThread *thread, const char *name,
     struct QemuThreadData *data;
 
     data = g_malloc(sizeof *data);
+    InitializeSRWLock(&data->lock);
     data->start_routine = start_routine;
     data->arg = arg;
     data->mode = mode;
@@ -364,10 +364,6 @@ void qemu_thread_create(QemuThread *thread, const char *name,
     data->name = g_strdup(name);
     notifier_list_init(&data->exit);
 
-    if (data->mode != QEMU_THREAD_DETACHED) {
-        InitializeCriticalSection(&data->cs);
-    }
-
     hThread = (HANDLE) _beginthreadex(NULL, 0, win32_start_routine,
                                       data, 0, &thread->tid);
     if (!hThread) {
@@ -406,14 +402,14 @@ HANDLE qemu_thread_get_handle(QemuThread *thread)
         return NULL;
     }
 
-    EnterCriticalSection(&data->cs);
+    AcquireSRWLockExclusive(&data->lock);
     if (!data->exited) {
         handle = OpenThread(SYNCHRONIZE | THREAD_SUSPEND_RESUME |
                             THREAD_SET_CONTEXT, FALSE, thread->tid);
     } else {
         handle = NULL;
     }
-    LeaveCriticalSection(&data->cs);
+    ReleaseSRWLockExclusive(&data->lock);
     return handle;
 }
 
-- 
2.53.0
Re: [PATCH] thread-win32: replace CRITICAL_SECTION with SRWLOCK
Posted by Kostiantyn Kostiuk 2 days, 10 hours ago
I think we don't need Windows XP support, so

Reviewed-by: Kostiantyn Kostiuk <kkostiuk@redhat.com>

On Mon, Mar 30, 2026 at 5:19 PM Paolo Bonzini <pbonzini@redhat.com> wrote:

> SRWLOCK is a much cheaper primitive than CRITICAL_SECTION, which
> basically exists only as a legacy API.  The SRWLOCK is a single word
> in memory and it is cheaper to just initialize it always.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  util/qemu-thread-win32.c | 16 ++++++----------
>  1 file changed, 6 insertions(+), 10 deletions(-)
>
> diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c
> index 272afc33856..3037732a6fe 100644
> --- a/util/qemu-thread-win32.c
> +++ b/util/qemu-thread-win32.c
> @@ -242,7 +242,7 @@ struct QemuThreadData {
>      /* Only used for joinable threads. */
>      bool              exited;
>      void             *ret;
> -    CRITICAL_SECTION  cs;
> +    SRWLOCK           lock;
>  };
>
>  static bool atexit_registered;
> @@ -295,9 +295,9 @@ void qemu_thread_exit(void *arg)
>      notifier_list_notify(&data->exit, NULL);
>      if (data->mode == QEMU_THREAD_JOINABLE) {
>          data->ret = arg;
> -        EnterCriticalSection(&data->cs);
> +        AcquireSRWLockExclusive(&data->lock);
>          data->exited = true;
> -        LeaveCriticalSection(&data->cs);
> +        ReleaseSRWLockExclusive(&data->lock);
>      } else {
>          g_free(data);
>      }
> @@ -328,7 +328,6 @@ void *qemu_thread_join(QemuThread *thread)
>          CloseHandle(handle);
>      }
>      ret = data->ret;
> -    DeleteCriticalSection(&data->cs);
>      g_free(data);
>      return ret;
>  }
> @@ -357,6 +356,7 @@ void qemu_thread_create(QemuThread *thread, const char
> *name,
>      struct QemuThreadData *data;
>
>      data = g_malloc(sizeof *data);
> +    InitializeSRWLock(&data->lock);
>      data->start_routine = start_routine;
>      data->arg = arg;
>      data->mode = mode;
> @@ -364,10 +364,6 @@ void qemu_thread_create(QemuThread *thread, const
> char *name,
>      data->name = g_strdup(name);
>      notifier_list_init(&data->exit);
>
> -    if (data->mode != QEMU_THREAD_DETACHED) {
> -        InitializeCriticalSection(&data->cs);
> -    }
> -
>      hThread = (HANDLE) _beginthreadex(NULL, 0, win32_start_routine,
>                                        data, 0, &thread->tid);
>      if (!hThread) {
> @@ -406,14 +402,14 @@ HANDLE qemu_thread_get_handle(QemuThread *thread)
>          return NULL;
>      }
>
> -    EnterCriticalSection(&data->cs);
> +    AcquireSRWLockExclusive(&data->lock);
>      if (!data->exited) {
>          handle = OpenThread(SYNCHRONIZE | THREAD_SUSPEND_RESUME |
>                              THREAD_SET_CONTEXT, FALSE, thread->tid);
>      } else {
>          handle = NULL;
>      }
> -    LeaveCriticalSection(&data->cs);
> +    ReleaseSRWLockExclusive(&data->lock);
>      return handle;
>  }
>
> --
> 2.53.0
>
>