12using namespace MaxOS::processes;
13using namespace MaxOS::processes::resources;
14using namespace MaxOS::common;
15using namespace MaxOS::memory;
16using namespace MaxOS::KPI;
22: m_owner_process(owner_process)
27 ASSERT(shared_memory !=
nullptr,
"Shared memory resource not found\n");
30 ASSERT(shared_memory->size() == SERVICE_SHARED_MEM_SIZE,
"Shared memory resource size mismatch\n");
34 m_message_ring = (service_message_ring_t*)address;
37 m_data_region = (uintptr_t)address + MESSAGE_SIZE;
42BridgeHandler::~BridgeHandler() =
default;
53size_t BridgeHandler::store_data(
const void *buffer,
size_t size,
bool reserve_only) {
59 bool is_mapped = size >= MAX_COPY_SIZE;
65 MemoryManager::switch_active_memory_manager(m_owner_process->
memory_manager);
67 MemoryManager::switch_active_memory_manager(caller);
73 ASSERT(data !=
nullptr,
"Could not allocate memory for bridge\n");
76 if (!reserve_only && !is_mapped)
77 memcpy(data, buffer, size);
80 return (
size_t)data - (is_mapped ? 0 : m_data_region);
89service_resource_message_t* BridgeHandler::aquire_slot() {
95 size_t head = __atomic_load_n(&m_message_ring->head, __ATOMIC_RELAXED);
96 size_t tail = __atomic_load_n(&m_message_ring->tail, __ATOMIC_ACQUIRE);
98 ASSERT((head < MESSAGE_SLOTS && tail < MESSAGE_SLOTS),
"invalid queue indexes for resource bridge");
101 size_t next = (head + 1) % MESSAGE_SLOTS;
108 if(!__atomic_compare_exchange_n(&m_message_ring->head, &head, next,
true,__ATOMIC_ACQ_REL,__ATOMIC_RELAXED))
113 return &m_message_ring->ring_buffer[slot];
123 return __atomic_fetch_add(&m_next_id, 1, __ATOMIC_RELAXED);
142 bool is_read = command == ServiceResourceCommand::R_READ;
143 bool is_page_mapped = size >= MAX_COPY_SIZE;
144 size_t offset = store_data(buffer, size, is_read);
147 auto slot = aquire_slot();
149 __atomic_store_n(&slot->resource_id,
id, __ATOMIC_RELAXED);
150 __atomic_store_n(&slot->flags, flags, __ATOMIC_RELAXED);
151 __atomic_store_n(&slot->command, (uint8_t)command, __ATOMIC_RELAXED);
152 __atomic_store_n(&slot->data_size, size, __ATOMIC_RELAXED);
153 __atomic_store_n(&slot->data_offset, offset, __ATOMIC_RELAXED);
154 __atomic_store_n(&slot->data_page_mapped, is_page_mapped, __ATOMIC_RELAXED);
155 __atomic_store_n(&slot->response, 0, __ATOMIC_RELAXED);
156 __atomic_store_n(&slot->state, (uint8_t)ServiceMessageSlotState::REQUEST, __ATOMIC_RELEASE);
159 while (__atomic_load_n(&slot->state, __ATOMIC_ACQUIRE) == (uint8_t)ServiceMessageSlotState::REQUEST)
163 if (is_read && !is_page_mapped)
164 memcpy((
void*)buffer, (
void*)m_data_region + offset, size);
168 if (is_page_mapped) {
170 MemoryManager::switch_active_memory_manager(m_owner_process->
memory_manager);
172 MemoryManager::switch_active_memory_manager(caller);
182 int64_t response = __atomic_load_n(&slot->response, __ATOMIC_RELAXED);
183 __atomic_store_n(&slot->state, (uint8_t)ServiceMessageSlotState::FREE,__ATOMIC_RELEASE);
189BridgeResource::BridgeResource(
const string &name,
size_t flags,
resource_type_t type)
194BridgeResource::~BridgeResource() =
default;
202 m_handler -> send_to_bridge(m_id, ServiceResourceCommand::R_OPEN, 0,0, flags);
211 m_handler -> send_to_bridge(m_id, ServiceResourceCommand::R_CLOSE, 0,0, flags);
224 return m_handler -> send_to_bridge(m_id, ServiceResourceCommand::R_READ, buffer, size, flags);
236 return m_handler -> send_to_bridge(m_id, ServiceResourceCommand::R_WRITE, buffer, size, flags);
254 return m_handler -> send_to_bridge(m_id, ServiceResourceCommand::S_GET, name().c_str(),name().length() + 1, 0) > 0;
265 m_handler -> send_to_bridge(m_id, ServiceResourceCommand::S_CREATE, name().c_str(),name().length() + 1, 0);
270BridgeResourceRegistry::BridgeResourceRegistry(
const string &shared_name,
size_t resource_id)
277BridgeResourceRegistry::~BridgeResourceRegistry() =
default;
283 if(resource !=
nullptr)
288 attempt_resource->attach_wrapper(&m_handler);
291 if (attempt_resource->get_on_bridge()) {
293 return attempt_resource;
297 delete attempt_resource;
320 resource->attach_wrapper(&m_handler);
321 resource->create_on_bridge();
VirtualMemoryManager * vmm()
Handles memory allocation and deallocation.
static MemoryManager * s_kernel_memory_manager
The memory manager for any kernel processes and all kernel allocations.
void unload_range_from_process(const void *start_address, size_t size)
Unload a shared range of pages from this vmm.
void * load_range_from_process(VirtualMemoryManager *other_vmm, const void *start_address, size_t size)
Loads the pages from a virtual memory region in another vmm into this one.
void * load_shared_memory(const string &name)
Load shared memory into the VMM's address space.
void unallocate(void *pointer) final
Frees a block of memory.
void * allocate(size_t size) final
Allocates a block of memory.
void setup_region(uintptr_t address, size_t length) final
Setup a region to be bump memory managed, creates a free chunk represent the whole region.
The global scheduler that manages all processes and threads across all cores.
static Process * current_process()
Gets the process on the currently executing core.
static Thread * current_thread()
Gets the thread on the currently executing core.
A process that can be scheduled by the Scheduler, wraps & manages threads as well as its own address ...
uint64_t pid() const
Gets the pid of the process.
memory::MemoryManager * memory_manager
The manager for memory used by this process.
A block memory that is mapped into multiple processes.
void yield()
Pass execution to the next ready thread.
resource_type_t m_type
The resource type that this registry manages.
virtual Resource * get_resource(const string &name)
Gets a resource from the registry by name.
bool register_resource(Resource *resource)
Registers a resource in the registry.
A handler to manage resource commands over shared memory.
BridgeHandler(string const &shared_name, Process *owner_process)
Constructs a handler to manage resource commands over shared memory.
size_t allocate_id()
Allocates an ID to identify a resource on the bridge.
int64_t send_to_bridge(size_t id, KPI::ServiceResourceCommand command, const void *buffer, size_t size, size_t flags)
Send a command and its associated data to the endpoint associated with this resource.
Resource * get_resource(const string &name) final
Gets a resource from the registry by name.
Resource * create_resource(const string &name, size_t flags, uintptr_t data) final
Create a new resource on the bridge.
A generic wrapper for a Resource that exists on a userspace server which exposes its operations as Re...
void close(size_t flags) final
Closes the resource.
void create_on_bridge()
Passes the creation of a resource to the bridge.
int write(const void *buffer, size_t size, size_t flags) final
write a certain amount of bytes to a resource
void open(size_t flags) final
Opens the resource.
int read(void *buffer, size_t size, size_t flags) final
Reads data from the resource.
bool get_on_bridge()
Attempt to get a resource on a bridge endpoint that may not be registered yet.
static BaseResourceRegistry * get_registry(resource_type_t type)
Gets a registry of a type.
A resource registry for a specific resource type.
KPI::Resource Resource
Alias to make the libsyscore Resource accessible here.
KPI::ResourceType resource_type_t
Alias to make the libsyscore ResourceType accessible here.
Defines scheduler resource classes for wrapping userspace bridge Resources in the Global Scheduler,...