Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use #:blocking? #t for some FFI calls #29

Open
dalev opened this issue Feb 9, 2022 · 1 comment
Open

use #:blocking? #t for some FFI calls #29

dalev opened this issue Feb 9, 2022 · 1 comment

Comments

@dalev
Copy link
Contributor

dalev commented Feb 9, 2022

Some Vulkan calls may block the calling (OS) thread. E.g., vkWaitForFences, vkDeviceWaitIdle, etc.

Cooperation with Racket's runtime could be improved by adding #:blocking? #t to those procedures' FFI _fun types. Without that, these procedures may prevent the runtime from making progress on other activies such as GC. (Note that this is even true if one were to "silo" Vulkan calls in a dedicated OS thread using racket/place.)

Now, I don't see anything in vk.xml that definitively identifies blocking calls, but maybe it's enough to simply scan for "Wait" in the name of the procedure?

Btw, this is somewhat related to issue #24: with #:blocking? #t, you don't want arguments to these procedures to be moved around in memory.

Fwiw, I can think of potential two work-arounds (untested!):

(1) Use call-in-os-thread to wrap blocking calls, and make-os-async-channel + sync to block in a runtime-friendly manner.

(2) Try extensions like vkGetFenceFdKHR + unsafe-file-descriptor->port. Then sync on the port.

But these both seem unnecessarily complicated (and they don't obviate the need for 'atomic-interior allocations.)

Edit: So, Ryan's talk about how the DB library handles blocking FFI calls is useful. IIUC, a blocking FFI call also blocks any racket (green) threads that were created in that OS thread. So, for a program to remain responsive, it needs blocking FFI calls marked with #:blocking? #t and also to invoke them using call-in-os-thread. (Or avoid the blocking call entirely with an approach like (2).) All that to say, I was wrong to characterize (1) as a work-around; rather, it's a point in the design space that programmers can consider once #:blocking? #t is available.

@Aeva
Copy link

Aeva commented Mar 2, 2022

You can probably get most or all blocking APIs from vk.xml by searching for commands that list VK_TIMEOUT as a success code, and/or have a uint64_t parameter called timeout. The spec is very precise about how things should be named, so I imagine this is no exception. vkAcquireNextImageKHR is an example of such a function.

Some of these are more important than others to handle correctly though. From a practical standpoint, most graphics applications avoid doing any kind of synchronization with the GPU with ideally the only API stalls being from presenting the final image.

You have the right idea though. Any time your application's render thread would be blocked by such a thing, it is best to run background tasks, and Racket's GC is a good candidate for that sort of thing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants