{"id":17313137,"url":"https://github.com/tatsuya6502/bitwise_rust","last_synced_at":"2026-03-07T18:01:12.921Z","repository":{"id":138123279,"uuid":"49213462","full_name":"tatsuya6502/bitwise_rust","owner":"tatsuya6502","description":"Rust-based Erlang NIF examples for showing Erlang VM's scheduler issues","archived":false,"fork":false,"pushed_at":"2016-01-19T00:56:30.000Z","size":14,"stargazers_count":10,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-04T22:26:05.485Z","etag":null,"topics":["demo-apps","elixir","erlang","examples","rust"],"latest_commit_sha":null,"homepage":null,"language":"Rust","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/tatsuya6502.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}},"created_at":"2016-01-07T15:41:34.000Z","updated_at":"2025-02-23T07:59:00.000Z","dependencies_parsed_at":"2023-03-19T12:06:54.585Z","dependency_job_id":null,"html_url":"https://github.com/tatsuya6502/bitwise_rust","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/tatsuya6502/bitwise_rust","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tatsuya6502%2Fbitwise_rust","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tatsuya6502%2Fbitwise_rust/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tatsuya6502%2Fbitwise_rust/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tatsuya6502%2Fbitwise_rust/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tatsuya6502","download_url":"https://codeload.github.com/tatsuya6502/bitwise_rust/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tatsuya6502%2Fbitwise_rust/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30225404,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-07T17:00:40.062Z","status":"ssl_error","status_checked_at":"2026-03-07T17:00:39.026Z","response_time":53,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["demo-apps","elixir","erlang","examples","rust"],"created_at":"2024-10-15T12:45:51.885Z","updated_at":"2026-03-07T18:01:12.905Z","avatar_url":"https://github.com/tatsuya6502.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bitwise_rust: Rust-based Erlang NIF examples showing Erlang VM's scheduler concerns\n\nThis is a [Rust](https://www.rust-lang.org/) port of Steve Vinoski's\n[bitwise](https://github.com/vinoski/bitwise) example.\n\nRecently tested with:\n\n- Rust 1.5.0\n- Erlang/OTP 18.2.1\n- (**TODO**) Elixir 1.2\n\n## What is Bitwise?\n\nThe `bitwise` module implements several Erlang Native Implemented\nFunctions (NIFs) intended to show several different effects NIFs can\nhave on Erlang scheduler threads. The module supplies several variants\nof a function `exor/2` that takes a binary and a byte value and\napplies *exclusive-or* of\n\nthat byte to every byte in the binary and returns a new binary of the\nresulting values. These variants operate as follows:\n\n* One example, `exor_bad/2`, shows a misbehaving NIF that, given a\n  large enough input binary, takes up far too much time on a scheduler\n  thread, running for multiple seconds. Normally, a NIF should run on\n  a scheduler thread for only a millisecond or less.\n\n* Another example uses Erlang code to break the large input binary\n  into 4MB chunks, calling `exor_bad/2` separately for each chunk and\n  then reassembling the results.\n\n* The `exor_yield/2` variant uses the\n  [enif_schedule_nif function](http://www.erlang.org/doc/man/erl_nif.html#enif_schedule_nif),\n  introduced in Erlang/OTP 17.3, to ensure the NIF yields the\n  scheduler thread after consuming a 1 millisecond timeslice. It uses\n  `enif_schedule_nif` to reschedule itself to run in the future to\n  continue its *exclusive-or* operation on the input binary.\n\n* The final variant, `exor_dirty/2`, uses dirty schedulers, introduced\n  as an experimental feature in Erlang 17.0. This approach schedules\n  the NIF to run on a dirty scheduler thread rather than a regular\n  scheduler thread. Since dirty scheduler threads are not\n  [managed threads](https://github.com/erlang/otp/blob/maint/erts/emulator/internal_doc/ThreadProgress.md),\n  they are not constrained the same way regular scheduler threads are\n  with respect to long-running CPU- or I/O-intensive tasks.\n\n## About the Original Bitwise by Steve Vinoski\n\nThe original C and Erlang code in [bitwise](https://github.com/vinoski/bitwise/)\nwas presented at Chicago Erlang, 22 Sep 2014. The code has evolved\nsince that talk, including a fix for the example of how\n`enif_consume_timeslice()` and `enif_schedule_nif()` are used\ntogether. In the Chicago Erlang presentation, the code presented for\nthis area miscalculated timeslice percentages; this has been\nfixed. The slides have been updated to include this fix as well, which\nmeans the slides here, in the file\n[`vinoski-opt-native-code.pdf`](https://github.com/vinoski/bitwise/blob/master/vinoski-opt-native-code.pdf),\ndiffer from those originally presented.\n\nThat code was also presented at CodeMesh 2014, 5 Nov 2014. The slides\nfor that talk, which are in the file\n[`vinoski-schedulers.pdf`](https://github.com/vinoski/bitwise/blob/master/vinoski-schedulers.pdf),\ninclude more details than those for the Chicago Erlang talk,\nspecifically about a possible dirty driver API.\n\n## Long Scheduling\n\nA useful Erlang feature not shown in the code or the Chicago Erlang\nslides, but mentioned in the CodeMesh slides, is the ability to detect\nwhen native code spends too much time on a regular scheduler thread by\ncalling `erlang:system_monitor/2` with the `{long_schedule, Time}`\noption. For example, the following code can be interactively run in an\nErlang shell to cause the shell to receive messages when any NIFs\nexecute on a regular scheduler thread for 10ms or more:\n\n```erl\n1\u003e erlang:system_monitor(self(), [{long_schedule, 10}]).\nundefined\n```\n\nIf any NIF executions meet or exceed the 10ms limit, the shell will\nreceive messages similar to the following:\n\n```erl\n2\u003e spawn(fun() -\u003e bitwise:exor(LargeBinary, 16#5A) end).\n\u003c0.39.0\u003e\n3\u003e flush().\nShell got {monitor,\u003c0.39.0\u003e,long_schedule,\n                   [{timeout,6018},{in,undefined},{out,undefined}]}\n```\n\nHere, the `{timeout, 6018}` portion of the message shows that\n`bitwise:exor/2` executed for slightly more than 6 seconds.\n\nSee the\n[erlang:system_monitor/2 documentation](http://www.erlang.org/doc/man/erlang.html#system_monitor-2)\nfor more details.\n\n## License\n\nThis example programs are open sourced under the MIT license. See the\nLICENCE file for more details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftatsuya6502%2Fbitwise_rust","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftatsuya6502%2Fbitwise_rust","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftatsuya6502%2Fbitwise_rust/lists"}