1484543d1Sopenharmony_ci/* 2484543d1Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3484543d1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4484543d1Sopenharmony_ci * you may not use this file except in compliance with the License. 5484543d1Sopenharmony_ci * You may obtain a copy of the License at 6484543d1Sopenharmony_ci * 7484543d1Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8484543d1Sopenharmony_ci * 9484543d1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10484543d1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11484543d1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12484543d1Sopenharmony_ci * See the License for the specific language governing permissions and 13484543d1Sopenharmony_ci * limitations under the License. 14484543d1Sopenharmony_ci */ 15484543d1Sopenharmony_ci 16484543d1Sopenharmony_ci#ifndef HICORO_POLLER_H 17484543d1Sopenharmony_ci#define HICORO_POLLER_H 18484543d1Sopenharmony_ci#ifndef _MSC_VER 19484543d1Sopenharmony_ci#include <sys/epoll.h> 20484543d1Sopenharmony_ci#include <sys/eventfd.h> 21484543d1Sopenharmony_ci#endif 22484543d1Sopenharmony_ci#include <list> 23484543d1Sopenharmony_ci#include <map> 24484543d1Sopenharmony_ci#include <unordered_map> 25484543d1Sopenharmony_ci#include <array> 26484543d1Sopenharmony_ci#include "qos.h" 27484543d1Sopenharmony_ci#include "sync/sync.h" 28484543d1Sopenharmony_ci#include "internal_inc/non_copyable.h" 29484543d1Sopenharmony_ci#include "c/executor_task.h" 30484543d1Sopenharmony_ci#include "c/timer.h" 31484543d1Sopenharmony_ci#include "eu/worker_thread.h" 32484543d1Sopenharmony_cinamespace ffrt { 33484543d1Sopenharmony_cienum class PollerRet { 34484543d1Sopenharmony_ci RET_NULL, 35484543d1Sopenharmony_ci RET_EPOLL, 36484543d1Sopenharmony_ci RET_TIMER, 37484543d1Sopenharmony_ci}; 38484543d1Sopenharmony_ci 39484543d1Sopenharmony_cienum class EpollStatus { 40484543d1Sopenharmony_ci WAIT, 41484543d1Sopenharmony_ci WAKE, 42484543d1Sopenharmony_ci TEARDOWN, 43484543d1Sopenharmony_ci}; 44484543d1Sopenharmony_ci 45484543d1Sopenharmony_cienum class TimerStatus { 46484543d1Sopenharmony_ci EXECUTING, 47484543d1Sopenharmony_ci EXECUTED, 48484543d1Sopenharmony_ci}; 49484543d1Sopenharmony_ci 50484543d1Sopenharmony_ciconstexpr int EPOLL_EVENT_SIZE = 1024; 51484543d1Sopenharmony_ci 52484543d1Sopenharmony_cistruct WakeDataWithCb { 53484543d1Sopenharmony_ci WakeDataWithCb() {} 54484543d1Sopenharmony_ci WakeDataWithCb(int fdVal, void *dataVal, std::function<void(void *, uint32_t)> cbVal, CPUEUTask *taskVal) 55484543d1Sopenharmony_ci : fd(fdVal), data(dataVal), cb(cbVal), task(taskVal) 56484543d1Sopenharmony_ci {} 57484543d1Sopenharmony_ci 58484543d1Sopenharmony_ci int fd = 0; 59484543d1Sopenharmony_ci void* data = nullptr; 60484543d1Sopenharmony_ci std::function<void(void*, uint32_t)> cb = nullptr; 61484543d1Sopenharmony_ci CPUEUTask* task = nullptr; 62484543d1Sopenharmony_ci uint32_t monitorEvents = 0; 63484543d1Sopenharmony_ci}; 64484543d1Sopenharmony_ci 65484543d1Sopenharmony_cistruct TimerDataWithCb { 66484543d1Sopenharmony_ci TimerDataWithCb() {} 67484543d1Sopenharmony_ci TimerDataWithCb(void *dataVal, void (*cbVal)(void *), CPUEUTask *taskVal, bool repeat, uint64_t timeout) 68484543d1Sopenharmony_ci : data(dataVal), cb(cbVal), task(taskVal), repeat(repeat), timeout(timeout) 69484543d1Sopenharmony_ci {} 70484543d1Sopenharmony_ci 71484543d1Sopenharmony_ci void* data = nullptr; 72484543d1Sopenharmony_ci void(*cb)(void*) = nullptr; 73484543d1Sopenharmony_ci int handle = -1; 74484543d1Sopenharmony_ci CPUEUTask* task = nullptr; 75484543d1Sopenharmony_ci bool repeat = false; 76484543d1Sopenharmony_ci uint64_t timeout = 0; 77484543d1Sopenharmony_ci}; 78484543d1Sopenharmony_ci 79484543d1Sopenharmony_cistruct SyncData { 80484543d1Sopenharmony_ci SyncData() {} 81484543d1Sopenharmony_ci SyncData(void *eventsPtr, int maxEvents, int *nfdsPtr, TimePoint waitTP) 82484543d1Sopenharmony_ci : eventsPtr(eventsPtr), maxEvents(maxEvents), nfdsPtr(nfdsPtr), waitTP(waitTP) 83484543d1Sopenharmony_ci {} 84484543d1Sopenharmony_ci 85484543d1Sopenharmony_ci void* eventsPtr = nullptr; 86484543d1Sopenharmony_ci int maxEvents = 0; 87484543d1Sopenharmony_ci int* nfdsPtr = nullptr; 88484543d1Sopenharmony_ci TimePoint waitTP; 89484543d1Sopenharmony_ci}; 90484543d1Sopenharmony_ci 91484543d1Sopenharmony_ciusing EventVec = typename std::vector<epoll_event>; 92484543d1Sopenharmony_ciclass Poller : private NonCopyable { 93484543d1Sopenharmony_ci using WakeDataList = typename std::list<std::unique_ptr<struct WakeDataWithCb>>; 94484543d1Sopenharmony_cipublic: 95484543d1Sopenharmony_ci Poller() noexcept; 96484543d1Sopenharmony_ci ~Poller() noexcept; 97484543d1Sopenharmony_ci 98484543d1Sopenharmony_ci int AddFdEvent(int op, uint32_t events, int fd, void* data, ffrt_poller_cb cb) noexcept; 99484543d1Sopenharmony_ci int DelFdEvent(int fd) noexcept; 100484543d1Sopenharmony_ci int WaitFdEvent(struct epoll_event *eventsVec, int maxevents, int timeout) noexcept; 101484543d1Sopenharmony_ci 102484543d1Sopenharmony_ci PollerRet PollOnce(int timeout = -1) noexcept; 103484543d1Sopenharmony_ci void WakeUp() noexcept; 104484543d1Sopenharmony_ci 105484543d1Sopenharmony_ci int RegisterTimer(uint64_t timeout, void* data, ffrt_timer_cb cb, bool repeat = false) noexcept; 106484543d1Sopenharmony_ci int UnregisterTimer(int handle) noexcept; 107484543d1Sopenharmony_ci ffrt_timer_query_t GetTimerStatus(int handle) noexcept; 108484543d1Sopenharmony_ci 109484543d1Sopenharmony_ci uint8_t GetPollCount() noexcept; 110484543d1Sopenharmony_ci 111484543d1Sopenharmony_ci uint64_t GetTaskWaitTime(CPUEUTask* task) noexcept; 112484543d1Sopenharmony_ci 113484543d1Sopenharmony_ci bool DetermineEmptyMap() noexcept; 114484543d1Sopenharmony_ci bool DeterminePollerReady() noexcept; 115484543d1Sopenharmony_ci 116484543d1Sopenharmony_ci void ClearCachedEvents(CPUEUTask* task) noexcept; 117484543d1Sopenharmony_ci 118484543d1Sopenharmony_ciprivate: 119484543d1Sopenharmony_ci void ReleaseFdWakeData() noexcept; 120484543d1Sopenharmony_ci void WakeSyncTask(std::unordered_map<CPUEUTask*, EventVec>& syncTaskEvents) noexcept; 121484543d1Sopenharmony_ci void ProcessWaitedFds(int nfds, std::unordered_map<CPUEUTask*, EventVec>& syncTaskEvents, 122484543d1Sopenharmony_ci std::array<epoll_event, EPOLL_EVENT_SIZE>& waitedEvents) noexcept; 123484543d1Sopenharmony_ci 124484543d1Sopenharmony_ci void ExecuteTimerCb(TimePoint timer) noexcept; 125484543d1Sopenharmony_ci void ProcessTimerDataCb(CPUEUTask* task) noexcept; 126484543d1Sopenharmony_ci void RegisterTimerImpl(const TimerDataWithCb& data) noexcept; 127484543d1Sopenharmony_ci 128484543d1Sopenharmony_ci void CacheEventsAndDoMask(CPUEUTask* task, EventVec& eventVec) noexcept; 129484543d1Sopenharmony_ci int FetchCachedEventAndDoUnmask(CPUEUTask* task, struct epoll_event* eventsVec) noexcept; 130484543d1Sopenharmony_ci int FetchCachedEventAndDoUnmask(EventVec& cachedEventsVec, struct epoll_event* eventsVec) noexcept; 131484543d1Sopenharmony_ci 132484543d1Sopenharmony_ci bool IsFdExist() noexcept; 133484543d1Sopenharmony_ci bool IsTimerReady() noexcept; 134484543d1Sopenharmony_ci 135484543d1Sopenharmony_ci int m_epFd; 136484543d1Sopenharmony_ci uint8_t pollerCount_ = 0; 137484543d1Sopenharmony_ci int timerHandle_ = -1; 138484543d1Sopenharmony_ci EpollStatus flag_ = EpollStatus::WAKE; 139484543d1Sopenharmony_ci struct WakeDataWithCb m_wakeData; 140484543d1Sopenharmony_ci std::unordered_map<int, WakeDataList> m_wakeDataMap; 141484543d1Sopenharmony_ci std::unordered_map<int, int> m_delCntMap; 142484543d1Sopenharmony_ci std::unordered_map<CPUEUTask*, SyncData> m_waitTaskMap; 143484543d1Sopenharmony_ci std::unordered_map<CPUEUTask*, EventVec> m_cachedTaskEvents; 144484543d1Sopenharmony_ci 145484543d1Sopenharmony_ci std::unordered_map<int, TimerStatus> executedHandle_; 146484543d1Sopenharmony_ci std::multimap<TimePoint, TimerDataWithCb> timerMap_; 147484543d1Sopenharmony_ci std::atomic_bool fdEmpty_ {true}; 148484543d1Sopenharmony_ci std::atomic_bool timerEmpty_ {true}; 149484543d1Sopenharmony_ci mutable spin_mutex m_mapMutex; 150484543d1Sopenharmony_ci mutable spin_mutex timerMutex_; 151484543d1Sopenharmony_ci}; 152484543d1Sopenharmony_ci 153484543d1Sopenharmony_cistruct PollerProxy { 154484543d1Sopenharmony_cipublic: 155484543d1Sopenharmony_ci static PollerProxy& Instance(); 156484543d1Sopenharmony_ci 157484543d1Sopenharmony_ci Poller& GetPoller(const QoS& qos = QoS(ffrt_qos_default)) 158484543d1Sopenharmony_ci { 159484543d1Sopenharmony_ci return qosPollers[static_cast<size_t>(qos())]; 160484543d1Sopenharmony_ci } 161484543d1Sopenharmony_ci 162484543d1Sopenharmony_ciprivate: 163484543d1Sopenharmony_ci std::array<Poller, QoS::MaxNum()> qosPollers; 164484543d1Sopenharmony_ci}; 165484543d1Sopenharmony_ci} // namespace ffrt 166484543d1Sopenharmony_ci#endif