Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
wine
Manage
Activity
Members
Labels
Plan
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
frmdstryr
wine
Commits
94d1bc52
Commit
94d1bc52
authored
9 months ago
by
Alexandre Julliard
Browse files
Options
Downloads
Patches
Plain Diff
ntdll: Move some synchronization Rtl functions to sync.c.
parent
88414d0c
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
dlls/ntdll/rtl.c
+0
-385
0 additions, 385 deletions
dlls/ntdll/rtl.c
dlls/ntdll/sync.c
+372
-0
372 additions, 0 deletions
dlls/ntdll/sync.c
with
372 additions
and
385 deletions
dlls/ntdll/rtl.c
+
0
−
385
View file @
94d1bc52
...
...
@@ -101,204 +101,6 @@ static const int hex_table[] = {
-
1
,
10
,
11
,
12
,
13
,
14
,
15
/* 0x60-0x66 */
};
/*
* resource functions
*/
/***********************************************************************
* RtlInitializeResource (NTDLL.@)
*
* xxxResource() functions implement multiple-reader-single-writer lock.
* The code is based on information published in WDJ January 1999 issue.
*/
void
WINAPI
RtlInitializeResource
(
LPRTL_RWLOCK
rwl
)
{
if
(
rwl
)
{
rwl
->
iNumberActive
=
0
;
rwl
->
uExclusiveWaiters
=
0
;
rwl
->
uSharedWaiters
=
0
;
rwl
->
hOwningThreadId
=
0
;
rwl
->
dwTimeoutBoost
=
0
;
/* no info on this one, default value is 0 */
RtlInitializeCriticalSectionEx
(
&
rwl
->
rtlCS
,
0
,
RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO
);
rwl
->
rtlCS
.
DebugInfo
->
Spare
[
0
]
=
(
DWORD_PTR
)(
__FILE__
": RTL_RWLOCK.rtlCS"
);
NtCreateSemaphore
(
&
rwl
->
hExclusiveReleaseSemaphore
,
SEMAPHORE_ALL_ACCESS
,
NULL
,
0
,
65535
);
NtCreateSemaphore
(
&
rwl
->
hSharedReleaseSemaphore
,
SEMAPHORE_ALL_ACCESS
,
NULL
,
0
,
65535
);
}
}
/***********************************************************************
* RtlDeleteResource (NTDLL.@)
*/
void
WINAPI
RtlDeleteResource
(
LPRTL_RWLOCK
rwl
)
{
if
(
rwl
)
{
RtlEnterCriticalSection
(
&
rwl
->
rtlCS
);
if
(
rwl
->
iNumberActive
||
rwl
->
uExclusiveWaiters
||
rwl
->
uSharedWaiters
)
ERR
(
"Deleting active MRSW lock (%p), expect failure
\n
"
,
rwl
);
rwl
->
hOwningThreadId
=
0
;
rwl
->
uExclusiveWaiters
=
rwl
->
uSharedWaiters
=
0
;
rwl
->
iNumberActive
=
0
;
NtClose
(
rwl
->
hExclusiveReleaseSemaphore
);
NtClose
(
rwl
->
hSharedReleaseSemaphore
);
RtlLeaveCriticalSection
(
&
rwl
->
rtlCS
);
rwl
->
rtlCS
.
DebugInfo
->
Spare
[
0
]
=
0
;
RtlDeleteCriticalSection
(
&
rwl
->
rtlCS
);
}
}
/***********************************************************************
* RtlAcquireResourceExclusive (NTDLL.@)
*/
BYTE
WINAPI
RtlAcquireResourceExclusive
(
LPRTL_RWLOCK
rwl
,
BYTE
fWait
)
{
BYTE
retVal
=
0
;
if
(
!
rwl
)
return
0
;
start:
RtlEnterCriticalSection
(
&
rwl
->
rtlCS
);
if
(
rwl
->
iNumberActive
==
0
)
/* lock is free */
{
rwl
->
iNumberActive
=
-
1
;
retVal
=
1
;
}
else
if
(
rwl
->
iNumberActive
<
0
)
/* exclusive lock in progress */
{
if
(
rwl
->
hOwningThreadId
==
ULongToHandle
(
GetCurrentThreadId
())
)
{
retVal
=
1
;
rwl
->
iNumberActive
--
;
goto
done
;
}
wait:
if
(
fWait
)
{
NTSTATUS
status
;
rwl
->
uExclusiveWaiters
++
;
RtlLeaveCriticalSection
(
&
rwl
->
rtlCS
);
status
=
NtWaitForSingleObject
(
rwl
->
hExclusiveReleaseSemaphore
,
FALSE
,
NULL
);
if
(
HIWORD
(
status
)
)
goto
done
;
goto
start
;
/* restart the acquisition to avoid deadlocks */
}
}
else
/* one or more shared locks are in progress */
if
(
fWait
)
goto
wait
;
if
(
retVal
==
1
)
rwl
->
hOwningThreadId
=
ULongToHandle
(
GetCurrentThreadId
());
done:
RtlLeaveCriticalSection
(
&
rwl
->
rtlCS
);
return
retVal
;
}
/***********************************************************************
* RtlAcquireResourceShared (NTDLL.@)
*/
BYTE
WINAPI
RtlAcquireResourceShared
(
LPRTL_RWLOCK
rwl
,
BYTE
fWait
)
{
NTSTATUS
status
=
STATUS_UNSUCCESSFUL
;
BYTE
retVal
=
0
;
if
(
!
rwl
)
return
0
;
start:
RtlEnterCriticalSection
(
&
rwl
->
rtlCS
);
if
(
rwl
->
iNumberActive
<
0
)
{
if
(
rwl
->
hOwningThreadId
==
ULongToHandle
(
GetCurrentThreadId
())
)
{
rwl
->
iNumberActive
--
;
retVal
=
1
;
goto
done
;
}
if
(
fWait
)
{
rwl
->
uSharedWaiters
++
;
RtlLeaveCriticalSection
(
&
rwl
->
rtlCS
);
status
=
NtWaitForSingleObject
(
rwl
->
hSharedReleaseSemaphore
,
FALSE
,
NULL
);
if
(
HIWORD
(
status
)
)
goto
done
;
goto
start
;
}
}
else
{
if
(
status
!=
STATUS_WAIT_0
)
/* otherwise RtlReleaseResource() has already done it */
rwl
->
iNumberActive
++
;
retVal
=
1
;
}
done:
RtlLeaveCriticalSection
(
&
rwl
->
rtlCS
);
return
retVal
;
}
/***********************************************************************
* RtlReleaseResource (NTDLL.@)
*/
void
WINAPI
RtlReleaseResource
(
LPRTL_RWLOCK
rwl
)
{
RtlEnterCriticalSection
(
&
rwl
->
rtlCS
);
if
(
rwl
->
iNumberActive
>
0
)
/* have one or more readers */
{
if
(
--
rwl
->
iNumberActive
==
0
)
{
if
(
rwl
->
uExclusiveWaiters
)
{
wake_exclusive:
rwl
->
uExclusiveWaiters
--
;
NtReleaseSemaphore
(
rwl
->
hExclusiveReleaseSemaphore
,
1
,
NULL
);
}
}
}
else
if
(
rwl
->
iNumberActive
<
0
)
/* have a writer, possibly recursive */
{
if
(
++
rwl
->
iNumberActive
==
0
)
{
rwl
->
hOwningThreadId
=
0
;
if
(
rwl
->
uExclusiveWaiters
)
goto
wake_exclusive
;
else
if
(
rwl
->
uSharedWaiters
)
{
UINT
n
=
rwl
->
uSharedWaiters
;
rwl
->
iNumberActive
=
rwl
->
uSharedWaiters
;
/* prevent new writers from joining until
* all queued readers have done their thing */
rwl
->
uSharedWaiters
=
0
;
NtReleaseSemaphore
(
rwl
->
hSharedReleaseSemaphore
,
n
,
NULL
);
}
}
}
RtlLeaveCriticalSection
(
&
rwl
->
rtlCS
);
}
/***********************************************************************
* RtlDumpResource (NTDLL.@)
*/
void
WINAPI
RtlDumpResource
(
LPRTL_RWLOCK
rwl
)
{
if
(
rwl
)
{
MESSAGE
(
"RtlDumpResource(%p):
\n\t
active count = %i
\n\t
waiting readers = %i
\n\t
waiting writers = %i
\n
"
,
rwl
,
rwl
->
iNumberActive
,
rwl
->
uSharedWaiters
,
rwl
->
uExclusiveWaiters
);
if
(
rwl
->
iNumberActive
)
MESSAGE
(
"
\t
owner thread = %p
\n
"
,
rwl
->
hOwningThreadId
);
}
}
/*
* misc functions
*/
static
LONG
WINAPI
debug_exception_handler
(
EXCEPTION_POINTERS
*
eptr
)
{
...
...
@@ -1429,193 +1231,6 @@ PVOID WINAPI RtlDecodePointer( PVOID ptr )
return
(
PVOID
)(
ptrval
^
get_pointer_obfuscator
());
}
/*************************************************************************
* RtlInitializeSListHead [NTDLL.@]
*/
VOID
WINAPI
RtlInitializeSListHead
(
PSLIST_HEADER
list
)
{
#ifdef _WIN64
list
->
Alignment
=
list
->
Region
=
0
;
list
->
Header16
.
HeaderType
=
1
;
/* we use the 16-byte header */
#else
list
->
Alignment
=
0
;
#endif
}
/*************************************************************************
* RtlQueryDepthSList [NTDLL.@]
*/
WORD
WINAPI
RtlQueryDepthSList
(
PSLIST_HEADER
list
)
{
#ifdef _WIN64
return
list
->
Header16
.
Depth
;
#else
return
list
->
Depth
;
#endif
}
/*************************************************************************
* RtlFirstEntrySList [NTDLL.@]
*/
PSLIST_ENTRY
WINAPI
RtlFirstEntrySList
(
const
SLIST_HEADER
*
list
)
{
#ifdef _WIN64
return
(
SLIST_ENTRY
*
)((
ULONG_PTR
)
list
->
Header16
.
NextEntry
<<
4
);
#else
return
list
->
Next
.
Next
;
#endif
}
/*************************************************************************
* RtlInterlockedFlushSList [NTDLL.@]
*/
PSLIST_ENTRY
WINAPI
RtlInterlockedFlushSList
(
PSLIST_HEADER
list
)
{
SLIST_HEADER
old
,
new
;
#ifdef _WIN64
if
(
!
list
->
Header16
.
NextEntry
)
return
NULL
;
new
.
Alignment
=
new
.
Region
=
0
;
new
.
Header16
.
HeaderType
=
1
;
/* we use the 16-byte header */
do
{
old
=
*
list
;
new
.
Header16
.
Sequence
=
old
.
Header16
.
Sequence
+
1
;
}
while
(
!
InterlockedCompareExchange128
((
__int64
*
)
list
,
new
.
Region
,
new
.
Alignment
,
(
__int64
*
)
&
old
));
return
(
SLIST_ENTRY
*
)((
ULONG_PTR
)
old
.
Header16
.
NextEntry
<<
4
);
#else
if
(
!
list
->
Next
.
Next
)
return
NULL
;
new
.
Alignment
=
0
;
do
{
old
=
*
list
;
new
.
Sequence
=
old
.
Sequence
+
1
;
}
while
(
InterlockedCompareExchange64
((
__int64
*
)
&
list
->
Alignment
,
new
.
Alignment
,
old
.
Alignment
)
!=
old
.
Alignment
);
return
old
.
Next
.
Next
;
#endif
}
/*************************************************************************
* RtlInterlockedPushEntrySList [NTDLL.@]
*/
PSLIST_ENTRY
WINAPI
RtlInterlockedPushEntrySList
(
PSLIST_HEADER
list
,
PSLIST_ENTRY
entry
)
{
SLIST_HEADER
old
,
new
;
#ifdef _WIN64
new
.
Header16
.
NextEntry
=
(
ULONG_PTR
)
entry
>>
4
;
do
{
old
=
*
list
;
entry
->
Next
=
(
SLIST_ENTRY
*
)((
ULONG_PTR
)
old
.
Header16
.
NextEntry
<<
4
);
new
.
Header16
.
Depth
=
old
.
Header16
.
Depth
+
1
;
new
.
Header16
.
Sequence
=
old
.
Header16
.
Sequence
+
1
;
}
while
(
!
InterlockedCompareExchange128
((
__int64
*
)
list
,
new
.
Region
,
new
.
Alignment
,
(
__int64
*
)
&
old
));
return
(
SLIST_ENTRY
*
)((
ULONG_PTR
)
old
.
Header16
.
NextEntry
<<
4
);
#else
new
.
Next
.
Next
=
entry
;
do
{
old
=
*
list
;
entry
->
Next
=
old
.
Next
.
Next
;
new
.
Depth
=
old
.
Depth
+
1
;
new
.
Sequence
=
old
.
Sequence
+
1
;
}
while
(
InterlockedCompareExchange64
((
__int64
*
)
&
list
->
Alignment
,
new
.
Alignment
,
old
.
Alignment
)
!=
old
.
Alignment
);
return
old
.
Next
.
Next
;
#endif
}
/*************************************************************************
* RtlInterlockedPopEntrySList [NTDLL.@]
*/
PSLIST_ENTRY
WINAPI
RtlInterlockedPopEntrySList
(
PSLIST_HEADER
list
)
{
SLIST_HEADER
old
,
new
;
PSLIST_ENTRY
entry
;
#ifdef _WIN64
do
{
old
=
*
list
;
if
(
!
(
entry
=
(
SLIST_ENTRY
*
)((
ULONG_PTR
)
old
.
Header16
.
NextEntry
<<
4
)))
return
NULL
;
/* entry could be deleted by another thread */
__TRY
{
new
.
Header16
.
NextEntry
=
(
ULONG_PTR
)
entry
->
Next
>>
4
;
new
.
Header16
.
Depth
=
old
.
Header16
.
Depth
-
1
;
new
.
Header16
.
Sequence
=
old
.
Header16
.
Sequence
+
1
;
}
__EXCEPT_PAGE_FAULT
{
}
__ENDTRY
}
while
(
!
InterlockedCompareExchange128
((
__int64
*
)
list
,
new
.
Region
,
new
.
Alignment
,
(
__int64
*
)
&
old
));
#else
do
{
old
=
*
list
;
if
(
!
(
entry
=
old
.
Next
.
Next
))
return
NULL
;
/* entry could be deleted by another thread */
__TRY
{
new
.
Next
.
Next
=
entry
->
Next
;
new
.
Depth
=
old
.
Depth
-
1
;
new
.
Sequence
=
old
.
Sequence
+
1
;
}
__EXCEPT_PAGE_FAULT
{
}
__ENDTRY
}
while
(
InterlockedCompareExchange64
((
__int64
*
)
&
list
->
Alignment
,
new
.
Alignment
,
old
.
Alignment
)
!=
old
.
Alignment
);
#endif
return
entry
;
}
/*************************************************************************
* RtlInterlockedPushListSListEx [NTDLL.@]
*/
PSLIST_ENTRY
WINAPI
RtlInterlockedPushListSListEx
(
PSLIST_HEADER
list
,
PSLIST_ENTRY
first
,
PSLIST_ENTRY
last
,
ULONG
count
)
{
SLIST_HEADER
old
,
new
;
#ifdef _WIN64
new
.
Header16
.
NextEntry
=
(
ULONG_PTR
)
first
>>
4
;
do
{
old
=
*
list
;
new
.
Header16
.
Depth
=
old
.
Header16
.
Depth
+
count
;
new
.
Header16
.
Sequence
=
old
.
Header16
.
Sequence
+
1
;
last
->
Next
=
(
SLIST_ENTRY
*
)((
ULONG_PTR
)
old
.
Header16
.
NextEntry
<<
4
);
}
while
(
!
InterlockedCompareExchange128
((
__int64
*
)
list
,
new
.
Region
,
new
.
Alignment
,
(
__int64
*
)
&
old
));
return
(
SLIST_ENTRY
*
)((
ULONG_PTR
)
old
.
Header16
.
NextEntry
<<
4
);
#else
new
.
Next
.
Next
=
first
;
do
{
old
=
*
list
;
new
.
Depth
=
old
.
Depth
+
count
;
new
.
Sequence
=
old
.
Sequence
+
1
;
last
->
Next
=
old
.
Next
.
Next
;
}
while
(
InterlockedCompareExchange64
((
__int64
*
)
&
list
->
Alignment
,
new
.
Alignment
,
old
.
Alignment
)
!=
old
.
Alignment
);
return
old
.
Next
.
Next
;
#endif
}
/*************************************************************************
* RtlInterlockedPushListSList [NTDLL.@]
*/
DEFINE_FASTCALL_WRAPPER
(
RtlInterlockedPushListSList
,
16
)
PSLIST_ENTRY
FASTCALL
RtlInterlockedPushListSList
(
PSLIST_HEADER
list
,
PSLIST_ENTRY
first
,
PSLIST_ENTRY
last
,
ULONG
count
)
{
return
RtlInterlockedPushListSListEx
(
list
,
first
,
last
,
count
);
}
/******************************************************************************
* RtlGetCompressionWorkSpaceSize [NTDLL.@]
*/
...
...
This diff is collapsed.
Click to expand it.
dlls/ntdll/sync.c
+
372
−
0
View file @
94d1bc52
...
...
@@ -34,6 +34,7 @@
#include
"winternl.h"
#include
"wine/debug.h"
#include
"wine/list.h"
#include
"wine/exception.h"
#include
"ntdll_misc.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
sync
);
...
...
@@ -999,3 +1000,374 @@ void WINAPI RtlWakeAddressSingle( const void *addr )
if
(
tid
)
NtAlertThreadByThreadId
(
(
HANDLE
)(
DWORD_PTR
)
tid
);
}
/*************************************************************************
* RtlInitializeSListHead (NTDLL.@)
*/
void
WINAPI
RtlInitializeSListHead
(
PSLIST_HEADER
list
)
{
#ifdef _WIN64
list
->
Alignment
=
list
->
Region
=
0
;
list
->
Header16
.
HeaderType
=
1
;
/* we use the 16-byte header */
#else
list
->
Alignment
=
0
;
#endif
}
/*************************************************************************
* RtlQueryDepthSList (NTDLL.@)
*/
WORD
WINAPI
RtlQueryDepthSList
(
PSLIST_HEADER
list
)
{
#ifdef _WIN64
return
list
->
Header16
.
Depth
;
#else
return
list
->
Depth
;
#endif
}
/*************************************************************************
* RtlFirstEntrySList (NTDLL.@)
*/
PSLIST_ENTRY
WINAPI
RtlFirstEntrySList
(
const
SLIST_HEADER
*
list
)
{
#ifdef _WIN64
return
(
SLIST_ENTRY
*
)((
ULONG_PTR
)
list
->
Header16
.
NextEntry
<<
4
);
#else
return
list
->
Next
.
Next
;
#endif
}
/*************************************************************************
* RtlInterlockedFlushSList (NTDLL.@)
*/
PSLIST_ENTRY
WINAPI
RtlInterlockedFlushSList
(
PSLIST_HEADER
list
)
{
SLIST_HEADER
old
,
new
;
#ifdef _WIN64
if
(
!
list
->
Header16
.
NextEntry
)
return
NULL
;
new
.
Alignment
=
new
.
Region
=
0
;
new
.
Header16
.
HeaderType
=
1
;
/* we use the 16-byte header */
do
{
old
=
*
list
;
new
.
Header16
.
Sequence
=
old
.
Header16
.
Sequence
+
1
;
}
while
(
!
InterlockedCompareExchange128
((
__int64
*
)
list
,
new
.
Region
,
new
.
Alignment
,
(
__int64
*
)
&
old
));
return
(
SLIST_ENTRY
*
)((
ULONG_PTR
)
old
.
Header16
.
NextEntry
<<
4
);
#else
if
(
!
list
->
Next
.
Next
)
return
NULL
;
new
.
Alignment
=
0
;
do
{
old
=
*
list
;
new
.
Sequence
=
old
.
Sequence
+
1
;
}
while
(
InterlockedCompareExchange64
((
__int64
*
)
&
list
->
Alignment
,
new
.
Alignment
,
old
.
Alignment
)
!=
old
.
Alignment
);
return
old
.
Next
.
Next
;
#endif
}
/*************************************************************************
* RtlInterlockedPushEntrySList (NTDLL.@)
*/
PSLIST_ENTRY
WINAPI
RtlInterlockedPushEntrySList
(
PSLIST_HEADER
list
,
PSLIST_ENTRY
entry
)
{
SLIST_HEADER
old
,
new
;
#ifdef _WIN64
new
.
Header16
.
NextEntry
=
(
ULONG_PTR
)
entry
>>
4
;
do
{
old
=
*
list
;
entry
->
Next
=
(
SLIST_ENTRY
*
)((
ULONG_PTR
)
old
.
Header16
.
NextEntry
<<
4
);
new
.
Header16
.
Depth
=
old
.
Header16
.
Depth
+
1
;
new
.
Header16
.
Sequence
=
old
.
Header16
.
Sequence
+
1
;
}
while
(
!
InterlockedCompareExchange128
((
__int64
*
)
list
,
new
.
Region
,
new
.
Alignment
,
(
__int64
*
)
&
old
));
return
(
SLIST_ENTRY
*
)((
ULONG_PTR
)
old
.
Header16
.
NextEntry
<<
4
);
#else
new
.
Next
.
Next
=
entry
;
do
{
old
=
*
list
;
entry
->
Next
=
old
.
Next
.
Next
;
new
.
Depth
=
old
.
Depth
+
1
;
new
.
Sequence
=
old
.
Sequence
+
1
;
}
while
(
InterlockedCompareExchange64
((
__int64
*
)
&
list
->
Alignment
,
new
.
Alignment
,
old
.
Alignment
)
!=
old
.
Alignment
);
return
old
.
Next
.
Next
;
#endif
}
/*************************************************************************
* RtlInterlockedPopEntrySList (NTDLL.@)
*/
PSLIST_ENTRY
WINAPI
RtlInterlockedPopEntrySList
(
PSLIST_HEADER
list
)
{
SLIST_HEADER
old
,
new
;
PSLIST_ENTRY
entry
;
#ifdef _WIN64
do
{
old
=
*
list
;
if
(
!
(
entry
=
(
SLIST_ENTRY
*
)((
ULONG_PTR
)
old
.
Header16
.
NextEntry
<<
4
)))
return
NULL
;
/* entry could be deleted by another thread */
__TRY
{
new
.
Header16
.
NextEntry
=
(
ULONG_PTR
)
entry
->
Next
>>
4
;
new
.
Header16
.
Depth
=
old
.
Header16
.
Depth
-
1
;
new
.
Header16
.
Sequence
=
old
.
Header16
.
Sequence
+
1
;
}
__EXCEPT_PAGE_FAULT
{
}
__ENDTRY
}
while
(
!
InterlockedCompareExchange128
((
__int64
*
)
list
,
new
.
Region
,
new
.
Alignment
,
(
__int64
*
)
&
old
));
#else
do
{
old
=
*
list
;
if
(
!
(
entry
=
old
.
Next
.
Next
))
return
NULL
;
/* entry could be deleted by another thread */
__TRY
{
new
.
Next
.
Next
=
entry
->
Next
;
new
.
Depth
=
old
.
Depth
-
1
;
new
.
Sequence
=
old
.
Sequence
+
1
;
}
__EXCEPT_PAGE_FAULT
{
}
__ENDTRY
}
while
(
InterlockedCompareExchange64
((
__int64
*
)
&
list
->
Alignment
,
new
.
Alignment
,
old
.
Alignment
)
!=
old
.
Alignment
);
#endif
return
entry
;
}
/*************************************************************************
* RtlInterlockedPushListSListEx (NTDLL.@)
*/
PSLIST_ENTRY
WINAPI
RtlInterlockedPushListSListEx
(
PSLIST_HEADER
list
,
PSLIST_ENTRY
first
,
PSLIST_ENTRY
last
,
ULONG
count
)
{
SLIST_HEADER
old
,
new
;
#ifdef _WIN64
new
.
Header16
.
NextEntry
=
(
ULONG_PTR
)
first
>>
4
;
do
{
old
=
*
list
;
new
.
Header16
.
Depth
=
old
.
Header16
.
Depth
+
count
;
new
.
Header16
.
Sequence
=
old
.
Header16
.
Sequence
+
1
;
last
->
Next
=
(
SLIST_ENTRY
*
)((
ULONG_PTR
)
old
.
Header16
.
NextEntry
<<
4
);
}
while
(
!
InterlockedCompareExchange128
((
__int64
*
)
list
,
new
.
Region
,
new
.
Alignment
,
(
__int64
*
)
&
old
));
return
(
SLIST_ENTRY
*
)((
ULONG_PTR
)
old
.
Header16
.
NextEntry
<<
4
);
#else
new
.
Next
.
Next
=
first
;
do
{
old
=
*
list
;
new
.
Depth
=
old
.
Depth
+
count
;
new
.
Sequence
=
old
.
Sequence
+
1
;
last
->
Next
=
old
.
Next
.
Next
;
}
while
(
InterlockedCompareExchange64
((
__int64
*
)
&
list
->
Alignment
,
new
.
Alignment
,
old
.
Alignment
)
!=
old
.
Alignment
);
return
old
.
Next
.
Next
;
#endif
}
/*************************************************************************
* RtlInterlockedPushListSList (NTDLL.@)
*/
DEFINE_FASTCALL_WRAPPER
(
RtlInterlockedPushListSList
,
16
)
PSLIST_ENTRY
FASTCALL
RtlInterlockedPushListSList
(
PSLIST_HEADER
list
,
PSLIST_ENTRY
first
,
PSLIST_ENTRY
last
,
ULONG
count
)
{
return
RtlInterlockedPushListSListEx
(
list
,
first
,
last
,
count
);
}
/***********************************************************************
* RtlInitializeResource (NTDLL.@)
*
* xxxResource() functions implement multiple-reader-single-writer lock.
* The code is based on information published in WDJ January 1999 issue.
*/
void
WINAPI
RtlInitializeResource
(
LPRTL_RWLOCK
rwl
)
{
if
(
!
rwl
)
return
;
rwl
->
iNumberActive
=
0
;
rwl
->
uExclusiveWaiters
=
0
;
rwl
->
uSharedWaiters
=
0
;
rwl
->
hOwningThreadId
=
0
;
rwl
->
dwTimeoutBoost
=
0
;
/* no info on this one, default value is 0 */
RtlInitializeCriticalSectionEx
(
&
rwl
->
rtlCS
,
0
,
RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO
);
rwl
->
rtlCS
.
DebugInfo
->
Spare
[
0
]
=
(
DWORD_PTR
)(
__FILE__
": RTL_RWLOCK.rtlCS"
);
NtCreateSemaphore
(
&
rwl
->
hExclusiveReleaseSemaphore
,
SEMAPHORE_ALL_ACCESS
,
NULL
,
0
,
65535
);
NtCreateSemaphore
(
&
rwl
->
hSharedReleaseSemaphore
,
SEMAPHORE_ALL_ACCESS
,
NULL
,
0
,
65535
);
}
/***********************************************************************
* RtlDeleteResource (NTDLL.@)
*/
void
WINAPI
RtlDeleteResource
(
LPRTL_RWLOCK
rwl
)
{
if
(
!
rwl
)
return
;
RtlEnterCriticalSection
(
&
rwl
->
rtlCS
);
if
(
rwl
->
iNumberActive
||
rwl
->
uExclusiveWaiters
||
rwl
->
uSharedWaiters
)
ERR
(
"Deleting active MRSW lock (%p), expect failure
\n
"
,
rwl
);
rwl
->
hOwningThreadId
=
0
;
rwl
->
uExclusiveWaiters
=
rwl
->
uSharedWaiters
=
0
;
rwl
->
iNumberActive
=
0
;
NtClose
(
rwl
->
hExclusiveReleaseSemaphore
);
NtClose
(
rwl
->
hSharedReleaseSemaphore
);
RtlLeaveCriticalSection
(
&
rwl
->
rtlCS
);
rwl
->
rtlCS
.
DebugInfo
->
Spare
[
0
]
=
0
;
RtlDeleteCriticalSection
(
&
rwl
->
rtlCS
);
}
/***********************************************************************
* RtlAcquireResourceExclusive (NTDLL.@)
*/
BYTE
WINAPI
RtlAcquireResourceExclusive
(
LPRTL_RWLOCK
rwl
,
BYTE
fWait
)
{
BYTE
retVal
=
0
;
if
(
!
rwl
)
return
0
;
for
(;;)
{
RtlEnterCriticalSection
(
&
rwl
->
rtlCS
);
if
(
rwl
->
iNumberActive
==
0
)
/* lock is free */
{
rwl
->
iNumberActive
=
-
1
;
retVal
=
1
;
}
else
if
(
rwl
->
iNumberActive
<
0
)
/* exclusive lock in progress */
{
if
(
rwl
->
hOwningThreadId
==
ULongToHandle
(
GetCurrentThreadId
())
)
{
retVal
=
1
;
rwl
->
iNumberActive
--
;
break
;
}
wait:
if
(
fWait
)
{
NTSTATUS
status
;
rwl
->
uExclusiveWaiters
++
;
RtlLeaveCriticalSection
(
&
rwl
->
rtlCS
);
status
=
NtWaitForSingleObject
(
rwl
->
hExclusiveReleaseSemaphore
,
FALSE
,
NULL
);
if
(
HIWORD
(
status
)
)
break
;
continue
;
/* restart the acquisition to avoid deadlocks */
}
}
else
/* one or more shared locks are in progress */
if
(
fWait
)
goto
wait
;
if
(
retVal
==
1
)
rwl
->
hOwningThreadId
=
ULongToHandle
(
GetCurrentThreadId
());
break
;
}
RtlLeaveCriticalSection
(
&
rwl
->
rtlCS
);
return
retVal
;
}
/***********************************************************************
* RtlAcquireResourceShared (NTDLL.@)
*/
BYTE
WINAPI
RtlAcquireResourceShared
(
LPRTL_RWLOCK
rwl
,
BYTE
fWait
)
{
NTSTATUS
status
=
STATUS_UNSUCCESSFUL
;
BYTE
retVal
=
0
;
if
(
!
rwl
)
return
0
;
for
(;;)
{
RtlEnterCriticalSection
(
&
rwl
->
rtlCS
);
if
(
rwl
->
iNumberActive
<
0
)
{
if
(
rwl
->
hOwningThreadId
==
ULongToHandle
(
GetCurrentThreadId
())
)
{
rwl
->
iNumberActive
--
;
retVal
=
1
;
break
;
}
if
(
fWait
)
{
rwl
->
uSharedWaiters
++
;
RtlLeaveCriticalSection
(
&
rwl
->
rtlCS
);
status
=
NtWaitForSingleObject
(
rwl
->
hSharedReleaseSemaphore
,
FALSE
,
NULL
);
if
(
HIWORD
(
status
)
)
break
;
continue
;
}
}
else
{
if
(
status
!=
STATUS_WAIT_0
)
/* otherwise RtlReleaseResource() has already done it */
rwl
->
iNumberActive
++
;
retVal
=
1
;
}
break
;
}
RtlLeaveCriticalSection
(
&
rwl
->
rtlCS
);
return
retVal
;
}
/***********************************************************************
* RtlReleaseResource (NTDLL.@)
*/
void
WINAPI
RtlReleaseResource
(
LPRTL_RWLOCK
rwl
)
{
RtlEnterCriticalSection
(
&
rwl
->
rtlCS
);
if
(
rwl
->
iNumberActive
>
0
)
/* have one or more readers */
{
if
(
--
rwl
->
iNumberActive
==
0
)
{
if
(
rwl
->
uExclusiveWaiters
)
{
rwl
->
uExclusiveWaiters
--
;
NtReleaseSemaphore
(
rwl
->
hExclusiveReleaseSemaphore
,
1
,
NULL
);
}
}
}
else
if
(
rwl
->
iNumberActive
<
0
)
/* have a writer, possibly recursive */
{
if
(
++
rwl
->
iNumberActive
==
0
)
{
rwl
->
hOwningThreadId
=
0
;
if
(
rwl
->
uExclusiveWaiters
)
{
rwl
->
uExclusiveWaiters
--
;
NtReleaseSemaphore
(
rwl
->
hExclusiveReleaseSemaphore
,
1
,
NULL
);
}
else
if
(
rwl
->
uSharedWaiters
)
{
UINT
n
=
rwl
->
uSharedWaiters
;
rwl
->
iNumberActive
=
rwl
->
uSharedWaiters
;
/* prevent new writers from joining until
* all queued readers have done their thing */
rwl
->
uSharedWaiters
=
0
;
NtReleaseSemaphore
(
rwl
->
hSharedReleaseSemaphore
,
n
,
NULL
);
}
}
}
RtlLeaveCriticalSection
(
&
rwl
->
rtlCS
);
}
/***********************************************************************
* RtlDumpResource (NTDLL.@)
*/
void
WINAPI
RtlDumpResource
(
LPRTL_RWLOCK
rwl
)
{
if
(
!
rwl
)
return
;
ERR
(
"%p: active count = %i waiting readers = %i waiting writers = %i owner thread = %p"
,
rwl
,
rwl
->
iNumberActive
,
rwl
->
uSharedWaiters
,
rwl
->
uExclusiveWaiters
,
rwl
->
hOwningThreadId
);
ERR
(
"
\n
"
);
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment