Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
fba184a0
Commit
fba184a0
authored
Sep 10, 2012
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rwlock: reduce footprint and factor Win32 and OS/2 back-ends
parent
4cd019b1
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
118 additions
and
152 deletions
+118
-152
include/vlc_threads.h
include/vlc_threads.h
+12
-23
src/Makefile.am
src/Makefile.am
+2
-0
src/misc/rwlock.h
src/misc/rwlock.h
+99
-0
src/os2/thread.c
src/os2/thread.c
+1
-74
src/win32/thread.c
src/win32/thread.c
+4
-55
No files found.
include/vlc_threads.h
View file @
fba184a0
...
...
@@ -159,17 +159,7 @@ typedef struct
#define VLC_STATIC_COND { 0, 0 }
typedef
HANDLE
vlc_sem_t
;
typedef
struct
{
vlc_mutex_t
mutex
;
vlc_cond_t
wait
;
unsigned
long
readers
;
DWORD
writer
;
}
vlc_rwlock_t
;
#define VLC_STATIC_RWLOCK \
{ VLC_STATIC_MUTEX, VLC_STATIC_COND, 0, 0 }
typedef
struct
vlc_rwlock
vlc_rwlock_t
;
typedef
struct
vlc_threadvar
*
vlc_threadvar_t
;
typedef
struct
vlc_timer
*
vlc_timer_t
;
...
...
@@ -189,7 +179,6 @@ typedef struct
HMTX
hmtx
;
}
;
}
vlc_mutex_t
;
#define VLC_STATIC_MUTEX { false, { { false, 0 } } }
typedef
struct
...
...
@@ -197,7 +186,6 @@ typedef struct
HEV
hev
;
unsigned
clock
;
}
vlc_cond_t
;
#define VLC_STATIC_COND { 0, 0 }
typedef
struct
...
...
@@ -208,21 +196,22 @@ typedef struct
int
count
;
}
vlc_sem_t
;
typedef
struct
{
vlc_mutex_t
mutex
;
vlc_cond_t
wait
;
unsigned
long
readers
;
int
writer
;
}
vlc_rwlock_t
;
#define VLC_STATIC_RWLOCK \
{ VLC_STATIC_MUTEX, VLC_STATIC_COND, 0, 0 }
typedef
struct
vlc_rwlock
vlc_rwlock_t
;
typedef
struct
vlc_threadvar
*
vlc_threadvar_t
;
typedef
struct
vlc_timer
*
vlc_timer_t
;
#endif
#ifndef VLC_STATIC_RWLOCK
struct
vlc_rwlock
{
vlc_mutex_t
mutex
;
vlc_cond_t
wait
;
long
state
;
};
# define VLC_STATIC_RWLOCK { VLC_STATIC_MUTEX, VLC_STATIC_COND, 0 }
#endif
#if defined( WIN32 ) && !defined ETIMEDOUT
# define ETIMEDOUT 10060
/* This is the value in winsock.h. */
#endif
...
...
src/Makefile.am
View file @
fba184a0
...
...
@@ -269,6 +269,7 @@ SOURCES_libvlc_win32 = \
win32/dirs.c
\
win32/filesystem.c
\
win32/plugin.c
\
misc/rwlock.h
\
win32/thread.c
\
win32/specific.c
\
win32/winsock.c
\
...
...
@@ -287,6 +288,7 @@ SOURCES_libvlc_os2 = \
os2/dirs.c
\
os2/filesystem.c
\
os2/plugin.c
\
misc/rwlock.h
\
os2/thread.c
\
os2/specific.c
\
os2/rand.c
\
...
...
src/misc/rwlock.h
0 → 100644
View file @
fba184a0
/*****************************************************************************
* rwlock.h : generic back-end for LibVLC read/write locks
*****************************************************************************
* Copyright (C) 2009-2012 Rémi Denis-Courmont
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <limits.h>
#include <assert.h>
#include <vlc_common.h>
/* NOTE:
* lock->state is a signed long integer:
* - The sign bit is set when the lock is held for writing.
* - The other bits code the number of times the lock is held for reading.
* Consequently:
* - The value is negative if and only if the lock is held for writing.
* - The value is zero if and only if the lock is not held at all.
*/
#define READER_MASK LONG_MAX
#define WRITER_BIT LONG_MIN
void
vlc_rwlock_init
(
vlc_rwlock_t
*
lock
)
{
vlc_mutex_init
(
&
lock
->
mutex
);
vlc_cond_init
(
&
lock
->
wait
);
lock
->
state
=
0
;
}
void
vlc_rwlock_destroy
(
vlc_rwlock_t
*
lock
)
{
vlc_cond_destroy
(
&
lock
->
wait
);
vlc_mutex_destroy
(
&
lock
->
mutex
);
}
void
vlc_rwlock_rdlock
(
vlc_rwlock_t
*
lock
)
{
vlc_mutex_lock
(
&
lock
->
mutex
);
/* Recursive read-locking is allowed.
* Ensure that there is no active writer. */
while
(
lock
->
state
<
0
)
{
assert
(
lock
->
state
==
WRITER_BIT
);
vlc_cond_wait
(
&
lock
->
wait
,
&
lock
->
mutex
);
}
if
(
unlikely
(
lock
->
state
>=
READER_MASK
))
abort
();
/* An overflow is certainly a recursion bug. */
lock
->
state
++
;
vlc_mutex_unlock
(
&
lock
->
mutex
);
}
void
vlc_rwlock_wrlock
(
vlc_rwlock_t
*
lock
)
{
vlc_mutex_lock
(
&
lock
->
mutex
);
/* Wait until nobody owns the lock in any way. */
while
(
lock
->
state
!=
0
)
vlc_cond_wait
(
&
lock
->
wait
,
&
lock
->
mutex
);
lock
->
state
=
WRITER_BIT
;
vlc_mutex_unlock
(
&
lock
->
mutex
);
}
void
vlc_rwlock_unlock
(
vlc_rwlock_t
*
lock
)
{
vlc_mutex_lock
(
&
lock
->
mutex
);
if
(
lock
->
state
<
0
)
{
/* Write unlock */
assert
(
lock
->
state
==
WRITER_BIT
);
/* Let reader and writer compete. OS scheduler decides who wins. */
lock
->
state
=
0
;
vlc_cond_broadcast
(
&
lock
->
wait
);
}
else
{
/* Read unlock */
assert
(
lock
->
state
>
0
);
/* If there are no readers left, wake up one pending writer. */
if
(
--
lock
->
state
==
0
)
vlc_cond_signal
(
&
lock
->
wait
);
}
vlc_mutex_unlock
(
&
lock
->
mutex
);
}
src/os2/thread.c
View file @
fba184a0
...
...
@@ -428,80 +428,7 @@ void vlc_sem_wait (vlc_sem_t *sem)
}
while
(
rc
==
ERROR_INTERRUPT
);
}
/*** Read/write locks */
void
vlc_rwlock_init
(
vlc_rwlock_t
*
lock
)
{
vlc_mutex_init
(
&
lock
->
mutex
);
vlc_cond_init
(
&
lock
->
wait
);
lock
->
readers
=
0
;
/* active readers */
lock
->
writer
=
0
;
/* ID of active writer */
}
void
vlc_rwlock_destroy
(
vlc_rwlock_t
*
lock
)
{
vlc_cond_destroy
(
&
lock
->
wait
);
vlc_mutex_destroy
(
&
lock
->
mutex
);
}
void
vlc_rwlock_rdlock
(
vlc_rwlock_t
*
lock
)
{
vlc_mutex_lock
(
&
lock
->
mutex
);
/* Recursive read-locking is allowed. */
while
(
lock
->
writer
!=
0
)
{
assert
(
lock
->
readers
==
0
);
vlc_cond_wait
(
&
lock
->
wait
,
&
lock
->
mutex
);
}
if
(
unlikely
(
lock
->
readers
==
ULONG_MAX
))
abort
();
lock
->
readers
++
;
vlc_mutex_unlock
(
&
lock
->
mutex
);
}
static
void
vlc_rwlock_rdunlock
(
vlc_rwlock_t
*
lock
)
{
vlc_mutex_lock
(
&
lock
->
mutex
);
assert
(
lock
->
readers
>
0
);
/* If there are no readers left, wake up a writer. */
if
(
--
lock
->
readers
==
0
)
vlc_cond_signal
(
&
lock
->
wait
);
vlc_mutex_unlock
(
&
lock
->
mutex
);
}
void
vlc_rwlock_wrlock
(
vlc_rwlock_t
*
lock
)
{
vlc_mutex_lock
(
&
lock
->
mutex
);
/* Wait until nobody owns the lock in either way. */
while
((
lock
->
readers
>
0
)
||
(
lock
->
writer
!=
0
))
vlc_cond_wait
(
&
lock
->
wait
,
&
lock
->
mutex
);
assert
(
lock
->
writer
==
0
);
lock
->
writer
=
_gettid
();
vlc_mutex_unlock
(
&
lock
->
mutex
);
}
static
void
vlc_rwlock_wrunlock
(
vlc_rwlock_t
*
lock
)
{
vlc_mutex_lock
(
&
lock
->
mutex
);
assert
(
lock
->
writer
==
_gettid
());
assert
(
lock
->
readers
==
0
);
lock
->
writer
=
0
;
/* Write unlock */
/* Let reader and writer compete. Scheduler decides who wins. */
vlc_cond_broadcast
(
&
lock
->
wait
);
vlc_mutex_unlock
(
&
lock
->
mutex
);
}
void
vlc_rwlock_unlock
(
vlc_rwlock_t
*
lock
)
{
/* Note: If the lock is held for reading, lock->writer is nul.
* If the lock is held for writing, only this thread can store a value to
* lock->writer. Either way, lock->writer is safe to fetch here. */
if
(
lock
->
writer
!=
0
)
vlc_rwlock_wrunlock
(
lock
);
else
vlc_rwlock_rdunlock
(
lock
);
}
#include "misc/rwlock.h"
/*** Thread-specific variables (TLS) ***/
struct
vlc_threadvar
...
...
src/win32/thread.c
View file @
fba184a0
...
...
@@ -303,81 +303,30 @@ void vlc_sem_wait (vlc_sem_t *sem)
}
/*** Read/write locks */
#if 0
/* SRW (Slim Read Write) locks are available in Vista+ only */
void vlc_rwlock_init (vlc_rwlock_t *lock)
{
vlc_mutex_init
(
&
lock
->
mutex
);
vlc_cond_init
(
&
lock
->
wait
);
lock
->
readers
=
0
;
/* active readers */
lock
->
writer
=
0
;
/* ID of active writer */
}
void vlc_rwlock_destroy (vlc_rwlock_t *lock)
{
vlc_cond_destroy
(
&
lock
->
wait
);
vlc_mutex_destroy
(
&
lock
->
mutex
);
}
void vlc_rwlock_rdlock (vlc_rwlock_t *lock)
{
vlc_mutex_lock
(
&
lock
->
mutex
);
/* Recursive read-locking is allowed. We only need to ensure that there is
* no active writer. */
while
(
lock
->
writer
!=
0
)
{
assert
(
lock
->
readers
==
0
);
vlc_cond_wait
(
&
lock
->
wait
,
&
lock
->
mutex
);
}
if
(
unlikely
(
lock
->
readers
==
ULONG_MAX
))
abort
();
lock
->
readers
++
;
vlc_mutex_unlock
(
&
lock
->
mutex
);
}
static
void
vlc_rwlock_rdunlock
(
vlc_rwlock_t
*
lock
)
{
vlc_mutex_lock
(
&
lock
->
mutex
);
assert
(
lock
->
readers
>
0
);
/* If there are no readers left, wake up a writer. */
if
(
--
lock
->
readers
==
0
)
vlc_cond_signal
(
&
lock
->
wait
);
vlc_mutex_unlock
(
&
lock
->
mutex
);
}
void vlc_rwlock_wrlock (vlc_rwlock_t *lock)
{
vlc_mutex_lock
(
&
lock
->
mutex
);
/* Wait until nobody owns the lock in either way. */
while
((
lock
->
readers
>
0
)
||
(
lock
->
writer
!=
0
))
vlc_cond_wait
(
&
lock
->
wait
,
&
lock
->
mutex
);
assert
(
lock
->
writer
==
0
);
lock
->
writer
=
GetCurrentThreadId
();
vlc_mutex_unlock
(
&
lock
->
mutex
);
}
static
void
vlc_rwlock_wrunlock
(
vlc_rwlock_t
*
lock
)
{
vlc_mutex_lock
(
&
lock
->
mutex
);
assert
(
lock
->
writer
==
GetCurrentThreadId
());
assert
(
lock
->
readers
==
0
);
lock
->
writer
=
0
;
/* Write unlock */
/* Let reader and writer compete. Scheduler decides who wins. */
vlc_cond_broadcast
(
&
lock
->
wait
);
vlc_mutex_unlock
(
&
lock
->
mutex
);
}
void vlc_rwlock_unlock (vlc_rwlock_t *lock)
{
/* Note: If the lock is held for reading, lock->writer is nul.
* If the lock is held for writing, only this thread can store a value to
* lock->writer. Either way, lock->writer is safe to fetch here. */
if
(
lock
->
writer
!=
0
)
vlc_rwlock_wrunlock
(
lock
);
else
vlc_rwlock_rdunlock
(
lock
);
}
#else
# include "misc/rwlock.h"
#endif
/*** Thread-specific variables (TLS) ***/
struct
vlc_threadvar
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment