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 HICORO_POLLER_H 17 #define HICORO_POLLER_H 18 #ifndef _MSC_VER 19 #include <sys/epoll.h> 20 #include <sys/eventfd.h> 21 #endif 22 #include "qos.h" 23 #include "sync/sync.h" 24 #ifdef FFRT_IO_TASK_SCHEDULER 25 #include <list> 26 #include <unordered_map> 27 #include <array> 28 #include "internal_inc/non_copyable.h" 29 namespace ffrt { 30 enum class PollerRet { 31 RET_NULL, 32 RET_EPOLL, 33 RET_TIMER, 34 }; 35 36 enum class EpollStatus { 37 WAIT, 38 WAKE, 39 TEARDOWN, 40 }; 41 42 enum class TimerStatus { 43 EXECUTING, 44 EXECUTED, 45 }; 46 47 struct WakeDataWithCb { WakeDataWithCbWakeDataWithCb48 WakeDataWithCb() {} WakeDataWithCbWakeDataWithCb49 WakeDataWithCb(int fdVal, void *dataVal, std::function<void(void *, uint32_t, uint8_t)> cbVal) 50 : fd(fdVal), data(dataVal), cb(cbVal) {} 51 52 int fd = 0; 53 void *data = nullptr; 54 std::function<void(void *, uint32_t, uint8_t)> cb = nullptr; 55 }; 56 57 struct TimerDataWithCb { TimerDataWithCbTimerDataWithCb58 TimerDataWithCb() {} TimerDataWithCbTimerDataWithCb59 TimerDataWithCb(void* dataVal, void(*cbVal)(void*)) : data(dataVal), cb(cbVal) {} 60 61 void* data = nullptr; 62 void(*cb)(void*) = nullptr; 63 int handle = -1; 64 }; 65 66 class Poller : private NonCopyable { 67 using WakeDataList = typename std::list<std::unique_ptr<struct WakeDataWithCb>>; 68 public: 69 Poller() noexcept; 70 ~Poller() noexcept; 71 72 int AddFdEvent(uint32_t events, int fd, void* data, ffrt_poller_cb cb) noexcept; 73 int DelFdEvent(int fd) noexcept; 74 75 PollerRet PollOnce(int timeout = -1) noexcept; 76 void WakeUp() noexcept; 77 78 int RegisterTimer(uint64_t timeout, void* data, void(*cb)(void*)) noexcept; 79 void DeregisterTimer(int handle) noexcept; 80 bool DetermineEmptyMap() noexcept; 81 ffrt_timer_query_t GetTimerStatus(int handle) noexcept; 82 83 private: 84 void ReleaseFdWakeData() noexcept; 85 void ExecuteTimerCb(std::multimap<time_point_t, TimerDataWithCb>::iterator& timer) noexcept; 86 87 int m_epFd; 88 uint8_t pollerCount_ = 0; 89 int timerHandle_ = -1; 90 EpollStatus flag_ = EpollStatus::WAKE; 91 struct WakeDataWithCb m_wakeData; 92 std::unordered_map<int, WakeDataList> m_wakeDataMap; 93 std::unordered_map<int, int> m_delCntMap; 94 std::unordered_map<int, TimerStatus> executedHandle_; 95 std::multimap<time_point_t, TimerDataWithCb> timerMap_; 96 std::atomic_bool fdEmpty_ {true}; 97 std::atomic_bool timerEmpty_ {true}; 98 mutable spin_mutex m_mapMutex; 99 mutable spin_mutex timerMutex_; 100 #ifndef _MSC_VER 101 std::vector<epoll_event> m_events; 102 #endif 103 }; 104 105 struct PollerProxy { 106 public: InstancePollerProxy107 static inline PollerProxy* Instance() 108 { 109 static PollerProxy pollerInstance; 110 return &pollerInstance; 111 } 112 113 Poller& GetPoller(const QoS& qos = ffrt_qos_default) 114 { 115 return qosPollers[static_cast<size_t>(qos)]; 116 } 117 118 private: 119 std::array<Poller, QoS::Max()> qosPollers; 120 }; 121 } // namespace ffrt 122 #endif 123 #endif