obj: object header is no longer allocated automatically
This commit is contained in:
@@ -2,6 +2,8 @@
|
|||||||
#include <socks/object.h>
|
#include <socks/object.h>
|
||||||
#include <socks/device.h>
|
#include <socks/device.h>
|
||||||
|
|
||||||
|
#define DEVICE_CAST(p) OBJECT_C_CAST(struct device, dev_base, &device_type, p)
|
||||||
|
|
||||||
static struct device *root_device = NULL;
|
static struct device *root_device = NULL;
|
||||||
static struct object_type device_type = {
|
static struct object_type device_type = {
|
||||||
.ob_name = "device",
|
.ob_name = "device",
|
||||||
@@ -20,10 +22,10 @@ kern_status_t device_init(void)
|
|||||||
kern_status_t set_root_device(struct device *dev)
|
kern_status_t set_root_device(struct device *dev)
|
||||||
{
|
{
|
||||||
if (root_device) {
|
if (root_device) {
|
||||||
object_deref(object_header(root_device));
|
object_deref(&root_device->dev_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
object_ref(object_header(dev));
|
object_ref(&dev->dev_base);
|
||||||
root_device = dev;
|
root_device = dev;
|
||||||
|
|
||||||
return KERN_OK;
|
return KERN_OK;
|
||||||
@@ -36,5 +38,5 @@ struct device *device_alloc(void)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return object_data(dev_object);
|
return DEVICE_CAST(dev_object);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,15 +21,15 @@ An object is made up of two distinct halves: the **header** and the
|
|||||||
system, while the data is the programmer-defined part of the object,
|
system, while the data is the programmer-defined part of the object,
|
||||||
and can be used however the object-creator wants.
|
and can be used however the object-creator wants.
|
||||||
|
|
||||||
Object behaviour is defined by an `object_type_t` instance.
|
Object behaviour is defined by a `struct object_type` instance.
|
||||||
An `object_type_t` provides the object system with all the information
|
A `struct object_type` provides the object system with all the information
|
||||||
it needs to instantiate and interact with your objects.
|
it needs to instantiate and interact with your objects.
|
||||||
|
|
||||||
|
|
||||||
The Object Header
|
The Object Header
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
The object header is defined in `include/socks/object.h` as `object_t`.
|
The object header is defined in `include/socks/object.h` as `struct object`.
|
||||||
It contains information that is used by the object system, and typically
|
It contains information that is used by the object system, and typically
|
||||||
should not be directly accessed outside of the object system.
|
should not be directly accessed outside of the object system.
|
||||||
|
|
||||||
@@ -37,10 +37,10 @@ The contents of the object header include:
|
|||||||
|
|
||||||
* `ob_magic`: A magic value used to identify active objects.
|
* `ob_magic`: A magic value used to identify active objects.
|
||||||
Functions that retrieve an object's header from its data (and vice versa)
|
Functions that retrieve an object's header from its data (and vice versa)
|
||||||
do not have type checking (i.e. they convert between `object_t *` and `void *`
|
do not have type checking (i.e. they convert between `struct object *` and `void *`
|
||||||
using simple pointer arithmetic), so checking for this magic number helps
|
using simple pointer arithmetic), so checking for this magic number helps
|
||||||
protect against non-objects being passed to functions expecting objects.
|
protect against non-objects being passed to functions expecting objects.
|
||||||
* `ob_type`: A pointer to the `object_type_t` that was used to create the
|
* `ob_type`: A pointer to the `struct object_type` that was used to create the
|
||||||
object. Outside of the object system, this can be used as a read-only
|
object. Outside of the object system, this can be used as a read-only
|
||||||
way to query type information about an object.
|
way to query type information about an object.
|
||||||
* `ob_lock`: A general-purpose per-object lock. This lock is *not* reserved
|
* `ob_lock`: A general-purpose per-object lock. This lock is *not* reserved
|
||||||
@@ -56,35 +56,24 @@ The contents of the object header include:
|
|||||||
queue entry.
|
queue entry.
|
||||||
|
|
||||||
|
|
||||||
The Object Data
|
When defining a C structure for use when creating objects, you should
|
||||||
---------------
|
define a member of type `struct object` somewhere within the structure.
|
||||||
|
It does not have to be the first member in the struct. The object system
|
||||||
The object data section is the programmer-defined part of the object, and
|
provides a number of macros to simplify converting a `struct object *`
|
||||||
can be used for any purpose, although it is typically used as storage space
|
to a pointer of your structure.
|
||||||
for a C structure. For example the data section of a `task` object is used
|
|
||||||
to store an instance of a `task_t` C structure containing the task data.
|
|
||||||
|
|
||||||
The object header and data are allocated together in a single contiguous
|
|
||||||
chunk, with the data coming after the header. **However**, you should
|
|
||||||
interactive with the object as if you don't know this. The only safe
|
|
||||||
way to convert between an object header pointer and data pointer is to
|
|
||||||
use the `object_header()` and `object_data()` functions respectively.
|
|
||||||
|
|
||||||
The object data pointer is guaranteed to be aligned on a `long` boundary.
|
|
||||||
|
|
||||||
|
|
||||||
The Object Type
|
The Object Type
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
The object type defines the name, size, and behaviour of an object.
|
The object type defines the name, size, and behaviour of an object.
|
||||||
It is defined using the `object_type_t` C structure.
|
It is defined using the `struct object_type` C structure.
|
||||||
|
|
||||||
Some notable parts of `object_type_t` include:
|
Some notable parts of `struct object_type` include:
|
||||||
|
|
||||||
* `ob_name`: Human-readable name of the object type. For example:
|
* `ob_name`: Human-readable name of the object type. For example:
|
||||||
"namespace", "set", "task", etc.
|
"namespace", "set", "task", etc.
|
||||||
* `ob_size`: The length of the data section of the object in bytes.
|
* `ob_size`: The length of the data section of the object in bytes.
|
||||||
* `ob_cache`: An instance of `vm_cache_t` from which objects of this
|
* `ob_cache`: An instance of `struct vm_cache` from which objects of this
|
||||||
type are allocated. This cache is initialised and managed by the
|
type are allocated. This cache is initialised and managed by the
|
||||||
object system on behalf of the programmer, so this can be ignored
|
object system on behalf of the programmer, so this can be ignored
|
||||||
outside of the object system.
|
outside of the object system.
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <socks/queue.h>
|
#include <socks/queue.h>
|
||||||
#include <socks/status.h>
|
#include <socks/status.h>
|
||||||
|
#include <socks/object.h>
|
||||||
|
|
||||||
struct device;
|
struct device;
|
||||||
|
|
||||||
@@ -67,6 +68,7 @@ struct bus_device {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct device {
|
struct device {
|
||||||
|
struct object dev_base;
|
||||||
enum device_type dev_type;
|
enum device_type dev_type;
|
||||||
struct device *dev_parent;
|
struct device *dev_parent;
|
||||||
struct queue dev_children;
|
struct queue dev_children;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define SOCKS_KEXT_H_
|
#define SOCKS_KEXT_H_
|
||||||
|
|
||||||
#include <socks/status.h>
|
#include <socks/status.h>
|
||||||
|
#include <socks/object.h>
|
||||||
#include <socks/compiler.h>
|
#include <socks/compiler.h>
|
||||||
#include <socks/btree.h>
|
#include <socks/btree.h>
|
||||||
|
|
||||||
@@ -69,6 +70,7 @@ struct kext_info {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct kext {
|
struct kext {
|
||||||
|
struct object k_base;
|
||||||
enum kext_flags k_flags;
|
enum kext_flags k_flags;
|
||||||
char k_ident[KEXT_IDENT_MAX];
|
char k_ident[KEXT_IDENT_MAX];
|
||||||
uint64_t k_ident_hash;
|
uint64_t k_ident_hash;
|
||||||
|
|||||||
@@ -13,6 +13,13 @@ extern "C" {
|
|||||||
#define OBJECT_MAGIC 0xBADDCAFE
|
#define OBJECT_MAGIC 0xBADDCAFE
|
||||||
#define OBJECT_NAME_MAX 64
|
#define OBJECT_NAME_MAX 64
|
||||||
|
|
||||||
|
#define OBJECT_CAST(to_type, to_type_member, p) \
|
||||||
|
((to_type *)((uintptr_t)p) - offsetof(to_type, to_type_member))
|
||||||
|
#define OBJECT_C_CAST(c_type, c_type_member, obj_type, objp) \
|
||||||
|
OBJECT_IS_TYPE(objp, obj_type) ? OBJECT_CAST(c_type, c_type_member, (objp)) : NULL
|
||||||
|
#define OBJECT_IS_TYPE(obj, type_ptr) \
|
||||||
|
((obj)->ob_type == (type_ptr))
|
||||||
|
|
||||||
struct object;
|
struct object;
|
||||||
struct object_attrib;
|
struct object_attrib;
|
||||||
|
|
||||||
@@ -63,6 +70,7 @@ extern kern_status_t object_type_unregister(struct object_type *p);
|
|||||||
|
|
||||||
extern struct object_namespace *global_namespace(void);
|
extern struct object_namespace *global_namespace(void);
|
||||||
extern struct object_namespace *object_namespace_create(void);
|
extern struct object_namespace *object_namespace_create(void);
|
||||||
|
extern struct object *ns_header(struct object_namespace *ns);
|
||||||
extern kern_status_t object_namespace_get_object(struct object_namespace *ns, const char *path, struct object **out);
|
extern kern_status_t object_namespace_get_object(struct object_namespace *ns, const char *path, struct object **out);
|
||||||
extern kern_status_t object_publish(struct object_namespace *ns, const char *path, struct object *obj);
|
extern kern_status_t object_publish(struct object_namespace *ns, const char *path, struct object *obj);
|
||||||
extern kern_status_t object_unpublish(struct object_namespace *ns, struct object *obj);
|
extern kern_status_t object_unpublish(struct object_namespace *ns, struct object *obj);
|
||||||
@@ -72,8 +80,6 @@ extern struct object *object_ref(struct object *obj);
|
|||||||
extern void object_deref(struct object *obj);
|
extern void object_deref(struct object *obj);
|
||||||
extern void object_lock(struct object *obj, unsigned long *flags);
|
extern void object_lock(struct object *obj, unsigned long *flags);
|
||||||
extern void object_unlock(struct object *obj, unsigned long flags);
|
extern void object_unlock(struct object *obj, unsigned long flags);
|
||||||
extern void *object_data(struct object *obj);
|
|
||||||
extern struct object *object_header(void *p);
|
|
||||||
static inline kern_status_t object_get(const char *path, struct object **out)
|
static inline kern_status_t object_get(const char *path, struct object **out)
|
||||||
{
|
{
|
||||||
return object_namespace_get_object(global_namespace(), path, out);
|
return object_namespace_get_object(global_namespace(), path, out);
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ enum sched_mode {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct task {
|
struct task {
|
||||||
|
struct object t_base;
|
||||||
|
|
||||||
struct task *t_parent;
|
struct task *t_parent;
|
||||||
unsigned int t_id;
|
unsigned int t_id;
|
||||||
enum task_state t_state;
|
enum task_state t_state;
|
||||||
@@ -66,6 +68,8 @@ struct task {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct thread {
|
struct thread {
|
||||||
|
struct object thr_base;
|
||||||
|
|
||||||
enum thread_state tr_state;
|
enum thread_state tr_state;
|
||||||
enum thread_flags tr_flags;
|
enum thread_flags tr_flags;
|
||||||
struct task *tr_parent;
|
struct task *tr_parent;
|
||||||
@@ -131,8 +135,8 @@ static inline void rq_unlock(struct runqueue *rq, unsigned long flags)
|
|||||||
extern struct runqueue *cpu_rq(unsigned int cpu);
|
extern struct runqueue *cpu_rq(unsigned int cpu);
|
||||||
|
|
||||||
extern struct task *task_alloc(void);
|
extern struct task *task_alloc(void);
|
||||||
static inline struct task *task_ref(struct task *task) { return (struct task *)object_data(object_ref(object_header(task))); }
|
static inline struct task *task_ref(struct task *task) { return OBJECT_CAST(struct task, t_base, object_ref(&task->t_base)); }
|
||||||
static inline void task_deref(struct task *task) { object_deref(object_header(task)); }
|
static inline void task_deref(struct task *task) { object_deref(&task->t_base); }
|
||||||
extern struct task *task_from_pid(unsigned int pid);
|
extern struct task *task_from_pid(unsigned int pid);
|
||||||
extern struct task *kernel_task(void);
|
extern struct task *kernel_task(void);
|
||||||
extern struct task *idle_task(void);
|
extern struct task *idle_task(void);
|
||||||
@@ -150,12 +154,12 @@ extern void end_charge_period(void);
|
|||||||
|
|
||||||
static inline void task_lock_irqsave(struct task *task, unsigned long *flags)
|
static inline void task_lock_irqsave(struct task *task, unsigned long *flags)
|
||||||
{
|
{
|
||||||
object_lock(object_header(task), flags);
|
object_lock(&task->t_base, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void task_unlock_irqrestore(struct task *task, unsigned long flags)
|
static inline void task_unlock_irqrestore(struct task *task, unsigned long flags)
|
||||||
{
|
{
|
||||||
object_unlock(object_header(task), flags);
|
object_unlock(&task->t_base, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern struct thread *thread_alloc(void);
|
extern struct thread *thread_alloc(void);
|
||||||
|
|||||||
18
kxld/kext.c
18
kxld/kext.c
@@ -5,13 +5,17 @@
|
|||||||
#include <socks/object.h>
|
#include <socks/object.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#define KEXT_CAST(p) OBJECT_C_CAST(struct kext, k_base, &kext_type, p)
|
||||||
|
|
||||||
static spin_lock_t kext_tree_lock = SPIN_LOCK_INIT;
|
static spin_lock_t kext_tree_lock = SPIN_LOCK_INIT;
|
||||||
static struct object *kext_set;
|
static struct object *kext_set;
|
||||||
struct btree kext_tree;
|
struct btree kext_tree;
|
||||||
|
|
||||||
|
static struct object_type kext_type;
|
||||||
|
|
||||||
static kern_status_t kext_query_name(struct object *obj, char out[OBJECT_NAME_MAX])
|
static kern_status_t kext_query_name(struct object *obj, char out[OBJECT_NAME_MAX])
|
||||||
{
|
{
|
||||||
struct kext *kext = object_data(obj);
|
struct kext *kext = KEXT_CAST(obj);
|
||||||
strncpy(out, kext->k_ident, OBJECT_NAME_MAX - 1);
|
strncpy(out, kext->k_ident, OBJECT_NAME_MAX - 1);
|
||||||
out[OBJECT_NAME_MAX - 1] = 0;
|
out[OBJECT_NAME_MAX - 1] = 0;
|
||||||
return KERN_OK;
|
return KERN_OK;
|
||||||
@@ -19,7 +23,7 @@ static kern_status_t kext_query_name(struct object *obj, char out[OBJECT_NAME_MA
|
|||||||
|
|
||||||
static kern_status_t kext_destroy(struct object *obj)
|
static kern_status_t kext_destroy(struct object *obj)
|
||||||
{
|
{
|
||||||
struct kext *kext = object_data(obj);
|
struct kext *kext = KEXT_CAST(obj);
|
||||||
if (kext->k_dependencies) {
|
if (kext->k_dependencies) {
|
||||||
kfree(kext->k_dependencies);
|
kfree(kext->k_dependencies);
|
||||||
}
|
}
|
||||||
@@ -103,7 +107,7 @@ struct kext *kext_get_by_id(const char *ident)
|
|||||||
|
|
||||||
struct kext *kext = kext_get(ident);
|
struct kext *kext = kext_get(ident);
|
||||||
if (kext) {
|
if (kext) {
|
||||||
struct object *kext_obj = object_header(kext);
|
struct object *kext_obj = &kext->k_base;
|
||||||
object_ref(kext_obj);
|
object_ref(kext_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,12 +130,12 @@ struct kext *kext_alloc(void)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return object_data(kext_obj);
|
return KEXT_CAST(kext_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void kext_release(struct kext *kext)
|
void kext_release(struct kext *kext)
|
||||||
{
|
{
|
||||||
object_deref(object_header(kext));
|
object_deref(&kext->k_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
kern_status_t kext_register(struct kext *kext)
|
kern_status_t kext_register(struct kext *kext)
|
||||||
@@ -145,8 +149,8 @@ kern_status_t kext_register(struct kext *kext)
|
|||||||
return KERN_NAME_EXISTS;
|
return KERN_NAME_EXISTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct object *kext_obj = object_header(kext);
|
struct object *kext_obj = &kext->k_base;
|
||||||
object_ref(object_header(kext));
|
object_ref(kext_obj);
|
||||||
kext_add(kext);
|
kext_add(kext);
|
||||||
|
|
||||||
set_add_object(kext_set, kext_obj);
|
set_add_object(kext_set, kext_obj);
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
#include <socks/object.h>
|
#include <socks/object.h>
|
||||||
|
|
||||||
|
#define NAMESPACE_CAST(p) OBJECT_C_CAST(struct object_namespace, ns_base, &ns_type, p)
|
||||||
|
|
||||||
|
static struct object_type ns_type;
|
||||||
static struct object_namespace *global_ns;
|
static struct object_namespace *global_ns;
|
||||||
|
|
||||||
struct object_namespace {
|
struct object_namespace {
|
||||||
/* root directory set object */
|
/* root directory set object */
|
||||||
|
struct object ns_base;
|
||||||
struct object *ns_root;
|
struct object *ns_root;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -16,13 +20,13 @@ static kern_status_t ns_query_name(struct object *obj, char out[OBJECT_NAME_MAX]
|
|||||||
|
|
||||||
static kern_status_t ns_get_child_at(struct object *obj, size_t at, struct object **out)
|
static kern_status_t ns_get_child_at(struct object *obj, size_t at, struct object **out)
|
||||||
{
|
{
|
||||||
struct object_namespace *ns = object_data(obj);
|
struct object_namespace *ns = NAMESPACE_CAST(obj);
|
||||||
return object_get_child_at(ns->ns_root, at, out);
|
return object_get_child_at(ns->ns_root, at, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
static kern_status_t ns_get_child_named(struct object *obj, const char *name, struct object **out)
|
static kern_status_t ns_get_child_named(struct object *obj, const char *name, struct object **out)
|
||||||
{
|
{
|
||||||
struct object_namespace *ns = object_data(obj);
|
struct object_namespace *ns = NAMESPACE_CAST(obj);
|
||||||
return object_get_child_named(ns->ns_root, name, out);
|
return object_get_child_named(ns->ns_root, name, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +40,6 @@ static struct object_type ns_type = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void init_global_namespace(void)
|
void init_global_namespace(void)
|
||||||
{
|
{
|
||||||
object_type_register(&ns_type);
|
object_type_register(&ns_type);
|
||||||
@@ -51,7 +54,7 @@ struct object_namespace *global_namespace(void)
|
|||||||
struct object_namespace *object_namespace_create(void)
|
struct object_namespace *object_namespace_create(void)
|
||||||
{
|
{
|
||||||
struct object *ns_object = object_create(&ns_type);
|
struct object *ns_object = object_create(&ns_type);
|
||||||
struct object_namespace *ns = object_data(ns_object);
|
struct object_namespace *ns = NAMESPACE_CAST(ns_object);
|
||||||
ns->ns_root = set_create("/");
|
ns->ns_root = set_create("/");
|
||||||
return ns;
|
return ns;
|
||||||
}
|
}
|
||||||
@@ -93,6 +96,11 @@ static void cleanup_object_path(char *path, size_t len, size_t *parts)
|
|||||||
path[final_len] = 0;
|
path[final_len] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct object *ns_header(struct object_namespace *ns)
|
||||||
|
{
|
||||||
|
return &ns->ns_base;
|
||||||
|
}
|
||||||
|
|
||||||
kern_status_t object_publish(struct object_namespace *ns, const char *path, struct object *obj)
|
kern_status_t object_publish(struct object_namespace *ns, const char *path, struct object *obj)
|
||||||
{
|
{
|
||||||
if (*path != '/') {
|
if (*path != '/') {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ kern_status_t object_type_register(struct object_type *p)
|
|||||||
spin_unlock_irqrestore(&object_types_lock, flags);
|
spin_unlock_irqrestore(&object_types_lock, flags);
|
||||||
|
|
||||||
p->ob_cache.c_name = p->ob_name;
|
p->ob_cache.c_name = p->ob_name;
|
||||||
p->ob_cache.c_obj_size = sizeof(struct object) + p->ob_size;
|
p->ob_cache.c_obj_size = p->ob_size;
|
||||||
p->ob_cache.c_page_order = VM_PAGE_16K;
|
p->ob_cache.c_page_order = VM_PAGE_16K;
|
||||||
|
|
||||||
vm_cache_init(&p->ob_cache);
|
vm_cache_init(&p->ob_cache);
|
||||||
|
|||||||
17
obj/set.c
17
obj/set.c
@@ -1,13 +1,18 @@
|
|||||||
#include <socks/object.h>
|
#include <socks/object.h>
|
||||||
|
|
||||||
|
#define SET_CAST(p) OBJECT_C_CAST(struct set, s_base, &set_type, p)
|
||||||
|
|
||||||
struct set {
|
struct set {
|
||||||
|
struct object s_base;
|
||||||
struct queue s_list;
|
struct queue s_list;
|
||||||
char s_name[OBJECT_NAME_MAX];
|
char s_name[OBJECT_NAME_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct object_type set_type;
|
||||||
|
|
||||||
static kern_status_t set_query_name(struct object *obj, char out[OBJECT_NAME_MAX])
|
static kern_status_t set_query_name(struct object *obj, char out[OBJECT_NAME_MAX])
|
||||||
{
|
{
|
||||||
struct set *set = object_data(obj);
|
struct set *set = SET_CAST(obj);
|
||||||
strncpy(out, set->s_name, OBJECT_NAME_MAX - 1);
|
strncpy(out, set->s_name, OBJECT_NAME_MAX - 1);
|
||||||
out[OBJECT_NAME_MAX - 1] = 0;
|
out[OBJECT_NAME_MAX - 1] = 0;
|
||||||
|
|
||||||
@@ -16,7 +21,7 @@ static kern_status_t set_query_name(struct object *obj, char out[OBJECT_NAME_MAX
|
|||||||
|
|
||||||
static kern_status_t set_get_child_at(struct object *obj, size_t at, struct object **out)
|
static kern_status_t set_get_child_at(struct object *obj, size_t at, struct object **out)
|
||||||
{
|
{
|
||||||
struct set *set = object_data(obj);
|
struct set *set = SET_CAST(obj);
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
queue_foreach(struct object, child, &set->s_list, ob_list) {
|
queue_foreach(struct object, child, &set->s_list, ob_list) {
|
||||||
if (i == at) {
|
if (i == at) {
|
||||||
@@ -32,7 +37,7 @@ static kern_status_t set_get_child_at(struct object *obj, size_t at, struct obje
|
|||||||
|
|
||||||
static kern_status_t set_get_child_named(struct object *obj, const char *name, struct object **out)
|
static kern_status_t set_get_child_named(struct object *obj, const char *name, struct object **out)
|
||||||
{
|
{
|
||||||
struct set *set = object_data(obj);
|
struct set *set = SET_CAST(obj);
|
||||||
char child_name[OBJECT_NAME_MAX];
|
char child_name[OBJECT_NAME_MAX];
|
||||||
|
|
||||||
queue_foreach(struct object, child, &set->s_list, ob_list) {
|
queue_foreach(struct object, child, &set->s_list, ob_list) {
|
||||||
@@ -72,7 +77,7 @@ struct object *set_create(const char *name)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct set *set = object_data(set_obj);
|
struct set *set = SET_CAST(set_obj);
|
||||||
set->s_list = QUEUE_INIT;
|
set->s_list = QUEUE_INIT;
|
||||||
strncpy(set->s_name, name, sizeof set->s_name - 1);
|
strncpy(set->s_name, name, sizeof set->s_name - 1);
|
||||||
set->s_name[sizeof set->s_name - 1] = 0;
|
set->s_name[sizeof set->s_name - 1] = 0;
|
||||||
@@ -86,7 +91,7 @@ kern_status_t set_add_object(struct object *set_obj, struct object *obj)
|
|||||||
return KERN_INVALID_ARGUMENT;
|
return KERN_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct set *set = object_data(set_obj);
|
struct set *set = SET_CAST(set_obj);
|
||||||
|
|
||||||
char child_name[OBJECT_NAME_MAX];
|
char child_name[OBJECT_NAME_MAX];
|
||||||
char obj_name[OBJECT_NAME_MAX];
|
char obj_name[OBJECT_NAME_MAX];
|
||||||
@@ -115,7 +120,7 @@ kern_status_t set_remove_object(struct object *set_obj, struct object *obj)
|
|||||||
return KERN_INVALID_ARGUMENT;
|
return KERN_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct set *set = object_data(set_obj);
|
struct set *set = SET_CAST(set_obj);
|
||||||
queue_delete(&set->s_list, &obj->ob_list);
|
queue_delete(&set->s_list, &obj->ob_list);
|
||||||
object_deref(obj);
|
object_deref(obj);
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
#include <socks/cpu.h>
|
#include <socks/cpu.h>
|
||||||
#include <socks/libc/stdio.h>
|
#include <socks/libc/stdio.h>
|
||||||
|
|
||||||
|
#define TASK_CAST(p) OBJECT_C_CAST(struct task, t_base, &task_type, p)
|
||||||
|
|
||||||
static struct object_type task_type = {
|
static struct object_type task_type = {
|
||||||
.ob_name = "task",
|
.ob_name = "task",
|
||||||
.ob_size = sizeof(struct task),
|
.ob_size = sizeof(struct task),
|
||||||
@@ -144,7 +146,7 @@ struct task *task_alloc(void)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct task *t = object_data(task_obj);
|
struct task *t = TASK_CAST(task_obj);
|
||||||
memset(t, 0x00, sizeof *t);
|
memset(t, 0x00, sizeof *t);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
#include <socks/cpu.h>
|
#include <socks/cpu.h>
|
||||||
#include <socks/machine/thread.h>
|
#include <socks/machine/thread.h>
|
||||||
|
|
||||||
|
#define THREAD_CAST(p) OBJECT_C_CAST(struct thread, thr_base, &thread_type, p)
|
||||||
|
|
||||||
static struct object_type thread_type = {
|
static struct object_type thread_type = {
|
||||||
.ob_name = "thread",
|
.ob_name = "thread",
|
||||||
.ob_size = sizeof(struct thread),
|
.ob_size = sizeof(struct thread),
|
||||||
@@ -20,7 +22,7 @@ struct thread *thread_alloc(void)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct thread *t = object_data(thread_obj);
|
struct thread *t = THREAD_CAST(thread_obj);
|
||||||
memset(t, 0x00, sizeof *t);
|
memset(t, 0x00, sizeof *t);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|||||||
11
test/obj.c
11
test/obj.c
@@ -3,13 +3,18 @@
|
|||||||
#include <socks/init.h>
|
#include <socks/init.h>
|
||||||
#include <socks/libc/stdio.h>
|
#include <socks/libc/stdio.h>
|
||||||
|
|
||||||
|
#define TEST_CAST(p) OBJECT_C_CAST(struct test_object, base, &test_type, p)
|
||||||
|
|
||||||
struct test_object {
|
struct test_object {
|
||||||
|
struct object base;
|
||||||
char name[OBJECT_NAME_MAX];
|
char name[OBJECT_NAME_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct object_type test_type;
|
||||||
|
|
||||||
static kern_status_t test_query_name(struct object *obj, char out[OBJECT_NAME_MAX])
|
static kern_status_t test_query_name(struct object *obj, char out[OBJECT_NAME_MAX])
|
||||||
{
|
{
|
||||||
struct test_object *test = object_data(obj);
|
struct test_object *test = TEST_CAST(obj);
|
||||||
strncpy(out, test->name, OBJECT_NAME_MAX);
|
strncpy(out, test->name, OBJECT_NAME_MAX);
|
||||||
out[OBJECT_NAME_MAX - 1] = 0;
|
out[OBJECT_NAME_MAX - 1] = 0;
|
||||||
return KERN_OK;
|
return KERN_OK;
|
||||||
@@ -58,7 +63,7 @@ static int run_obj_tests(void)
|
|||||||
object_type_register(&test_type);
|
object_type_register(&test_type);
|
||||||
|
|
||||||
struct object *test_obj = object_create(&test_type);
|
struct object *test_obj = object_create(&test_type);
|
||||||
struct test_object *test = object_data(test_obj);
|
struct test_object *test = TEST_CAST(test_obj);
|
||||||
snprintf(test->name, sizeof test->name, "object1");
|
snprintf(test->name, sizeof test->name, "object1");
|
||||||
kern_status_t status = object_publish(global_namespace(), "/misc/objects", test_obj);
|
kern_status_t status = object_publish(global_namespace(), "/misc/objects", test_obj);
|
||||||
if (status == KERN_OK) {
|
if (status == KERN_OK) {
|
||||||
@@ -73,7 +78,7 @@ static int run_obj_tests(void)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
print_object_tree(object_header(global_namespace()), 0);
|
print_object_tree(ns_header(global_namespace()), 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user