Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fd3b80c9 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "[adb] Optimize fdevent machinery" into rvc-dev

parents 3b1ce566 76820308
Loading
Loading
Loading
Loading
+17 −15
Original line number Diff line number Diff line
@@ -63,7 +63,10 @@ fdevent* fdevent_context::Create(unique_fd fd, std::variant<fd_func, fd_func2> f

    int fd_num = fd.get();

    fdevent* fde = new fdevent();
    auto [it, inserted] = this->installed_fdevents_.emplace(fd_num, fdevent{});
    CHECK(inserted);

    fdevent* fde = &it->second;
    fde->id = fdevent_id_++;
    fde->state = 0;
    fde->fd = std::move(fd);
@@ -76,10 +79,6 @@ fdevent* fdevent_context::Create(unique_fd fd, std::variant<fd_func, fd_func2> f
        LOG(ERROR) << "failed to set non-blocking mode for fd " << fde->fd.get();
    }

    auto [it, inserted] = this->installed_fdevents_.emplace(fd_num, fde);
    CHECK(inserted);
    UNUSED(it);

    this->Register(fde);
    return fde;
}
@@ -92,12 +91,12 @@ unique_fd fdevent_context::Destroy(fdevent* fde) {

    this->Unregister(fde);

    auto erased = this->installed_fdevents_.erase(fde->fd.get());
    unique_fd fd = std::move(fde->fd);

    auto erased = this->installed_fdevents_.erase(fd.get());
    CHECK_EQ(1UL, erased);

    unique_fd result = std::move(fde->fd);
    delete fde;
    return result;
    return fd;
}

