[kernel] Store object ids instead of full koids
In preparation for futexes, I wanted to make kobjects a bit lighter. Storing 32 bits of object id, and 8 bits of type (and not ending the class in a ushort for handle count, which meant all kobjects were likely to have a bunch of pad bytes), the kobject class data is now just one 8 byte word. Also from this, change logs that mention threads or processes from printing the full koid to just 2 bytes of object id from both process and thread, which makes following the logs much easier.
This commit is contained in:
@@ -7,30 +7,29 @@
|
|||||||
|
|
||||||
namespace obj {
|
namespace obj {
|
||||||
|
|
||||||
static j6_koid_t next_koids [static_cast<size_t>(kobject::type::max)] = { 0 };
|
static constexpr unsigned types_count = static_cast<unsigned>(kobject::type::max);
|
||||||
|
|
||||||
|
static uint32_t next_oids [types_count] = { 0 };
|
||||||
|
|
||||||
|
static_assert(types_count <= (1 << kobject::koid_type_bits),
|
||||||
|
"kobject::koid_type_bits cannot represent all kobject types");
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
oid_generate(kobject::type t)
|
||||||
|
{
|
||||||
|
kassert(t < kobject::type::max, "Object type out of bounds");
|
||||||
|
unsigned type_int = static_cast<unsigned>(t);
|
||||||
|
return __atomic_fetch_add(&next_oids[type_int], 1, __ATOMIC_RELAXED);
|
||||||
|
}
|
||||||
|
|
||||||
kobject::kobject(type t) :
|
kobject::kobject(type t) :
|
||||||
m_koid(koid_generate(t)),
|
m_handle_count {0},
|
||||||
m_handle_count(0)
|
m_type {t},
|
||||||
|
m_obj_id {oid_generate(t)}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
kobject::~kobject() {}
|
kobject::~kobject() {}
|
||||||
|
|
||||||
j6_koid_t
|
|
||||||
kobject::koid_generate(type t)
|
|
||||||
{
|
|
||||||
kassert(t < type::max, "Object type out of bounds");
|
|
||||||
uint64_t type_int = static_cast<uint64_t>(t);
|
|
||||||
uint64_t id = __atomic_fetch_add(&next_koids[type_int], 1, __ATOMIC_SEQ_CST);
|
|
||||||
return (type_int << 48) | id;
|
|
||||||
}
|
|
||||||
|
|
||||||
kobject::type
|
|
||||||
kobject::koid_type(j6_koid_t koid)
|
|
||||||
{
|
|
||||||
return static_cast<type>((koid >> 48) & 0xffffull);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
kobject::on_no_handles()
|
kobject::on_no_handles()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,24 +23,31 @@ public:
|
|||||||
max
|
max
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// The koid's most significant bits represent the object's type
|
||||||
|
static constexpr unsigned koid_type_bits = 4;
|
||||||
|
static constexpr unsigned koid_type_mask = (1 << koid_type_bits) - 1;
|
||||||
|
static constexpr unsigned koid_type_shift = (8 * sizeof(j6_koid_t)) - koid_type_bits;
|
||||||
|
|
||||||
kobject(type t);
|
kobject(type t);
|
||||||
virtual ~kobject();
|
virtual ~kobject();
|
||||||
|
|
||||||
/// Generate a new koid for a given type
|
|
||||||
/// \arg t The object type
|
|
||||||
/// \returns A new unique koid
|
|
||||||
static j6_koid_t koid_generate(type t);
|
|
||||||
|
|
||||||
/// Get the kobject type from a given koid
|
/// Get the kobject type from a given koid
|
||||||
/// \arg koid An existing koid
|
/// \arg koid An existing koid
|
||||||
/// \returns The object type for the koid
|
/// \returns The object type for the koid
|
||||||
static type koid_type(j6_koid_t koid);
|
inline static type koid_type(j6_koid_t koid) {
|
||||||
|
return static_cast<type>((koid >> koid_type_shift) & koid_type_mask);
|
||||||
|
}
|
||||||
|
|
||||||
/// Get this object's type
|
/// Get this object's type
|
||||||
inline type get_type() const { return koid_type(m_koid); }
|
inline type get_type() const { return m_type; }
|
||||||
|
|
||||||
/// Get this object's koid
|
/// Get this object's koid
|
||||||
inline j6_koid_t koid() const { return m_koid; }
|
inline j6_koid_t koid() const {
|
||||||
|
return (static_cast<j6_koid_t>(m_type) << koid_type_shift) | m_obj_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get this object's type-relative object id
|
||||||
|
inline uint32_t obj_id() const { return m_obj_id; }
|
||||||
|
|
||||||
/// Increment the handle refcount
|
/// Increment the handle refcount
|
||||||
inline void handle_retain() { ++m_handle_count; }
|
inline void handle_retain() { ++m_handle_count; }
|
||||||
@@ -63,8 +70,9 @@ private:
|
|||||||
kobject(const kobject &other) = delete;
|
kobject(const kobject &other) = delete;
|
||||||
kobject(const kobject &&other) = delete;
|
kobject(const kobject &&other) = delete;
|
||||||
|
|
||||||
j6_koid_t m_koid;
|
|
||||||
uint16_t m_handle_count;
|
uint16_t m_handle_count;
|
||||||
|
type m_type;
|
||||||
|
uint32_t m_obj_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace obj
|
} // namespace obj
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ j6_status_t
|
|||||||
process_create(j6_handle_t *self)
|
process_create(j6_handle_t *self)
|
||||||
{
|
{
|
||||||
process *p = construct_handle<process>(self);
|
process *p = construct_handle<process>(self);
|
||||||
log::info(logs::task, "Process %llx created", p->koid());
|
log::info(logs::task, "Process <%02lx> created", p->obj_id());
|
||||||
return j6_status_ok;
|
return j6_status_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ process_kill(process *self)
|
|||||||
{
|
{
|
||||||
process &p = process::current();
|
process &p = process::current();
|
||||||
|
|
||||||
log::info(logs::task, "Process %llx killed by process %llx", self->koid(), p.koid());
|
log::info(logs::task, "Process <%02lx> killed by process <%02lx>", self->obj_id(), p.obj_id());
|
||||||
self->exit(-1u);
|
self->exit(-1u);
|
||||||
|
|
||||||
return j6_status_ok;
|
return j6_status_ok;
|
||||||
@@ -32,7 +32,7 @@ j6_status_t
|
|||||||
process_exit(int32_t status)
|
process_exit(int32_t status)
|
||||||
{
|
{
|
||||||
process &p = process::current();
|
process &p = process::current();
|
||||||
log::info(logs::task, "Process %llx exiting with code %d", p.koid(), status);
|
log::info(logs::task, "Process <%02lx> exiting with code %d", p.obj_id(), status);
|
||||||
|
|
||||||
p.exit(status);
|
p.exit(status);
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ j6_status_t
|
|||||||
log(const char *message)
|
log(const char *message)
|
||||||
{
|
{
|
||||||
thread &th = thread::current();
|
thread &th = thread::current();
|
||||||
log::info(logs::syscall, "Message[%llx]: %s", th.koid(), message);
|
log::info(logs::syscall, "Message <%02lx:%02lx>: %s", th.parent().obj_id(), th.obj_id(), message);
|
||||||
return j6_status_ok;
|
return j6_status_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ j6_status_t
|
|||||||
noop()
|
noop()
|
||||||
{
|
{
|
||||||
thread &th = thread::current();
|
thread &th = thread::current();
|
||||||
log::verbose(logs::syscall, "Thread %llx called noop syscall.", th.koid());
|
log::verbose(logs::syscall, "Thread <%02lx:%02lx> called noop syscall.", th.parent().obj_id(), th.koid());
|
||||||
return j6_status_ok;
|
return j6_status_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ thread_create(j6_handle_t *self, process *proc, uintptr_t stack_top, uintptr_t e
|
|||||||
*self = child->self_handle();
|
*self = child->self_handle();
|
||||||
child->set_state(thread::state::ready);
|
child->set_state(thread::state::ready);
|
||||||
|
|
||||||
log::verbose(logs::task, "Thread %llx:%llx spawned new thread %llx:%llx",
|
log::verbose(logs::task, "Thread <%02lx:%02lx> spawned new thread <%02lx:%02lx>",
|
||||||
parent_pr.koid(), parent_th.koid(), proc->koid(), child->koid());
|
parent_pr.obj_id(), parent_th.obj_id(), proc->obj_id(), child->obj_id());
|
||||||
|
|
||||||
return j6_status_ok;
|
return j6_status_ok;
|
||||||
}
|
}
|
||||||
@@ -31,7 +31,7 @@ thread_create(j6_handle_t *self, process *proc, uintptr_t stack_top, uintptr_t e
|
|||||||
j6_status_t
|
j6_status_t
|
||||||
thread_kill(thread *self)
|
thread_kill(thread *self)
|
||||||
{
|
{
|
||||||
log::verbose(logs::task, "Killing thread %llx", self->koid());
|
log::verbose(logs::task, "Killing thread <%02lx:%02lx>", self->parent().obj_id(), self->obj_id());
|
||||||
self->exit();
|
self->exit();
|
||||||
return j6_status_ok;
|
return j6_status_ok;
|
||||||
}
|
}
|
||||||
@@ -46,7 +46,7 @@ j6_status_t
|
|||||||
thread_exit()
|
thread_exit()
|
||||||
{
|
{
|
||||||
thread &th = thread::current();
|
thread &th = thread::current();
|
||||||
log::verbose(logs::task, "Thread %llx exiting", th.koid());
|
log::verbose(logs::task, "Thread <%02lx:%02lx> exiting", th.parent().obj_id(), th.obj_id());
|
||||||
th.exit();
|
th.exit();
|
||||||
|
|
||||||
log::error(logs::task, "returned to exit syscall");
|
log::error(logs::task, "returned to exit syscall");
|
||||||
@@ -60,7 +60,7 @@ thread_sleep(uint64_t duration)
|
|||||||
|
|
||||||
uint64_t til = clock::get().value() + duration;
|
uint64_t til = clock::get().value() + duration;
|
||||||
|
|
||||||
log::verbose(logs::task, "Thread %llx sleeping until %llu", th.koid(), til);
|
log::verbose(logs::task, "Thread <%02lx:%02lx> sleeping until %llu", th.parent().obj_id(), th.obj_id(), til);
|
||||||
th.set_wake_timeout(til);
|
th.set_wake_timeout(til);
|
||||||
th.block();
|
th.block();
|
||||||
return j6_status_ok;
|
return j6_status_ok;
|
||||||
|
|||||||
Reference in New Issue
Block a user