|
59 | 59 | * SDL_LoadFileAsync as a convenience function. This will handle allocating a
|
60 | 60 | * buffer, slurping in the file data, and null-terminating it; you still check
|
61 | 61 | * for results later.
|
| 62 | + * |
| 63 | + * Behind the scenes, SDL will use newer, efficient APIs on platforms that |
| 64 | + * support them: Linux's io_uring and Windows 11's IoRing, for example. If |
| 65 | + * those technologies aren't available, SDL will offload the work to a thread |
| 66 | + * pool that will manage otherwise-synchronous loads without blocking the app. |
| 67 | + * |
| 68 | + * ## Best Practices |
| 69 | + * |
| 70 | + * Simple non-blocking i/o--for an app that just wants to pick up data |
| 71 | + * whenever it's ready without losing framerate waiting on disks to spin--can |
| 72 | + * use whatever pattern works well for the program. In this case, simply call |
| 73 | + * SDL_ReadAsyncIO, or maybe SDL_LoadFileAsync, as needed. Once a frame, call |
| 74 | + * SDL_GetAsyncIOResult to check for any completed tasks and deal with the |
| 75 | + * data as it arrives. |
| 76 | + * |
| 77 | + * If two separate pieces of the same program need their own i/o, it is legal |
| 78 | + * for each to create their own queue. This will prevent either piece from |
| 79 | + * accidentally consuming the other's completed tasks. Each queue does require |
| 80 | + * some amount of resources, but it is not an overwhelming cost. Do not make a |
| 81 | + * queue for each task, however. It is better to put many tasks into a single |
| 82 | + * queue. They will be reported in order of completion, not in the order they |
| 83 | + * were submitted, so it doesn't generally matter what order tasks are started. |
| 84 | + * |
| 85 | + * One async i/o queue can be shared by multiple threads, or one thread can |
| 86 | + * have more than one queue, but the most efficient way--if ruthless |
| 87 | + * efficiency is the goal--is to have one queue per thread, with multiple |
| 88 | + * threads working in parallel, and attempt to keep each queue loaded with |
| 89 | + * tasks that are both started by and consumed by the same thread. On modern |
| 90 | + * platforms that can use newer interfaces, this can keep data flowing as |
| 91 | + * efficiently as possible all the way from storage hardware to the app, with |
| 92 | + * no contention between threads for access to the same queue. |
| 93 | + * |
| 94 | + * Written data is not guaranteed to make it to physical media by the time a |
| 95 | + * closing task is completed, unless SDL_CloseAsyncIO is called with its |
| 96 | + * `flush` parameter set to true, which is to say that a successful result |
| 97 | + * here can still result in lost data during an unfortunately-timed power |
| 98 | + * outage if not flushed. However, flushing will take longer and may be |
| 99 | + * unnecessary, depending on the app's needs. |
62 | 100 | */
|
63 | 101 |
|
64 | 102 | #ifndef SDL_asyncio_h_
|
|
0 commit comments