This allows having multiple task schedulers without having to switch the
global "target" scheduler for INVOKE_ macros.
An important side effect of this change is that it's not possible to use
the regular INVOKE_ macros from a non-coroutine context anymore. A
series of complimentary SCHED_INVOKE_ macros was added that behave
identically, but allow explicitly specifying a scheduler as the first
argument. The stage loop has been slightly refactored to accomodate this
behavior.
Removed dummy char fields from arg structs, as their only purpose was to
hack around silly standard preprocessor limitations. { } should now be
used instead of NO_ARGS.
A sized pointer struct simply contains a pointer to an args struct of
the interface's corresponding type, and a size_t field with the size of
that struct. In case of interface inheritance, the sized pointer can be
"cast" to the base type by accessing the union member "base", enabling a
form of polymorphism.
A sized pointer can be constructed like so:
// alias for convenience
typedef TASK_IFACE_ARGS_SIZED_PTR_TYPE(MyInterface) MyInterfaceSptr;
MyInterfaceSptr sptr = TASK_IFACE_SARGS(MyInterface,
.foo = bar,
.spam = eggs
);
* Smarter generic entity macros
The list of "core" entities is now defined in one macro, and hardcoded
_Generic dispatch tables are eliminated
* Get rid of "custom" entities
All entities are now "first-class". The list of known entity types has
been moved to known_entities.h. The system no longer needs to know the
definition of all entity structs.
* Refactor guts of ENT_BOX/ENT_UNBOX
Made the functions inline, Box::ent is now a proper pointer type (but
please don't use it directly), ENT_UNBOX returns NULL if the box is
"empty" (references NULL entity)
* Merge TASK_BIND_UNBOXED with TASK_BIND
* s/YoumuMyon/YoumuAMyon for consistency
TASK_HOST_CUSTOM_ENT(type) allocates a custom entity from a reserved
region on the task's stack (same as TASK_MALLOC) and registers it. The
entity will be automatically unregistered when the task terminates for
any reason. Only one entity can be hosted by any particular task. This
macro returns a pointer to the hosted entity.
TASK_HOST_EVENTS(events) associates a custom array of events (created
with COEVENTS_ARRAY) with the task. All events in the array are
automatically initialized when this macro is called, and cancelled when
the task terminates for any reason. Only one array of events can be
hosted by any particular task.
TASK_MALLOC(size) allocates a memory region with a lifetime bound to the
active task. It can't be free'd manually.
Allocation requests are served from a dedicated region on the task's
stack whenever possible, which is fast and essentially free. If there is
not enough free space to serve the request, then the memory is allocated
on the heap. Such heap allocations are automatically free'd when the
task expires.
The allocated memory is zero-initialized and aligned as strictly as
max_align_t.