Created
March 31, 2025 17:38
-
-
Save alexcrichton/99c9d63cfd15673cfe2fa34a7993e20b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdint.h> | |
#define P3_TASK_VERSION1 1 | |
typedef struct p3_task_v1 { | |
// For now it's `P3_TASK_VERSION1`, and this indicates what fields are present | |
// in this structure. Accessing a vX field must check that `version` here is | |
// `>= X`. | |
int version; | |
// Embedder-defined pointer passed to callbacks below. Exported tasks control | |
// this and it's opaque to other users. | |
void *ptr; | |
// For the current exported task, register `callback(code, ptr)` to happen | |
// when `waitable` gets signaled. Basically add `waitable` to a waitable set | |
// and arrange for the callback to get invoked when the current exported task | |
// gets the notification the waitable is ready. | |
// | |
// If already registered this removes the previous callback and returns its | |
// `ptr` field. If waitable was not previously registered this returns `NULL`. | |
void* (*waitable_register)( | |
void *p3_task_ptr, // `p3_task_v1.ptr` | |
uint32_t waitable, | |
void(*complete)(uint32_t code, void *ptr), | |
void *ptr | |
); | |
// Dual of the above, but removes it from the waitable set and/or tracking. | |
// | |
// Returns `NULL` if `waitable` was not registered or returns the `ptr` field | |
// provided during registration. | |
void *(*waitable_unregister)( | |
void *p3_task_ptr, // `p3_task_v1.ptr` | |
uint32_t waitable | |
); | |
} p3_task_v1; | |
// Sets the return value of `p3_task_get` below tot he provided pointer. | |
// | |
// This sets a `static` in-memory to this value. This is called whenever an | |
// exported tasks starts work to initialize the memory. When an exported task | |
// finishes work it would probably set this back to NULL. | |
// | |
// The lifetime of the `task` pointer must be the same as the lifetime of the | |
// exported task itself. | |
void p3_task_set(struct p3_task_v1 *task); | |
// Get the task set by `p3_task_set` prior. | |
// | |
// The lifetime of the returned pointer is bound to the currently running task. | |
// Callers should assert this is not-null. | |
// | |
// This is used when an imported function or intrinsic is used and needs to work | |
// with waitable registration/unregistration. | |
struct p3_task_v1 *p3_task_get(void); | |
// ============================================================================= | |
// Example of a future extension to this API. This is just hypothetical, not | |
// actually going to be in any header. | |
// Tasks below would have `version` set to this value. | |
#define P3_TASK_VERSION2 2 | |
typedef struct p3_task_v2 { | |
// Must still provide all v1 functionality. | |
p3_task_v1 v1; | |
// Some new functionality, but all prior functionality must still be provided. | |
void (*v2_functionality)(void *p3_task_ptr); | |
} p3_task_v2; | |
// Hypothetical v3 | |
#define P3_TASK_VERSION3 3 | |
typedef struct p3_task_v3 { | |
// Always starts with previous version | |
p3_task_v2 v2; | |
void (*v3_functionality)(void *p3_task_ptr); | |
} p3_task_v3; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment