{"id":17278356,"url":"https://github.com/lbphacker/coro","last_synced_at":"2025-07-26T09:37:48.353Z","repository":{"id":159451671,"uuid":"351153901","full_name":"LBPHacker/coro","owner":"LBPHacker","description":"A very simple coroutine library for C based on getcontext","archived":false,"fork":false,"pushed_at":"2021-08-27T15:07:52.000Z","size":30,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-14T09:21:22.002Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LBPHacker.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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":"2021-03-24T16:42:26.000Z","updated_at":"2021-09-29T13:16:27.000Z","dependencies_parsed_at":"2023-07-13T01:00:29.701Z","dependency_job_id":null,"html_url":"https://github.com/LBPHacker/coro","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/LBPHacker/coro","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LBPHacker%2Fcoro","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LBPHacker%2Fcoro/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LBPHacker%2Fcoro/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LBPHacker%2Fcoro/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LBPHacker","download_url":"https://codeload.github.com/LBPHacker/coro/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LBPHacker%2Fcoro/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267145958,"owners_count":24042657,"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","status":"online","status_checked_at":"2025-07-26T02:00:08.937Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2024-10-15T09:11:31.850Z","updated_at":"2025-07-26T09:37:48.326Z","avatar_url":"https://github.com/LBPHacker.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Coro\n\nOr: _as if we don't have enough things to worry about_\n\n## What (is all this)?\n\nA very simple coroutine library for C that is semantically similar to\n[Lua's](https://www.lua.org/manual/5.1/manual.html#2.11), except there's no\nGC involved so you have to free coroutines yourself, which you can only do\nif they're dead (have terminated). Currently heavily depends on the\n[getcontext](https://linux.die.net/man/3/getcontext) family of\nfunctions, which seem to have been phased out of POSIX, very sad.\n\nThis library is not thread-safe, which, seeing as it's a coroutine library,\nshouldn't come as a surprise if you're considering using it. Regardless, you can\nconfigure (see below) the library to make its global state `_Thread_local`\nrather than `static` if you so wish, and if your compiler supports it, to get\nsafety guarantees for at least the case in which your threads talk to each other\nvery little and never try to use the same coroutines.\n\n## Why (would you do this)?\n\nI just really wanted to get the itch to write some sort of coroutine library\nfor C out of my system.\n\n## When (should I use this)?\n\nNever, unless you're sure that the rest of your program can handle the sort\nof context transfers [setcontext](https://linux.die.net/man/3/getcontext) does.\nEspecially not when using C++; this library will eat your exceptions for\nbreakfast. There might be platform-dependent ways to solve this problem, but I\nhaven't yet looked into these; PRs are welcome.\n\nAlso don't use this if you can't guarantee that you won't overflow the stacks\nallocated for your coroutines; see the code below. ~If you can't guarantee\nthis but still would like to use the library, consider building (see way below)\nwith `-Duse_mmap_stack=true` to have the library ask Linux for stacks that\nimmediately and reliably crash your program with a `SIGSEGV` when overflowed,\nrather than break your allocator and cause a double free two weeks later.~\n[`MAP_GROWSDOWN` seems to be useless](https://stackoverflow.com/questions/56888725/why-is-map-growsdown-mapping-does-not-grow); requires further investigation.\n\n## Who (should I blame if my program dies)?\n\nYourself, see the [license](LICENSE.md).\n\n## How (would I use this)?\n\nThe same way you'd do it in Lua. See [coro.h](include/coro.h) and\n[03.c](test/03.c). But [tl;dr](deptest/deptest.c):\n\n```c\n#include \u003cstdio.h\u003e\n#include \u003cassert.h\u003e\n\n#include \"coro.h\"\n\nstruct context\n{\n\tint input;\n};\n\nstatic void *cofunc(void *data)\n{\n\tstruct context *pctx = (struct context *)data;\n\tpctx-\u003einput *= pctx-\u003einput;\n\tprintf(\"hello from cofunc\\n\");\n\t// * There first parameter of coro_yield is similar to the second parameter\n\t//   of coro_resume, see below.\n\tassert(!coro_yield((void **)\u0026pctx));\n\tpctx-\u003einput += 42;\n\treturn data;\n}\n\nstatic int func(int input)\n{\n\tstruct context ctx;\n\tstruct context *pctx = \u0026ctx;\n\tpctx-\u003einput = input;\n\tstruct coro *co;\n\t// * All functions barring coro_status and coro_getudata return\n\t//   CORO_OK = 0 on success. See coro.h for other possible return values.\n\t// * Tell the library to allocate 0x1000 bytes to be used as stack\n\t//   by the new coroutine.\n\tassert(!coro_create(\u0026co, cofunc, 0x1000U));\n\tprintf(\"input is now %i\\n\", pctx-\u003einput);\n\t// * Pass a pointer to a pointer-sized area as the second parameter.\n\t//   This is necessary because not only do we want to send data to the\n\t//   coroutine, we also want to receive data from it.\n\tassert(!coro_resume(co, (void **)\u0026pctx));\n\tprintf(\"input is now %i\\n\", pctx-\u003einput);\n\tassert(!coro_resume(co, (void **)\u0026pctx));\n\tprintf(\"input is now %i\\n\", pctx-\u003einput);\n\tassert(!coro_free(co));\n\treturn pctx-\u003einput;\n}\n\nint main(int argc, char *argv[])\n{\n\tprintf(\"result is %i\\n\", func(argc));\n\treturn 0;\n}\n\n```\n\nBuild and install with [Meson](https://mesonbuild.com/) and\n[Ninja](https://ninja-build.org/) like so:\n\n```sh\ncd coro\nmeson build\ncd build\nninja test\nsudo ninja install\n```\n\nIf you wish to make the global state thread-local, configure the build site\nwith `use_thread_local` set to `true`:\n\n```sh\ncd coro\nmeson -Duse_thread_local=true build\ncd build\nninja test\nsudo ninja install\n```\n\nThe Meson script exports the dependency `coro_dep`. Installing also creates a\n`coro.pc` [pkg-config](https://linux.die.net/man/1/pkg-config) file, which lets\nyou link against this dependency with other build systems, and with\n`dependency('coro')` in Meson.\n\nYou can uninstall the library with:\n\n```sh\nsudo ninja uninstall\n```\n\nBuild options:\n\n| name | type | default | description |\n|-|-|-|-|\n| `use_thread_local` | boolean | `true` | Make the global coro state `_Thread_local` rather than `static` |\n| `use_mmap_stack` | boolean | ~`true`~ `false` | ~Allocate coro stacks with `mmap` and `MAP_GROWSDOWN` (Linux) rather than `malloc`~ `MAP_GROWSDOWN` seems to be useless, see above |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flbphacker%2Fcoro","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flbphacker%2Fcoro","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flbphacker%2Fcoro/lists"}