You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1.5 KiB


utask (micro-task) is an extremely lightweight cooperative multitasking library. µTasks are simply executed round-robin until each one yields.

By using compiler extensions in the form of synchronization builtins and carefully constructed clobber lists, utask gets an absolutely minimal context switch. Instead of saving and restoring all registers every time (on some architectures this is a lot — a RISC-V with floating point has 63 registers!), utask simply invalidates all registers before the context switch. This tells the compiler that after the switch, it is responsible for recomputing the contents of any registers that had active allocations. This is much faster, because chances are, you do not have all 63 registers in use at once.

Supported architectures

  • RISC-V

API example

static void task1_f(uintptr_t arg);
static void task2_f(uintptr_t arg);

utask_decl_stack(task1_s, 1024);
utask_decl_stack(task2_s, 1024);

utask_t task1 = {
	.func = task1_f,
	.stack = task1_s,
	.stack_size = sizeof(task1_s),
	.name = "task1",

utask_t task2 = {
	.func = task2_f,
	.stack = task2_s,
	.stack_size = sizeof(task2_s),
	.name = "task2",

int main()
	utask_add(&task2, 0);
	utask_add(&task1, 0);

static void task1_f(uintptr_t arg)
	printf("Hello, ");

static void task2_f(uintptr_t arg)


This code may not be used by anybody for any purpose. Be gay, do crime.