1 /**
2 * Copyright (c) 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 "plugins/ets/runtime/ets_taskpool.h"
17
18 namespace ark::ets {
19
Taskpool()20 Taskpool::Taskpool() : taskId_(1) {}
21
GenerateTaskId()22 EtsLong Taskpool::GenerateTaskId()
23 {
24 return taskId_++;
25 }
26
TaskSubmitted(EtsLong taskId)27 void Taskpool::TaskSubmitted(EtsLong taskId)
28 {
29 os::memory::LockHolder lh(taskpoolLock_);
30 waitingTasks_[taskId]++;
31 }
32
DecrementTaskCounter(EtsLong taskId,PandaUnorderedMap<EtsLong,size_t> & tasks)33 size_t Taskpool::DecrementTaskCounter(EtsLong taskId, PandaUnorderedMap<EtsLong, size_t> &tasks)
34 {
35 auto taskIter = tasks.find(taskId);
36 ASSERT(taskIter != tasks.end());
37 auto tasksCount = --(taskIter->second);
38 if (tasksCount == 0) {
39 tasks.erase(taskIter);
40 }
41 return tasksCount;
42 }
43
TaskStarted(uint32_t coroutineId,EtsLong taskId)44 bool Taskpool::TaskStarted(uint32_t coroutineId, EtsLong taskId)
45 {
46 os::memory::LockHolder lh(taskpoolLock_);
47 auto waitingTasksCountWithId = DecrementTaskCounter(taskId, waitingTasks_);
48 if (tasksToBeCanceled_.find(taskId) != tasksToBeCanceled_.end()) {
49 if ((waitingTasksCountWithId == 0) && (runningTasks_.find(taskId) == runningTasks_.end())) {
50 // No tasks with this id in the taskpool
51 tasksToBeCanceled_.erase(taskId);
52 }
53 // escompat.Error will be occurred for the current task
54 return false;
55 }
56 executingTasks_.insert({coroutineId, taskId});
57 runningTasks_[taskId]++;
58 return true;
59 }
60
TaskFinished(uint32_t coroutineId,EtsLong taskId)61 bool Taskpool::TaskFinished(uint32_t coroutineId, EtsLong taskId)
62 {
63 os::memory::LockHolder lh(taskpoolLock_);
64 ASSERT(executingTasks_[coroutineId] == taskId);
65 executingTasks_.erase(coroutineId);
66 auto runningTasksCountWithId = DecrementTaskCounter(taskId, runningTasks_);
67 if (tasksToBeCanceled_.find(taskId) != tasksToBeCanceled_.end()) {
68 if ((runningTasksCountWithId == 0) && (waitingTasks_.find(taskId) == waitingTasks_.end())) {
69 // No tasks with this id in the taskpool
70 tasksToBeCanceled_.erase(taskId);
71 }
72 // escompat.Error will be occurred for the current task
73 return false;
74 }
75 return true;
76 }
77
CancelTask(EtsLong taskId)78 bool Taskpool::CancelTask(EtsLong taskId)
79 {
80 os::memory::LockHolder lh(taskpoolLock_);
81 if ((waitingTasks_.find(taskId) == waitingTasks_.end()) && (runningTasks_.find(taskId) == runningTasks_.end())) {
82 // No tasks with this id in the taskpool, escompat.Error will be occurred by taskpool.cancel
83 return false;
84 }
85 tasksToBeCanceled_.insert(taskId);
86 return true;
87 }
88
IsTaskCanceled(uint32_t coroutineId) const89 bool Taskpool::IsTaskCanceled(uint32_t coroutineId) const
90 {
91 os::memory::LockHolder lh(taskpoolLock_);
92 auto it = executingTasks_.find(coroutineId);
93 if (it == executingTasks_.end()) {
94 // Current coroutine is not executing a task
95 return false;
96 }
97 auto taskId = it->second;
98 return tasksToBeCanceled_.find(taskId) != tasksToBeCanceled_.end();
99 }
100
101 } // namespace ark::ets
102