1 /**
2 * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "runtime/mem/gc/workers/gc_workers_task_pool.h"
17
18 namespace ark::mem {
19
IncreaseSolvedTasks()20 void GCWorkersTaskPool::IncreaseSolvedTasks()
21 {
22 // Atomic with seq_cst order reason: solved_tasks_ value synchronization
23 auto solvedTasksOldValue = solvedTasks_.fetch_add(1, std::memory_order_seq_cst);
24 if (solvedTasksOldValue + 1U == sendedTasks_) {
25 os::memory::LockHolder lock(allSolvedTasksCondVarLock_);
26 allSolvedTasksCondVar_.Signal();
27
28 // Here we use double check to be sure that IncreaseSolvedTasks method will release
29 // all_solved_tasks_cond_var_lock_ before GCWorkersTaskPool deleting in GC::DestroyWorkersTaskPool method
30 if (solvedTasksOldValue >= solvedTasksSnapshot_ && solvedTasksOldValue + 1U == sendedTasks_) {
31 solvedTasksSnapshot_ = solvedTasksOldValue + 1U;
32 }
33 }
34 }
35
AddTask(GCWorkersTask && task)36 bool GCWorkersTaskPool::AddTask(GCWorkersTask &&task)
37 {
38 sendedTasks_++;
39 [[maybe_unused]] GCWorkersTaskTypes type = task.GetType();
40 if (this->TryAddTask(std::forward<GCWorkersTask &&>(task))) {
41 LOG(DEBUG, GC) << "Added a new " << GCWorkersTaskTypesToString(type) << " to gc task pool";
42 return true;
43 }
44 // Couldn't add gc workers task to pool
45 sendedTasks_--;
46 return false;
47 }
48
RunGCWorkersTask(GCWorkersTask * task,void * workerData)49 void GCWorkersTaskPool::RunGCWorkersTask(GCWorkersTask *task, void *workerData)
50 {
51 gc_->WorkerTaskProcessing(task, workerData);
52 IncreaseSolvedTasks();
53 }
54
WaitUntilTasksEnd()55 void GCWorkersTaskPool::WaitUntilTasksEnd()
56 {
57 for (;;) {
58 // Current thread can to help workers with gc task processing.
59 // Try to get gc workers task from pool if it's possible and run the task immediately
60 this->RunInCurrentThread();
61 os::memory::LockHolder lock(allSolvedTasksCondVarLock_);
62 // If all sended task were solved then break from wait loop
63 // Here we use double check to be sure that IncreaseSolvedTasks method will release
64 // all_solved_tasks_cond_var_lock_ before GCWorkersTaskPool deleting in GC::DestroyWorkersTaskPool method
65 if (solvedTasks_ == sendedTasks_ && solvedTasks_ == solvedTasksSnapshot_) {
66 ResetTasks();
67 break;
68 }
69 allSolvedTasksCondVar_.TimedWait(&allSolvedTasksCondVarLock_, ALL_GC_TASKS_FINISH_WAIT_TIMEOUT);
70 }
71 }
72
73 } // namespace ark::mem
74