[vlc-commits] win32: make thread killed flag atomic

Rémi Denis-Courmont git at videolan.org
Fri May 27 20:44:21 CEST 2016


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Fri May 27 21:38:51 2016 +0300| [f2f32ee7fa693490a6559dd632075586e451bc92] | committer: Rémi Denis-Courmont

win32: make thread killed flag atomic

Setting the flag in APC had the benefit of not needing atomicity, but
it meant the flag only got set at the next opportunity to run APC's.

Especially vlc_testcancel() is not an alertable function, so it would
typically be slower. If the thread did not go to alertable sleep, then
vlc_testcancel() would not work at all.

Since vlc_cancel() and vlc_testcancel() do not imply any memory
barriers, the loads and stores can be relaxed. That removes most if not
all of the overhead of the atomic operations.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=f2f32ee7fa693490a6559dd632075586e451bc92
---

 src/win32/thread.c |   23 +++--------------------
 1 file changed, 3 insertions(+), 20 deletions(-)

diff --git a/src/win32/thread.c b/src/win32/thread.c
index a2f2380..0f8ef5d 100644
--- a/src/win32/thread.c
+++ b/src/win32/thread.c
@@ -53,11 +53,7 @@ struct vlc_thread
     HANDLE         id;
 
     bool           killable;
-#if IS_INTERRUPTIBLE
-    bool           killed;
-#else
     atomic_bool    killed;
-#endif
     vlc_cleanup_t *cleaners;
 
     void        *(*entry) (void *);
@@ -478,11 +474,7 @@ static int vlc_clone_attr (vlc_thread_t *p_handle, bool detached,
     th->entry = entry;
     th->data = data;
     th->killable = false; /* not until vlc_entry() ! */
-#if IS_INTERRUPTIBLE
-    th->killed = false;
-#else
     atomic_init(&th->killed, false);
-#endif
     th->cleaners = NULL;
 
     /* When using the MSVCRT C library you have to use the _beginthreadex
@@ -565,19 +557,15 @@ int vlc_set_priority (vlc_thread_t th, int priority)
 /* APC procedure for thread cancellation */
 static void CALLBACK vlc_cancel_self (ULONG_PTR self)
 {
-    struct vlc_thread *th = (void *)self;
-
-    if (likely(th != NULL))
-        th->killed = true;
+    (void) self;
 }
 #endif
 
 void vlc_cancel (vlc_thread_t th)
 {
+    atomic_store_explicit(&th->killed, true, memory_order_relaxed);
 #if IS_INTERRUPTIBLE
     QueueUserAPC (vlc_cancel_self, th->id, (uintptr_t)th);
-#else
-    atomic_store (&th->killed, true);
 #endif
 }
 
@@ -611,13 +599,8 @@ void vlc_testcancel (void)
         return; /* Main thread - cannot be cancelled anyway */
     if (!th->killable)
         return;
-#if IS_INTERRUPTIBLE
-    if (likely(!th->killed))
-        return;
-#else
-    if (!atomic_load(&th->killed))
+    if (!atomic_load_explicit(&th->killed, memory_order_relaxed))
         return;
-#endif
 
     th->killable = true; /* Do not re-enter cancellation cleanup */
 



More information about the vlc-commits mailing list