{"id":16153867,"url":"https://github.com/roginvs/c_threads","last_synced_at":"2026-01-19T22:31:22.628Z","repository":{"id":77829617,"uuid":"221509277","full_name":"roginvs/c_threads","owner":"roginvs","description":"Calculate crc32 in threads. University homework","archived":false,"fork":false,"pushed_at":"2020-01-14T09:51:03.000Z","size":1932,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-06T23:42:33.672Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"HTML","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/roginvs.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":"2019-11-13T16:55:25.000Z","updated_at":"2020-09-12T15:12:13.000Z","dependencies_parsed_at":"2023-02-23T21:00:50.906Z","dependency_job_id":null,"html_url":"https://github.com/roginvs/c_threads","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/roginvs/c_threads","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roginvs%2Fc_threads","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roginvs%2Fc_threads/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roginvs%2Fc_threads/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roginvs%2Fc_threads/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/roginvs","download_url":"https://codeload.github.com/roginvs/c_threads/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roginvs%2Fc_threads/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28587239,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-19T20:45:59.482Z","status":"ssl_error","status_checked_at":"2026-01-19T20:45:41.500Z","response_time":67,"last_error":"SSL_read: 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":[],"created_at":"2024-10-10T01:14:47.514Z","updated_at":"2026-01-19T22:31:22.614Z","avatar_url":"https://github.com/roginvs.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Эксперименты с реализацией gzip в threads\n\n## Сборка и прогон тестов (Linux или Mac)\n\n```sh\n./build-and-test.sh\n```\n\nРезультат прогона тестов для последних коммитов\nможно посмотреть в [Github Actions](./../../actions)\n\n![build status badge](https://github.com/roginvs/c_threads/workflows/ci_test/badge.svg)\n\n## Запуск\n\n```sh\n./main.out \u003cinput file\u003e \u003coutput file\u003e\n```\n\n## Комментарии для Windows\n\nТ.к. код завязан на `pthread` и `mmap`, то самое просто это запускать код в Docker:\n\n```cmd\ndocker run -v %cd%:/app -ti --name ubuntu ubuntu bash\napt-get update \u0026\u0026 apt-get install -y build-essential xxd\n```\n\nМожно использовать VSCode remote developing extensions и подключиться прямо в контейнер\n\n## Алгоритм работы\n\nОсновная функция `gzip` из файла `gzip.c` принимает следующие аргументы:\n\n```C\nvoid gzip(\n  /** Указатель на входные данные */\n  uint8_t *input_buf,\n\n  /** Размер входных данных */\n  int32_t input_buf_len,\n\n  /** Количество потоков */\n  int32_t threads_count,\n\n  /** Коллбэк для записи кодированных данных */\n  write_handler write,\n\n  /** Произвольный указатель, он будет передан в коллбэк */\n  void *write_user_data\n);\n\n/** Тип колбека на запись */\ntypedef void (*write_handler)(\n  /** Указатель на данные которые нужно записать */\n  uint8_t *buf,\n  /** Длинна данных */\n  uint32_t len,\n  /** Произвольный указатель */\n  void *user_data\n);\n\n```\n\nФункция вызывает коллбэк на запись (несколько раз) и возвращает управление когда всё завершено.\n\nВнутри функции создается `threads_count` потоков. Каждый поток самостоятельно разбирает номер блока для себя.\n\nКогда поток закончил, то он ожидает до тех пор, как `worker_is_allowed_to_write` станет равным его номеру блока.\n\nКак только это произошло, поток вызывает коллбэк, увеличивает `worker_is_allowed_to_write` и рассылает всем остальным потокам уведомление что переменная поменялась. После этого поток повторяет свой цикл пока есть несделанные блоки.\n\nМастер так же ожидает `worker_is_allowed_to_write`. Как только последний блок готов, мастер завершает потоки и дописывает footer.\n\n## CRC32\n\nРеализован подсчёт CRC32 в воркерах. Детали можно посмотреть в файле `crc32.c`\n\n```C\n/** Выполняет однопоточный подсчёт CRC */\nuint32_t crc32(const uint8_t *data, uint32_t length)\n```\n\nДля многопоточного crc нужно использовать функции:\n\n```C\n/** Считает crc для блока с учётом положения блока. Возвращает промежуточный результат */\nuint32_t crc32_partial_block(\n  /** Указатель на блок */\n  const uint8_t *data,\n  /** Длинна блока */\n  uint32_t block_length,\n  /**\n   * Количество байт до этого блока.\n   * Используются только значения 0, 1, 2, 3, \u003e4. Т.е. любое число больше 4 даст тот же результат */\n  uint32_t bytes_before,\n  /**\n   * Количество байт после этого блока.\n   * */\n  uint32_t bytes_after\n)\n\n/** Соединить данные от блоков. Не обязятельно в исходном порядке */\nuint32_t crc32_block_combine(uint32_t crc1, uint32_t crc2)\n\n/** Финальное преобразование */\nuint32_t crc32_finallize(uint32_t crc)\n```\n\nДля каждого блока данных нужно подсчитать значение `crc32_partial_block`. Затем значения каждого блока нужно\nсобрать воедино в любом порядке с `crc32_block_combine`. Можно использовать `CRC32_INITIAL` для удобства.\nИ в конце финализировать значение с `crc32_finallize`.\n\nПримечание: параллелльный CRC не работает на данных меньше 4 байта. Это баг.\nДля данных меньше 4-й байт можно подсчитать CRC через обычный `crc32`\n\n## Сжатие\n\nНа текущий момент сжатие как таковое не реализованно, используется deflate без сжатия. Предполагается что функция `compress_chunk` будет определять как именно сохранять текущий блок.\n\n## Граничные случаи на больших данных\n\nКод нуждается в проверке на граничные случаи. Что будет если входной файл размером 0xFFFFFFFF? Или на байт больше? Или на два байта больше?\n\n## Ссылки\n\n- https://tools.ietf.org/html/rfc1951\n- https://tools.ietf.org/html/rfc1952\n- http://www.sunshine2k.de/coding/javascript/crc/crc_js.html\n- http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html\n- https://nicst.de/crc.pdf\n\n## Заметки на псевдокоде по алгоритму синхронизации потоков\n\n```python\n\nmaster:\n  lock MutexWorkerWrite\n  createThreads()\n\n  unlock MutexWorkerWrite\n  broadcast ConditionWorkerIsAllowedToWrite\n\n  wait until last block is done\n\n\nworker:\n  pickUpTask()\n  doCalculation()\n\n  lock MutexWorkerWrite\n  while (ValueMasterIsReadyToRead !== myId):\n    wait ConditionWorkerIsAllowedToWrite\n  # Here we change output buf\n  # Copy whole thing to output buf\n  # Increase current pending state\n  # Broadcast\n  unlock MutexWorkerWrite\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froginvs%2Fc_threads","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Froginvs%2Fc_threads","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froginvs%2Fc_threads/lists"}