1 /* 2 * Copyright (c) 2023 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 #ifndef PANDA_LIBPANDABASE_TASKMANAGER_TASK_STATISTICS_FINE_GRAINED_TASK_STATISTICS_IMPL_H 17 #define PANDA_LIBPANDABASE_TASKMANAGER_TASK_STATISTICS_FINE_GRAINED_TASK_STATISTICS_IMPL_H 18 19 #include <atomic> 20 #include <unordered_map> 21 #include "libpandabase/os/mutex.h" 22 #include "libpandabase/taskmanager/task_statistics/task_statistics.h" 23 24 namespace panda::taskmanager { 25 26 /// This version of TaskStatistics uses a separate lock for each type of task. 27 class FineGrainedTaskStatisticsImpl : public TaskStatistics { 28 class GuardedCounter { 29 public: counter_(startValue)30 explicit GuardedCounter(size_t startValue = 0) : counter_(startValue) {} 31 32 GuardedCounter &operator+=(size_t value) 33 { 34 os::memory::LockHolder lockHolder(lock_); 35 counter_ += value; 36 return *this; 37 } 38 39 friend bool operator==(const GuardedCounter &lv, const GuardedCounter &rv) 40 { 41 os::memory::LockHolder lvLockHolder(lv.lock_); 42 os::memory::LockHolder rvLockHolder(rv.lock_); 43 return lv.counter_ == rv.counter_; 44 } 45 NoGuardedSetValue(size_t value)46 void NoGuardedSetValue(size_t value) 47 { 48 counter_ = value; 49 } 50 GetMutex()51 os::memory::Mutex &GetMutex() 52 { 53 return lock_; 54 } 55 SetValue(size_t value)56 void SetValue(size_t value) 57 { 58 os::memory::LockHolder lockHolder(lock_); 59 counter_ = value; 60 } 61 GetValue()62 size_t GetValue() const 63 { 64 os::memory::LockHolder lockHolder(lock_); 65 return counter_; 66 } 67 CalcCountOfTasksInSystem(const GuardedCounter & addedCount,const GuardedCounter & executedCount,const GuardedCounter & poppedCount)68 friend size_t CalcCountOfTasksInSystem(const GuardedCounter &addedCount, const GuardedCounter &executedCount, 69 const GuardedCounter &poppedCount) 70 { 71 os::memory::LockHolder addedLockHolder(addedCount.lock_); 72 os::memory::LockHolder executedLockHolder(executedCount.lock_); 73 os::memory::LockHolder poppedLockHolder(poppedCount.lock_); 74 ASSERT(addedCount.counter_ >= executedCount.counter_ + poppedCount.counter_); 75 return addedCount.counter_ - executedCount.counter_ - poppedCount.counter_; 76 } 77 78 private: 79 mutable os::memory::Mutex lock_; 80 size_t counter_; 81 }; 82 83 using TaskPropertiesGuardedCounter = std::unordered_map<TaskProperties, GuardedCounter, TaskProperties::Hash>; 84 85 public: 86 FineGrainedTaskStatisticsImpl(); 87 ~FineGrainedTaskStatisticsImpl() override = default; 88 89 NO_COPY_SEMANTIC(FineGrainedTaskStatisticsImpl); 90 NO_MOVE_SEMANTIC(FineGrainedTaskStatisticsImpl); 91 92 void IncrementCount(TaskStatus status, TaskProperties properties, size_t count) override; 93 size_t GetCount(TaskStatus status, TaskProperties properties) const override; 94 95 size_t GetCountOfTaskInSystem() const override; 96 size_t GetCountOfTasksInSystemWithTaskProperties(TaskProperties properties) const override; 97 98 void ResetAllCounters() override; 99 void ResetCountersWithTaskProperties(TaskProperties properties) override; 100 101 private: 102 std::unordered_map<TaskStatus, TaskPropertiesGuardedCounter> taskPropertiesCounterMap_; 103 }; 104 105 } // namespace panda::taskmanager 106 107 #endif // PANDA_LIBPANDABASE_TASKMANAGER_TASK_STATISTICS_FINE_GRAINED_TASK_STATISTICS_IMPL_H 108