void fdevent_context::Add(fdevent* fde, unsigned events) {
@@ -123,9 +122,9 @@ std::optional<std::chrono::milliseconds> fdevent_context::CalculatePollDuration(

    for (const auto& [fd, fde] : this->installed_fdevents_) {
        UNUSED(fd);
        auto timeout_opt = fde->timeout;
        auto timeout_opt = fde.timeout;
        if (timeout_opt) {
            auto deadline = fde->last_active + *timeout_opt;
            auto deadline = fde.last_active + *timeout_opt;
            auto time_left = duration_cast<std::chrono::milliseconds>(deadline - now);
            if (time_left < 0ms) {
                time_left = 0ms;
@@ -194,11 +193,13 @@ static std::unique_ptr<fdevent_context> fdevent_create_context() {
#endif
}

static auto& g_ambient_fdevent_context =
        *new std::unique_ptr<fdevent_context>(fdevent_create_context());
static auto& g_ambient_fdevent_context() {
    static auto context = fdevent_create_context().release();
    return context;
}

static fdevent_context* fdevent_get_ambient() {
    return g_ambient_fdevent_context.get();
    return g_ambient_fdevent_context();
}

fdevent* fdevent_create(int fd, fd_func func, void* arg) {
@@ -256,5 +257,6 @@ size_t fdevent_installed_count() {
}

void fdevent_reset() {
    g_ambient_fdevent_context = fdevent_create_context();
    auto old = std::exchange(g_ambient_fdevent_context(), fdevent_create_context().release());
    delete old;
}
+15 −15
Original line number Diff line number Diff line
@@ -52,6 +52,20 @@ struct fdevent_event {
    unsigned events;
};

struct fdevent final {
    uint64_t id;

    unique_fd fd;
    int force_eof = 0;

    uint16_t state = 0;
    std::optional<std::chrono::milliseconds> timeout;
    std::chrono::steady_clock::time_point last_active;

    std::variant<fd_func, fd_func2> func;
    void* arg = nullptr;
};

struct fdevent_context {
  public:
    virtual ~fdevent_context() = default;
@@ -113,7 +127,7 @@ struct fdevent_context {
    std::atomic<bool> terminate_loop_ = false;

  protected:
    std::unordered_map<int, fdevent*> installed_fdevents_;
    std::unordered_map<int, fdevent> installed_fdevents_;

  private:
    uint64_t fdevent_id_ = 0;
@@ -121,20 +135,6 @@ struct fdevent_context {
    std::deque<std::function<void()>> run_queue_ GUARDED_BY(run_queue_mutex_);
};

struct fdevent {
    uint64_t id;

    unique_fd fd;
    int force_eof = 0;

    uint16_t state = 0;
    std::optional<std::chrono::milliseconds> timeout;
    std::chrono::steady_clock::time_point last_active;

    std::variant<fd_func, fd_func2> func;
    void* arg = nullptr;
};

// Backwards compatibility shims that forward to the global fdevent_context.
fdevent* fdevent_create(int fd, fd_func func, void* arg);
fdevent* fdevent_create(int fd, fd_func2 func, void* arg);
+8 −8
Original line number Diff line number Diff line
@@ -155,15 +155,15 @@ void fdevent_context_epoll::Loop() {
            event_map[fde] = events;
        }

        for (const auto& [fd, fde] : installed_fdevents_) {
        for (auto& [fd, fde] : installed_fdevents_) {
            unsigned events = 0;
            if (auto it = event_map.find(fde); it != event_map.end()) {
            if (auto it = event_map.find(&fde); it != event_map.end()) {
                events = it->second;
            }

            if (events == 0) {
                if (fde->timeout) {
                    auto deadline = fde->last_active + *fde->timeout;
                if (fde.timeout) {
                    auto deadline = fde.last_active + *fde.timeout;
                    if (deadline < post_poll) {
                        events |= FDE_TIMEOUT;
                    }
@@ -171,13 +171,13 @@ void fdevent_context_epoll::Loop() {
            }

            if (events != 0) {
                LOG(DEBUG) << dump_fde(fde) << " got events " << std::hex << std::showbase
                LOG(DEBUG) << dump_fde(&fde) << " got events " << std::hex << std::showbase
                           << events;
                fde_events.push_back({fde, events});
                fde->last_active = post_poll;
                fde_events.push_back({&fde, events});
                fde.last_active = post_poll;
            }
        }
        this->HandleEvents(std::move(fde_events));
        this->HandleEvents(fde_events);
        fde_events.clear();
    }

+1 −6
Original line number Diff line number Diff line
@@ -47,12 +47,7 @@ struct fdevent_context_epoll final : public fdevent_context {
  protected:
    virtual void Interrupt() final;

  public:
    // All operations to fdevent should happen only in the main thread.
    // That's why we don't need a lock for fdevent.
    std::unordered_map<int, fdevent*> epoll_node_map_;
    std::list<fdevent*> pending_list_;

  private:
    unique_fd epoll_fd_;
    unique_fd interrupt_fd_;
    fdevent* interrupt_fde_ = nullptr;
+10 −7
Original line number Diff line number Diff line
@@ -103,24 +103,27 @@ static std::string dump_pollfds(const std::vector<adb_pollfd>& pollfds) {
void fdevent_context_poll::Loop() {
    main_thread_id_ = android::base::GetThreadId();

    std::vector<adb_pollfd> pollfds;
    std::vector<fdevent_event> poll_events;

    while (true) {
        if (terminate_loop_) {
            break;
        }

        D("--- --- waiting for events");
        std::vector<adb_pollfd> pollfds;
        pollfds.clear();
        for (const auto& [fd, fde] : this->installed_fdevents_) {
            adb_pollfd pfd;
            pfd.fd = fd;
            pfd.events = 0;
            if (fde->state & FDE_READ) {
            if (fde.state & FDE_READ) {
                pfd.events |= POLLIN;
            }
            if (fde->state & FDE_WRITE) {
            if (fde.state & FDE_WRITE) {
                pfd.events |= POLLOUT;
            }
            if (fde->state & FDE_ERROR) {
            if (fde.state & FDE_ERROR) {
                pfd.events |= POLLERR;
            }
#if defined(__linux__)
@@ -147,7 +150,6 @@ void fdevent_context_poll::Loop() {
        }

        auto post_poll = std::chrono::steady_clock::now();
        std::vector<fdevent_event> poll_events;

        for (const auto& pollfd : pollfds) {
            unsigned events = 0;
@@ -170,7 +172,7 @@ void fdevent_context_poll::Loop() {

            auto it = this->installed_fdevents_.find(pollfd.fd);
            CHECK(it != this->installed_fdevents_.end());
            fdevent* fde = it->second;
            fdevent* fde = &it->second;

            if (events == 0) {
                if (fde->timeout) {
@@ -187,7 +189,8 @@ void fdevent_context_poll::Loop() {
                fde->last_active = post_poll;
            }
        }
        this->HandleEvents(std::move(poll_events));
        this->HandleEvents(poll_events);
        poll_events.clear();
    }

    main_thread_id_.reset();