Live data from Hacker News

Fixing stutters in Papers Please on Linux

blog.jhm.dev

131–140 of 202 posts

Re: Fixing stutters in Papers Please on Linux

#131

Earlier quoted context omitted.

It's common in application of certain size and compatibility expectations. Windows and Mac games will bundle their dependencies as much as possible as well. Same for large apps. Nobody wants to end to in a situation where their relatively expensive purchase doesn't work because of the version of local libs.

Does bundling dependencies imply static linking, though? Why can’t they just dynamically link to the bundled dependency?

Not really, it can be bundled either as static or dynamic.

Re: Fixing stutters in Papers Please on Linux

#132
post #3

Fun write up. Here’s another example of a binary patch to fix a Linux game issue: https://steamcommunity.com/app/333300/discussions/0/26463606...

Gotta remember the byte patternsearch using grep (and replacement using printf/dd). Clever use of Unix tools.

Re: Fixing stutters in Papers Please on Linux

#133
post #122

strace tip of the day: you don't need lsof, strace can keep track of open fds quite well, just use the -y flag. -y --decode-fds --decode-fds=path Print paths associated with file descriptor arguments. -yy --decode-fds=all Print all available information associated with file descriptors: protocol-specific information associated with socket file descriptors, block/character device number associated with device file des…

That's a great tip, thanks.

Re: Fixing stutters in Papers Please on Linux

#134

Earlier quoted context omitted.

> I agree the algorithm leaves something to be desired, but the only reason it is user-visible is the performance bug in Linux. The only reason it wasn’t user-visible was luck. Robust applications don’t depend on luck. Something tells me you’ll think twice before calling close() in a time-sensitive context in your future performance engineering endeavors. That’s because both you and I now know that no implementation…

There's no guarantee for the runtime of any function. It's perfectly valid for the OS to swap your program instructions to disk, and then take seconds or even minutes to load it back. It's effectively impossible to avoid depending on what you call "luck". The OS does not provide nearly enough guarantees to build useful interactive applications without also depending on other reasonable performance expectations.

> It's perfectly valid for the OS to swap your program instructions to disk, and then take seconds or even minutes to load it back.

It’s not valid to swap your program instructions to disk if you call mlock() on your executable pages. Indeed, performance sensitive applications do just that. https://man7.org/linux/man-pages/man2/mlock.2.html

> It's effectively impossible to avoid depending on what you call "luck". The OS does not provide nearly enough guarantees to build useful interactive applications without also depending on other reasonable performance expectations.

This is all self-evidently false. You likely wrote your comment on a POSIX-based interactive application. It just takes knowledge of how the system works and what the specifications are. Well-designed programs are hard to come by but they do exist.

Re: Fixing stutters in Papers Please on Linux

#135

Earlier quoted context omitted.

What the proposed patch does is delay a specific latent operation to an asynchronous context so that close() doesn’t block on that operation (which is freeing some memory). The proposed patch isn’t a comprehensive fix, it admits there are still other sources of relatively high close() latency. So that got me thinking, there is no way to fix this “bug” because there is no specification on how long close() should take…

close() is typically a blocking operation. But when it happens in devfs, procfs, tmpfs, or some other ram only filesystem I expect it to be fast unless documented otherwise.

Especially when you are in devfs you should not assume anything at all! Close in devfs is just a function pointer which is overridden by each of the myriad device drivers that expose files in /dev. Your close() could be the final one which lets the driver perform some cleanup. It might decide to borrow your thread to do it. Maybe some device was about to be ejected/disabled but could not previously because you were holding an FD to it.

The same goes for /proc and /sys which are very similar to /dev in that they represent various entry points into the kernel.

Re: Fixing stutters in Papers Please on Linux

#136
post #105
post #93

Earlier quoted context omitted.

It's not like Windows doesn't have its own issues to fix. Except developers do it anyway, because of the market size. Windows isn't perfect or better for gaming.

> Windows isn't perfect or better for gaming. This assessment depends entirely on the perspective. From a developer's POV, Windows definitively is the better platform, as it's very monolithic in that you can rely on the presence and longevity of APIs. Depending on the dev's influence on the market and the success of the game, you even get free optimisation, support, and bug fixes from h/w vendors in the form of game-…

> you can rely on the presence and longevity of APIs

That can be moot. Arguably, I can run more Windows games on Linux using Wine than on actual Windows, especially the older those games are.

Optimizations or work on drivers done by outside developers isn't unusual for Linux too. In fact something like Cyberpunk 2077 became playable on Linux without CDPR getting involved, except for them providing the game to Mesa and Wine developers before the release. And they even added a whole Vulkan extension to make it more playable without CDPR lifting a finger.

Overall I'd say Windows offers no advantages besides being more entrenched among gaming developers for historic reasons.

If Linux would have provided the same market size as Windows, developers would work with it no matter OS specific idiosyncrasies, same as they do with Windows now.

Re: Fixing stutters in Papers Please on Linux

#138
post #95
post #82

Earlier quoted context omitted.

I’m no fan of mailing lists, but GitHub PRs get ignored in much the same way.

There’s ignored, and there is “not aware that it’s unresolved”. How do mailing list flows handle the “give me a list of open patches”?

People treat emails like tickets, representing things that should be done. They put them in particular email directories depending on their personal workflow. When they are either done or rejected, they delete the email, archive it, or mark it as read.

It's not unlike the github workflow except that it's up to each person to define the way they prefer to work. Not a single policy that's decided by the project owner. Planning/tracking also happens more in private instead of public. You may think that's worse, but perhaps you can also see why some might prefer it?

Re: Fixing stutters in Papers Please on Linux

#139

From the description of the problem (a freeze every 3 seconds) I knew exactly what it was. You can fix it by simply upgrading SDL as they fixed this bug 2 years ago. https://github.com/spurious/SDL-mirror/commit/59728f9802c786...

Why is udev not used in this case?

Probably because a commercial developer is not going to want to link a LGPL library with their program. [0]

https://github.com/systemd/systemd/blob/main/src/libudev/lib...

Re: Fixing stutters in Papers Please on Linux

#140

Earlier quoted context omitted.

Or, io_uring the thing. One could probably wrap close() with LD_PRELOAD and not touch the binary...

While tempting, you can’t generally fix this by simply patching close() with some function that converts it to an unchecked asynchronous operation. If that were the case, you could just do that in the kernel. Close() is expected to complete synchronously. This matters because posix guarantees that open()/pipe() etc. will return the lowest file descriptor not in use[1]. I.e. this should work: close(0); fd = open(“/foo…

Are you sure such code exists? Doesn't the standard tell you to always treat the fd type as opaque anyway?

Referring to exactly the point you cite, the standard seems to be making no strong statement at all. It says to allocate from the lowest fd but that calls which may return multiple fds do not need to guarantee they are adjacent. I always took this to mean the values should pack downward and should not be e.g. allocated randomly, though it never seemed clear to me why, as the standard seems to be planning for multithreaded code.

So you are interpreting it one way, but the same statement seems to imply that fds are not meant to be introspected and should always be taken at face value from a call that generates a valid fd.

Post reply on HN