[Yellowstone] Use mutex to wait for denali to spawn VFS.

Kind of a hacky way to pass a signal between threads but works as
a POC for thread synchronization.
This commit is contained in:
Drew Galbraith 2023-10-25 19:08:00 -07:00
parent 6cb0041253
commit adfffdd3c3
3 changed files with 36 additions and 17 deletions

View File

@ -8,6 +8,12 @@
#include "hw/pcie.h"
#include "yellowstone_server.h"
glcr::ErrorCode SpawnProcess(z_cap_t vmmo_cap, z_cap_t yellowstone_cap) {
uint64_t vaddr;
RET_ERR(ZAddressSpaceMap(gSelfVmasCap, 0, vmmo_cap, &vaddr));
return SpawnProcessFromElfRegion(vaddr, yellowstone_cap);
}
uint64_t main(uint64_t port_cap) {
dbgln("Yellowstone Initializing.");
check(ParseInitPort(port_cap));
@ -15,10 +21,13 @@ uint64_t main(uint64_t port_cap) {
ASSIGN_OR_RETURN(auto server, YellowstoneServer::Create());
Thread server_thread = server->RunServer();
uint64_t vaddr;
check(ZAddressSpaceMap(gSelfVmasCap, 0, gBootDenaliVmmoCap, &vaddr));
ASSIGN_OR_RETURN(YellowstoneClient client, server->CreateClient());
check(SpawnProcessFromElfRegion(vaddr, client.Capability()));
ASSIGN_OR_RETURN(YellowstoneClient client1, server->CreateClient());
check(SpawnProcess(gBootDenaliVmmoCap, client1.Capability()));
check(server->WaitDenaliRegistered());
ASSIGN_OR_RETURN(YellowstoneClient client2, server->CreateClient());
check(SpawnProcess(gBootVictoriaFallsVmmoCap, client2.Capability()));
check(server_thread.Join());
dbgln("Yellowstone Finished Successfully.");

View File

@ -30,13 +30,19 @@ glcr::ErrorOr<PartitionInfo> HandleDenaliRegistration(z_cap_t endpoint_cap) {
} // namespace
glcr::ErrorOr<glcr::UniquePtr<YellowstoneServer>> YellowstoneServer::Create() {
z_cap_t cap;
RET_ERR(ZEndpointCreate(&cap));
return glcr::UniquePtr<YellowstoneServer>(new YellowstoneServer(cap));
z_cap_t endpoint_cap;
RET_ERR(ZEndpointCreate(&endpoint_cap));
ASSIGN_OR_RETURN(Mutex mut, Mutex::Create());
RET_ERR(mut.Lock());
return glcr::UniquePtr<YellowstoneServer>(
new YellowstoneServer(endpoint_cap, glcr::Move(mut)));
}
YellowstoneServer::YellowstoneServer(z_cap_t endpoint_cap)
: YellowstoneServerBase(endpoint_cap) {}
YellowstoneServer::YellowstoneServer(z_cap_t endpoint_cap, Mutex&& mutex)
: YellowstoneServerBase(endpoint_cap),
has_denali_mutex_(glcr::Move(mutex)) {}
glcr::ErrorCode YellowstoneServer::HandleGetAhciInfo(const Empty&,
AhciInfo& info) {
@ -69,13 +75,7 @@ glcr::ErrorCode YellowstoneServer::HandleRegisterEndpoint(
device_id_ = part_info_or.value().device_id;
lba_offset_ = part_info_or.value().partition_lba;
uint64_t vaddr;
check(ZAddressSpaceMap(gSelfVmasCap, 0, gBootVictoriaFallsVmmoCap, &vaddr));
auto client_or = CreateClient();
if (!client_or.ok()) {
check(client_or.error());
}
check(SpawnProcessFromElfRegion(vaddr, client_or.value().Capability()));
check(has_denali_mutex_.Release());
} else if (req.endpoint_name() == "victoriafalls") {
victoria_falls_cap_ = req.endpoint_capability();
} else {
@ -83,3 +83,8 @@ glcr::ErrorCode YellowstoneServer::HandleRegisterEndpoint(
}
return glcr::OK;
}
glcr::ErrorCode YellowstoneServer::WaitDenaliRegistered() {
RET_ERR(has_denali_mutex_.Lock());
return has_denali_mutex_.Release();
}

View File

@ -3,6 +3,7 @@
#include <glacier/memory/unique_ptr.h>
#include <glacier/status/error_or.h>
#include <mammoth/endpoint_server.h>
#include <mammoth/mutex.h>
#include <mammoth/port_server.h>
#include <mammoth/thread.h>
@ -18,6 +19,8 @@ class YellowstoneServer : public YellowstoneServerBase {
glcr::ErrorCode HandleRegisterEndpoint(const RegisterEndpointRequest&,
Empty&) override;
glcr::ErrorCode WaitDenaliRegistered();
private:
// TODO: Store these in a data structure.
z_cap_t denali_cap_ = 0;
@ -27,5 +30,7 @@ class YellowstoneServer : public YellowstoneServerBase {
PciReader pci_reader_;
YellowstoneServer(z_cap_t endpoint_cap);
Mutex has_denali_mutex_;
YellowstoneServer(z_cap_t endpoint_cap, Mutex&& mutex);
};