-
Notifications
You must be signed in to change notification settings - Fork 92
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
08e4a29
commit e43b37a
Showing
12 changed files
with
271 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// Compiler for PHP (aka KPHP) | ||
// Copyright (c) 2024 LLC «V Kontakte» | ||
// Distributed under the GPL v3 License, see LICENSE.notice.txt | ||
|
||
#include "runtime-light/stdlib/fork/wait-queue-context.h" | ||
|
||
#include "runtime-light/component/component.h" | ||
#include "runtime-light/stdlib/fork/fork-context.h" | ||
|
||
WaitQueueContext &WaitQueueContext::get() noexcept { | ||
return ForkComponentContext::get().wait_queue_context; | ||
} | ||
|
||
int64_t WaitQueueContext::create_queue(const array<Optional<int64_t>> &fork_ids) noexcept { | ||
auto &memory_resource{get_component_context()->runtime_allocator.memory_resource}; | ||
unordered_map<int64_t, task_t<fork_result>> forks(unordered_map<int64_t, task_t<fork_result>>::allocator_type{memory_resource}); | ||
std::for_each(fork_ids.begin(), fork_ids.end(), [&forks](const auto &it) { | ||
Optional<int64_t> fork_id = it.get_value(); | ||
if (fork_id.has_value()) { | ||
if (auto task = ForkComponentContext::get().pop_fork(fork_id.val()); task.has_value()) { | ||
forks[fork_id.val()] = std::move(task.val()); | ||
} | ||
} | ||
}); | ||
int64_t queue_id{++next_wait_queue_id}; | ||
wait_queues.emplace(queue_id, WaitQueue(memory_resource, std::move(forks))); | ||
php_debug("WaitQueueContext: create queue %ld with %ld forks", queue_id, fork_ids.size().size); | ||
return queue_id; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// Compiler for PHP (aka KPHP) | ||
// Copyright (c) 2024 LLC «V Kontakte» | ||
// Distributed under the GPL v3 License, see LICENSE.notice.txt | ||
|
||
#pragma once | ||
|
||
#include <cstdint> | ||
|
||
#include "runtime-core/core-types/decl/optional.h" | ||
#include "runtime-core/memory-resource/resource_allocator.h" | ||
#include "runtime-core/memory-resource/unsynchronized_pool_resource.h" | ||
#include "runtime-light/stdlib/fork/wait-queue.h" | ||
#include "runtime-light/utils/concepts.h" | ||
|
||
class WaitQueueContext { | ||
template<hashable Key, typename Value> | ||
using unordered_map = memory_resource::stl::unordered_map<Key, Value, memory_resource::unsynchronized_pool_resource>; | ||
|
||
unordered_map<int64_t, WaitQueue> wait_queues; | ||
static constexpr auto WAIT_QUEUE_INIT_ID = 0; | ||
int64_t next_wait_queue_id{WAIT_QUEUE_INIT_ID}; | ||
|
||
public: | ||
explicit WaitQueueContext(memory_resource::unsynchronized_pool_resource &memory_resource) noexcept | ||
: wait_queues(unordered_map<int64_t, WaitQueue>::allocator_type{memory_resource}) {} | ||
|
||
static WaitQueueContext &get() noexcept; | ||
|
||
int64_t create_queue(const array<Optional<int64_t>> &fork_ids) noexcept; | ||
|
||
Optional<WaitQueue *> get_queue(int64_t queue_id) noexcept { | ||
if (auto it = wait_queues.find(queue_id); it != wait_queues.end()) { | ||
return &it->second; | ||
} | ||
return {}; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
// Compiler for PHP (aka KPHP) | ||
// Copyright (c) 2024 LLC «V Kontakte» | ||
// Distributed under the GPL v3 License, see LICENSE.notice.txt | ||
|
||
#pragma once | ||
|
||
#include <algorithm> | ||
#include <coroutine> | ||
#include <cstdint> | ||
|
||
#include "runtime-core/memory-resource/resource_allocator.h" | ||
#include "runtime-core/memory-resource/unsynchronized_pool_resource.h" | ||
#include "runtime-light/coroutine/task.h" | ||
#include "runtime-light/stdlib/fork/fork.h" | ||
#include "runtime-light/utils/concepts.h" | ||
|
||
class WaitQueue { | ||
template<hashable Key, typename Value> | ||
using unordered_map = memory_resource::stl::unordered_map<Key, Value, memory_resource::unsynchronized_pool_resource>; | ||
|
||
template<typename T> | ||
using deque = memory_resource::stl::deque<T, memory_resource::unsynchronized_pool_resource>; | ||
|
||
unordered_map<int64_t, task_t<fork_result>> forks; | ||
unordered_map<int64_t, task_t<fork_result>::awaiter_t> fork_awaiters; | ||
deque<std::coroutine_handle<>> awaited_handles; | ||
|
||
public: | ||
WaitQueue(const WaitQueue &) = delete; | ||
WaitQueue &operator=(const WaitQueue &) = delete; | ||
|
||
WaitQueue(WaitQueue &&other) noexcept | ||
: forks(std::move(other.forks)) | ||
, fork_awaiters(std::move(other.fork_awaiters)) | ||
, awaited_handles(std::move(other.awaited_handles)) {} | ||
|
||
explicit WaitQueue(memory_resource::unsynchronized_pool_resource &memory_resource, unordered_map<int64_t, task_t<fork_result>> &&forks_) noexcept | ||
: forks(std::move(forks_)) | ||
, fork_awaiters(unordered_map<int64_t, task_t<fork_result>::awaiter_t>::allocator_type{memory_resource}) | ||
, awaited_handles(deque<std::coroutine_handle<>>::allocator_type{memory_resource}) { | ||
for (auto &fork : forks) { | ||
fork_awaiters.emplace(fork.first, std::addressof(fork.second)); | ||
} | ||
} | ||
|
||
void push(int64_t fork_id, task_t<fork_result> &&fork) noexcept { | ||
auto [fork_it, fork_success] = forks.emplace(fork_id, std::move(fork)); | ||
auto [awaiter_id, awaiter_success] = fork_awaiters.emplace(fork_id, std::addressof(fork_it->second)); | ||
if (!awaited_handles.empty()) { | ||
awaiter_id->second.await_suspend(awaited_handles.front()); | ||
} | ||
} | ||
|
||
Optional<std::pair<int64_t, task_t<fork_result>>> pop() noexcept { | ||
auto it = std::find_if(forks.begin(), forks.end(), [](std::pair<const int64_t, task_t<fork_result>> &fork) { return fork.second.done(); }); | ||
if (it != forks.end()) { | ||
auto fork = std::move(*it); | ||
forks.erase(fork.first); | ||
fork_awaiters.erase(fork.first); | ||
return fork; | ||
} else { | ||
return {}; | ||
} | ||
} | ||
|
||
void subscribe_coro_handle(std::coroutine_handle<> coro) noexcept { | ||
if (awaited_handles.empty()) { | ||
std::for_each(fork_awaiters.begin(), fork_awaiters.end(), [coro](auto &awaiter) { awaiter.second.await_suspend(coro); }); | ||
} | ||
awaited_handles.push_back(coro); | ||
} | ||
|
||
void move_coro_handle() noexcept { | ||
if (!awaited_handles.empty()) { | ||
awaited_handles.pop_front(); | ||
} | ||
std::coroutine_handle<> next_awaiter = awaited_handles.empty() ? std::noop_coroutine() : awaited_handles.front(); | ||
std::for_each(fork_awaiters.begin(), fork_awaiters.end(), | ||
[&](auto &awaiter) { awaiter.second.await_suspend(next_awaiter);}); | ||
} | ||
|
||
bool has_ready_fork() const noexcept { | ||
return std::any_of(forks.begin(), forks.end(), [](const auto &fork) { | ||
return fork.second.done(); | ||
}); | ||
} | ||
|
||
size_t size() const noexcept { | ||
return forks.size(); | ||
} | ||
|
||
bool empty() const noexcept { | ||
return forks.empty(); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.