Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
July 2021
- 86 participants
- 1756 messages
Re: Proposal to take over macOS packaging
by Zhenbo Li
Hi,
How about using Gcenx's package[1]? If Gcenx's package is okay, I
think we may avoid some duplicate jobs.
[1]: https://github.com/Gcenx/homebrew-wine
On Thu, Jul 29, 2021 at 2:33 AM Gijs Vermeulen <gijsvrm(a)gmail.com> wrote:
>
> Hi everyone,
>
> Currently, official macOS packages haven't been released since wine-5.7. Thus I'm sending this email on behalf of myself and Dean Greer to officially nominate ourselves to take over the macOS packaging.
>
> There are, however, some specifics we'd like to discuss.
>
> The old packages were built with compatibility for macOS 10.8 and higher, but Apple stopped supporting 10.8 a very long time ago and it would be hard to keep supporting it for the packages.
>
> To get anything lower functional would mean needing to compile all the needed dylibs on the lowest supported version, as package managers don't have prebuilds for these versions.
>
> The ideal solution would be to raise the minimum macOS version to 10.13. This version has only recently lost support and would allow us to ship feature-complete packages.
>
> Metal also started maturing a lot from 10.13 onwards. [1]
>
> Is this something that you could agree too?
>
> Kind regards,
> Gijs & Dean
>
> [1] https://source.winehq.org/git/wine.git/commit/0d23ecd9ec8a0c24e5444e0fc9cf6…
--
Sincerely,
Zhenbo Li
July 29, 2021
Re: [PATCH] wined3d: Negiotiate less specific memory types on allocation failure.
by Zebediah Figura (she/her)
On 7/29/21 11:31 AM, Jan Sikorski wrote:
> Drop HOST_CACHED and/or DEVICE_LOCAL properties in case the device does
> not support a particular combination or there is no more space in a heap.
>
> Signed-off-by: Jan Sikorski <jsikorski(a)codeweavers.com>
> ---
> Superseeds 210471
> ---
> dlls/wined3d/buffer.c | 24 ++++++++++++++++++------
> 1 file changed, 18 insertions(+), 6 deletions(-)
>
> diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
> index 4c5e2054fe0..6b0d84ce7a0 100644
> --- a/dlls/wined3d/buffer.c
> +++ b/dlls/wined3d/buffer.c
> @@ -1387,8 +1387,8 @@ static BOOL wined3d_buffer_vk_create_buffer_object(struct wined3d_buffer_vk *buf
> struct wined3d_context_vk *context_vk)
> {
> struct wined3d_resource *resource = &buffer_vk->b.resource;
> + VkMemoryPropertyFlags memory_type, want_memory_type;
> uint32_t bind_flags = resource->bind_flags;
> - VkMemoryPropertyFlags memory_type;
> VkBufferUsageFlags usage;
>
> usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
> @@ -1409,16 +1409,28 @@ static BOOL wined3d_buffer_vk_create_buffer_object(struct wined3d_buffer_vk *buf
> if (bind_flags & (WINED3D_BIND_RENDER_TARGET | WINED3D_BIND_DEPTH_STENCIL))
> FIXME("Ignoring some bind flags %#x.\n", bind_flags);
>
> - memory_type = 0;
> + want_memory_type = 0;
> if (!(resource->usage & WINED3DUSAGE_DYNAMIC))
> - memory_type |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
> + want_memory_type |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
> if (resource->access & WINED3D_RESOURCE_ACCESS_MAP_R)
> - memory_type |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
> + want_memory_type |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
> else if (resource->access & WINED3D_RESOURCE_ACCESS_MAP_W)
> - memory_type |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
> + want_memory_type |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
>
> - if (!(wined3d_context_vk_create_bo(context_vk, resource->size, usage, memory_type, &buffer_vk->bo)))
> + memory_type = want_memory_type;
> +
> + while (!wined3d_context_vk_create_bo(context_vk, resource->size, usage, memory_type, &buffer_vk->bo))
> {
> + if (memory_type & VK_MEMORY_PROPERTY_HOST_CACHED_BIT)
> + {
> + memory_type = want_memory_type & ~VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
> + continue;
> + }
> + if (memory_type & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
> + {
> + memory_type = (want_memory_type &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
> + continue;
> + }
> WARN("Failed to create Vulkan buffer.\n");
> return FALSE;
> }
>
This will still spew an ERR message, though, which seems less than ideal.
Also, the while loop seems awkward to me, couldn't we instead do
something like (abbreviated):
if (!wined3d_context_vk_create_bo(memory_type)
&& !wined3d_context_vk_create_bo(memory_type & ~HOST_CACHED)
&& !wined3d_context_vk_create_bo(memory_type & ~DEVICE_LOCAL))
July 29, 2021
[PATCH] wined3d: Negiotiate less specific memory types on allocation failure.
by Jan Sikorski
Drop HOST_CACHED and/or DEVICE_LOCAL properties in case the device does
not support a particular combination or there is no more space in a heap.
Signed-off-by: Jan Sikorski <jsikorski(a)codeweavers.com>
---
Superseeds 210471
---
dlls/wined3d/buffer.c | 24 ++++++++++++++++++------
1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 4c5e2054fe0..6b0d84ce7a0 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -1387,8 +1387,8 @@ static BOOL wined3d_buffer_vk_create_buffer_object(struct wined3d_buffer_vk *buf
struct wined3d_context_vk *context_vk)
{
struct wined3d_resource *resource = &buffer_vk->b.resource;
+ VkMemoryPropertyFlags memory_type, want_memory_type;
uint32_t bind_flags = resource->bind_flags;
- VkMemoryPropertyFlags memory_type;
VkBufferUsageFlags usage;
usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
@@ -1409,16 +1409,28 @@ static BOOL wined3d_buffer_vk_create_buffer_object(struct wined3d_buffer_vk *buf
if (bind_flags & (WINED3D_BIND_RENDER_TARGET | WINED3D_BIND_DEPTH_STENCIL))
FIXME("Ignoring some bind flags %#x.\n", bind_flags);
- memory_type = 0;
+ want_memory_type = 0;
if (!(resource->usage & WINED3DUSAGE_DYNAMIC))
- memory_type |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
+ want_memory_type |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
if (resource->access & WINED3D_RESOURCE_ACCESS_MAP_R)
- memory_type |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
+ want_memory_type |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
else if (resource->access & WINED3D_RESOURCE_ACCESS_MAP_W)
- memory_type |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
+ want_memory_type |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
- if (!(wined3d_context_vk_create_bo(context_vk, resource->size, usage, memory_type, &buffer_vk->bo)))
+ memory_type = want_memory_type;
+
+ while (!wined3d_context_vk_create_bo(context_vk, resource->size, usage, memory_type, &buffer_vk->bo))
{
+ if (memory_type & VK_MEMORY_PROPERTY_HOST_CACHED_BIT)
+ {
+ memory_type = want_memory_type & ~VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
+ continue;
+ }
+ if (memory_type & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
+ {
+ memory_type = (want_memory_type &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
+ continue;
+ }
WARN("Failed to create Vulkan buffer.\n");
return FALSE;
}
--
2.30.2
July 29, 2021
[PATCH] combase: When looking up an apartment which has a given creator thread ID use multi-threaded apartment only if the thread doesn't have an apartment-threaded one.
by Dmitry Timoshkov
CoIncrementMTAUsage() always creates the MTA if it doesn't already exist,
and mta->tid may accidently match the apt->tid of the apartment-threaded
apartment of the thread.
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/combase/apartment.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/dlls/combase/apartment.c b/dlls/combase/apartment.c
index 108d6a71c5c..690bc69db1b 100644
--- a/dlls/combase/apartment.c
+++ b/dlls/combase/apartment.c
@@ -663,13 +663,20 @@ struct apartment * apartment_findfromtid(DWORD tid)
EnterCriticalSection(&apt_cs);
LIST_FOR_EACH_ENTRY(apt, &apts, struct apartment, entry)
{
- if (apt->tid == tid)
+ if (apt != mta && apt->tid == tid)
{
result = apt;
apartment_addref(result);
break;
}
}
+
+ if (!result && mta && mta->tid == tid)
+ {
+ result = mta;
+ apartment_addref(result);
+ }
+
LeaveCriticalSection(&apt_cs);
return result;
--
2.31.1
July 29, 2021
Re: [PATCH] wined3d: Do not request device local memory if we also want it to be host visible.
by Jan Sikorski
> On 29 Jul 2021, at 16:52, Zebediah Figura (she/her) <zfigura(a)codeweavers.com> wrote:
>
> On 7/29/21 9:41 AM, Henri Verbeet wrote:
>> On Thu, 29 Jul 2021 at 16:38, Jan Sikorski <jsikorski(a)codeweavers.com> wrote:
>>>> On 29 Jul 2021, at 16:24, Henri Verbeet <hverbeet(a)gmail.com> wrote:
>>>> On Thu, 29 Jul 2021 at 13:52, Jan Sikorski <jsikorski(a)codeweavers.com> wrote:
>>>>> @@ -1410,12 +1410,12 @@ static BOOL wined3d_buffer_vk_create_buffer_object(struct wined3d_buffer_vk *buf
>>>>> FIXME("Ignoring some bind flags %#x.\n", bind_flags);
>>>>>
>>>>> memory_type = 0;
>>>>> - if (!(resource->usage & WINED3DUSAGE_DYNAMIC))
>>>>> - memory_type |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
>>>>> if (resource->access & WINED3D_RESOURCE_ACCESS_MAP_R)
>>>>> memory_type |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
>>>>> else if (resource->access & WINED3D_RESOURCE_ACCESS_MAP_W)
>>>>> memory_type |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
>>>>> + else if (!(resource->usage & WINED3DUSAGE_DYNAMIC))
>>>>> + memory_type |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
>>>>>
>>>> If I understand correctly, we'd get here for DEFAULT resources with
>>>> CPU read/write access. I wonder if there would be any advantage in
>>>> using DEVICE_LOCAL | HOST_VISIBLE on GPUs that do in fact support that
>>>> memory type, perhaps using a scheme similar to vkd3d's
>>>> vkd3d_select_memory_type().
>>>
>>> We could just try to allocate it and retry without DEVICE_LOCAL if it fails. That would also work in case this type is supported but out of space.
>>>
>> Yeah, that should work.
>
> In my case I have a heap with DEVICE_LOCAL | HOST_VISIBLE, but not (as is requested) DEVICE_LOCAL | HOST_VISIBLE | HOST_CACHED. If we're talking about DEFAULT resources, would it make sense to drop HOST_CACHED rather than DEVICE_LOCAL?
>
Hm, maybe it would, how about this:
While failed:
1. If type had DEVICE LOCAL and HOST CACHED bits, set it to desired type with HOST CACHED dropped, and retry
2. If type had DEVICE LOCAL and HOST VISIBLE bits, set it to desired type with DEVICE LOCAL dropped, and retry
3. Else, give up
So if it’s all 3, we’d try DEVICE LOCAL | HOST VISIBLE first, then HOST VISIBLE | HOST CACHED.
If it’s DEVICE LOCAL | HOST VISIBLE, we try just HOST VISIBLE.
If it was DEVICE LOCAL | HOST CACHED, we’d drop HOST CACHED, but we don’t ever request that.
- Jan
July 29, 2021
[PATCH v3 3/3] ntdll: Improve the Nt{Query,Set}TimerResolution() stubs.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
v2: Forgot a todo_wine in kernelbase:sync.
v3: Removed the todo_wine in kernelbase:sync.
---
dlls/kernelbase/tests/sync.c | 8 ++---
dlls/ntdll/tests/time.c | 60 ++++++++++++++++++------------------
dlls/ntdll/unix/sync.c | 33 +++++++++++++++++---
3 files changed, 63 insertions(+), 38 deletions(-)
diff --git a/dlls/kernelbase/tests/sync.c b/dlls/kernelbase/tests/sync.c
index 8127b4238b9..acbfdeff0b7 100644
--- a/dlls/kernelbase/tests/sync.c
+++ b/dlls/kernelbase/tests/sync.c
@@ -195,7 +195,7 @@ static void test_Sleep(void)
/* Get the timer resolution before... */
r1 = 156250;
status = NtQueryTimerResolution(&dummy, &dummy, &r1);
- todo_wine ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
+ ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
for (i = 0; i < 50; i++) {
Sleep(1);
@@ -207,15 +207,15 @@ static void test_Sleep(void)
/* ...and after in case some other process changes it during this test */
r2 = 156250;
status = NtQueryTimerResolution(&dummy, &dummy, &r2);
- todo_wine ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
+ ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
elapsed_time = (t2.QuadPart - t1.QuadPart) / (double)frequency.QuadPart;
min = 50.0 * (r1 < r2 ? r1 : r2) / 10000000.0;
max = 50.0 * (r1 < r2 ? r2 : r1) / 10000000.0;
/* Add an extra 1s to account for potential scheduling delays */
- todo_wine ok(0.9 * min <= elapsed_time && elapsed_time <= 1.0 + max,
- "got %f, expected between %f and %f\n", elapsed_time, min, max);
+ ok(0.9 * min <= elapsed_time && elapsed_time <= 1.0 + max,
+ "got %f, expected between %f and %f\n", elapsed_time, min, max);
}
START_TEST(sync)
diff --git a/dlls/ntdll/tests/time.c b/dlls/ntdll/tests/time.c
index 5f9c49989d8..f75b159f441 100644
--- a/dlls/ntdll/tests/time.c
+++ b/dlls/ntdll/tests/time.c
@@ -218,16 +218,16 @@ static void test_RtlQueryPerformanceCounter(void)
#define CHECK_CURRENT_TIMER(expected) \
do { \
- todo_wine ok(status == STATUS_SUCCESS, "NtSetTimerResolution failed %x\n", status); \
- todo_wine ok(cur2 == (expected), "expected new timer resolution %u, got %u\n", (expected), cur2); \
+ ok(status == STATUS_SUCCESS, "NtSetTimerResolution failed %x\n", status); \
+ ok(cur2 == (expected), "expected new timer resolution %u, got %u\n", (expected), cur2); \
min2 = min + 10; \
cur2 = min2 + 1; \
max2 = cur2 + 1; \
status = NtQueryTimerResolution(&min2, &max2, &cur2); \
- todo_wine ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed %x\n", status); \
- todo_wine ok(min2 == min, "NtQueryTimerResolution() expected min=%u, got %u\n", min, min2); \
- todo_wine ok(max2 == max, "NtQueryTimerResolution() expected max=%u, got %u\n", max, max2); \
- todo_wine ok(cur2 == expected, "NtQueryTimerResolution() expected timer resolution %u, got %u\n", (expected), cur2); \
+ ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed %x\n", status); \
+ ok(min2 == min, "NtQueryTimerResolution() expected min=%u, got %u\n", min, min2); \
+ ok(max2 == max, "NtQueryTimerResolution() expected max=%u, got %u\n", max, max2); \
+ ok(cur2 == expected, "NtQueryTimerResolution() expected timer resolution %u, got %u\n", (expected), cur2); \
} while (0)
static void test_TimerResolution(void)
@@ -236,46 +236,46 @@ static void test_TimerResolution(void)
NTSTATUS status;
status = NtQueryTimerResolution(NULL, &max, &cur);
- todo_wine ok(status == STATUS_ACCESS_VIOLATION, "NtQueryTimerResolution(NULL,,) success\n");
+ ok(status == STATUS_ACCESS_VIOLATION, "NtQueryTimerResolution(NULL,,) success\n");
status = NtQueryTimerResolution(&min, NULL, &cur);
- todo_wine ok(status == STATUS_ACCESS_VIOLATION, "NtQueryTimerResolution(,NULL,) success\n");
+ ok(status == STATUS_ACCESS_VIOLATION, "NtQueryTimerResolution(,NULL,) success\n");
status = NtQueryTimerResolution(&min, &max, NULL);
- todo_wine ok(status == STATUS_ACCESS_VIOLATION, "NtQueryTimerResolution(,,NULL) success\n");
+ ok(status == STATUS_ACCESS_VIOLATION, "NtQueryTimerResolution(,,NULL) success\n");
min = 212121;
cur = min + 1;
max = cur + 1;
status = NtQueryTimerResolution(&min, &max, &cur);
- todo_wine ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
- todo_wine ok(min == 156250 /* 1/64s HPET */ || min == 156001 /* RTC */,
- "unexpected minimum timer resolution %u\n", min);
+ ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
+ ok(min == 156250 /* 1/64s HPET */ || min == 156001 /* RTC */,
+ "unexpected minimum timer resolution %u\n", min);
ok(0 < max, "invalid maximum timer resolution, should be 0 < %u\n", max);
- todo_wine ok(max <= cur && cur <= min, "invalid timer resolutions, should be %u <= %u <= %u\n", max, cur, min);
+ ok(max <= cur && cur <= min, "invalid timer resolutions, should be %u <= %u <= %u\n", max, cur, min);
status = NtSetTimerResolution(0, FALSE, NULL);
- todo_wine ok(status == STATUS_ACCESS_VIOLATION, "NtSetTimerResolution(,,NULL) success\n");
+ ok(status == STATUS_ACCESS_VIOLATION, "NtSetTimerResolution(,,NULL) success\n");
/* Nothing happens if that pointer is not good */
status = NtSetTimerResolution(cur - 1, TRUE, NULL);
- todo_wine ok(status == STATUS_ACCESS_VIOLATION, "NtSetTimerResolution() failed %x\n", status);
+ ok(status == STATUS_ACCESS_VIOLATION, "NtSetTimerResolution() failed %x\n", status);
min2 = min + 1;
cur2 = min2 + 1;
max2 = cur2 + 1;
status = NtQueryTimerResolution(&min2, &max2, &cur2);
- todo_wine ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
- todo_wine ok(min2 == min, "NtQueryTimerResolution() expected min=%u, got %u\n", min, min2);
- todo_wine ok(max2 == max, "NtQueryTimerResolution() expected max=%u, got %u\n", max, max2);
- todo_wine ok(cur2 == cur, "NtQueryTimerResolution() expected timer resolution %u, got %u\n", cur, cur2);
+ ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
+ ok(min2 == min, "NtQueryTimerResolution() expected min=%u, got %u\n", min, min2);
+ ok(max2 == max, "NtQueryTimerResolution() expected max=%u, got %u\n", max, max2);
+ ok(cur2 == cur, "NtQueryTimerResolution() expected timer resolution %u, got %u\n", cur, cur2);
/* 'fails' until the first valid timer resolution request */
cur2 = 7654321;
status = NtSetTimerResolution(0, FALSE, &cur2);
- todo_wine ok(status == STATUS_TIMER_RESOLUTION_NOT_SET, "NtSetTimerResolution() failed %x\n", status);
+ ok(status == STATUS_TIMER_RESOLUTION_NOT_SET, "NtSetTimerResolution() failed %x\n", status);
/* and returns the current timer resolution */
- todo_wine ok(cur2 == cur, "expected requested timer resolution %u, got %u\n", cur, cur2);
+ ok(cur2 == cur, "expected requested timer resolution %u, got %u\n", cur, cur2);
cur2 = 7654321;
@@ -285,18 +285,18 @@ static void test_TimerResolution(void)
/* Rescinds our timer resolution request */
cur2 = 7654321;
status = NtSetTimerResolution(0, FALSE, &cur2);
- todo_wine ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %x\n", status);
+ ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %x\n", status);
/* -> the timer resolution was reset to its initial value */
- todo_wine ok(cur2 == cur, "expected requested timer resolution %u, got %u\n", min, cur2);
+ ok(cur2 == cur, "expected requested timer resolution %u, got %u\n", min, cur2);
cur2 = 7654321;
status = NtSetTimerResolution(0, FALSE, &cur2);
- todo_wine ok(status == STATUS_TIMER_RESOLUTION_NOT_SET, "NtSetTimerResolution() failed %x\n", status);
- todo_wine ok(cur2 == cur, "expected requested timer resolution %u, got %u\n", cur, cur2);
+ ok(status == STATUS_TIMER_RESOLUTION_NOT_SET, "NtSetTimerResolution() failed %x\n", status);
+ ok(cur2 == cur, "expected requested timer resolution %u, got %u\n", cur, cur2);
cur2 = 7654321;
status = NtSetTimerResolution(min + 1, TRUE, &cur2);
- todo_wine ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %x\n", status);
+ ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %x\n", status);
/* This works because:
* - Either cur is the minimum (15.6 ms) resolution already, i.e. the
* closest valid value 'set' is rounded to.
@@ -310,8 +310,8 @@ static void test_TimerResolution(void)
cur2 = 7654321;
set = max < cur ? cur - 1 : max;
status = NtSetTimerResolution(set, TRUE, &cur2);
- todo_wine ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %x\n", status);
- todo_wine ok(cur2 <= set, "expected new timer resolution %u <= %u\n", cur2, set);
+ ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %x\n", status);
+ ok(cur2 <= set, "expected new timer resolution %u <= %u\n", cur2, set);
trace("timer resolution: %u(max) <= %u(cur) <= %u(prev) <= %u(min)\n", max, cur2, cur, min);
cur2 = 7654321;
@@ -321,8 +321,8 @@ static void test_TimerResolution(void)
/* Cleanup by rescinding the last request */
cur2 = 7654321;
status = NtSetTimerResolution(0, FALSE, &cur2);
- todo_wine ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %x\n", status);
- todo_wine ok(cur2 == cur, "expected requested timer resolution %u, got %u\n", set, cur2);
+ ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %x\n", status);
+ ok(cur2 == cur, "expected requested timer resolution %u, got %u\n", set, cur2);
}
static void test_RtlQueryTimeZoneInformation(void)
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
index 7bdce91e034..d839195fd07 100644
--- a/dlls/ntdll/unix/sync.c
+++ b/dlls/ntdll/unix/sync.c
@@ -1599,8 +1599,13 @@ NTSTATUS WINAPI NtSetSystemTime( const LARGE_INTEGER *new, LARGE_INTEGER *old )
*/
NTSTATUS WINAPI NtQueryTimerResolution( ULONG *min_res, ULONG *max_res, ULONG *current_res )
{
- FIXME( "(%p,%p,%p), stub!\n", min_res, max_res, current_res );
- return STATUS_NOT_IMPLEMENTED;
+ TRACE( "(%p,%p,%p)\n", min_res, max_res, current_res );
+ if (!min_res || !max_res || !current_res)
+ return STATUS_ACCESS_VIOLATION;
+
+ *max_res = *current_res = 10000; /* See NtSetTimerResolution() */
+ *min_res = 156250;
+ return STATUS_SUCCESS;
}
@@ -1609,8 +1614,28 @@ NTSTATUS WINAPI NtQueryTimerResolution( ULONG *min_res, ULONG *max_res, ULONG *c
*/
NTSTATUS WINAPI NtSetTimerResolution( ULONG res, BOOLEAN set, ULONG *current_res )
{
- FIXME( "(%u,%u,%p), stub!\n", res, set, current_res );
- return STATUS_NOT_IMPLEMENTED;
+ static BOOL has_request = FALSE;
+ TRACE( "(%u,%u,%p), semi-stub!\n", res, set, current_res );
+
+ if (!current_res)
+ return STATUS_ACCESS_VIOLATION;
+
+ /* Wine has no support for anything other that 1 ms and does not keep of
+ * track resolution requests anyway.
+ * Fortunately NtSetTimerResolution() should ignore requests to lower the
+ * timer resolution. So by claiming that 'some other process' requested the
+ * max resolution already, there no need to actually change it.
+ */
+ *current_res = 10000;
+
+ /* Just keep track of whether this process requested a specific timer
+ * resolution.
+ */
+ if (!has_request && !set)
+ return STATUS_TIMER_RESOLUTION_NOT_SET;
+ has_request = set;
+
+ return STATUS_SUCCESS;
}
--
2.20.1
July 29, 2021
[PATCH v3 2/3] ntdll/tests: Add some Nt{Query,Set}TimerResolution() tests.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
v2: No change since v1.
---
dlls/ntdll/tests/time.c | 110 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 110 insertions(+)
diff --git a/dlls/ntdll/tests/time.c b/dlls/ntdll/tests/time.c
index ee683e9a0aa..5f9c49989d8 100644
--- a/dlls/ntdll/tests/time.c
+++ b/dlls/ntdll/tests/time.c
@@ -216,6 +216,115 @@ static void test_RtlQueryPerformanceCounter(void)
}
#endif
+#define CHECK_CURRENT_TIMER(expected) \
+ do { \
+ todo_wine ok(status == STATUS_SUCCESS, "NtSetTimerResolution failed %x\n", status); \
+ todo_wine ok(cur2 == (expected), "expected new timer resolution %u, got %u\n", (expected), cur2); \
+ min2 = min + 10; \
+ cur2 = min2 + 1; \
+ max2 = cur2 + 1; \
+ status = NtQueryTimerResolution(&min2, &max2, &cur2); \
+ todo_wine ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed %x\n", status); \
+ todo_wine ok(min2 == min, "NtQueryTimerResolution() expected min=%u, got %u\n", min, min2); \
+ todo_wine ok(max2 == max, "NtQueryTimerResolution() expected max=%u, got %u\n", max, max2); \
+ todo_wine ok(cur2 == expected, "NtQueryTimerResolution() expected timer resolution %u, got %u\n", (expected), cur2); \
+ } while (0)
+
+static void test_TimerResolution(void)
+{
+ ULONG min, max, cur, min2, max2, cur2, set;
+ NTSTATUS status;
+
+ status = NtQueryTimerResolution(NULL, &max, &cur);
+ todo_wine ok(status == STATUS_ACCESS_VIOLATION, "NtQueryTimerResolution(NULL,,) success\n");
+
+ status = NtQueryTimerResolution(&min, NULL, &cur);
+ todo_wine ok(status == STATUS_ACCESS_VIOLATION, "NtQueryTimerResolution(,NULL,) success\n");
+
+ status = NtQueryTimerResolution(&min, &max, NULL);
+ todo_wine ok(status == STATUS_ACCESS_VIOLATION, "NtQueryTimerResolution(,,NULL) success\n");
+
+ min = 212121;
+ cur = min + 1;
+ max = cur + 1;
+ status = NtQueryTimerResolution(&min, &max, &cur);
+ todo_wine ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
+ todo_wine ok(min == 156250 /* 1/64s HPET */ || min == 156001 /* RTC */,
+ "unexpected minimum timer resolution %u\n", min);
+ ok(0 < max, "invalid maximum timer resolution, should be 0 < %u\n", max);
+ todo_wine ok(max <= cur && cur <= min, "invalid timer resolutions, should be %u <= %u <= %u\n", max, cur, min);
+
+ status = NtSetTimerResolution(0, FALSE, NULL);
+ todo_wine ok(status == STATUS_ACCESS_VIOLATION, "NtSetTimerResolution(,,NULL) success\n");
+
+ /* Nothing happens if that pointer is not good */
+ status = NtSetTimerResolution(cur - 1, TRUE, NULL);
+ todo_wine ok(status == STATUS_ACCESS_VIOLATION, "NtSetTimerResolution() failed %x\n", status);
+
+ min2 = min + 1;
+ cur2 = min2 + 1;
+ max2 = cur2 + 1;
+ status = NtQueryTimerResolution(&min2, &max2, &cur2);
+ todo_wine ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
+ todo_wine ok(min2 == min, "NtQueryTimerResolution() expected min=%u, got %u\n", min, min2);
+ todo_wine ok(max2 == max, "NtQueryTimerResolution() expected max=%u, got %u\n", max, max2);
+ todo_wine ok(cur2 == cur, "NtQueryTimerResolution() expected timer resolution %u, got %u\n", cur, cur2);
+
+ /* 'fails' until the first valid timer resolution request */
+ cur2 = 7654321;
+ status = NtSetTimerResolution(0, FALSE, &cur2);
+ todo_wine ok(status == STATUS_TIMER_RESOLUTION_NOT_SET, "NtSetTimerResolution() failed %x\n", status);
+ /* and returns the current timer resolution */
+ todo_wine ok(cur2 == cur, "expected requested timer resolution %u, got %u\n", cur, cur2);
+
+
+ cur2 = 7654321;
+ status = NtSetTimerResolution(max - 1, TRUE, &cur2);
+ CHECK_CURRENT_TIMER(max);
+
+ /* Rescinds our timer resolution request */
+ cur2 = 7654321;
+ status = NtSetTimerResolution(0, FALSE, &cur2);
+ todo_wine ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %x\n", status);
+ /* -> the timer resolution was reset to its initial value */
+ todo_wine ok(cur2 == cur, "expected requested timer resolution %u, got %u\n", min, cur2);
+
+ cur2 = 7654321;
+ status = NtSetTimerResolution(0, FALSE, &cur2);
+ todo_wine ok(status == STATUS_TIMER_RESOLUTION_NOT_SET, "NtSetTimerResolution() failed %x\n", status);
+ todo_wine ok(cur2 == cur, "expected requested timer resolution %u, got %u\n", cur, cur2);
+
+ cur2 = 7654321;
+ status = NtSetTimerResolution(min + 1, TRUE, &cur2);
+ todo_wine ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %x\n", status);
+ /* This works because:
+ * - Either cur is the minimum (15.6 ms) resolution already, i.e. the
+ * closest valid value 'set' is rounded to.
+ * - Or some other application requested a higher timer resolution, cur,
+ * and any attempt to lower the resolution has no effect until that
+ * request is rescinded (hopefully after this test is done).
+ */
+ CHECK_CURRENT_TIMER(cur);
+
+ /* The requested resolution may (win7) or may not be rounded */
+ cur2 = 7654321;
+ set = max < cur ? cur - 1 : max;
+ status = NtSetTimerResolution(set, TRUE, &cur2);
+ todo_wine ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %x\n", status);
+ todo_wine ok(cur2 <= set, "expected new timer resolution %u <= %u\n", cur2, set);
+ trace("timer resolution: %u(max) <= %u(cur) <= %u(prev) <= %u(min)\n", max, cur2, cur, min);
+
+ cur2 = 7654321;
+ status = NtSetTimerResolution(cur + 1, TRUE, &cur2);
+ CHECK_CURRENT_TIMER(cur); /* see min + 1 test */
+
+ /* Cleanup by rescinding the last request */
+ cur2 = 7654321;
+ status = NtSetTimerResolution(0, FALSE, &cur2);
+ todo_wine ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %x\n", status);
+ todo_wine ok(cur2 == cur, "expected requested timer resolution %u, got %u\n", set, cur2);
+}
+
static void test_RtlQueryTimeZoneInformation(void)
{
RTL_DYNAMIC_TIME_ZONE_INFORMATION tzinfo, tzinfo2;
@@ -379,4 +488,5 @@ START_TEST(time)
#if defined(__i386__) || defined(__x86_64__)
test_RtlQueryPerformanceCounter();
#endif
+ test_TimerResolution();
}
--
2.20.1
July 29, 2021
[PATCH v3 1/3] kernelbase/tests: Fix the Sleep() test for non-default timer resolutions.
by Francois Gouget
Also defend against timer resolution changes during the test.
Reduce the test duration a bit.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51533
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
v2: The timer resolution change and test duration.
v3: No change.
This should fix the failures on cw-rx460 when the Radeon driver sets
the timer resolution to 2 ms.
---
dlls/kernelbase/tests/sync.c | 29 +++++++++++++++++++++++++----
1 file changed, 25 insertions(+), 4 deletions(-)
diff --git a/dlls/kernelbase/tests/sync.c b/dlls/kernelbase/tests/sync.c
index 50ce62602b0..8127b4238b9 100644
--- a/dlls/kernelbase/tests/sync.c
+++ b/dlls/kernelbase/tests/sync.c
@@ -19,10 +19,14 @@
*/
#include <stdarg.h>
+#include <stdlib.h>
+
+#include <ntstatus.h>
+#define WIN32_NO_STATUS
#include <windef.h>
#include <winbase.h>
-#include <stdlib.h>
#include <winerror.h>
+#include <winternl.h>
#include "wine/test.h"
@@ -176,7 +180,9 @@ static void test_Sleep(void)
{
LARGE_INTEGER frequency;
LARGE_INTEGER t1, t2;
- double elapsed_time;
+ double elapsed_time, min, max;
+ ULONG dummy, r1, r2;
+ NTSTATUS status;
BOOL ret;
int i;
@@ -186,15 +192,30 @@ static void test_Sleep(void)
ret = QueryPerformanceCounter(&t1);
ok(ret, "QueryPerformanceCounter failed\n");
- for (i = 0; i < 100; i++) {
+ /* Get the timer resolution before... */
+ r1 = 156250;
+ status = NtQueryTimerResolution(&dummy, &dummy, &r1);
+ todo_wine ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
+
+ for (i = 0; i < 50; i++) {
Sleep(1);
}
ret = QueryPerformanceCounter(&t2);
ok(ret, "QueryPerformanceCounter failed\n");
+ /* ...and after in case some other process changes it during this test */
+ r2 = 156250;
+ status = NtQueryTimerResolution(&dummy, &dummy, &r2);
+ todo_wine ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
+
elapsed_time = (t2.QuadPart - t1.QuadPart) / (double)frequency.QuadPart;
- todo_wine ok(elapsed_time >= 1.5 && elapsed_time <= 4.0, "got %f\n", elapsed_time);
+ min = 50.0 * (r1 < r2 ? r1 : r2) / 10000000.0;
+ max = 50.0 * (r1 < r2 ? r2 : r1) / 10000000.0;
+
+ /* Add an extra 1s to account for potential scheduling delays */
+ todo_wine ok(0.9 * min <= elapsed_time && elapsed_time <= 1.0 + max,
+ "got %f, expected between %f and %f\n", elapsed_time, min, max);
}
START_TEST(sync)
--
2.20.1
July 29, 2021
Re: [PATCH v2 3/3] ntdll: Improve the Nt{Query, Set}TimerResolution() stubs.
by Francois Gouget
On Thu, 29 Jul 2021, Francois Gouget wrote:
> Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
> ---
> v2: Only rebased.
I forgot to remove a todo_wine during the rebase :-(
It's the only failure highlighted by the TestBot so hopefully v3 will be
all good.
--
Francois Gouget <fgouget(a)codeweavers.com>
July 29, 2021
Re: [PATCH v2 3/3] ntdll: Improve the Nt{Query, Set}TimerResolution() stubs.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=94700
Your paranoid android.
=== debiant2 (32 bit report) ===
kernelbase:
sync.c:198: Test succeeded inside todo block: NtQueryTimerResolution() failed (0)
=== debiant2 (32 bit Arabic:Morocco report) ===
kernelbase:
sync.c:198: Test succeeded inside todo block: NtQueryTimerResolution() failed (0)
=== debiant2 (32 bit German report) ===
kernelbase:
sync.c:198: Test succeeded inside todo block: NtQueryTimerResolution() failed (0)
=== debiant2 (32 bit French report) ===
kernelbase:
sync.c:198: Test succeeded inside todo block: NtQueryTimerResolution() failed (0)
=== debiant2 (32 bit Hebrew:Israel report) ===
kernelbase:
sync.c:198: Test succeeded inside todo block: NtQueryTimerResolution() failed (0)
=== debiant2 (32 bit Hindi:India report) ===
kernelbase:
sync.c:198: Test succeeded inside todo block: NtQueryTimerResolution() failed (0)
=== debiant2 (32 bit Japanese:Japan report) ===
kernelbase:
sync.c:198: Test succeeded inside todo block: NtQueryTimerResolution() failed (0)
=== debiant2 (32 bit Chinese:China report) ===
kernelbase:
sync.c:198: Test succeeded inside todo block: NtQueryTimerResolution() failed (0)
=== debiant2 (32 bit WoW report) ===
kernelbase:
sync.c:198: Test succeeded inside todo block: NtQueryTimerResolution() failed (0)
=== debiant2 (64 bit WoW report) ===
kernelbase:
sync.c:198: Test succeeded inside todo block: NtQueryTimerResolution() failed (0)
July 29, 2021