{"id":13605758,"url":"https://github.com/mackron/c89atomic","last_synced_at":"2025-04-09T12:08:14.658Z","repository":{"id":52382241,"uuid":"274112852","full_name":"mackron/c89atomic","owner":"mackron","description":"C89 compatible atomics.","archived":false,"fork":false,"pushed_at":"2025-02-19T00:32:07.000Z","size":41,"stargazers_count":79,"open_issues_count":2,"forks_count":11,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-04-02T11:02:11.890Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mackron.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":"2020-06-22T10:57:47.000Z","updated_at":"2025-02-19T00:32:10.000Z","dependencies_parsed_at":"2024-01-14T06:53:34.602Z","dependency_job_id":"7efedc5d-a1aa-458f-8d6f-9aa7470b41f6","html_url":"https://github.com/mackron/c89atomic","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/mackron%2Fc89atomic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mackron%2Fc89atomic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mackron%2Fc89atomic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mackron%2Fc89atomic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mackron","download_url":"https://codeload.github.com/mackron/c89atomic/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248036067,"owners_count":21037092,"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":[],"created_at":"2024-08-01T19:01:02.406Z","updated_at":"2025-04-09T12:08:14.638Z","avatar_url":"https://github.com/mackron.png","language":"C","funding_links":[],"categories":["C"],"sub_categories":[],"readme":"\u003ch4 align=\"center\"\u003eC89 compatible atomics.\u003c/h4\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://discord.gg/9vpqbjU\"\u003e\u003cimg src=\"https://img.shields.io/discord/712952679415939085?label=discord\u0026logo=discord\" alt=\"discord\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://twitter.com/mackron\"\u003e\u003cimg src=\"https://img.shields.io/twitter/follow/mackron?style=flat\u0026label=twitter\u0026color=1da1f2\u0026logo=twitter\" alt=\"twitter\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nThis library aims to implement an equivalent to the C11 atomics library. It's intended to be used as a way to\nenable the use of atomics in a mostly consistent manner to modern C, while still enabling compatibility with\nolder compilers. This is *not* a drop-in replacement for C11 atomics, but is very similar. Only limited testing\nhas been done so use at your own risk. I'm happy to accept feedback and pull requests with bug fixes.\n\nWhen compiling with GCC and Clang, this library will translate to a one-to-one wrapper around the `__atomic_*`\nintrinsics provided by the compiler.\n\nWhen compiling with Visual C++ things are a bit more complicated because it does not have support for C11 style\natomic intrinsics. This library will try to use the `_Interlocked*` intrinsics instead, and if unavailable will\nuse inlined assembly (x86 only).\n\nSupported compilers are Visual Studio back to VC6, GCC and Clang. If you need support for a different compiler\nI'm happy to add support (pull requests appreciated). This library currently assumes the `int` data type is\n32 bits.\n\n\nUsage\n-----\nThis is a header-only library. Just add `c89atomic.h` to your source tree and include it:\n\n```c\n#include \"c89atomic.h\"\n```\n\nEverything is implemented with defines and inline functions. There are no source files or build scripts to\ndeal with.\n\n\nDifferences With C11\n--------------------\nFor practicality, this is not a drop-in replacement for C11's `stdatomic.h`. Below are the main differences\nbetween c89atomic and stdatomic.\n\n  * All operations require an explicit size which is specified by the name of the function, and only 8-,\n    16-, 32- and 64-bit operations are supported. Objects of an arbitrary sizes are not supported.\n  * Some extra APIs are included:\n    - `c89atomic_compare_and_swap_*()`\n    - `c89atomic_test_and_set_*()`\n    - `c89atomic_clear_*()`\n  * All APIs are namespaced with `c89`.\n  * `c89atomic_*` data types are undecorated.\n\n\nCompare Exchange\n----------------\nThis library implements a simple compare-and-swap function called `c89atomic_compare_and_swap_*()` which is\nslightly different to C11's `atomic_compare_exchange_*()`. This is named differently to distinguish between\nthe two. `c89atomic_compare_and_swap_*()` returns the old value as the return value, whereas\n`atomic_compare_exchange_*()` will return it through a parameter and supports explicit memory orders for\nsuccess and failure cases.\n\nWith Visual Studio and versions of GCC earlier than 4.7, an implementation of `atomic_compare_exchange_*()`\nis included which is implemented in terms of `c89atomic_compare_and_swap_*()`, but there's subtle details to be\naware of with this implementation. Note that the following only applies for Visual Studio and versions of GCC\nearlier than 4.7. Later versions of GCC and Clang use the `__atomic_compare_exchange_n()` intrinsic directly\nand are not subject to the following.\n\nBelow is the 32-bit implementation of `c89atomic_compare_exchange_strong_explicit_32()` which is implemented\nthe same for the weak versions and other sizes, and only for Visual Studio and old versions of GCC (prior to\n4.7):\n\n```c\nc89atomic_bool c89atomic_compare_exchange_strong_explicit_32(volatile c89atomic_uint32* dst,\n                                                             volatile c89atomic_uint32* expected,\n                                                             c89atomic_uint32 desired,\n                                                             c89atomic_memory_order successOrder,\n                                                             c89atomic_memory_order failureOrder)\n{\n    c89atomic_uint32 expectedValue;\n    c89atomic_uint32 result;\n\n    expectedValue = c89atomic_load_explicit_32(expected, c89atomic_memory_order_seq_cst);\n    result = c89atomic_compare_and_swap_32(dst, expectedValue, desired);\n    if (result == expectedValue) {\n        return 1;\n    } else {\n        c89atomic_store_explicit_32(expected, result, failureOrder);\n        return 0;\n    }\n}\n```\n\nThe call to `c89atomic_store_explicit_32()` is not atomic with respect to the main compare-and-swap operation\nwhich may cause problems when `expected` points to memory that is shared between threads. This only becomes an\nissue if `expected` can be accessed from multiple threads at the same time which for the most part will never\nhappen because a compare-and-swap will almost always be used in a loop with a local variable being used for the\nexpected value.\n\nIf the above is a concern, you should consider reworking your code to use `c89atomic_compare_and_swap_*()`\ndirectly, which is atomic and more efficient. Alternatively you'll need to use a lock to synchronize access\nto `expected`, upgrade your compiler, or use a different library.\n\n\n\nTypes and Functions\n-------------------\nThe following types and functions are implemented:\n```\n+-----------------------------------------+-----------------------------------------------+\n| C11 Atomics                             | C89 Atomics                                   |\n+-----------------------------------------+-----------------------------------------------+\n| #include \u003cstdatomic.h\u003e                  | #include \"c89atomic.h\"                        |\n+-----------------------------------------+-----------------------------------------------+\n| memory_order                            | c89atomic_memory_order                        |\n|     memory_order_relaxed                |     c89atomic_memory_order_relaxed            |\n|     memory_order_consume                |     c89atomic_memory_order_consume            |\n|     memory_order_acquire                |     c89atomic_memory_order_acquire            |\n|     memory_order_release                |     c89atomic_memory_order_release            |\n|     memory_order_acq_rel                |     c89atomic_memory_order_acq_rel            |\n|     memory_order_seq_cst                |     c89atomic_memory_order_seq_cst            |\n+-----------------------------------------+-----------------------------------------------+\n| atomic_flag                             | c89atomic_flag                                |\n| atomic_bool                             | c89atomic_bool                                |\n| atomic_int8                             | c89atomic_int8                                |\n| atomic_uint8                            | c89atomic_uint8                               |\n| atomic_int16                            | c89atomic_int16                               |\n| atomic_uint16                           | c89atomic_uint16                              |\n| atomic_int32                            | c89atomic_int32                               |\n| atomic_uint32                           | c89atomic_uint32                              |\n| atomic_int64                            | c89atomic_int64                               |\n| atomic_uint64                           | c89atomic_uint64                              |\n+-----------------------------------------+-----------------------------------------------+\n| atomic_flag_test_and_set                | c89atomic_flag_test_and_set                   |\n| atomic_flag_test_and_set_explicit       | c89atomic_flag_test_and_set_explicit          |\n|                                         | c89atomic_test_and_set_8                      |\n|                                         | c89atomic_test_and_set_16                     |\n|                                         | c89atomic_test_and_set_32                     |\n|                                         | c89atomic_test_and_set_64                     |\n|                                         | c89atomic_test_and_set_explicit_8             |\n|                                         | c89atomic_test_and_set_explicit_16            |\n|                                         | c89atomic_test_and_set_explicit_32            |\n|                                         | c89atomic_test_and_set_explicit_64            |\n+-----------------------------------------+-----------------------------------------------+\n| atomic_flag_clear                       | c89atomic_flag_clear                          |\n| atomic_flag_clear_explicit              | c89atomic_flag_clear_explicit                 |\n|                                         | c89atomic_clear_8                             |\n|                                         | c89atomic_clear_16                            |\n|                                         | c89atomic_clear_32                            |\n|                                         | c89atomic_clear_64                            |\n|                                         | c89atomic_clear_explicit_8                    |\n|                                         | c89atomic_clear_explicit_16                   |\n|                                         | c89atomic_clear_explicit_32                   |\n|                                         | c89atomic_clear_explicit_64                   |\n+-----------------------------------------+-----------------------------------------------+\n| atomic_store                            | c89atomic_store_8                             |\n| atomic_store_explicit                   | c89atomic_store_16                            |\n|                                         | c89atomic_store_32                            |\n|                                         | c89atomic_store_64                            |\n|                                         | c89atomic_store_explicit_8                    |\n|                                         | c89atomic_store_explicit_16                   |\n|                                         | c89atomic_store_explicit_32                   |\n|                                         | c89atomic_store_explicit_64                   |\n+-----------------------------------------+-----------------------------------------------+\n| atomic_load                             | c89atomic_load_8                              |\n| atomic_load_explicit                    | c89atomic_load_16                             |\n|                                         | c89atomic_load_32                             |\n|                                         | c89atomic_load_64                             |\n|                                         | c89atomic_load_explicit_8                     |\n|                                         | c89atomic_load_explicit_16                    |\n|                                         | c89atomic_load_explicit_32                    |\n|                                         | c89atomic_load_explicit_64                    |\n+-----------------------------------------+-----------------------------------------------+\n| atomic_exchange                         | c89atomic_exchange_8                          |\n| atomic_exchange_explicit                | c89atomic_exchange_16                         |\n|                                         | c89atomic_exchange_32                         |\n|                                         | c89atomic_exchange_64                         |\n|                                         | c89atomic_exchange_explicit_8                 |\n|                                         | c89atomic_exchange_explicit_16                |\n|                                         | c89atomic_exchange_explicit_32                |\n|                                         | c89atomic_exchange_explicit_64                |\n+-----------------------------------------+-----------------------------------------------+\n| atomic_compare_exchange_weak            | c89atomic_compare_exchange_weak_8             |\n| atomic_compare_exchange_weak_explicit   | c89atomic_compare_exchange_weak_16            |\n| atomic_compare_exchange_strong          | c89atomic_compare_exchange_weak_32            |\n| atomic_compare_exchange_strong_explicit | c89atomic_compare_exchange_weak_64            |\n|                                         | c89atomic_compare_exchange_weak_explicit_8    |\n|                                         | c89atomic_compare_exchange_weak_explicit_16   |\n|                                         | c89atomic_compare_exchange_weak_explicit_32   |\n|                                         | c89atomic_compare_exchange_weak_explicit_64   |\n|                                         | c89atomic_compare_exchange_strong_8           |\n|                                         | c89atomic_compare_exchange_strong_16          |\n|                                         | c89atomic_compare_exchange_strong_32          |\n|                                         | c89atomic_compare_exchange_strong_64          |\n|                                         | c89atomic_compare_exchange_strong_explicit_8  |\n|                                         | c89atomic_compare_exchange_strong_explicit_16 |\n|                                         | c89atomic_compare_exchange_strong_explicit_32 |\n|                                         | c89atomic_compare_exchange_strong_explicit_64 |\n+-----------------------------------------+-----------------------------------------------+\n| atomic_fetch_add                        | c89atomic_fetch_add_8                         |\n| atomic_fetch_add_explicit               | c89atomic_fetch_add_16                        |\n|                                         | c89atomic_fetch_add_32                        |\n|                                         | c89atomic_fetch_add_64                        |\n|                                         | c89atomic_fetch_add_explicit_8                |\n|                                         | c89atomic_fetch_add_explicit_16               |\n|                                         | c89atomic_fetch_add_explicit_32               |\n|                                         | c89atomic_fetch_add_explicit_64               |\n+-----------------------------------------+-----------------------------------------------+\n| atomic_fetch_sub                        | c89atomic_fetch_sub_8                         |\n| atomic_fetch_sub_explicit               | c89atomic_fetch_sub_16                        |\n|                                         | c89atomic_fetch_sub_32                        |\n|                                         | c89atomic_fetch_sub_64                        |\n|                                         | c89atomic_fetch_sub_explicit_8                |\n|                                         | c89atomic_fetch_sub_explicit_16               |\n|                                         | c89atomic_fetch_sub_explicit_32               |\n|                                         | c89atomic_fetch_sub_explicit_64               |\n+-----------------------------------------+-----------------------------------------------+\n| atomic_fetch_or                         | c89atomic_fetch_or_8                          |\n| atomic_fetch_or_explicit                | c89atomic_fetch_or_16                         |\n|                                         | c89atomic_fetch_or_32                         |\n|                                         | c89atomic_fetch_or_64                         |\n|                                         | c89atomic_fetch_or_explicit_8                 |\n|                                         | c89atomic_fetch_or_explicit_16                |\n|                                         | c89atomic_fetch_or_explicit_32                |\n|                                         | c89atomic_fetch_or_explicit_64                |\n+-----------------------------------------+-----------------------------------------------+\n| atomic_fetch_xor                        | c89atomic_fetch_xor_8                         |\n| atomic_fetch_xor_explicit               | c89atomic_fetch_xor_16                        |\n|                                         | c89atomic_fetch_xor_32                        |\n|                                         | c89atomic_fetch_xor_64                        |\n|                                         | c89atomic_fetch_xor_explicit_8                |\n|                                         | c89atomic_fetch_xor_explicit_16               |\n|                                         | c89atomic_fetch_xor_explicit_32               |\n|                                         | c89atomic_fetch_xor_explicit_64               |\n+-----------------------------------------+-----------------------------------------------+\n| atomic_fetch_and                        | c89atomic_fetch_and_8                         |\n| atomic_fetch_and_explicit               | c89atomic_fetch_and_16                        |\n|                                         | c89atomic_fetch_and_32                        |\n|                                         | c89atomic_fetch_and_64                        |\n|                                         | c89atomic_fetch_and_explicit_8                |\n|                                         | c89atomic_fetch_and_explicit_16               |\n|                                         | c89atomic_fetch_and_explicit_32               |\n|                                         | c89atomic_fetch_and_explicit_64               |\n+-----------------------------------------+-----------------------------------------------+\n| atomic_thread_fence()                   | c89atomic_thread_fence                        |\n| atomic_signal_fence()                   | c89atomic_signal_fence                        |\n+-----------------------------------------+-----------------------------------------------+\n| atomic_is_lock_free                     | c89atomic_is_lock_free_8                      |\n|                                         | c89atomic_is_lock_free_16                     |\n|                                         | c89atomic_is_lock_free_32                     |\n|                                         | c89atomic_is_lock_free_64                     |\n+-----------------------------------------+-----------------------------------------------+\n| (Not Defined)                           | c89atomic_compare_and_swap_8                  |\n|                                         | c89atomic_compare_and_swap_16                 |\n|                                         | c89atomic_compare_and_swap_32                 |\n|                                         | c89atomic_compare_and_swap_64                 |\n|                                         | c89atomic_compare_and_swap_ptr                |\n|                                         | c89atomic_compiler_fence                      |\n+-----------------------------------------+-----------------------------------------------+\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmackron%2Fc89atomic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmackron%2Fc89atomic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmackron%2Fc89atomic/lists"}