Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
a9c215ce
Commit
a9c215ce
authored
Jan 26, 2017
by
Piotr Caban
Committed by
Alexandre Julliard
Jan 26, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msvcr100: Add reader_writer_lock implementation.
Signed-off-by:
Piotr Caban
<
piotr@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
245426c7
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
170 additions
and
7 deletions
+170
-7
lock.c
dlls/msvcrt/lock.c
+170
-7
No files found.
dlls/msvcrt/lock.c
View file @
a9c215ce
...
...
@@ -746,7 +746,17 @@ typedef struct
DEFINE_THISCALL_WRAPPER
(
reader_writer_lock_ctor
,
4
)
reader_writer_lock
*
__thiscall
reader_writer_lock_ctor
(
reader_writer_lock
*
this
)
{
FIXME
(
"(%p) stub
\n
"
,
this
);
TRACE
(
"(%p)
\n
"
,
this
);
if
(
!
keyed_event
)
{
HANDLE
event
;
NtCreateKeyedEvent
(
&
event
,
GENERIC_READ
|
GENERIC_WRITE
,
NULL
,
0
);
if
(
InterlockedCompareExchangePointer
(
&
keyed_event
,
event
,
NULL
)
!=
NULL
)
NtClose
(
event
);
}
memset
(
this
,
0
,
sizeof
(
*
this
));
return
this
;
}
...
...
@@ -755,7 +765,42 @@ reader_writer_lock* __thiscall reader_writer_lock_ctor(reader_writer_lock *this)
DEFINE_THISCALL_WRAPPER
(
reader_writer_lock_dtor
,
4
)
void
__thiscall
reader_writer_lock_dtor
(
reader_writer_lock
*
this
)
{
FIXME
(
"(%p) stub
\n
"
,
this
);
TRACE
(
"(%p)
\n
"
,
this
);
if
(
this
->
thread_id
!=
0
||
this
->
count
)
WARN
(
"destroying locked reader_writer_lock
\n
"
);
}
static
inline
void
spin_wait_for_next_rwl
(
rwl_queue
*
q
)
{
SpinWait
sw
;
if
(
q
->
next
)
return
;
SpinWait_ctor
(
&
sw
,
&
spin_wait_yield
);
SpinWait__Reset
(
&
sw
);
while
(
!
q
->
next
)
SpinWait__SpinOnce
(
&
sw
);
SpinWait_dtor
(
&
sw
);
}
/* Remove when proper InterlockedOr implementation is added to wine */
static
LONG
InterlockedOr
(
LONG
*
d
,
LONG
v
)
{
LONG
l
;
while
(
~
(
l
=
*
d
)
&
v
)
if
(
InterlockedCompareExchange
(
d
,
l
|
v
,
l
)
==
l
)
break
;
return
l
;
}
static
LONG
InterlockedAnd
(
LONG
*
d
,
LONG
v
)
{
LONG
l
=
*
d
,
old
;
while
((
l
&
v
)
!=
l
)
{
if
((
old
=
InterlockedCompareExchange
(
d
,
l
&
v
,
l
))
==
l
)
break
;
l
=
old
;
}
return
l
;
}
/* ?lock@reader_writer_lock@Concurrency@@QAEXXZ */
...
...
@@ -763,7 +808,30 @@ void __thiscall reader_writer_lock_dtor(reader_writer_lock *this)
DEFINE_THISCALL_WRAPPER
(
reader_writer_lock_lock
,
4
)
void
__thiscall
reader_writer_lock_lock
(
reader_writer_lock
*
this
)
{
FIXME
(
"(%p) stub
\n
"
,
this
);
rwl_queue
q
=
{
NULL
},
*
last
;
TRACE
(
"(%p)
\n
"
,
this
);
if
(
this
->
thread_id
==
GetCurrentThreadId
())
FIXME
(
"throw improper_lock exception
\n
"
);
last
=
InterlockedExchangePointer
((
void
**
)
&
this
->
writer_tail
,
&
q
);
if
(
last
)
{
last
->
next
=
&
q
;
NtWaitForKeyedEvent
(
keyed_event
,
&
q
,
0
,
NULL
);
}
else
{
this
->
writer_head
=
&
q
;
if
(
InterlockedOr
(
&
this
->
count
,
WRITER_WAITING
))
NtWaitForKeyedEvent
(
keyed_event
,
&
q
,
0
,
NULL
);
}
this
->
thread_id
=
GetCurrentThreadId
();
this
->
writer_head
=
&
this
->
active
;
this
->
active
.
next
=
NULL
;
if
(
InterlockedCompareExchangePointer
((
void
**
)
&
this
->
writer_tail
,
&
this
->
active
,
&
q
)
!=
&
q
)
{
spin_wait_for_next_rwl
(
&
q
);
this
->
active
.
next
=
q
.
next
;
}
}
/* ?lock_read@reader_writer_lock@Concurrency@@QAEXXZ */
...
...
@@ -771,7 +839,37 @@ void __thiscall reader_writer_lock_lock(reader_writer_lock *this)
DEFINE_THISCALL_WRAPPER
(
reader_writer_lock_lock_read
,
4
)
void
__thiscall
reader_writer_lock_lock_read
(
reader_writer_lock
*
this
)
{
FIXME
(
"(%p) stub
\n
"
,
this
);
rwl_queue
q
;
TRACE
(
"(%p)
\n
"
,
this
);
if
(
this
->
thread_id
==
GetCurrentThreadId
())
FIXME
(
"throw improper_lock exception
\n
"
);
do
{
q
.
next
=
this
->
reader_head
;
}
while
(
InterlockedCompareExchangePointer
((
void
**
)
&
this
->
reader_head
,
&
q
,
q
.
next
)
!=
q
.
next
);
if
(
!
q
.
next
)
{
rwl_queue
*
head
;
LONG
count
;
while
(
!
((
count
=
this
->
count
)
&
WRITER_WAITING
))
if
(
InterlockedCompareExchange
(
&
this
->
count
,
count
+
1
,
count
)
==
count
)
break
;
if
(
count
&
WRITER_WAITING
)
NtWaitForKeyedEvent
(
keyed_event
,
&
q
,
0
,
NULL
);
head
=
InterlockedExchangePointer
((
void
**
)
&
this
->
reader_head
,
NULL
);
while
(
head
&&
head
!=
&
q
)
{
rwl_queue
*
next
=
head
->
next
;
InterlockedIncrement
(
&
this
->
count
);
NtReleaseKeyedEvent
(
keyed_event
,
head
,
0
,
NULL
);
head
=
next
;
}
}
else
{
NtWaitForKeyedEvent
(
keyed_event
,
&
q
,
0
,
NULL
);
}
}
/* ?try_lock@reader_writer_lock@Concurrency@@QAE_NXZ */
...
...
@@ -779,7 +877,37 @@ void __thiscall reader_writer_lock_lock_read(reader_writer_lock *this)
DEFINE_THISCALL_WRAPPER
(
reader_writer_lock_try_lock
,
4
)
MSVCRT_bool
__thiscall
reader_writer_lock_try_lock
(
reader_writer_lock
*
this
)
{
FIXME
(
"(%p) stub
\n
"
,
this
);
rwl_queue
q
=
{
NULL
};
TRACE
(
"(%p)
\n
"
,
this
);
if
(
this
->
thread_id
==
GetCurrentThreadId
())
FIXME
(
"throw improper_lock exception
\n
"
);
if
(
InterlockedCompareExchangePointer
((
void
**
)
&
this
->
writer_tail
,
&
q
,
NULL
))
return
FALSE
;
this
->
writer_head
=
&
q
;
if
(
!
InterlockedCompareExchange
(
&
this
->
count
,
WRITER_WAITING
,
0
))
{
this
->
thread_id
=
GetCurrentThreadId
();
this
->
writer_head
=
&
this
->
active
;
this
->
active
.
next
=
NULL
;
if
(
InterlockedCompareExchangePointer
((
void
**
)
&
this
->
writer_tail
,
&
this
->
active
,
&
q
)
!=
&
q
)
{
spin_wait_for_next_rwl
(
&
q
);
this
->
active
.
next
=
q
.
next
;
}
return
TRUE
;
}
if
(
InterlockedCompareExchangePointer
((
void
**
)
&
this
->
writer_tail
,
NULL
,
&
q
)
==
&
q
)
return
FALSE
;
spin_wait_for_next_rwl
(
&
q
);
this
->
writer_head
=
q
.
next
;
if
(
!
InterlockedOr
(
&
this
->
count
,
WRITER_WAITING
))
{
this
->
thread_id
=
GetCurrentThreadId
();
this
->
writer_head
=
&
this
->
active
;
this
->
active
.
next
=
q
.
next
;
return
TRUE
;
}
return
FALSE
;
}
...
...
@@ -788,7 +916,12 @@ MSVCRT_bool __thiscall reader_writer_lock_try_lock(reader_writer_lock *this)
DEFINE_THISCALL_WRAPPER
(
reader_writer_lock_try_lock_read
,
4
)
MSVCRT_bool
__thiscall
reader_writer_lock_try_lock_read
(
reader_writer_lock
*
this
)
{
FIXME
(
"(%p) stub
\n
"
,
this
);
LONG
count
;
TRACE
(
"(%p)
\n
"
,
this
);
while
(
!
((
count
=
this
->
count
)
&
WRITER_WAITING
))
if
(
InterlockedCompareExchange
(
&
this
->
count
,
count
+
1
,
count
)
==
count
)
return
TRUE
;
return
FALSE
;
}
...
...
@@ -797,7 +930,37 @@ MSVCRT_bool __thiscall reader_writer_lock_try_lock_read(reader_writer_lock *this
DEFINE_THISCALL_WRAPPER
(
reader_writer_lock_unlock
,
4
)
void
__thiscall
reader_writer_lock_unlock
(
reader_writer_lock
*
this
)
{
FIXME
(
"(%p) stub
\n
"
,
this
);
LONG
count
;
rwl_queue
*
head
,
*
next
;
TRACE
(
"(%p)
\n
"
,
this
);
if
((
count
=
this
->
count
)
&
~
WRITER_WAITING
)
{
count
=
InterlockedDecrement
(
&
this
->
count
);
if
(
count
!=
WRITER_WAITING
)
return
;
NtReleaseKeyedEvent
(
keyed_event
,
this
->
writer_head
,
0
,
NULL
);
return
;
}
this
->
thread_id
=
0
;
next
=
this
->
writer_head
->
next
;
if
(
next
)
{
NtReleaseKeyedEvent
(
keyed_event
,
next
,
0
,
NULL
);
return
;
}
InterlockedAnd
(
&
this
->
count
,
~
WRITER_WAITING
);
head
=
InterlockedExchangePointer
((
void
**
)
&
this
->
reader_head
,
NULL
);
while
(
head
)
{
next
=
head
->
next
;
InterlockedIncrement
(
&
this
->
count
);
NtReleaseKeyedEvent
(
keyed_event
,
head
,
0
,
NULL
);
head
=
next
;
}
if
(
InterlockedCompareExchangePointer
((
void
**
)
&
this
->
writer_tail
,
NULL
,
this
->
writer_head
)
==
this
->
writer_head
)
return
;
InterlockedOr
(
&
this
->
count
,
WRITER_WAITING
);
}
#endif
...
...
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