mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 08:24:32 -08:00
[kernel] Make mailbox non-fixed-length again
Going back to letting mailboxes use variable-length data. Note that this requires extra copies, so shared memory channels should be used for anything in the hot path. But this allows better RPC over mailboxes and other flexibility. Other changes: - added a j6::proto::sl::client class to act as a service locator client, instead of duplicating that code in every program. - moved protocol ids into j6/tables/protocols.inc so that C++ clients can easily have their own API
This commit is contained in:
@@ -7,6 +7,34 @@ enum j6_proto_base_tag
|
||||
j6_proto_base_status,
|
||||
j6_proto_base_get_proto_id,
|
||||
j6_proto_base_proto_id,
|
||||
j6_proto_base_open_channel,
|
||||
j6_proto_base_opened_channel,
|
||||
|
||||
j6_proto_base_first_proto_id /// The first protocol-specific ID
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <util/hash.h>
|
||||
namespace j6::proto {
|
||||
|
||||
enum class style { mailbox, channel };
|
||||
|
||||
#define PROTOCOL(name, desc, type) namespace name { \
|
||||
inline constexpr uint64_t id = #desc##_id; \
|
||||
inline constexpr proto::style style = proto::style:: type; }
|
||||
|
||||
#include <j6/tables/protocols.inc>
|
||||
#undef PROTOCOL
|
||||
|
||||
} // namespace j6::proto
|
||||
#endif // __cplusplus
|
||||
|
||||
extern "C" const uint64_t j6_proto_style_mailbox;
|
||||
extern "C" const uint64_t j6_proto_style_channel;
|
||||
|
||||
#define PROTOCOL(name, desc, type) \
|
||||
extern "C" const uint64_t j6_proto_ ## name ## _id; \
|
||||
extern "C" const uint64_t j6_proto_ ## name ## _style;
|
||||
|
||||
#include <j6/tables/protocols.inc>
|
||||
#undef PROTOCOL
|
||||
13
src/libraries/j6/include/j6/protocols.hh
Normal file
13
src/libraries/j6/include/j6/protocols.hh
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
/// \file protocols.hh
|
||||
/// High-level C++ base protocol interface
|
||||
|
||||
namespace j6::proto {
|
||||
|
||||
class client
|
||||
{
|
||||
public:
|
||||
|
||||
};
|
||||
|
||||
} // namespace j6::proto
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
#include <j6/protocols.h>
|
||||
|
||||
extern const uint64_t j6_proto_sl_id;
|
||||
|
||||
enum j6_proto_sl_tag
|
||||
{
|
||||
j6_proto_sl_register = j6_proto_base_first_proto_id,
|
||||
|
||||
27
src/libraries/j6/include/j6/protocols/service_locator.hh
Normal file
27
src/libraries/j6/include/j6/protocols/service_locator.hh
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <j6/protocols/service_locator.h>
|
||||
#include <j6/types.h>
|
||||
|
||||
namespace j6::proto::sl {
|
||||
|
||||
class client
|
||||
{
|
||||
public:
|
||||
/// Constructor.
|
||||
/// \arg slp_mb Handle to the service locator service's mailbox
|
||||
client(j6_handle_t slp_mb);
|
||||
|
||||
/// Register a handle as a service with the locator.
|
||||
/// \arg proto_id The protocol this handle supports
|
||||
/// \arg handle The mailbox or channel handle
|
||||
j6_status_t register_service(uint64_t proto_id, j6_handle_t handle);
|
||||
|
||||
/// Look up a handle with the locator service.
|
||||
/// \arg proto_id The protocol to look for
|
||||
/// \arg handle [out] The mailbox or channel handle
|
||||
j6_status_t lookup_service(uint64_t proto_id, j6_handle_t &handle);
|
||||
|
||||
private:
|
||||
j6_handle_t m_service;
|
||||
};
|
||||
|
||||
} // namespace j6::proto::sl
|
||||
2
src/libraries/j6/include/j6/tables/protocols.inc
Normal file
2
src/libraries/j6/include/j6/tables/protocols.inc
Normal file
@@ -0,0 +1,2 @@
|
||||
PROTOCOL(sl, service_locator, mailbox)
|
||||
PROTOCOL(vfs, virtual_filesystem, channel)
|
||||
@@ -11,6 +11,7 @@ j6 = module("j6",
|
||||
"memutils.cpp",
|
||||
"mutex.cpp",
|
||||
"protocol_ids.cpp",
|
||||
"protocols/service_locator.cpp",
|
||||
"syscalls.s.cog",
|
||||
"sysconf.cpp.cog",
|
||||
"syslog.cpp",
|
||||
@@ -27,6 +28,7 @@ j6 = module("j6",
|
||||
"j6/memutils.h",
|
||||
"j6/protocols.h",
|
||||
"j6/protocols/service_locator.h",
|
||||
"j6/protocols/service_locator.hh",
|
||||
"j6/syscalls.h.cog",
|
||||
"j6/sysconf.h.cog",
|
||||
"j6/syslog.hh",
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
#include <util/hash.h>
|
||||
#include <j6/protocols.h>
|
||||
|
||||
extern "C"
|
||||
const uint64_t j6_proto_sl_id = "jsix.protocol.service_locator"_id;
|
||||
extern "C" const uint64_t j6_proto_style_mailbox = (uint64_t)j6::proto::style::mailbox;
|
||||
extern "C" const uint64_t j6_proto_style_channel = (uint64_t)j6::proto::style::channel;
|
||||
|
||||
#define PROTOCOL(name, desc, type) \
|
||||
extern "C" const uint64_t j6_proto_##name##_id = j6::proto::name::id; \
|
||||
extern "C" const uint64_t j6_proto_##name##_style = j6_proto_style_##type;
|
||||
|
||||
#include <j6/tables/protocols.inc>
|
||||
64
src/libraries/j6/protocols/service_locator.cpp
Normal file
64
src/libraries/j6/protocols/service_locator.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
#include <j6/errors.h>
|
||||
#include <j6/protocols/service_locator.hh>
|
||||
#include <j6/syscalls.h>
|
||||
#include <j6/syslog.hh>
|
||||
|
||||
#ifndef __j6kernel
|
||||
|
||||
namespace j6::proto::sl {
|
||||
|
||||
client::client(j6_handle_t slp_mb) :
|
||||
m_service {slp_mb}
|
||||
{
|
||||
}
|
||||
|
||||
j6_status_t
|
||||
client::register_service(uint64_t proto_id, j6_handle_t handle)
|
||||
{
|
||||
uint64_t tag = j6_proto_sl_register;
|
||||
size_t handle_count = 1;
|
||||
size_t data = proto_id;
|
||||
size_t data_size = sizeof(proto_id);
|
||||
|
||||
j6_status_t s = j6_mailbox_call(m_service, &tag,
|
||||
&data, &data_size, data_size,
|
||||
&handle, &handle_count);
|
||||
|
||||
if (s != j6_status_ok)
|
||||
return s;
|
||||
|
||||
if (tag == j6_proto_base_status)
|
||||
return data; // contains a status
|
||||
|
||||
return j6_err_unexpected;
|
||||
}
|
||||
|
||||
j6_status_t
|
||||
client::lookup_service(uint64_t proto_id, j6_handle_t &handle)
|
||||
{
|
||||
uint64_t tag = j6_proto_sl_find;
|
||||
size_t handle_count = 1;
|
||||
size_t data = proto_id;
|
||||
size_t data_size = sizeof(proto_id);
|
||||
handle = j6_handle_invalid;
|
||||
|
||||
j6::syslog("Looking up service for %x", proto_id);
|
||||
j6_status_t s = j6_mailbox_call(m_service, &tag,
|
||||
&data, &data_size, data_size,
|
||||
&handle, &handle_count);
|
||||
|
||||
if (s != j6_status_ok)
|
||||
return s;
|
||||
|
||||
if (tag == j6_proto_sl_result)
|
||||
return j6_status_ok; // handle is already in `handle`
|
||||
|
||||
else if (tag == j6_proto_base_status)
|
||||
return data; // contains a status
|
||||
|
||||
return j6_err_unexpected;
|
||||
}
|
||||
|
||||
|
||||
} // namespace j6::proto::sl
|
||||
#endif // __j6kernel
|
||||
Reference in New Issue
Block a user