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
December 2024
- 9 participants
- 76 messages
[PATCH v7 03/30] ntsync: Introduce NTSYNC_IOC_WAIT_ANY.
by Elizabeth Figura
This corresponds to part of the functionality of the NT syscall
NtWaitForMultipleObjects(). Specifically, it implements the behaviour where
the third argument (wait_any) is TRUE, and it does not handle alertable waits.
Those features have been split out into separate patches to ease review.
This patch therefore implements the wait/wake infrastructure which comprises the
core of ntsync's functionality.
NTSYNC_IOC_WAIT_ANY is a vectored wait function similar to poll(). Unlike
poll(), it "consumes" objects when they are signaled. For semaphores, this means
decreasing one from the internal counter. At most one object can be consumed by
this function.
This wait/wake model is fundamentally different from that used anywhere else in
the kernel, and for that reason ntsync does not use any existing infrastructure,
such as futexes, kernel mutexes or semaphores, or wait_event().
Up to 64 objects can be waited on at once. As soon as one is signaled, the
object with the lowest index is consumed, and that index is returned via the
"index" field.
A timeout is supported. The timeout is passed as a u64 nanosecond value, which
represents absolute time measured against either the MONOTONIC or REALTIME clock
(controlled by the flags argument). If U64_MAX is passed, the ioctl waits
indefinitely.
This ioctl validates that all objects belong to the relevant device. This is not
necessary for any technical reason related to NTSYNC_IOC_WAIT_ANY, but will be
necessary for NTSYNC_IOC_WAIT_ALL introduced in the following patch.
Some padding fields are added for alignment and for fields which will be added
in future patches (split out to ease review).
Signed-off-by: Elizabeth Figura <zfigura(a)codeweavers.com>
---
drivers/misc/ntsync.c | 247 +++++++++++++++++++++++++++++++++++-
include/uapi/linux/ntsync.h | 14 ++
2 files changed, 260 insertions(+), 1 deletion(-)
diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c
index cb3a3bd97ba0..900cc5ce5761 100644
--- a/drivers/misc/ntsync.c
+++ b/drivers/misc/ntsync.c
@@ -6,11 +6,16 @@
*/
#include <linux/anon_inodes.h>
+#include <linux/atomic.h>
#include <linux/file.h>
#include <linux/fs.h>
+#include <linux/hrtimer.h>
+#include <linux/ktime.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/overflow.h>
+#include <linux/sched.h>
+#include <linux/sched/signal.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <uapi/linux/ntsync.h>
@@ -30,6 +35,8 @@ enum ntsync_type {
*
* Both rely on struct file for reference counting. Individual
* ntsync_obj objects take a reference to the device when created.
+ * Wait operations take a reference to each object being waited on for
+ * the duration of the wait.
*/
struct ntsync_obj {
@@ -47,12 +54,55 @@ struct ntsync_obj {
__u32 max;
} sem;
} u;
+
+ struct list_head any_waiters;
+};
+
+struct ntsync_q_entry {
+ struct list_head node;
+ struct ntsync_q *q;
+ struct ntsync_obj *obj;
+ __u32 index;
+};
+
+struct ntsync_q {
+ struct task_struct *task;
+
+ /*
+ * Protected via atomic_try_cmpxchg(). Only the thread that wins the
+ * compare-and-swap may actually change object states and wake this
+ * task.
+ */
+ atomic_t signaled;
+
+ __u32 count;
+ struct ntsync_q_entry entries[];
};
struct ntsync_device {
struct file *file;
};
+static void try_wake_any_sem(struct ntsync_obj *sem)
+{
+ struct ntsync_q_entry *entry;
+
+ lockdep_assert_held(&sem->lock);
+
+ list_for_each_entry(entry, &sem->any_waiters, node) {
+ struct ntsync_q *q = entry->q;
+ int signaled = -1;
+
+ if (!sem->u.sem.count)
+ break;
+
+ if (atomic_try_cmpxchg(&q->signaled, &signaled, entry->index)) {
+ sem->u.sem.count--;
+ wake_up_process(q->task);
+ }
+ }
+}
+
/*
* Actually change the semaphore state, returning -EOVERFLOW if it is made
* invalid.
@@ -87,7 +137,9 @@ static int ntsync_sem_release(struct ntsync_obj *sem, void __user *argp)
spin_lock(&sem->lock);
prev_count = sem->u.sem.count;
- ret = release_sem_state(sem, args);
+ ret = post_sem_state(sem, args);
+ if (!ret)
+ try_wake_any_sem(sem);
spin_unlock(&sem->lock);
@@ -140,6 +192,7 @@ static struct ntsync_obj *ntsync_alloc_obj(struct ntsync_device *dev,
obj->dev = dev;
get_file(dev->file);
spin_lock_init(&obj->lock);
+ INIT_LIST_HEAD(&obj->any_waiters);
return obj;
}
@@ -187,6 +240,196 @@ static int ntsync_create_sem(struct ntsync_device *dev, void __user *argp)
return fd;
}
+static struct ntsync_obj *get_obj(struct ntsync_device *dev, int fd)
+{
+ struct file *file = fget(fd);
+ struct ntsync_obj *obj;
+
+ if (!file)
+ return NULL;
+
+ if (file->f_op != &ntsync_obj_fops) {
+ fput(file);
+ return NULL;
+ }
+
+ obj = file->private_data;
+ if (obj->dev != dev) {
+ fput(file);
+ return NULL;
+ }
+
+ return obj;
+}
+
+static void put_obj(struct ntsync_obj *obj)
+{
+ fput(obj->file);
+}
+
+static int ntsync_schedule(const struct ntsync_q *q, const struct ntsync_wait_args *args)
+{
+ ktime_t timeout = ns_to_ktime(args->timeout);
+ clockid_t clock = CLOCK_MONOTONIC;
+ ktime_t *timeout_ptr;
+ int ret = 0;
+
+ timeout_ptr = (args->timeout == U64_MAX ? NULL : &timeout);
+
+ if (args->flags & NTSYNC_WAIT_REALTIME)
+ clock = CLOCK_REALTIME;
+
+ do {
+ if (signal_pending(current)) {
+ ret = -ERESTARTSYS;
+ break;
+ }
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (atomic_read(&q->signaled) != -1) {
+ ret = 0;
+ break;
+ }
+ ret = schedule_hrtimeout_range_clock(timeout_ptr, 0, HRTIMER_MODE_ABS, clock);
+ } while (ret < 0);
+ __set_current_state(TASK_RUNNING);
+
+ return ret;
+}
+
+/*
+ * Allocate and initialize the ntsync_q structure, but do not queue us yet.
+ */
+static int setup_wait(struct ntsync_device *dev,
+ const struct ntsync_wait_args *args,
+ struct ntsync_q **ret_q)
+{
+ const __u32 count = args->count;
+ int fds[NTSYNC_MAX_WAIT_COUNT];
+ struct ntsync_q *q;
+ __u32 i, j;
+
+ if (args->pad[0] || args->pad[1] || args->pad[2] || (args->flags & ~NTSYNC_WAIT_REALTIME))
+ return -EINVAL;
+
+ if (args->count > NTSYNC_MAX_WAIT_COUNT)
+ return -EINVAL;
+
+ if (copy_from_user(fds, u64_to_user_ptr(args->objs),
+ array_size(count, sizeof(*fds))))
+ return -EFAULT;
+
+ q = kmalloc(struct_size(q, entries, count), GFP_KERNEL);
+ if (!q)
+ return -ENOMEM;
+ q->task = current;
+ atomic_set(&q->signaled, -1);
+ q->count = count;
+
+ for (i = 0; i < count; i++) {
+ struct ntsync_q_entry *entry = &q->entries[i];
+ struct ntsync_obj *obj = get_obj(dev, fds[i]);
+
+ if (!obj)
+ goto err;
+
+ entry->obj = obj;
+ entry->q = q;
+ entry->index = i;
+ }
+
+ *ret_q = q;
+ return 0;
+
+err:
+ for (j = 0; j < i; j++)
+ put_obj(q->entries[j].obj);
+ kfree(q);
+ return -EINVAL;
+}
+
+static void try_wake_any_obj(struct ntsync_obj *obj)
+{
+ switch (obj->type) {
+ case NTSYNC_TYPE_SEM:
+ try_wake_any_sem(obj);
+ break;
+ }
+}
+
+static int ntsync_wait_any(struct ntsync_device *dev, void __user *argp)
+{
+ struct ntsync_wait_args args;
+ struct ntsync_q *q;
+ int signaled;
+ __u32 i;
+ int ret;
+
+ if (copy_from_user(&args, argp, sizeof(args)))
+ return -EFAULT;
+
+ ret = setup_wait(dev, &args, &q);
+ if (ret < 0)
+ return ret;
+
+ /* queue ourselves */
+
+ for (i = 0; i < args.count; i++) {
+ struct ntsync_q_entry *entry = &q->entries[i];
+ struct ntsync_obj *obj = entry->obj;
+
+ spin_lock(&obj->lock);
+ list_add_tail(&entry->node, &obj->any_waiters);
+ spin_unlock(&obj->lock);
+ }
+
+ /* check if we are already signaled */
+
+ for (i = 0; i < args.count; i++) {
+ struct ntsync_obj *obj = q->entries[i].obj;
+
+ if (atomic_read(&q->signaled) != -1)
+ break;
+
+ spin_lock(&obj->lock);
+ try_wake_any_obj(obj);
+ spin_unlock(&obj->lock);
+ }
+
+ /* sleep */
+
+ ret = ntsync_schedule(q, &args);
+
+ /* and finally, unqueue */
+
+ for (i = 0; i < args.count; i++) {
+ struct ntsync_q_entry *entry = &q->entries[i];
+ struct ntsync_obj *obj = entry->obj;
+
+ spin_lock(&obj->lock);
+ list_del(&entry->node);
+ spin_unlock(&obj->lock);
+
+ put_obj(obj);
+ }
+
+ signaled = atomic_read(&q->signaled);
+ if (signaled != -1) {
+ struct ntsync_wait_args __user *user_args = argp;
+
+ /* even if we caught a signal, we need to communicate success */
+ ret = 0;
+
+ if (put_user(signaled, &user_args->index))
+ ret = -EFAULT;
+ } else if (!ret) {
+ ret = -ETIMEDOUT;
+ }
+
+ kfree(q);
+ return ret;
+}
+
static int ntsync_char_open(struct inode *inode, struct file *file)
{
struct ntsync_device *dev;
@@ -218,6 +461,8 @@ static long ntsync_char_ioctl(struct file *file, unsigned int cmd,
switch (cmd) {
case NTSYNC_IOC_CREATE_SEM:
return ntsync_create_sem(dev, argp);
+ case NTSYNC_IOC_WAIT_ANY:
+ return ntsync_wait_any(dev, argp);
default:
return -ENOIOCTLCMD;
}
diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h
index 9af9d8125553..40ffdc41d5bb 100644
--- a/include/uapi/linux/ntsync.h
+++ b/include/uapi/linux/ntsync.h
@@ -15,7 +15,21 @@ struct ntsync_sem_args {
__u32 max;
};
+#define NTSYNC_WAIT_REALTIME 0x1
+
+struct ntsync_wait_args {
+ __u64 timeout;
+ __u64 objs;
+ __u32 count;
+ __u32 index;
+ __u32 flags;
+ __u32 pad[3];
+};
+
+#define NTSYNC_MAX_WAIT_COUNT 64
+
#define NTSYNC_IOC_CREATE_SEM _IOW ('N', 0x80, struct ntsync_sem_args)
+#define NTSYNC_IOC_WAIT_ANY _IOWR('N', 0x82, struct ntsync_wait_args)
#define NTSYNC_IOC_SEM_RELEASE _IOWR('N', 0x81, __u32)
--
2.45.2
Dec. 13, 2024
[PATCH v7 02/30] ntsync: Rename NTSYNC_IOC_SEM_POST to NTSYNC_IOC_SEM_RELEASE.
by Elizabeth Figura
Use the more common "release" terminology, which is also the term used by NT,
instead of "post" (which is used by POSIX).
Signed-off-by: Elizabeth Figura <zfigura(a)codeweavers.com>
---
drivers/misc/ntsync.c | 10 +++++-----
include/uapi/linux/ntsync.h | 2 +-
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c
index 2e7f698268c1..cb3a3bd97ba0 100644
--- a/drivers/misc/ntsync.c
+++ b/drivers/misc/ntsync.c
@@ -57,7 +57,7 @@ struct ntsync_device {
* Actually change the semaphore state, returning -EOVERFLOW if it is made
* invalid.
*/
-static int post_sem_state(struct ntsync_obj *sem, __u32 count)
+static int release_sem_state(struct ntsync_obj *sem, __u32 count)
{
__u32 sum;
@@ -71,7 +71,7 @@ static int post_sem_state(struct ntsync_obj *sem, __u32 count)
return 0;
}
-static int ntsync_sem_post(struct ntsync_obj *sem, void __user *argp)
+static int ntsync_sem_release(struct ntsync_obj *sem, void __user *argp)
{
__u32 __user *user_args = argp;
__u32 prev_count;
@@ -87,7 +87,7 @@ static int ntsync_sem_post(struct ntsync_obj *sem, void __user *argp)
spin_lock(&sem->lock);
prev_count = sem->u.sem.count;
- ret = post_sem_state(sem, args);
+ ret = release_sem_state(sem, args);
spin_unlock(&sem->lock);
@@ -114,8 +114,8 @@ static long ntsync_obj_ioctl(struct file *file, unsigned int cmd,
void __user *argp = (void __user *)parm;
switch (cmd) {
- case NTSYNC_IOC_SEM_POST:
- return ntsync_sem_post(obj, argp);
+ case NTSYNC_IOC_SEM_RELEASE:
+ return ntsync_sem_release(obj, argp);
default:
return -ENOIOCTLCMD;
}
diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h
index 27d8cb3dd5b7..9af9d8125553 100644
--- a/include/uapi/linux/ntsync.h
+++ b/include/uapi/linux/ntsync.h
@@ -17,6 +17,6 @@ struct ntsync_sem_args {
#define NTSYNC_IOC_CREATE_SEM _IOW ('N', 0x80, struct ntsync_sem_args)
-#define NTSYNC_IOC_SEM_POST _IOWR('N', 0x81, __u32)
+#define NTSYNC_IOC_SEM_RELEASE _IOWR('N', 0x81, __u32)
#endif
--
2.45.2
Dec. 13, 2024
[PATCH v7 01/30] ntsync: Return the fd from NTSYNC_IOC_CREATE_SEM.
by Elizabeth Figura
Simplify the user API a bit by returning the fd as return value from the ioctl
instead of through the argument pointer.
Signed-off-by: Elizabeth Figura <zfigura(a)codeweavers.com>
---
drivers/misc/ntsync.c | 7 ++-----
include/uapi/linux/ntsync.h | 3 +--
2 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c
index 4954553b7baa..2e7f698268c1 100644
--- a/drivers/misc/ntsync.c
+++ b/drivers/misc/ntsync.c
@@ -165,7 +165,6 @@ static int ntsync_obj_get_fd(struct ntsync_obj *obj)
static int ntsync_create_sem(struct ntsync_device *dev, void __user *argp)
{
- struct ntsync_sem_args __user *user_args = argp;
struct ntsync_sem_args args;
struct ntsync_obj *sem;
int fd;
@@ -182,12 +181,10 @@ static int ntsync_create_sem(struct ntsync_device *dev, void __user *argp)
sem->u.sem.count = args.count;
sem->u.sem.max = args.max;
fd = ntsync_obj_get_fd(sem);
- if (fd < 0) {
+ if (fd < 0)
kfree(sem);
- return fd;
- }
- return put_user(fd, &user_args->sem);
+ return fd;
}
static int ntsync_char_open(struct inode *inode, struct file *file)
diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h
index dcfa38fdc93c..27d8cb3dd5b7 100644
--- a/include/uapi/linux/ntsync.h
+++ b/include/uapi/linux/ntsync.h
@@ -11,12 +11,11 @@
#include <linux/types.h>
struct ntsync_sem_args {
- __u32 sem;
__u32 count;
__u32 max;
};
-#define NTSYNC_IOC_CREATE_SEM _IOWR('N', 0x80, struct ntsync_sem_args)
+#define NTSYNC_IOC_CREATE_SEM _IOW ('N', 0x80, struct ntsync_sem_args)
#define NTSYNC_IOC_SEM_POST _IOWR('N', 0x81, __u32)
--
2.45.2
Dec. 13, 2024
[PATCH v7 00/30] NT synchronization primitive driver
by Elizabeth Figura
This patch series implements a new char misc driver, /dev/ntsync, which is used
to implement Windows NT synchronization primitives.
NT synchronization primitives are unique in that the wait functions both are
vectored, operate on multiple types of object with different behaviour (mutex,
semaphore, event), and affect the state of the objects they wait on. This model
is not compatible with existing kernel synchronization objects or interfaces,
and therefore the ntsync driver implements its own wait queues and locking.
This patch series is rebased against the "char-misc-next" branch of
gregkh/char-misc.git.
== Background ==
The Wine project emulates the Windows API in user space. One particular part of
that API, namely the NT synchronization primitives, have historically been
implemented via RPC to a dedicated "kernel" process. However, more recent
applications use these APIs more strenuously, and the overhead of RPC has become
a bottleneck.
The NT synchronization APIs are too complex to implement on top of existing
primitives without sacrificing correctness. Certain operations, such as
NtPulseEvent() or the "wait-for-all" mode of NtWaitForMultipleObjects(), require
direct control over the underlying wait queue, and implementing a wait queue
sufficiently robust for Wine in user space is not possible. This proposed
driver, therefore, implements the problematic interfaces directly in the Linux
kernel.
This driver was presented at Linux Plumbers Conference 2023. For those further
interested in the history of synchronization in Wine and past attempts to solve
this problem in user space, a recording of the presentation can be viewed here:
https://www.youtube.com/watch?v=NjU4nyWyhU8
== Performance ==
The performance measurements described below are copied from earlier versions of
the patch set. While some of the code has changed, I do not currently anticipate
that it has changed drastically enough to affect those measurements.
The gain in performance varies wildly depending on the application in question
and the user's hardware. For some games NT synchronization is not a bottleneck
and no change can be observed, but for others frame rate improvements of 50 to
150 percent are not atypical. The following table lists frame rate measurements
from a variety of games on a variety of hardware, taken by users Dmitry
Skvortsov, FuzzyQuils, OnMars, and myself:
Game Upstream ntsync improvement
===========================================================================
Anger Foot 69 99 43%
Call of Juarez 99.8 224.1 125%
Dirt 3 110.6 860.7 678%
Forza Horizon 5 108 160 48%
Lara Croft: Temple of Osiris 141 326 131%
Metro 2033 164.4 199.2 21%
Resident Evil 2 26 77 196%
The Crew 26 51 96%
Tiny Tina's Wonderlands 130 360 177%
Total War Saga: Troy 109 146 34%
===========================================================================
== Patches ==
The intended semantics of the patches are broadly intended to match those of the
corresponding Windows functions. For those not already familiar with the Windows
functions (or their undocumented behaviour), patch 27/28 provides a detailed
specification, and individual patches also include a brief description of the
API they are implementing.
The patches making use of this driver in Wine can be retrieved or browsed here:
https://repo.or.cz/wine/zf.git/shortlog/refs/heads/ntsync7
== Previous versions ==
Changes from v6:
* rename NTSYNC_IOC_SEM_POST to NTSYNC_IOC_SEM_RELEASE (matching the NT
terminology instead of POSIX),
* change object creation ioctls to return the fds directly in the return value
instead of through the args struct, which simplifies the API a bit.
* Link to v6: https://lore.kernel.org/lkml/20241209185904.507350-1-zfigura(a)codeweavers.…
* Link to v5: https://lore.kernel.org/lkml/20240519202454.1192826-1-zfigura(a)codeweavers…
* Link to v4: https://lore.kernel.org/lkml/20240416010837.333694-1-zfigura(a)codeweavers.…
* Link to v3: https://lore.kernel.org/lkml/20240329000621.148791-1-zfigura(a)codeweavers.…
* Link to v2: https://lore.kernel.org/lkml/20240219223833.95710-1-zfigura(a)codeweavers.c…
* Link to v1: https://lore.kernel.org/lkml/20240214233645.9273-1-zfigura(a)codeweavers.co…
* Link to RFC v2: https://lore.kernel.org/lkml/20240131021356.10322-1-zfigura(a)codeweavers.c…
* Link to RFC v1: https://lore.kernel.org/lkml/20240124004028.16826-1-zfigura(a)codeweavers.c…
Elizabeth Figura (30):
ntsync: Return the fd from NTSYNC_IOC_CREATE_SEM.
ntsync: Rename NTSYNC_IOC_SEM_POST to NTSYNC_IOC_SEM_RELEASE.
ntsync: Introduce NTSYNC_IOC_WAIT_ANY.
ntsync: Introduce NTSYNC_IOC_WAIT_ALL.
ntsync: Introduce NTSYNC_IOC_CREATE_MUTEX.
ntsync: Introduce NTSYNC_IOC_MUTEX_UNLOCK.
ntsync: Introduce NTSYNC_IOC_MUTEX_KILL.
ntsync: Introduce NTSYNC_IOC_CREATE_EVENT.
ntsync: Introduce NTSYNC_IOC_EVENT_SET.
ntsync: Introduce NTSYNC_IOC_EVENT_RESET.
ntsync: Introduce NTSYNC_IOC_EVENT_PULSE.
ntsync: Introduce NTSYNC_IOC_SEM_READ.
ntsync: Introduce NTSYNC_IOC_MUTEX_READ.
ntsync: Introduce NTSYNC_IOC_EVENT_READ.
ntsync: Introduce alertable waits.
selftests: ntsync: Add some tests for semaphore state.
selftests: ntsync: Add some tests for mutex state.
selftests: ntsync: Add some tests for NTSYNC_IOC_WAIT_ANY.
selftests: ntsync: Add some tests for NTSYNC_IOC_WAIT_ALL.
selftests: ntsync: Add some tests for wakeup signaling with
WINESYNC_IOC_WAIT_ANY.
selftests: ntsync: Add some tests for wakeup signaling with
WINESYNC_IOC_WAIT_ALL.
selftests: ntsync: Add some tests for manual-reset event state.
selftests: ntsync: Add some tests for auto-reset event state.
selftests: ntsync: Add some tests for wakeup signaling with events.
selftests: ntsync: Add tests for alertable waits.
selftests: ntsync: Add some tests for wakeup signaling via alerts.
selftests: ntsync: Add a stress test for contended waits.
maintainers: Add an entry for ntsync.
docs: ntsync: Add documentation for the ntsync uAPI.
ntsync: No longer depend on BROKEN.
Documentation/userspace-api/index.rst | 1 +
Documentation/userspace-api/ntsync.rst | 385 +++++
MAINTAINERS | 9 +
drivers/misc/Kconfig | 1 -
drivers/misc/ntsync.c | 992 +++++++++++-
include/uapi/linux/ntsync.h | 42 +-
tools/testing/selftests/Makefile | 1 +
.../selftests/drivers/ntsync/.gitignore | 1 +
.../testing/selftests/drivers/ntsync/Makefile | 7 +
tools/testing/selftests/drivers/ntsync/config | 1 +
.../testing/selftests/drivers/ntsync/ntsync.c | 1343 +++++++++++++++++
11 files changed, 2767 insertions(+), 16 deletions(-)
create mode 100644 Documentation/userspace-api/ntsync.rst
create mode 100644 tools/testing/selftests/drivers/ntsync/.gitignore
create mode 100644 tools/testing/selftests/drivers/ntsync/Makefile
create mode 100644 tools/testing/selftests/drivers/ntsync/config
create mode 100644 tools/testing/selftests/drivers/ntsync/ntsync.c
base-commit: cdd30ebb1b9f36159d66f088b61aee264e649d7a
--
2.45.2
Dec. 13, 2024
Re: Clarification regarding clean room guidelines and headers / prototypes
by Alexandre Julliard
Fabian Maurer <dark.shadow4(a)web.de> writes:
> Hello,
>
> Not sure who, apart from Alexandre, could help here, but I wanted to ask for
> some clarification on the clean room guidelines (https://gitlab.winehq.org/
> wine/wine/-/wikis/Clean-Room-Guidelines)
>
> Let's say we want to add a few new COM classes / interfaces from WinRT for
> some program. What is the official way to get those header definitions? Copy
> paste from the official SDK?
You can look at the headers but you can't copy/paste them wholesale.
> Or worse, there is some windows adjacent dlls that only contain typelibs - can
> we decompile those typelibs to get the COM interface definitions?
Again, you can look at some specific definitions, but you can't use the
decompiled typelib directly.
> Or how about undocumented functions that are documented by third parties? ROS
> is off limits, all others as well? There are for example C# projects that
> provide P/Invoke definitions of otherwise undocumented functions.
You can look for some hints about undocumented functions, but the right
way is to write test cases.
--
Alexandre Julliard
julliard(a)winehq.org
Dec. 13, 2024
wine Conformance-Tests page download url broken
by zhengxianwei
https://gitlab.winehq.org/wine/wine/-/wikis/Conformance-Tests
- https://test.winehq.org/builds/winetest-latest.exe for the 32-bit
Windows executable.
- https://test.winehq.org/builds/winetest64-latest.exe for the 64-bit
Windows executable.
download link broken
Dec. 13, 2024
Re: Photoshop 2023 flink
by zhengxianwei
Thank you very much for your suggestions.
However, it still doesn’t work, and the issue is the same as shown in my
video.
That said, I’ve learned a lot about the basics of offscreen rendering from
your reply.
It seems like its Windows messages are a bit chaotic, often rendering the
background layer over the foreground. It feels like the background layer
assumes there’s nothing on top of it.
In theory, with a window style like CLIPCHILDREN, overlapping regions
shouldn’t be rendered.
I’d like to know how you typically analyze these kinds of issues. For
instance, when you suspect something went wrong, how do you output
intermediate rendering results? Are there any debugging methods you
recommend?
On Thu, Dec 12, 2024 at 9:09 PM Rémi Bernon <rbernon(a)codeweavers.com> wrote:
> On 12/12/24 02:12, zhengxianwei wrote:
> > I think it might be related to this part of the PR. Offscreen rendering
> > could be causing some states to not sync properly. However, I’m not very
> > familiar with offscreen rendering yet, so I’m still reviewing this PR.
> >
> >
> > https://gitlab.winehq.org/wine/wine/-/merge_requests/6427
> > https://gitlab.winehq.org/wine/wine/-/merge_requests/6467
> >
> > On Sun, Dec 8, 2024 at 5:25 PM zhengxianwei <baikaishiuc(a)gmail.com>
> wrote:
> >
> >>
> >>
> >> On Sat, Dec 7, 2024 at 10:51 AM Zhiyi Zhang <zzhang(a)codeweavers.com>
> >> wrote:
> >>
> >>>
> >>>
> >>> On 12/6/24 17:19, zhengxianwei wrote:
> >>>> Hello, I am trying to run Photoshop 23 using the DLL generated by
> >>> VKD3D-Proton.
> >>>>
> >>>> I noticed that after opening an image, dragging it causes display
> >>> issues.
> >>>>
> >>>> Here’s a video showing the problem:
> >>> https://www.youtube.com/watch?v=JgWrsFx4GrM <
> >>> https://www.youtube.com/watch?v=JgWrsFx4GrM> (Because I have not been
> >>> using the successful obs recording, so I switched to recording with my
> cell
> >>> phone, the result is worse, sorry!)
> >>>>
> >>>> When I capture frames with RenderDoc, the images appear normal.
> >>>>
> >>>> I suspect the issue might be related to the desktop gui composition
> >>> process, but I’m unsure how to analyze such problems. Do you have any
> >>> suggestions?
> >>>>
> >>>
> >>> Looks like the `recent` window is fighting for z-order with its image
> >>> window. Use spy++ and see if they're the
> >>> same window.
> >>
> >>
> >> I used Spy++ to check, and if my operation was correct, these are indeed
> >> two separate windows.
> >>
> >>
> >>> If there are different windows, then it might be some window
> >>> manager/winex11.drv bugs.
> >>
> >> You can also try running it on macOS with winemac.drv to check if it's
> >>> caused by WM.
> >>
> >>
> >>
> >> This flickering only occurs when D3D12 hardware rendering is enabled.
> >>
> >>
> >> I disabled vkd3d-proton’s d3d12.dll and d3d12core.dll, forcing Photoshop
> >> 23 into the software rendering process (CPU mode). The flickering during
> >> dragging disappeared. Does this indicate that the window management is
> not
> >> the issue?
> >>
> >>
> >> After using spy++ to grab messages, I found that in cpu mode, there are
> >> many different types of messages (WM_ERASEBKGND, WM_MOUSEMOV,
> WM_MOUSEDOWN,
> >> WM_MOUSEUP, etc ) under the ps panel (the panel with the doraemon
> image),
> >> but in gpu mode, there is only WM_NCHITTEST, why is this?
> >>
> >> I feel that in gpu mode, the ps panel seems to be drawn with some kind
> of
> >> canvas, and all the events, are taken over by some other mechanism, but
> I
> >> don't clear what that mechanism is?
> >>
> >>
> >
>
> Hi! Yes there's been some possible regression related to offscreening.
> We were previously not allowing vulkan surfaces to be created on windows
> with children, but that was only checked at creation time, and vulkan
> surfaces could be successfully created before the window got children.
>
> This has been changed to implement vulkan child window rendering in a
> more general way, and windows with children are using offscreen
> rendering and being blit separately to clip the child windows out of the
> vulkan rendering area.
>
> In some cases the children windows aren't actually visible and don't
> need to be clipped out. In addition, offscreen rendering is known to be
> bogus and the blit is also not synchronized with the rendering at the
> moment. It works in some cases, doesn't work well in others.
>
> For the cases where the vulkan surface was created on a window without
> children, and which later got some invisible children added, it is
> indeed unnecessary to move the surface offscreen like we do now, and it
> causes a regression when the offscreen rendering doesn't work well.
>
> You can try with
> https://gitlab.winehq.org/wine/wine/-/merge_requests/6998, which is
> supposed to fix that case by checking whether children windows really
> need to be clipped out or not, and by moving the surface back onscreen
> if it's not necessary.
>
> --
> Rémi Bernon <rbernon(a)codeweavers.com>
>
Dec. 13, 2024
Re: Clarification regarding clean room guidelines and headers / prototypes
by Nikolay Sivov
On Thu, Dec 12, 2024 at 11:43 PM Hin-Tak Leung <htl10(a)users.sourceforge.net>
wrote:
> Data dump and programmatic dump from decompilation and even some other
> form of data dump is off-limit... I think perhaps sometimes (some of the)
> wine people are taking it quite strictly.
>
> For example, a while ago, I filed an issue about cp932/cp936/cp950/etc are
> not exactly the same as the unicode consortium's big5/jis/gb to unicode
> mappings - Microsoft for historical or whatever reasons have codepages
> which are not 100% identical to unicode consortium's mapping. I wrote a
> little program to just loop over the mapping and run it on windows, output
> it to text, and attached them to a bug report - and promptly had the
> attachments deleted from bugzilla as "you cannot dump window's data
> structure". But how else can you do it if you want an exact match of
> behavior? For my purpose then (for MS windows compliance/compatibility as
> far as a font's encoding coverage goes), I needed an exact match - it must
> be MS cp* exactly, and not the "approximately the same" unicode consortium
> mapping...
>
> I think the bugzilla issue is still open, but I haven't checked recently.
>
This should be resolved now, we are now using mappings files published by
Microsoft to generate binary mapping files.
>
> On Thursday 12 December 2024 at 21:49:53 GMT, Fabian Maurer <
> dark.shadow4(a)web.de> wrote:
>
>
> Hello,
>
> Not sure who, apart from Alexandre, could help here, but I wanted to ask
> for
> some clarification on the clean room guidelines (
> https://gitlab.winehq.org/
> wine/wine/-/wikis/Clean-Room-Guidelines)
>
> Let's say we want to add a few new COM classes / interfaces from WinRT for
> some program. What is the official way to get those header definitions?
> Copy
> paste from the official SDK?
>
> Or worse, there is some windows adjacent dlls that only contain typelibs -
> can
> we decompile those typelibs to get the COM interface definitions?
>
> Or how about undocumented functions that are documented by third parties?
> ROS
> is off limits, all others as well? There are for example C# projects that
> provide P/Invoke definitions of otherwise undocumented functions.
>
> I think it would be helpful for the wiki to be updated with a bit of
> clarification.
>
> Thanks in advance,
> Regards,
> Fabian Maurer
>
>
>
>
>
>
>
Dec. 12, 2024
Re: Clarification regarding clean room guidelines and headers / prototypes
by Hin-Tak Leung
Data dump and programmatic dump from decompilation and even some other form of data dump is off-limit... I think perhaps sometimes (some of the) wine people are taking it quite strictly.
For example, a while ago, I filed an issue about cp932/cp936/cp950/etc are not exactly the same as the unicode consortium's big5/jis/gb to unicode mappings - Microsoft for historical or whatever reasons have codepages which are not 100% identical to unicode consortium's mapping. I wrote a little program to just loop over the mapping and run it on windows, output it to text, and attached them to a bug report - and promptly had the attachments deleted from bugzilla as "you cannot dump window's data structure". But how else can you do it if you want an exact match of behavior? For my purpose then (for MS windows compliance/compatibility as far as a font's encoding coverage goes), I needed an exact match - it must be MS cp* exactly, and not the "approximately the same" unicode consortium mapping...
I think the bugzilla issue is still open, but I haven't checked recently.
On Thursday 12 December 2024 at 21:49:53 GMT, Fabian Maurer <dark.shadow4(a)web.de> wrote:
Hello,
Not sure who, apart from Alexandre, could help here, but I wanted to ask for
some clarification on the clean room guidelines (https://gitlab.winehq.org/
wine/wine/-/wikis/Clean-Room-Guidelines)
Let's say we want to add a few new COM classes / interfaces from WinRT for
some program. What is the official way to get those header definitions? Copy
paste from the official SDK?
Or worse, there is some windows adjacent dlls that only contain typelibs - can
we decompile those typelibs to get the COM interface definitions?
Or how about undocumented functions that are documented by third parties? ROS
is off limits, all others as well? There are for example C# projects that
provide P/Invoke definitions of otherwise undocumented functions.
I think it would be helpful for the wiki to be updated with a bit of
clarification.
Thanks in advance,
Regards,
Fabian Maurer
Dec. 12, 2024
Clarification regarding clean room guidelines and headers / prototypes
by Fabian Maurer
Hello,
Not sure who, apart from Alexandre, could help here, but I wanted to ask for
some clarification on the clean room guidelines (https://gitlab.winehq.org/
wine/wine/-/wikis/Clean-Room-Guidelines)
Let's say we want to add a few new COM classes / interfaces from WinRT for
some program. What is the official way to get those header definitions? Copy
paste from the official SDK?
Or worse, there is some windows adjacent dlls that only contain typelibs - can
we decompile those typelibs to get the COM interface definitions?
Or how about undocumented functions that are documented by third parties? ROS
is off limits, all others as well? There are for example C# projects that
provide P/Invoke definitions of otherwise undocumented functions.
I think it would be helpful for the wiki to be updated with a bit of
clarification.
Thanks in advance,
Regards,
Fabian Maurer
Dec. 12, 2024