diff --git a/static_core/docs/task_manager.md b/static_core/docs/task_manager.md index c5020a4e900f84a11b82f6cf4d3c8fd7137d6abc..5f922783a493e98fdea53e3919c3c5915c7af3f6 100644 --- a/static_core/docs/task_manager.md +++ b/static_core/docs/task_manager.md @@ -1,24 +1,54 @@ # Introduction -Internally in VM we have different tasks for two components `GC` and `JIT`. Both of this components can use more than one thread for solving one task or another. To optimize usage of hardware(cores)/OS(threads) resources we introduce TaskManager. The main goal of TaskManager is to use limited number of resources(OS threads) and schedule different types of tasks and achieve optimal metric values for `GC` and `JIT`. I.e. for example if we expect STW(stop-the-world pause) soon - we should increase priority for `GC` tasks. And vice-versa if we do not expect `GC` tasks anytime soon - we should increase priority for `JIT` tasks. +## Usage guide -For Hybrid mode (i.e. we can execute both static and dynamic code) TaskManager also should take into account the language context. I.e. if we are currently executing static code - the `GC` tasks for static instance have higher priority than `GC` tasks for dynamic instance, and vice versa. +### TaskManager startup -# Implementation details +To start usage of TaskManager you need to start it by `TaskManager::Start(...)`. Also, to finish you should call `TaskManager::Finish()`. +Main interface to use tasks manager is `TaskQueue`. You can get it by calling `TaskManager::CreateTaskQueue(...)`. +To delete queue use `TaskManager::DestroyTaskQueue(...)`. It's importent that **you must manage if TaskQueue is empty before delete it**. +Count of created queue is limited (MAX_COUNT_OF_QUEUE). -##Task +### TaskQueue -It is some limited by time task, which has these properties: -- priority of operation: `background` or `foreground`; -- for which VM instance (`static` or `dynamic`) this task is executed; -- which component is the owner of this task (`GC`, `JIT`, etc.) +When you got a TaskQueue from TaskManager, you can start interact with multithreading subsystem. +TaskQueue implements 2 types of tasks: `foreground` and `background`. `Foreground` tasks will be added in workers before `background` ones. +All queue method have at least 2 variation for usage of `foreground` and `background` tasks. + +#### Adding of tasks + +First you can do is add your functor in queue by following methods: +- `TaskQueueInterface::AddForegroundTask()` +- `TaskQueueInterface::AddBackgroundTask()` +And it will be completed as soon as possible. + +With following methods: +- `TaskQueueInterface::AddForegroundTaskInWaitList()` +- `TaskQueueInterface::AddBackgroundTaskInWaitList()` +You can postpone the start of the functor execution. Method returns `WaitId` that can be used to signal TaskQueue to start execution of the functor. +You should use `TaskQueueInterface::SignalWaitList()` method. +Also you can set timeout in `TaskQueueInterface::Add<...>InWaitList` and functor execution will be started after gotten time. The time is required to finish the task should be limited by some reasonable value, to make the whole system with Task management optimal. +#### Task waiting + +If you need tasks to be completed at a certain point in time, you need to use the following methods: +- `TaskQueueInterface::WaitTasks()` for all tasks from queue +- `TaskQueueInterface::WaitForegroundTasks()` for all foreground tasks +- `TaskQueueInterface::WaitBackgroundTasks()` for all background tasks +**This is the only guarantee that the result of the tasks will be visible in the queue owner thread.** + +#### Queue priority + +You can interact with the queue priority inside the scheduler. +Use method `TaskQueueInterface::SetPriority()` to set priority, but it have limitations with MIN_PRIORITY and MAX_PRIORITY. -##WorkerThread +### WorkerThread -WorkerThread is the thread which executing tasks. Each WorkerThread has two queues - one for the foreground tasks and one for the background tasks. WorkerThread always try to execute task from the foreground queue first, if it is empty, then it try to execute task from the background queue. If no tasks in both queues - WorkerThread request `TaskManager` for more tasks. +WorkerThread is the thread which executing tasks. Each WorkerThread has two queues - one for the foreground tasks and one for the background tasks. +WorkerThread always try to execute task from the foreground queue first, if it is empty, then it try to execute task from the background queue. +If no tasks in both queues - WorkerThread request `TaskManager` for more tasks. ##TaskManager