Announcement

Collapse
No announcement yet.

Windows NT Sync Driver Proposed For The Linux Kernel - Better Wine Performance

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #91
    Originally posted by indepe View Post
    ...
    I would want to know, also because others like myself might, down the road, try to implement something like that for other purposes, and if there are missing kernel features to implement cross-process synchronization well, then maybe kernel engineers should get a chance to implement those features for general use, outside of Wine. As far as I can tell so far, the patch request doesn't have that kind of information either, but I may have missed it so far.
    I don't think you will ever find such a use case, the only missing thing is Pulse and the WaitAll mode of WaitForMulipleObject(), both things that no one should ever use and probably no one does (and on top of that Pulse is also deprecrated by MS).

    The single thing that is useful from WaitForMultipleObjects() is that it can take objects of both fd:s, mutexes and semaphores. In Linux this would probably be solved in the future by adding something like mutexfd and semfd instead of changing select/poll/epoll.

    Originally posted by mrg666 View Post

    I checked the code and I agree that is limited with ntsync_device (still meaning a "giant lock" for Wine). I hope they can come up with a more granular approach than this. So, thanks!
    ‚Äč
    I don't think there can be a better solution (and the Wineserver already today have to perform a process wide lock for this) because the problem is the Win32 API that is broken here with the WaitAll mode (it's not possible to know which locks will be waited for in this mode before the call so this call have to go over all locks from all wine processes).

    edit: or yes you could do some lock-less magic here but it would be brittle and racy as hell so a simple mutex around the call is probably the best solution.
    Last edited by F.Ultra; 25 January 2024, 04:12 PM.

    Comment


    • #92
      Originally posted by Weasel View Post
      Ok, holding a lock around the eventfd syscall sounds like it would be correct in behavior.

      The only downside is, like I said, that requires writeable shared memory (to set the lock), and that can easily take down everything with just one misbehaving process.
      Yes, that's where it gets interesting...

      Originally posted by Weasel View Post
      Imagine the process crashes in the little time it holds the small lock (the one around the event, not the event itself). Now the lock is permanently held by something that doesn't exist anymore (crashed). What now?
      How to prevent this in general? There are so-called "robust" futexes, however this might be a part that is easier to do by a separate event-server process.

      Comment


      • #93
        Originally posted by F.Ultra View Post

        I don't think you will ever find such a use case, the only missing thing is Pulse and the WaitAll mode of WaitForMulipleObject(), both things that no one should ever use and probably no one does (and on top of that Pulse is also deprecrated by MS).
        In a very general sense (with a different API), both of these become much more meaningful in use cases where there is a more permanent waiting list (possibly for cyclic operations). And in the wait-all case, the optional requirement that all events need to be consumable at the same time and are then atomically consumed at the same time, is in my experience both unnecessary and complicating, making it ineffective and not work well for any process that needs to wait for more events than other processes that wait for the same events.

        Comment


        • #94
          Originally posted by Weasel View Post
          That deadlock has nothing to do with wineserver, and it's only a deadlock for a given process on Windows. Not even remotely an issue, just bad programming.

          Single threaded means it uses system similar to APCs/async handoffs. That is, when "waiting" for something (blocking I/O) it just goes to do the other queued tasks and is signalled when it is completed. It doesn't use an actual wait so it cannot deadlock. It only enters alertable sleep state when there's no tasks to perform.

          That can't deadlock because lack of tasks means it's simply waiting for a new task, not a cyclic wait.
          What if the task wineserver is asked todo need a access back.

          It is possible to run into a file system or process termination deadlock.

          weasel read wineserver man page and notice the wineserver -w where you wait for the current wineserver to terminate. Dig into code you can find in different places wineserver will be waiting on other parts to complete as part of a task.

          When you dig into the wineserver source code you will find waits on winedevice, wineboot and other things in places. Yes Wineserver can in fact deadlock. Its one of those rare bugs.

          Wine does not have thread or process who job is to detect deadlocks and deal with them automatically. Human manually using wineserver -k comes the support person instruction..

          Your presume about wineserver not having waits is wrong. The deadlock of wineserver is rare bug but it does happen. Windows has a built in part to detect these deadlocks and deal with them automatically. This is a missing feature of wine.

          Comment


          • #95
            Weasel Still missing a piece (in the principle of it) ?

            Comment


            • #96
              from what I understand this is less about the raw performance of the game and more about IO and loading things?
              if that is the case then i am very happy with this since i always felt windows games took a bit too long to load on linux.

              Comment


              • #97
                The way this is described, it seems this patch is already being provided by TKG (if I'm understanding correctly) but just named differently? The patch I'm talking about: https://github.com/Frogging-Family/l...winesync.patch

                Comment


                • #98
                  Originally posted by oiaohm View Post
                  What if the task wineserver is asked todo need a access back.

                  It is possible to run into a file system or process termination deadlock.

                  weasel read wineserver man page and notice the wineserver -w where you wait for the current wineserver to terminate. Dig into code you can find in different places wineserver will be waiting on other parts to complete as part of a task.

                  When you dig into the wineserver source code you will find waits on winedevice, wineboot and other things in places. Yes Wineserver can in fact deadlock. Its one of those rare bugs.

                  Wine does not have thread or process who job is to detect deadlocks and deal with them automatically. Human manually using wineserver -k comes the support person instruction..

                  Your presume about wineserver not having waits is wrong. The deadlock of wineserver is rare bug but it does happen. Windows has a built in part to detect these deadlocks and deal with them automatically. This is a missing feature of wine.
                  No, if the access is blocked it simply continues to the next task queued.

                  You don't really understand how "single threaded" apps that "appear" multi-threaded in terms of locks work, do you? AutoHotkey works the same way btw, it has "threads" and all the waiting stuff but internally it's literally just one thread.

                  Here's a short gist of it: You have one thread, and a list of tasks queued. If there's no tasks, you enter alertable sleep state until a task is pushed and alerts you. That's the only time you wait. Note that there's no deadlock here because you only sleep when you have no task. A deadlock is a wait when you have multiple tasks waiting for each other, so they never progress.

                  Now you can get tasks pushed asynchronously to the list (via stuff like APCs) but they don't get executed until you finish your current task. "Finish" doesn't mean completion. It means at any point you'd enter a "wait" state, for example waiting for blocking I/O, it simply checks the task list to find if there's anything else to do, and does it. Such async I/O is simply an APC that queues another task when it finishes.

                  In case you literally have no other task, you enter alertable sleep when waiting for I/O, then when new task gets pushed (due to APC and I/O finishing), you get waken up and continue. If you have other tasks queued, you execute those instead. But you NEVER wait until you actually finish your task or wait for a blocking operation or whatever, which doesn't depend on the other tasks.

                  A task without sufficient permissions can simply be discarded as if it didn't exist. Not a problem.

                  Deadlocks are impossible.

                  Comment


                  • #99
                    Originally posted by indepe View Post
                    Weasel Still missing a piece (in the principle of it) ?
                    Sorry I don't quite understand what you meant with a dedicated event process. I mean, sure that can work, just like wineserver does. But won't that kill performance? Can you give a simple pseudo rough code to see what you mean? How do you reduce amount of syscalls and task switching compared to wineserver?

                    Comment


                    • Originally posted by Weasel View Post
                      Sorry I don't quite understand what you meant with a dedicated event process. I mean, sure that can work, just like wineserver does. But won't that kill performance? Can you give a simple pseudo rough code to see what you mean? How do you reduce amount of syscalls and task switching compared to wineserver?
                      So far I don't have much experience with cross-process thread communication (however I do with single-process multi-threading). I just measured an atomic variable round trip using shared memory: process A sets a value that B is waiting for (by spinning on it), B responds by setting a value that A is waiting for. On a Zen2 CPU it takes just 35 ns or a bit less, for the whole round-trip (so about 17 ns for one direction). By comparison, a single syscall like getpid takes 179 ns, a syscall for a function number that doesn't exist (an empty syscall so to speak), a bit more than 150 ns (although I think it used to be less than that on older systems). (everything measured in a loop.) So that's good news for lock-free queues. Task switching can surely be reduced on the server side by giving the server a higher priority, but that is something I haven't measured between processes, and wineserver is using a higher priority already so that's not necessarily an area of improvement in comparison. If that's what you mean with task switching.

                      I wouldn't really want to give more details about things that I haven't fully implemented and not yet seen how they work out in practice.

                      Comment

                      Working...
                      X