{"id":20051890,"url":"https://github.com/p-ranav/psched","last_synced_at":"2025-07-07T19:37:00.888Z","repository":{"id":56468946,"uuid":"283283955","full_name":"p-ranav/psched","owner":"p-ranav","description":"Priority-based Task Scheduling for Modern C++","archived":false,"fork":false,"pushed_at":"2021-01-29T13:14:47.000Z","size":894,"stargazers_count":82,"open_issues_count":0,"forks_count":10,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-05-12T00:03:15.977Z","etag":null,"topics":["aging","concurrency","cpp17","header-only","lightweight","mit-license","priority","priority-modulation","priority-scheduling","queue","queueing","scheduling","single-header","single-header-lib","task-management","task-parallelism","task-queue","task-scheduler","task-starvation","threading"],"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/p-ranav.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":"2020-07-28T17:37:32.000Z","updated_at":"2024-04-18T09:07:59.000Z","dependencies_parsed_at":"2022-08-15T19:20:31.977Z","dependency_job_id":null,"html_url":"https://github.com/p-ranav/psched","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/p-ranav%2Fpsched","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p-ranav%2Fpsched/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p-ranav%2Fpsched/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p-ranav%2Fpsched/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/p-ranav","download_url":"https://codeload.github.com/p-ranav/psched/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224443942,"owners_count":17312127,"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":["aging","concurrency","cpp17","header-only","lightweight","mit-license","priority","priority-modulation","priority-scheduling","queue","queueing","scheduling","single-header","single-header-lib","task-management","task-parallelism","task-queue","task-scheduler","task-starvation","threading"],"created_at":"2024-11-13T12:07:31.787Z","updated_at":"2024-11-13T12:07:32.331Z","avatar_url":"https://github.com/p-ranav.png","language":"C++","readme":"# psched\n\n`psched` is a lightweight library that provides a priority-based task scheduler for modern C++.\n\n* The `psched` scheduler manages an array of concurrent queues, each queue assigned a priority-level\n* A task, when scheduled, is enqueued onto one of queues based on the task's priority\n* A pool of threads executes ready tasks, starting with the highest priority\n* The priority of starving tasks is modulated based on the age of the task\n\n\u003cp align=\"center\"\u003e\n  \u003cimg height=\"400\" src=\"img/priority_scheduling.png\"/\u003e  \n\u003c/p\u003e\n\n## Getting Started\n\nConsider the task set below. There are three periodic tasks: `a`, `b` and `c`. \n\n| Task | Period (ms) | Burst Time (ms) | Priority    |\n|------|-------------|-----------------|-------------|\n| a    |  250        | 130             | 0 (Lowest)  |\n| b    |  500        | 390             | 1           |\n| c    | 1000        | 560             | 2 (Highest) |\n\nHere, _burst time_ refers to the amount of time required by the task for executing on CPU.\n\n### Create a `PriorityScheduler`\n\nFirst, let's create a scheduler:\n\n```cpp\n#include \u003ciostream\u003e\n#include \u003cpsched/priority_scheduler.h\u003e\nusing namespace psched;\n\nint main() {\n  PriorityScheduler\u003cthreads\u003c3\u003e, \n                    queues\u003c3, maintain_size\u003c100, discard::oldest_task\u003e\u003e,\n                    aging_policy\u003c\n                        task_starvation_after\u003cstd::chrono::milliseconds, 250\u003e, \n                        increment_priority_by\u003c1\u003e\n                    \u003e\u003e\n      scheduler;\n```\n  \n### Create a `Task`\n  \n Create the first task, `Task a` like below. The task \"performs work\" for 130ms. The post-completion callback, called when the task has completed, can be used to study the temporal behavior of the task, e.g., waiting time, burst time, and turnaround time.\n \n ```cpp\n \n  Task a(\n      // Task action\n      [] { std::this_thread::sleep_for(std::chrono::milliseconds(130)); },\n  \n      // Task post-completion callback\n      [](const TaskStats \u0026stats) {\n        std::cout \u003c\u003c \"[Task a] \";\n        std::cout \u003c\u003c \"Waiting time = \" \u003c\u003c stats.waiting_time() \u003c\u003c \"ms; \";\n        std::cout \u003c\u003c \"Burst time = \" \u003c\u003c stats.burst_time() \u003c\u003c \"ms; \";\n        std::cout \u003c\u003c \"Turnaround time = \" \u003c\u003c stats.turnaround_time() \u003c\u003c \"ms\\n\";\n      }\n  );\n ```\n \n### Schedule the task\n \nNow, we can write a simple periodic timer that schedules this task at `priority\u003c0\u003e`:\n\n```cpp\n  auto timer_a = std::thread([\u0026scheduler, \u0026a]() {\n    while (true) {\n    \n      // Schedule the task\n      scheduler.schedule\u003cpriority\u003c0\u003e\u003e(a);\n      \n      // Sleep for 250ms and repeat\n      std::this_thread::sleep_for(std::chrono::milliseconds(250));\n    }\n  });\n```\n\n### Schedule more tasks\n\nWe can repeat the above code for tasks `b` and `c`:\n\n```cpp\n  Task b(\n      // Task action\n      [] { std::this_thread::sleep_for(std::chrono::milliseconds(390)); },\n      // Task post-completion callback\n      [](const TaskStats \u0026stats) {\n        std::cout \u003c\u003c \"[Task b] \";\n        std::cout \u003c\u003c \"Waiting time = \" \u003c\u003c stats.waiting_time() \u003c\u003c \"ms; \";\n        std::cout \u003c\u003c \"Burst time = \" \u003c\u003c stats.burst_time() \u003c\u003c \"ms; \";\n        std::cout \u003c\u003c \"Turnaround time = \" \u003c\u003c stats.turnaround_time() \u003c\u003c \"ms\\n\";\n      });\n\n  auto timer_b = std::thread([\u0026scheduler, \u0026b]() {\n    while (true) {\n      scheduler.schedule\u003cpriority\u003c1\u003e\u003e(b);\n      std::this_thread::sleep_for(std::chrono::milliseconds(500));\n    }\n  });\n\n  Task c(\n      // Task action\n      [] { std::this_thread::sleep_for(std::chrono::milliseconds(560)); },\n      // Task post-completion callback\n      [](const TaskStats \u0026stats) {\n        std::cout \u003c\u003c \"[Task c] \";\n        std::cout \u003c\u003c \"Waiting time = \" \u003c\u003c stats.waiting_time() \u003c\u003c \"ms; \";\n        std::cout \u003c\u003c \"Burst time = \" \u003c\u003c stats.burst_time() \u003c\u003c \"ms; \";\n        std::cout \u003c\u003c \"Turnaround time = \" \u003c\u003c stats.turnaround_time() \u003c\u003c \"ms\\n\";\n      });\n\n  auto timer_c = std::thread([\u0026scheduler, \u0026c]() {\n    while (true) {\n      scheduler.schedule\u003cpriority\u003c2\u003e\u003e(c);\n      std::this_thread::sleep_for(std::chrono::milliseconds(1000));\n    }\n  });\n\n  timer_a.join();\n  timer_b.join();\n  timer_c.join();\n}\n```\n\nRunning this sample may yield the following output:\n\n```bash\n./multiple_periodic_tasks\n[Task a] Waiting time = 0ms; Burst time = 133ms; Turnaround time = 133ms\n[Task c] Waiting time = 0ms; Burst time = 563ms; Turnaround time = 563ms\n[Task b] Waiting time = 0ms; Burst time = 395ms; Turnaround time = 395ms\n[Task a] Waiting time = 60ms; Burst time = 134ms; Turnaround time = 194ms\n[Task a] Waiting time = 0ms; Burst time = 131ms; Turnaround time = 131ms\n[Task b] Waiting time = 0ms; Burst time = 390ms; Turnaround time = 390ms\n[Task a] Waiting time = 3ms; Burst time = 135ms; Turnaround time = 139ms\n[Task a] Waiting time = 0ms; Burst time = 132ms; Turnaround time = 132ms\n[Task b] Waiting time = 8ms; Burst time = 393ms; Turnaround time = 402ms\n[Task c] Waiting time = 0ms; Burst time = 561ms; Turnaround time = 561ms\n[Task a] Waiting time = 6ms; Burst time = 133ms; Turnaround time = 139ms\n[Task b] Waiting time = [Task a] Waiting time = 0ms; Burst time = 393ms; Turnaround time = 393ms\n0ms; Burst time = 133ms; Turnaround time = 133ms\n[Task a] Waiting time = 11ms; Burst time = 134ms; Turnaround time = 145ms\n[Task a] Waiting time = 0ms; Burst time = 134ms; Turnaround time = 134ms\n[Task b] Waiting time = 11ms; Burst time = 394ms; Turnaround time = 405ms\n[Task c] Waiting time = 0ms; Burst time = 560ms; Turnaround time = 560ms\n[Task a] Waiting time = 7ms; Burst time = 132ms; Turnaround time = 139ms\n[Task b] Waiting time = 0ms; Burst time = 390ms; Turnaround time = 390ms\n[Task a] Waiting time = 0ms; Burst time = 130ms; Turnaround time = 130ms\n[Task a] Waiting time = 17ms; Burst time = 130ms; Turnaround time = 148ms\n[Task a] Waiting time = 0ms; Burst time = 131ms; Turnaround time = 131ms\n[Task b] Waiting time = 10ms; Burst time = 390ms; Turnaround time = 401ms\n[Task c] Waiting time = 0ms; Burst time = 560ms; Turnaround time = 560ms\n```\n\n## Building Samples\n\n```bash\ngit clone https://github.com/p-ranav/psched\ncd psched\nmkdir build \u0026\u0026 cd build\ncmake -DPSCHED_SAMPLES=ON ..\nmake\n```\n\n## Generating Single Header\n\n```bash\npython3 utils/amalgamate/amalgamate.py -c single_include.json -s .\n```\n\n## Contributing\nContributions are welcome, have a look at the CONTRIBUTING.md document for more information.\n\n## License\nThe project is available under the MIT license.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fp-ranav%2Fpsched","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fp-ranav%2Fpsched","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fp-ranav%2Fpsched/lists"}