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
005ed577
Commit
005ed577
authored
Apr 26, 2022
by
Rémi Bernon
Committed by
Alexandre Julliard
May 05, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Factor out heap serialization to heap_(lock|unlock) helpers.
Signed-off-by:
Rémi Bernon
<
rbernon@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
2e47e23d
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
65 additions
and
54 deletions
+65
-54
heap.c
dlls/ntdll/heap.c
+65
-54
No files found.
dlls/ntdll/heap.c
View file @
005ed577
...
...
@@ -162,7 +162,7 @@ typedef struct tagHEAP
DWORD
magic
;
/* Magic number */
DWORD
pending_pos
;
/* Position in pending free requests ring */
ARENA_INUSE
**
pending_free
;
/* Ring buffer for pending free requests */
RTL_CRITICAL_SECTION
c
ritSection
;
/* Critical section for serialization */
RTL_CRITICAL_SECTION
c
s
;
FREE_LIST_ENTRY
*
freeList
;
/* Free lists */
}
HEAP
;
...
...
@@ -324,13 +324,30 @@ static inline ULONG get_protection_type( DWORD flags )
return
(
flags
&
HEAP_CREATE_ENABLE_EXECUTE
)
?
PAGE_EXECUTE_READWRITE
:
PAGE_READWRITE
;
}
static
RTL_CRITICAL_SECTION_DEBUG
process_heap_c
ritsect
_debug
=
static
RTL_CRITICAL_SECTION_DEBUG
process_heap_c
s
_debug
=
{
0
,
0
,
NULL
,
/* will be set later */
{
&
process_heap_c
ritsect_debug
.
ProcessLocksList
,
&
process_heap_critsect
_debug
.
ProcessLocksList
},
{
&
process_heap_c
s_debug
.
ProcessLocksList
,
&
process_heap_cs
_debug
.
ProcessLocksList
},
0
,
0
,
{
(
DWORD_PTR
)(
__FILE__
": main process heap section"
)
}
};
static
inline
ULONG
heap_get_flags
(
const
HEAP
*
heap
,
ULONG
flags
)
{
flags
&=
HEAP_GENERATE_EXCEPTIONS
|
HEAP_NO_SERIALIZE
|
HEAP_ZERO_MEMORY
;
return
heap
->
flags
|
flags
;
}
static
void
heap_lock
(
HEAP
*
heap
,
ULONG
flags
)
{
if
(
heap_get_flags
(
heap
,
flags
)
&
HEAP_NO_SERIALIZE
)
return
;
RtlEnterCriticalSection
(
&
heap
->
cs
);
}
static
void
heap_unlock
(
HEAP
*
heap
,
ULONG
flags
)
{
if
(
heap_get_flags
(
heap
,
flags
)
&
HEAP_NO_SERIALIZE
)
return
;
RtlLeaveCriticalSection
(
&
heap
->
cs
);
}
/***********************************************************************
* HEAP_Dump
...
...
@@ -748,7 +765,7 @@ static void *allocate_large_block( HEAP *heap, DWORD flags, SIZE_T size )
/***********************************************************************
* free_large_block
*/
static
void
free_large_block
(
HEAP
*
heap
,
DWORD
flags
,
void
*
ptr
)
static
void
free_large_block
(
HEAP
*
heap
,
void
*
ptr
)
{
ARENA_LARGE
*
arena
=
(
ARENA_LARGE
*
)
ptr
-
1
;
LPVOID
address
=
arena
;
...
...
@@ -791,7 +808,7 @@ static void *realloc_large_block( HEAP *heap, DWORD flags, void *ptr, SIZE_T siz
return
NULL
;
}
memcpy
(
new_ptr
,
ptr
,
arena
->
data_size
);
free_large_block
(
heap
,
flags
,
ptr
);
free_large_block
(
heap
,
ptr
);
notify_free
(
ptr
);
return
new_ptr
;
}
...
...
@@ -958,31 +975,31 @@ static SUBHEAP *HEAP_CreateSubHeap( HEAP *heap, LPVOID address, DWORD flags,
if
(
!
processHeap
)
/* do it by hand to avoid memory allocations */
{
heap
->
c
ritSection
.
DebugInfo
=
&
process_heap_critsect
_debug
;
heap
->
c
ritSection
.
LockCount
=
-
1
;
heap
->
c
ritSection
.
RecursionCount
=
0
;
heap
->
c
ritSection
.
OwningThread
=
0
;
heap
->
c
ritSection
.
LockSemaphore
=
0
;
heap
->
c
ritSection
.
SpinCount
=
0
;
process_heap_c
ritsect_debug
.
CriticalSection
=
&
heap
->
critSection
;
heap
->
c
s
.
DebugInfo
=
&
process_heap_cs
_debug
;
heap
->
c
s
.
LockCount
=
-
1
;
heap
->
c
s
.
RecursionCount
=
0
;
heap
->
c
s
.
OwningThread
=
0
;
heap
->
c
s
.
LockSemaphore
=
0
;
heap
->
c
s
.
SpinCount
=
0
;
process_heap_c
s_debug
.
CriticalSection
=
&
heap
->
cs
;
}
else
{
RtlInitializeCriticalSection
(
&
heap
->
c
ritSection
);
heap
->
c
ritSection
.
DebugInfo
->
Spare
[
0
]
=
(
DWORD_PTR
)(
__FILE__
": HEAP.critSection
"
);
RtlInitializeCriticalSection
(
&
heap
->
c
s
);
heap
->
c
s
.
DebugInfo
->
Spare
[
0
]
=
(
DWORD_PTR
)(
__FILE__
": heap.cs
"
);
}
if
(
heap
->
shared
)
{
/* let's assume that only one thread at a time will try to do this */
HANDLE
sem
=
heap
->
c
ritSection
.
LockSemaphore
;
HANDLE
sem
=
heap
->
c
s
.
LockSemaphore
;
if
(
!
sem
)
NtCreateSemaphore
(
&
sem
,
SEMAPHORE_ALL_ACCESS
,
NULL
,
0
,
1
);
NtDuplicateObject
(
NtCurrentProcess
(),
sem
,
NtCurrentProcess
(),
&
sem
,
0
,
0
,
DUPLICATE_MAKE_GLOBAL
|
DUPLICATE_SAME_ACCESS
|
DUPLICATE_CLOSE_SOURCE
);
heap
->
c
ritSection
.
LockSemaphore
=
sem
;
RtlFreeHeap
(
processHeap
,
0
,
heap
->
c
ritSection
.
DebugInfo
);
heap
->
c
ritSection
.
DebugInfo
=
NULL
;
heap
->
c
s
.
LockSemaphore
=
sem
;
RtlFreeHeap
(
processHeap
,
0
,
heap
->
c
s
.
DebugInfo
);
heap
->
c
s
.
DebugInfo
=
NULL
;
}
}
...
...
@@ -1339,11 +1356,7 @@ static BOOL HEAP_IsRealArena( HEAP *heapPtr, /* [in] ptr to the heap */
BOOL
ret
=
FALSE
;
const
ARENA_LARGE
*
large_arena
;
flags
&=
HEAP_NO_SERIALIZE
;
flags
|=
heapPtr
->
flags
;
/* calling HeapLock may result in infinite recursion, so do the critsect directly */
if
(
!
(
flags
&
HEAP_NO_SERIALIZE
))
RtlEnterCriticalSection
(
&
heapPtr
->
critSection
);
heap_lock
(
heapPtr
,
flags
);
if
(
block
)
/* only check this single memory block */
{
...
...
@@ -1389,7 +1402,7 @@ static BOOL HEAP_IsRealArena( HEAP *heapPtr, /* [in] ptr to the heap */
ret
=
TRUE
;
done
:
if
(
!
(
flags
&
HEAP_NO_SERIALIZE
))
RtlLeaveCriticalSection
(
&
heapPtr
->
critSection
);
heap_unlock
(
heapPtr
,
flags
);
return
ret
;
}
...
...
@@ -1569,9 +1582,9 @@ HANDLE WINAPI RtlCreateHeap( ULONG flags, PVOID addr, SIZE_T totalSize, SIZE_T c
if
(
processHeap
)
{
HEAP
*
heapPtr
=
subheap
->
heap
;
RtlEnterCriticalSection
(
&
processHeap
->
c
ritSection
);
RtlEnterCriticalSection
(
&
processHeap
->
c
s
);
list_add_head
(
&
processHeap
->
entry
,
&
heapPtr
->
entry
);
RtlLeaveCriticalSection
(
&
processHeap
->
c
ritSection
);
RtlLeaveCriticalSection
(
&
processHeap
->
c
s
);
}
else
if
(
!
addr
)
{
...
...
@@ -1615,12 +1628,12 @@ HANDLE WINAPI RtlDestroyHeap( HANDLE heap )
if
(
heap
==
processHeap
)
return
heap
;
/* cannot delete the main process heap */
/* remove it from the per-process list */
RtlEnterCriticalSection
(
&
processHeap
->
c
ritSection
);
RtlEnterCriticalSection
(
&
processHeap
->
c
s
);
list_remove
(
&
heapPtr
->
entry
);
RtlLeaveCriticalSection
(
&
processHeap
->
c
ritSection
);
RtlLeaveCriticalSection
(
&
processHeap
->
c
s
);
heapPtr
->
c
ritSection
.
DebugInfo
->
Spare
[
0
]
=
0
;
RtlDeleteCriticalSection
(
&
heapPtr
->
c
ritSection
);
heapPtr
->
c
s
.
DebugInfo
->
Spare
[
0
]
=
0
;
RtlDeleteCriticalSection
(
&
heapPtr
->
c
s
);
LIST_FOR_EACH_ENTRY_SAFE
(
arena
,
arena_next
,
&
heapPtr
->
large_list
,
ARENA_LARGE
,
entry
)
{
...
...
@@ -1685,12 +1698,12 @@ void * WINAPI DECLSPEC_HOTPATCH RtlAllocateHeap( HANDLE heap, ULONG flags, SIZE_
}
if
(
rounded_size
<
HEAP_MIN_DATA_SIZE
)
rounded_size
=
HEAP_MIN_DATA_SIZE
;
if
(
!
(
flags
&
HEAP_NO_SERIALIZE
))
RtlEnterCriticalSection
(
&
heapPtr
->
critSection
);
heap_lock
(
heapPtr
,
flags
);
if
(
rounded_size
>=
HEAP_MIN_LARGE_BLOCK_SIZE
&&
(
flags
&
HEAP_GROWABLE
))
{
void
*
ret
=
allocate_large_block
(
heap
,
flags
,
size
);
if
(
!
(
flags
&
HEAP_NO_SERIALIZE
))
RtlLeaveCriticalSection
(
&
heapPtr
->
critSection
);
heap_unlock
(
heapPtr
,
flags
);
if
(
!
ret
&&
(
flags
&
HEAP_GENERATE_EXCEPTIONS
))
RtlRaiseStatus
(
STATUS_NO_MEMORY
);
TRACE
(
"(%p,%08x,%08lx): returning %p
\n
"
,
heap
,
flags
,
size
,
ret
);
return
ret
;
...
...
@@ -1702,7 +1715,7 @@ void * WINAPI DECLSPEC_HOTPATCH RtlAllocateHeap( HANDLE heap, ULONG flags, SIZE_
{
TRACE
(
"(%p,%08x,%08lx): returning NULL
\n
"
,
heap
,
flags
,
size
);
if
(
!
(
flags
&
HEAP_NO_SERIALIZE
))
RtlLeaveCriticalSection
(
&
heapPtr
->
critSection
);
heap_unlock
(
heapPtr
,
flags
);
if
(
flags
&
HEAP_GENERATE_EXCEPTIONS
)
RtlRaiseStatus
(
STATUS_NO_MEMORY
);
return
NULL
;
}
...
...
@@ -1728,7 +1741,7 @@ void * WINAPI DECLSPEC_HOTPATCH RtlAllocateHeap( HANDLE heap, ULONG flags, SIZE_
notify_alloc
(
pInUse
+
1
,
size
,
flags
&
HEAP_ZERO_MEMORY
);
initialize_block
(
pInUse
+
1
,
size
,
pInUse
->
unused_bytes
,
flags
);
if
(
!
(
flags
&
HEAP_NO_SERIALIZE
))
RtlLeaveCriticalSection
(
&
heapPtr
->
critSection
);
heap_unlock
(
heapPtr
,
flags
);
TRACE
(
"(%p,%08x,%08lx): returning %p
\n
"
,
heap
,
flags
,
size
,
pInUse
+
1
);
return
pInUse
+
1
;
...
...
@@ -1766,9 +1779,7 @@ BOOLEAN WINAPI DECLSPEC_HOTPATCH RtlFreeHeap( HANDLE heap, ULONG flags, void *pt
return
FALSE
;
}
flags
&=
HEAP_NO_SERIALIZE
;
flags
|=
heapPtr
->
flags
;
if
(
!
(
flags
&
HEAP_NO_SERIALIZE
))
RtlEnterCriticalSection
(
&
heapPtr
->
critSection
);
heap_lock
(
heapPtr
,
flags
);
/* Inform valgrind we are trying to free memory, so it can throw up an error message */
notify_free
(
ptr
);
...
...
@@ -1778,16 +1789,16 @@ BOOLEAN WINAPI DECLSPEC_HOTPATCH RtlFreeHeap( HANDLE heap, ULONG flags, void *pt
if
(
!
validate_block_pointer
(
heapPtr
,
&
subheap
,
pInUse
))
goto
error
;
if
(
!
subheap
)
free_large_block
(
heapPtr
,
flags
,
ptr
);
free_large_block
(
heapPtr
,
ptr
);
else
HEAP_MakeInUseBlockFree
(
subheap
,
pInUse
);
if
(
!
(
flags
&
HEAP_NO_SERIALIZE
))
RtlLeaveCriticalSection
(
&
heapPtr
->
critSection
);
heap_unlock
(
heapPtr
,
flags
);
TRACE
(
"(%p,%08x,%p): returning TRUE
\n
"
,
heap
,
flags
,
ptr
);
return
TRUE
;
error
:
if
(
!
(
flags
&
HEAP_NO_SERIALIZE
))
RtlLeaveCriticalSection
(
&
heapPtr
->
critSection
);
heap_unlock
(
heapPtr
,
flags
);
RtlSetLastWin32ErrorAndNtStatusFromNtStatus
(
STATUS_INVALID_PARAMETER
);
TRACE
(
"(%p,%08x,%p): returning FALSE
\n
"
,
heap
,
flags
,
ptr
);
return
FALSE
;
...
...
@@ -1829,7 +1840,7 @@ PVOID WINAPI RtlReAllocateHeap( HANDLE heap, ULONG flags, PVOID ptr, SIZE_T size
flags
&=
HEAP_GENERATE_EXCEPTIONS
|
HEAP_NO_SERIALIZE
|
HEAP_ZERO_MEMORY
|
HEAP_REALLOC_IN_PLACE_ONLY
;
flags
|=
heapPtr
->
flags
;
if
(
!
(
flags
&
HEAP_NO_SERIALIZE
))
RtlEnterCriticalSection
(
&
heapPtr
->
critSection
);
heap_lock
(
heapPtr
,
flags
);
rounded_size
=
ROUND_SIZE
(
size
)
+
HEAP_TAIL_EXTRA_SIZE
(
flags
);
if
(
rounded_size
<
size
)
goto
oom
;
/* overflow */
...
...
@@ -1923,19 +1934,19 @@ PVOID WINAPI RtlReAllocateHeap( HANDLE heap, ULONG flags, PVOID ptr, SIZE_T size
ret
=
pArena
+
1
;
done
:
if
(
!
(
flags
&
HEAP_NO_SERIALIZE
))
RtlLeaveCriticalSection
(
&
heapPtr
->
critSection
);
heap_unlock
(
heapPtr
,
flags
);
TRACE
(
"(%p,%08x,%p,%08lx): returning %p
\n
"
,
heap
,
flags
,
ptr
,
size
,
ret
);
return
ret
;
oom
:
if
(
!
(
flags
&
HEAP_NO_SERIALIZE
))
RtlLeaveCriticalSection
(
&
heapPtr
->
critSection
);
heap_unlock
(
heapPtr
,
flags
);
if
(
flags
&
HEAP_GENERATE_EXCEPTIONS
)
RtlRaiseStatus
(
STATUS_NO_MEMORY
);
RtlSetLastWin32ErrorAndNtStatusFromNtStatus
(
STATUS_NO_MEMORY
);
TRACE
(
"(%p,%08x,%p,%08lx): returning NULL
\n
"
,
heap
,
flags
,
ptr
,
size
);
return
NULL
;
error
:
if
(
!
(
flags
&
HEAP_NO_SERIALIZE
))
RtlLeaveCriticalSection
(
&
heapPtr
->
critSection
);
heap_unlock
(
heapPtr
,
flags
);
RtlSetLastWin32ErrorAndNtStatusFromNtStatus
(
STATUS_INVALID_PARAMETER
);
TRACE
(
"(%p,%08x,%p,%08lx): returning NULL
\n
"
,
heap
,
flags
,
ptr
,
size
);
return
NULL
;
...
...
@@ -1981,7 +1992,7 @@ BOOLEAN WINAPI RtlLockHeap( HANDLE heap )
{
HEAP
*
heapPtr
=
HEAP_GetPtr
(
heap
);
if
(
!
heapPtr
)
return
FALSE
;
RtlEnterCriticalSection
(
&
heapPtr
->
c
ritSection
);
RtlEnterCriticalSection
(
&
heapPtr
->
c
s
);
return
TRUE
;
}
...
...
@@ -2002,7 +2013,7 @@ BOOLEAN WINAPI RtlUnlockHeap( HANDLE heap )
{
HEAP
*
heapPtr
=
HEAP_GetPtr
(
heap
);
if
(
!
heapPtr
)
return
FALSE
;
RtlLeaveCriticalSection
(
&
heapPtr
->
c
ritSection
);
RtlLeaveCriticalSection
(
&
heapPtr
->
c
s
);
return
TRUE
;
}
...
...
@@ -2036,9 +2047,8 @@ SIZE_T WINAPI RtlSizeHeap( HANDLE heap, ULONG flags, const void *ptr )
RtlSetLastWin32ErrorAndNtStatusFromNtStatus
(
STATUS_INVALID_HANDLE
);
return
~
(
SIZE_T
)
0
;
}
flags
&=
HEAP_NO_SERIALIZE
;
flags
|=
heapPtr
->
flags
;
if
(
!
(
flags
&
HEAP_NO_SERIALIZE
))
RtlEnterCriticalSection
(
&
heapPtr
->
critSection
);
heap_lock
(
heapPtr
,
flags
);
pArena
=
(
const
ARENA_INUSE
*
)
ptr
-
1
;
if
(
!
validate_block_pointer
(
heapPtr
,
&
subheap
,
pArena
))
...
...
@@ -2055,7 +2065,8 @@ SIZE_T WINAPI RtlSizeHeap( HANDLE heap, ULONG flags, const void *ptr )
{
ret
=
(
pArena
->
size
&
ARENA_SIZE_MASK
)
-
pArena
->
unused_bytes
;
}
if
(
!
(
flags
&
HEAP_NO_SERIALIZE
))
RtlLeaveCriticalSection
(
&
heapPtr
->
critSection
);
heap_unlock
(
heapPtr
,
flags
);
TRACE
(
"(%p,%08x,%p): returning %08lx
\n
"
,
heap
,
flags
,
ptr
,
ret
);
return
ret
;
...
...
@@ -2102,7 +2113,7 @@ NTSTATUS WINAPI RtlWalkHeap( HANDLE heap, PVOID entry_ptr )
if
(
!
heapPtr
||
!
entry
)
return
STATUS_INVALID_PARAMETER
;
if
(
!
(
heapPtr
->
flags
&
HEAP_NO_SERIALIZE
))
RtlEnterCriticalSection
(
&
heapPtr
->
critSection
);
heap_lock
(
heapPtr
,
0
);
/* FIXME: enumerate large blocks too */
...
...
@@ -2207,7 +2218,7 @@ NTSTATUS WINAPI RtlWalkHeap( HANDLE heap, PVOID entry_ptr )
if
(
TRACE_ON
(
heap
))
HEAP_DumpEntry
(
entry
);
HW_end
:
if
(
!
(
heapPtr
->
flags
&
HEAP_NO_SERIALIZE
))
RtlLeaveCriticalSection
(
&
heapPtr
->
critSection
);
heap_unlock
(
heapPtr
,
0
);
return
ret
;
}
...
...
@@ -2230,7 +2241,7 @@ ULONG WINAPI RtlGetProcessHeaps( ULONG count, HANDLE *heaps )
ULONG
total
=
1
;
/* main heap */
struct
list
*
ptr
;
RtlEnterCriticalSection
(
&
processHeap
->
c
ritSection
);
RtlEnterCriticalSection
(
&
processHeap
->
c
s
);
LIST_FOR_EACH
(
ptr
,
&
processHeap
->
entry
)
total
++
;
if
(
total
<=
count
)
{
...
...
@@ -2238,7 +2249,7 @@ ULONG WINAPI RtlGetProcessHeaps( ULONG count, HANDLE *heaps )
LIST_FOR_EACH
(
ptr
,
&
processHeap
->
entry
)
*
heaps
++
=
LIST_ENTRY
(
ptr
,
HEAP
,
entry
);
}
RtlLeaveCriticalSection
(
&
processHeap
->
c
ritSection
);
RtlLeaveCriticalSection
(
&
processHeap
->
c
s
);
return
total
;
}
...
...
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