{"id":19662721,"url":"https://github.com/brunexgeek/utask","last_synced_at":"2026-05-11T01:49:10.377Z","repository":{"id":44808711,"uuid":"450988868","full_name":"brunexgeek/utask","owner":"brunexgeek","description":"Single file library implementing userspace cooperative multitasking","archived":false,"fork":false,"pushed_at":"2023-09-24T17:05:05.000Z","size":11,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-10T01:53:04.079Z","etag":null,"topics":["cooperative-multitasking","coroutines","multitasking","ucontext","userspace"],"latest_commit_sha":null,"homepage":"https://brunocosta.net.br/project/utask/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/brunexgeek.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-01-23T02:50:38.000Z","updated_at":"2024-07-06T21:32:19.000Z","dependencies_parsed_at":"2024-11-11T16:12:13.191Z","dependency_job_id":"bbe2a569-ad00-4310-a30b-e2be42f5525f","html_url":"https://github.com/brunexgeek/utask","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brunexgeek%2Futask","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brunexgeek%2Futask/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brunexgeek%2Futask/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brunexgeek%2Futask/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/brunexgeek","download_url":"https://codeload.github.com/brunexgeek/utask/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240971289,"owners_count":19886719,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cooperative-multitasking","coroutines","multitasking","ucontext","userspace"],"created_at":"2024-11-11T16:12:11.228Z","updated_at":"2026-05-11T01:49:05.343Z","avatar_url":"https://github.com/brunexgeek.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# utask: userspace cooperative mutitasking\n\n`utask` is a single file library implementing userspace cooperative multitasking inside native threads. Tasks have many-to-one relantionship with native threads (i.e. each thread has its own tasks) and you can create up to 128 tasks per thread.\n\nBy default, `utask` can be used only by one thread. If you want to use it in more threads, define `UTASK_MULTI_THREAD` before including `utask.h`. Defining `UTASK_MULTI_THREAD` incurs additional overhead to retrieve per thread internal information.\n\nThis library requires [ucontext](https://pubs.opengroup.org/onlinepubs/7908799/xsh/ucontext.h.html) API provided by GNU/Linux and some other operating systems.\n\n## Usage\n\nInclude `utask.h` in your project. You can include `utask.h` in any source file, but one of them (and only one) must define `UTASK_IMPL` before including it. That tells `utask` to define the library implementation. If you want to use tasks in more than one thread, also defines `UTASK_MULTI_THREAD`.\n\n```\n/* #define UTASK_MULTI_THREAD */\n#define UTASK_IMPL\n#include \"utask.h\"\n```\n\nBefore using any function you must initialize the task scheduler in the current thread with `utask_initialize`. The default number of tasks is 8 and the default stack size is 16 KiB. Always check the return value for errors.\n\n```\nint result = utask_initialize(2, UT_DEFAULT, UT_DEFAULT);\nif (result != UT_EOK)\n    abort(\"Failure\");\n```\n\nNow just create some tasks and start the task scheduler to run them. The function `utask_run` will block the execution until all tasks are finished. Make sure that inside `my_function_1` and `my_function_2` you call `utask_yield` regularly to give up processor time to other tasks. You can also create tasks inside other tasks.\n\n```\nutask_create(my_function_1, NULL);\nutask_create(my_function_2, NULL);\nutask_run();\nprintf(\"Finished running all tasks!\\n\");\n```\n\nRemember to terminate the task scheduler to release the allocated resources.\n\n```\nutask_terminate();\n```\n\n## API\n\n### utask_initialize\n\n`int utask_initialize( int max, int stack_size, int flags )`\n\nInitialize the task scheduler for the current thread.\n\nIf `UTASK_MULTI_THREAD` is not defined before `utask.h` is included\nonly one thread can use tasks. Otherwise, this function can be called\nfor each thread to initialize its task scheduler.\n\nThis function must be called outside a task.\n\n### utask_terminate\n\n`int utask_terminate()`\n\nTerminate the task scheduler for the current thread.\n\nThis function must be called outside a task.\n\n### utask_create\n\n`int utask_create(void (*func)(void*), void *arg)`\n\nCreate a new task and add it in the task scheduler's running queue. The return value is the task identifier (same value returned by `utask_id` function).\n\nThis function can be called inside and outside a task.\n\n### utask_run\n\n`int utask_run()`\n\nRun the task scheduler until all tasks are completed.\n\nTasks are selected via round-robin algorithm.\n\n### utask_yield\n\n`int utask_yield()`\n\nRelinquish control and enables the task scheduler run another task.\n\n### utask_id\n\n`int utask_id()`\n\nReturns the current task identifier.\n\n### utask_count\n\n`int utask_count()`\n\nReturns the number of tasks in runnable state.\n\n### utask_info\n\n`int utask_info( utask_info_t *info )`\n\nReturns information about the task scheduler state.\n\n# Stack size\n\nThere is no simple and portable way to accurately check for stack overflows. Furthermore, the task stack does not grow as needed, as operating systems usually do with threads. The library attempts to perform rudimentary validations to detect possible stack overflows, but this is not sufficient to ensure execution stability (especially if the call graph is deep). Be sure to test your application to verify that the specified stack size is sufficient for various use cases.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrunexgeek%2Futask","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbrunexgeek%2Futask","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrunexgeek%2Futask/lists"}