• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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