[PATCH 0/1] MR11742: krnl386: Don't free DISCARDABLE resources in FreeResource16.
If a resource is marked DISCARDABLE, it is not actually freed when its refcount reaches 0. In theory the resource's memory is freed when the system is low on memory, but its global handle remains valid to allow the resource to be resurrected with the same handle later. In practice, 16-bit programs can't run out of memory on modern hardware, and the game Tetris Jr. depends on its discardable resources never being discarded. See https://devblogs.microsoft.com/oldnewthing/20040202-00/?p=40783 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=23364 -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11742
From: Alex Henrie <alexhenrie24@gmail.com> If a resource is marked DISCARDABLE, it is not actually freed when its refcount reaches 0. In theory the resource's memory is freed when the system is low on memory, but its global handle remains valid to allow the resource to be resurrected with the same handle later. In practice, 16-bit programs can't run out of memory on modern hardware, and the game Tetris Jr. depends on its discardable resources never being discarded. See https://devblogs.microsoft.com/oldnewthing/20040202-00/?p=40783 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=23364 --- dlls/krnl386.exe16/resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/krnl386.exe16/resource.c b/dlls/krnl386.exe16/resource.c index bcdb01a3b30..52d24dc67ba 100644 --- a/dlls/krnl386.exe16/resource.c +++ b/dlls/krnl386.exe16/resource.c @@ -1125,7 +1125,7 @@ BOOL16 WINAPI FreeResource16( HGLOBAL16 handle ) if (pNameInfo->handle == handle) { if (pNameInfo->usage > 0) pNameInfo->usage--; - if (pNameInfo->usage == 0) + if (pNameInfo->usage == 0 && !(pNameInfo->flags & NE_SEGFLAGS_DISCARDABLE)) { GlobalFree16( pNameInfo->handle ); pNameInfo->handle = 0; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11742
Jinoh Kang (@iamahuman) commented about dlls/krnl386.exe16/resource.c:
if (pNameInfo->handle == handle) { if (pNameInfo->usage > 0) pNameInfo->usage--; - if (pNameInfo->usage == 0) + if (pNameInfo->usage == 0 && !(pNameInfo->flags & NE_SEGFLAGS_DISCARDABLE))
https://devblogs.microsoft.com/oldnewthing/20040202-00/?p=40783 says you're supposed to mark the segment discardable, not ignore the request entirely.
16-bit programs can't run out of memory on modern hardware
Are you sure? That 16-bit programs can utilize all memory of modern hardware? -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11742#note_149668
participants (3)
-
Alex Henrie -
Alex Henrie (@alexhenrie) -
Jinoh Kang (@iamahuman)