[vlc-commits] [Git][videolan/vlc][master] 4 commits: win32: only use the TLS list when needed
Steve Lhomme (@robUx4)
gitlab at videolan.org
Sat Oct 16 07:21:23 UTC 2021
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
d34f0d64 by Rémi Denis-Courmont at 2021-10-16T07:03:07+00:00
win32: only use the TLS list when needed
Old-style TLS keys only need to be in the list if they have a
per-thread destructor. If they don't, then don't put them in that list,
so iterating the list is faster.
- - - - -
6b1f004f by Rémi Denis-Courmont at 2021-10-16T07:03:07+00:00
os2: only use the TLS list when needed
Old-style TLS keys only need to be in the list if they have a
per-thread destructor. If they don't, then don't put them in that list,
so iterating the list is faster.
- - - - -
114812a3 by Rémi Denis-Courmont at 2021-10-16T07:03:07+00:00
win32: inline TLS accesses on exit
The VLC API "wastes" time preserving the thread's system error code.
There are no ways to consume those errors in the thread exit code, so
there is really no point in going out of our way here.
- - - - -
59d2debd by Rémi Denis-Courmont at 2021-10-16T07:03:07+00:00
win32: do not serialise thread exit
For historical reasons, the TLS cleanup was serialised on a critical
section. Now that there is a read/write lock, there are no reasons to
serialise exit. The thread exit process only reads the list head and
elements, does not modify the list per se; only vlc_threadvar_create()
and vlc_threadvar_delete() add and remove elements respectively.
This allows threads to exit in parallel.
- - - - -
2 changed files:
- src/os2/thread.c
- src/win32/thread.c
Changes:
=====================================
src/os2/thread.c
=====================================
@@ -167,13 +167,16 @@ int vlc_threadvar_create (vlc_threadvar_t *p_tls, void (*destr) (void *))
var->next = NULL;
*p_tls = var;
- vlc_mutex_lock (&super_mutex);
- var->prev = vlc_threadvar_last;
- if (var->prev)
- var->prev->next = var;
+ if (destr != NULL)
+ {
+ vlc_mutex_lock(&super_mutex);
+ var->prev = vlc_threadvar_last;
+ if (var->prev != NULL)
+ var->prev->next = var;
- vlc_threadvar_last = var;
- vlc_mutex_unlock (&super_mutex);
+ vlc_threadvar_last = var;
+ vlc_mutex_unlock(&super_mutex);
+ }
return 0;
}
@@ -181,17 +184,19 @@ void vlc_threadvar_delete (vlc_threadvar_t *p_tls)
{
struct vlc_threadvar *var = *p_tls;
- vlc_mutex_lock (&super_mutex);
- if (var->prev != NULL)
- var->prev->next = var->next;
-
- if (var->next != NULL)
- var->next->prev = var->prev;
- else
- vlc_threadvar_last = var->prev;
+ if (var->destr != NULL)
+ {
+ vlc_mutex_lock(&super_mutex);
+ if (var->prev != NULL)
+ var->prev->next = var->next;
- vlc_mutex_unlock (&super_mutex);
+ if (var->next != NULL)
+ var->next->prev = var->prev;
+ else
+ vlc_threadvar_last = var->prev;
+ vlc_mutex_unlock(&super_mutex);
+ }
DosFreeThreadLocalMemory( var->id );
free (var);
}
@@ -415,10 +420,11 @@ retry:
for (key = vlc_threadvar_last; key != NULL; key = key->prev)
{
void *value = vlc_threadvar_get (key);
- if (value != NULL && key->destroy != NULL)
+ if (value != NULL)
{
vlc_mutex_unlock (&super_mutex);
vlc_threadvar_set (key, NULL);
+ assert(key->destroy != NULL);
key->destroy (value);
goto retry;
}
=====================================
src/win32/thread.c
=====================================
@@ -94,13 +94,16 @@ int vlc_threadvar_create (vlc_threadvar_t *p_tls, void (*destr) (void *))
var->next = NULL;
*p_tls = var;
- AcquireSRWLockExclusive(&super_lock);
- var->prev = vlc_threadvar_last;
- if (var->prev)
- var->prev->next = var;
+ if (destr != NULL)
+ {
+ AcquireSRWLockExclusive(&super_lock);
+ var->prev = vlc_threadvar_last;
+ if (var->prev)
+ var->prev->next = var;
- vlc_threadvar_last = var;
- ReleaseSRWLockExclusive(&super_lock);
+ vlc_threadvar_last = var;
+ ReleaseSRWLockExclusive(&super_lock);
+ }
return 0;
}
@@ -108,17 +111,18 @@ void vlc_threadvar_delete (vlc_threadvar_t *p_tls)
{
struct vlc_threadvar *var = *p_tls;
- AcquireSRWLockExclusive(&super_lock);
- if (var->prev != NULL)
- var->prev->next = var->next;
-
- if (var->next != NULL)
- var->next->prev = var->prev;
- else
- vlc_threadvar_last = var->prev;
-
- ReleaseSRWLockExclusive(&super_lock);
+ if (var->destroy != NULL)
+ {
+ AcquireSRWLockExclusive(&super_lock);
+ if (var->prev != NULL)
+ var->prev->next = var->next;
+ if (var->next != NULL)
+ var->next->prev = var->prev;
+ else
+ vlc_threadvar_last = var->prev;
+ ReleaseSRWLockExclusive(&super_lock);
+ }
TlsFree (var->id);
free (var);
}
@@ -145,22 +149,23 @@ void *vlc_threadvar_get (vlc_threadvar_t key)
static void vlc_threadvars_cleanup(void)
{
- vlc_threadvar_t key;
+ const struct vlc_threadvar *key;
+
retry:
- /* TODO: use RW lock or something similar */
- AcquireSRWLockExclusive(&super_lock);
+ AcquireSRWLockShared(&super_lock);
for (key = vlc_threadvar_last; key != NULL; key = key->prev)
{
- void *value = vlc_threadvar_get(key);
- if (value != NULL && key->destroy != NULL)
+ void *value = TlsGetValue(key->id);
+ if (value != NULL)
{
- ReleaseSRWLockExclusive(&super_lock);
- vlc_threadvar_set(key, NULL);
+ ReleaseSRWLockShared(&super_lock);
+ TlsSetValue(key->id, NULL);
+ assert(key->destroy != NULL);
key->destroy(value);
goto retry;
}
}
- ReleaseSRWLockExclusive(&super_lock);
+ ReleaseSRWLockShared(&super_lock);
}
/*** Futeces^WAddress waits ***/
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/021d98336bb6d3cde4ff16c840cc5ec09bf8bc79...59d2debdba2a2ac437dab65357419c8b0bb840c6
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/021d98336bb6d3cde4ff16c840cc5ec09bf8bc79...59d2debdba2a2ac437dab65357419c8b0bb840c6
You're receiving this email because of your account on code.videolan.org.
More information about the vlc-commits
mailing list