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#include "base_queue.h" 17#include "dfx/log/ffrt_log_api.h" 18#include "tm/queue_task.h" 19#include "serial_queue.h" 20#include "concurrent_queue.h" 21#include "eventhandler_adapter_queue.h" 22#include "eventhandler_interactive_queue.h" 23 24namespace { 25using CreateFunc = std::unique_ptr<ffrt::BaseQueue>(*)(const ffrt_queue_attr_t*); 26const std::unordered_map<int, CreateFunc> CREATE_FUNC_MAP = { 27 { ffrt_queue_serial, ffrt::CreateSerialQueue }, 28 { ffrt_queue_concurrent, ffrt::CreateConcurrentQueue }, 29 { ffrt_queue_eventhandler_interactive, ffrt::CreateEventHandlerInteractiveQueue }, 30 { ffrt_queue_eventhandler_adapter, ffrt::CreateEventHandlerAdapterQueue }, 31}; 32} 33 34namespace ffrt { 35// 0预留为非法值 36std::atomic_uint32_t BaseQueue::queueId(1); 37void BaseQueue::Stop() 38{ 39 std::unique_lock lock(mutex_); 40 isExit_ = true; 41 42 ClearWhenMap(); 43 44 FFRT_LOGI("clear [queueId=%u] succ", queueId_); 45} 46 47void BaseQueue::Remove() 48{ 49 std::unique_lock lock(mutex_); 50 FFRT_COND_DO_ERR(isExit_, return, "cannot remove task, [queueId=%u] is exiting", queueId_); 51 52 ClearWhenMap(); 53 54 FFRT_LOGD("cancel [queueId=%u] all tasks succ", queueId_); 55} 56 57int BaseQueue::Remove(const char* name) 58{ 59 std::unique_lock lock(mutex_); 60 FFRT_COND_DO_ERR(isExit_, return FAILED, "cannot remove task, [queueId=%u] is exiting", queueId_); 61 62 int removedCount = 0; 63 for (auto iter = whenMap_.begin(); iter != whenMap_.end();) { 64 if (iter->second->IsMatch(name)) { 65 FFRT_LOGD("cancel task[%llu] %s succ", iter->second->gid, iter->second->label.c_str()); 66 iter->second->Notify(); 67 iter->second->Destroy(); 68 iter = whenMap_.erase(iter); 69 removedCount++; 70 } else { 71 ++iter; 72 } 73 } 74 75 return removedCount > 0 ? SUCC : FAILED; 76} 77 78int BaseQueue::Remove(const QueueTask* task) 79{ 80 std::unique_lock lock(mutex_); 81 FFRT_COND_DO_ERR(isExit_, return FAILED, "cannot remove task, [queueId=%u] is exiting", queueId_); 82 83 auto range = whenMap_.equal_range(task->GetUptime()); 84 for (auto it = range.first; it != range.second; it++) { 85 if (it->second == task) { 86 whenMap_.erase(it); 87 return SUCC; 88 } 89 } 90 91 return FAILED; 92} 93 94bool BaseQueue::HasTask(const char* name) 95{ 96 std::unique_lock lock(mutex_); 97 auto iter = std::find_if(whenMap_.cbegin(), whenMap_.cend(), 98 [name](const auto& pair) { return pair.second->IsMatch(name); }); 99 return iter != whenMap_.cend(); 100} 101 102void BaseQueue::PrintMutexOwner() 103{ 104 MutexOwnerType type = mutex_.GetOwnerType(); 105 if (type == MutexOwnerType::MUTEX_OWNER_TYPE_TASK) { 106 FFRT_LOGI("In queue %u, task %llu owns the lock for %llu us.", 107 queueId_, mutex_.GetOwnerId(), mutex_.GetDuration()); 108 } else { 109 FFRT_LOGI("In queue %u, thread %llu owns the lock for %llu us.", 110 queueId_, mutex_.GetOwnerId(), mutex_.GetDuration()); 111 } 112} 113 114void BaseQueue::ClearWhenMap() 115{ 116 for (auto it = whenMap_.begin(); it != whenMap_.end(); it++) { 117 if (it->second) { 118 it->second->Notify(); 119 it->second->Destroy(); 120 it->second = nullptr; 121 } 122 } 123 whenMap_.clear(); 124 cond_.NotifyOne(); 125} 126 127std::unique_ptr<BaseQueue> CreateQueue(int queueType, const ffrt_queue_attr_t* attr) 128{ 129 const auto iter = CREATE_FUNC_MAP.find(queueType); 130 FFRT_COND_DO_ERR((iter == CREATE_FUNC_MAP.end()), return nullptr, "invalid queue type"); 131 132 return iter->second(attr); 133} 134} // namespace ffrt 135