{"id":21048192,"url":"https://github.com/podusowski/lum","last_synced_at":"2025-03-13T22:42:02.616Z","repository":{"id":71845284,"uuid":"533905209","full_name":"podusowski/lum","owner":"podusowski","description":"Write predictable tests for multi-threaded C++. Inspired by Tokio's loom.","archived":false,"fork":false,"pushed_at":"2022-09-12T11:15:20.000Z","size":41,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-07T16:09:16.463Z","etag":null,"topics":["concurrency","testing"],"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/podusowski.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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-09-07T19:10:43.000Z","updated_at":"2023-02-20T16:44:55.000Z","dependencies_parsed_at":"2023-09-11T18:01:25.497Z","dependency_job_id":null,"html_url":"https://github.com/podusowski/lum","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/podusowski%2Flum","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/podusowski%2Flum/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/podusowski%2Flum/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/podusowski%2Flum/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/podusowski","download_url":"https://codeload.github.com/podusowski/lum/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243495489,"owners_count":20299921,"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":["concurrency","testing"],"created_at":"2024-11-19T14:42:28.121Z","updated_at":"2025-03-13T22:42:02.593Z","avatar_url":"https://github.com/podusowski.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"**This library is highly experimental and incomplete! It's OK to play around with the examples, but please don't use it in any of your projects!**\n\n\nTokio's [`loom`](https://docs.rs/loom/latest/loom/) inspired utility to test concurrency in your software.\n\n\nWhat does it do?\n----------------\nThere are various thread sanitizers which check whether your structures are synchronized, `lum` check your concurrent algorithms logic. Pretty vague, I know, let's see some examples.\n\nConsider [following code](cases/nosync.cpp). Program has two threads. One (commented as supplementary) writes a value, second one (main thread) reads it. Is this program correct? Well, no. Writes and reads aren't synchronized. In fact, we can even see a data race in both `ThreadSanitizer` and `helgrind`:\n\n``` \nWARNING: ThreadSanitizer: data race (pid=20480)\n  Read of size 4 at 0x7ffeaa08cebc by main thread:\n    #0 main \u003cnull\u003e (nosync+0xd04d3) (BuildId: bdf7a3f9f6d85eec41db285485f6aa4944621de9)\n\n  Previous write of size 4 at 0x7ffeaa08cebc by thread T1:\n    #0 main::$_0::operator()() const nosync.cpp (nosync+0xd0af9) (BuildId: bdf7a3f9f6d85eec41db285485f6aa4944621de9)\n```\n\nThis is pretty easy to fix, right? Just [put some mutexes here and there](cases/sync.cpp). `ThreadSanitizer` doesn't complain anymore, nor is `helgrind`. However, if we run the program couple of times, we'll see that it doesn't give predictable results:\n\n```\n$ while true; do ./sync; done\nvalue: 42\nvalue: 42\nvalue: 42\nvalue: 0\nvalue: 42\nvalue: 42\nvalue: 42\nvalue: 42\nvalue: 0\nvalue: 42\nvalue: 42\n```\n\nThe behavior is not deterministic because there is no way to tell which thread will acquire the mutex first. Sometimes it's acquired by the writer and we get `42`, but sometimes the variable id read by the main thread, resulting with still default value of `0`.\n\n`lum` lets you write tests which will use different combinations of whom gets the lock first. In above example, test would run two times (though there is a small caveat here). In the first iteration, \"calculating thread\" will get the lock first, in the second iteration, the \"reading thread\" will get it first. Both will happen in a deterministic way.\n\nThe [test version](tests/test.cpp) behaves kind of like a Schrödinger's cat, taking both probability paths at once. If we run it, in fact we will see both cases:\n\n```\nvalue: 0\nvalue: 42\n```\n\n\nLimitations and future plans\n----------------------------\n- Only single multithreading synchronization primitive is supported right now - a mutex.\n- `lum` works only with a single mutex.\n- It's VERY intrusive right now. Not only you have to swap `std::mutex` with `lum::mutex`, ~~but it also has additional constructor parameter~~. There are couple of ways to solve it though.\n\n\nEnabling logging\n----------------\nTo enable `lum`'s internal debug prints, define a `LUM_TRACE` environment variable. Its value doesn't matter.\n\n\nCheat sheet\n-----------\nBuilding with clang's ThreadSanitizer:\n```\ncmake -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_CXX_FLAGS=\"-fsanitize=thread\" -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -B build-tsan\ncmake --build build-tsan\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpodusowski%2Flum","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpodusowski%2Flum","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpodusowski%2Flum/lists"}