Compare commits
10 Commits
a0a6a061a4
...
325699d64a
| Author | SHA1 | Date | |
|---|---|---|---|
| 325699d64a | |||
| 286016040c | |||
| 04617e81e3 | |||
| 62770f4ab2 | |||
| 9001f8e064 | |||
| 537242e606 | |||
| dfffb45e66 | |||
| f5a83af0d7 | |||
| 7d25f1c31a | |||
| 95d33ddcb9 |
@@ -138,6 +138,7 @@ static struct console serialcon = {
|
||||
|
||||
static int serial_irq1(void)
|
||||
{
|
||||
#if 0
|
||||
if (serial_received(COM1)) {
|
||||
unsigned char c = serial_recv_byte(COM1);
|
||||
printk("serial: COM1 received %c", c);
|
||||
@@ -147,6 +148,7 @@ static int serial_irq1(void)
|
||||
unsigned char c = serial_recv_byte(COM3);
|
||||
printk("serial: COM3 received %c", c);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ extern void handle_table_destroy(struct handle_table *tab);
|
||||
|
||||
extern kern_status_t handle_table_alloc_handle(
|
||||
struct handle_table *tab,
|
||||
kern_handle_t value,
|
||||
struct handle **out_slot,
|
||||
kern_handle_t *out_handle);
|
||||
extern kern_status_t handle_table_free_handle(
|
||||
|
||||
+14
-2
@@ -21,8 +21,20 @@ struct msg {
|
||||
enum kmsg_status msg_status;
|
||||
struct btree_node msg_node;
|
||||
msgid_t msg_id;
|
||||
struct port *msg_sender_port;
|
||||
struct thread *msg_sender_thread;
|
||||
union {
|
||||
/* only valid for asynchronous messages (msg_status ==
|
||||
* KMSG_ASYNC) */
|
||||
struct {
|
||||
koid_t msg_sender_port_id;
|
||||
tid_t msg_sender_thread_id;
|
||||
};
|
||||
/* only valid for synchronous messages (msg_status !=
|
||||
* KMSG_ASYNC) */
|
||||
struct {
|
||||
struct port *msg_sender_port;
|
||||
struct thread *msg_sender_thread;
|
||||
};
|
||||
};
|
||||
kern_status_t msg_result;
|
||||
kern_msg_type_t msg_type;
|
||||
|
||||
|
||||
@@ -9,12 +9,6 @@ enum port_status {
|
||||
PORT_OFFLINE = 0,
|
||||
/* port is connected and ready to send messages */
|
||||
PORT_READY,
|
||||
/* port has sent a message, and is waiting for the remote to receive it
|
||||
*/
|
||||
PORT_SEND_BLOCKED,
|
||||
/* port has sent a message, and the remote has received it. waiting for
|
||||
* the remote to reply. */
|
||||
PORT_REPLY_BLOCKED,
|
||||
};
|
||||
|
||||
struct port {
|
||||
|
||||
@@ -143,9 +143,13 @@ extern kern_status_t sys_address_space_release(
|
||||
|
||||
extern kern_status_t sys_kern_log(const char *s);
|
||||
extern kern_status_t sys_kern_handle_close(kern_handle_t handle);
|
||||
extern kern_status_t sys_kern_handle_duplicate(
|
||||
kern_handle_t handle,
|
||||
kern_handle_t *out);
|
||||
extern kern_status_t sys_kern_handle_transfer(
|
||||
kern_handle_t src_task_handle,
|
||||
kern_handle_t src_handle,
|
||||
kern_handle_t dest_task_handle,
|
||||
kern_handle_t dest_handle,
|
||||
unsigned int mode,
|
||||
kern_handle_t *out_handle);
|
||||
extern kern_status_t sys_kern_config_get(
|
||||
kern_config_key_t key,
|
||||
void *ptr,
|
||||
@@ -191,6 +195,9 @@ extern kern_status_t sys_msg_write(
|
||||
extern kern_status_t sys_kern_object_wait(
|
||||
kern_wait_item_t *items,
|
||||
size_t nr_items);
|
||||
extern kern_status_t sys_kern_object_query(
|
||||
kern_handle_t object,
|
||||
kern_object_info_t *out);
|
||||
|
||||
extern kern_status_t sys_vm_controller_create(kern_handle_t *out);
|
||||
extern kern_status_t sys_vm_controller_recv(
|
||||
|
||||
+4
-4
@@ -2,6 +2,7 @@
|
||||
#include <kernel/channel.h>
|
||||
#include <kernel/msg.h>
|
||||
#include <kernel/port.h>
|
||||
#include <kernel/printk.h>
|
||||
#include <kernel/task.h>
|
||||
#include <kernel/thread.h>
|
||||
#include <kernel/util.h>
|
||||
@@ -101,7 +102,6 @@ static struct msg *get_next_msg(
|
||||
switch (msg->msg_status) {
|
||||
case KMSG_WAIT_RECEIVE:
|
||||
msg->msg_status = KMSG_WAIT_REPLY;
|
||||
msg->msg_sender_port->p_status = PORT_REPLY_BLOCKED;
|
||||
channel->c_msg_waiting--;
|
||||
return msg;
|
||||
case KMSG_ASYNC:
|
||||
@@ -157,12 +157,12 @@ extern kern_status_t channel_recv_msg(
|
||||
/* msg is now set to the next message to process */
|
||||
|
||||
if (msg->msg_type != KERN_MSG_TYPE_DATA) {
|
||||
/* event messages as asynchronous */
|
||||
/* event messages are asynchronous */
|
||||
out_msg->msg_id = msg->msg_id;
|
||||
out_msg->msg_type = msg->msg_type;
|
||||
out_msg->msg_event = msg->msg_event;
|
||||
out_msg->msg_sender = msg->msg_sender_thread->tr_parent->t_id;
|
||||
out_msg->msg_endpoint = msg->msg_sender_port->p_base.ob_id;
|
||||
out_msg->msg_sender = msg->msg_sender_thread_id;
|
||||
out_msg->msg_endpoint = msg->msg_sender_port_id;
|
||||
spin_unlock_irqrestore(&msg->msg_lock, msg_lock_flags);
|
||||
msg_free(msg);
|
||||
|
||||
|
||||
+54
-5
@@ -109,7 +109,7 @@ static kern_status_t encode_handle_indices(
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
kern_status_t handle_table_alloc_handle(
|
||||
static kern_status_t alloc_handle(
|
||||
struct handle_table *tab,
|
||||
struct handle **out_slot,
|
||||
kern_handle_t *out_handle)
|
||||
@@ -164,6 +164,53 @@ kern_status_t handle_table_alloc_handle(
|
||||
return encode_handle_indices(indices, out_handle);
|
||||
}
|
||||
|
||||
kern_status_t handle_table_alloc_handle(
|
||||
struct handle_table *tab,
|
||||
kern_handle_t value,
|
||||
struct handle **out_slot,
|
||||
kern_handle_t *out_handle)
|
||||
{
|
||||
if (value == KERN_HANDLE_INVALID) {
|
||||
return alloc_handle(tab, out_slot, out_handle);
|
||||
}
|
||||
|
||||
unsigned int indices[MAX_TABLE_DEPTH];
|
||||
if (decode_handle_indices(value, indices) != KERN_OK) {
|
||||
return KERN_HANDLE_INVALID;
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = 0; i < MAX_TABLE_DEPTH - 1; i++) {
|
||||
struct handle_table *next
|
||||
= tab->t_subtables.t_subtable_list[indices[i]];
|
||||
if (!next) {
|
||||
next = handle_table_create();
|
||||
tab->t_subtables.t_subtable_list[indices[i]] = next;
|
||||
}
|
||||
|
||||
if (!next) {
|
||||
return KERN_NO_MEMORY;
|
||||
}
|
||||
|
||||
tab = next;
|
||||
}
|
||||
|
||||
unsigned int handle_index = indices[i];
|
||||
bitmap_set(tab->t_handles.t_handle_map, handle_index);
|
||||
|
||||
struct handle *out = &tab->t_handles.t_handle_list[handle_index];
|
||||
|
||||
if (out->h_object) {
|
||||
object_unref(out->h_object);
|
||||
out->h_object = NULL;
|
||||
out->h_flags = 0;
|
||||
}
|
||||
|
||||
*out_slot = out;
|
||||
*out_handle = value;
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
kern_status_t handle_table_free_handle(
|
||||
struct handle_table *tab,
|
||||
kern_handle_t handle)
|
||||
@@ -294,11 +341,12 @@ kern_status_t handle_table_transfer(
|
||||
}
|
||||
|
||||
switch (src_handle.hnd_mode) {
|
||||
case KERN_MSG_HANDLE_IGNORE:
|
||||
case HANDLE_TRANSFER_IGNORE:
|
||||
break;
|
||||
case KERN_MSG_HANDLE_MOVE:
|
||||
case HANDLE_TRANSFER_MOVE:
|
||||
status = handle_table_alloc_handle(
|
||||
dst,
|
||||
KERN_HANDLE_INVALID,
|
||||
&dst_entry,
|
||||
&dst_value);
|
||||
if (status != KERN_OK) {
|
||||
@@ -315,9 +363,10 @@ kern_status_t handle_table_transfer(
|
||||
dst_handle.hnd_value = dst_value;
|
||||
dst_handle.hnd_result = KERN_OK;
|
||||
break;
|
||||
case KERN_MSG_HANDLE_COPY:
|
||||
case HANDLE_TRANSFER_COPY:
|
||||
status = handle_table_alloc_handle(
|
||||
dst,
|
||||
KERN_HANDLE_INVALID,
|
||||
&dst_entry,
|
||||
&dst_value);
|
||||
if (status != KERN_OK) {
|
||||
@@ -364,7 +413,7 @@ kern_status_t handle_table_transfer(
|
||||
&handle,
|
||||
NULL);
|
||||
|
||||
if (handle.hnd_mode != KERN_MSG_HANDLE_MOVE) {
|
||||
if (handle.hnd_mode != HANDLE_TRANSFER_MOVE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
+4
-5
@@ -83,8 +83,8 @@ kern_status_t port_connect(struct port *port, struct channel *remote)
|
||||
msg->msg_status = KMSG_ASYNC;
|
||||
msg->msg_type = KERN_MSG_TYPE_EVENT;
|
||||
msg->msg_event = KERN_MSG_EVENT_CONNECTION;
|
||||
msg->msg_sender_thread = current_thread();
|
||||
msg->msg_sender_port = port;
|
||||
msg->msg_sender_thread_id = current_thread()->tr_id;
|
||||
msg->msg_sender_port_id = port->p_base.ob_id;
|
||||
|
||||
unsigned long flags;
|
||||
channel_lock_irqsave(remote, &flags);
|
||||
@@ -112,8 +112,8 @@ kern_status_t port_disconnect(struct port *port)
|
||||
msg->msg_status = KMSG_ASYNC;
|
||||
msg->msg_type = KERN_MSG_TYPE_EVENT;
|
||||
msg->msg_event = KERN_MSG_EVENT_DISCONNECTION;
|
||||
msg->msg_sender_thread = current_thread();
|
||||
msg->msg_sender_port = port;
|
||||
msg->msg_sender_thread_id = current_thread()->tr_id;
|
||||
msg->msg_sender_port_id = port->p_base.ob_id;
|
||||
|
||||
unsigned long flags;
|
||||
channel_lock_irqsave(port->p_remote, &flags);
|
||||
@@ -148,7 +148,6 @@ kern_status_t port_send_msg(
|
||||
|
||||
unsigned long flags;
|
||||
channel_lock_irqsave(port->p_remote, &flags);
|
||||
port->p_status = PORT_SEND_BLOCKED;
|
||||
channel_enqueue_msg(port->p_remote, &msg);
|
||||
channel_unlock_irqrestore(port->p_remote, flags);
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
int memcmp(const void *vl, const void *vr, size_t n)
|
||||
{
|
||||
const unsigned char *l=vl, *r=vr;
|
||||
for (; n && *l == *r; n--, l++, r++);
|
||||
return n ? *l-*r : 0;
|
||||
const unsigned char *l = vl, *r = vr;
|
||||
for (; n && *l == *r; n--, l++, r++)
|
||||
;
|
||||
return n ? *l - *r : 0;
|
||||
}
|
||||
|
||||
+13
-13
@@ -1,24 +1,24 @@
|
||||
#include <stdint.h>
|
||||
#include <kernel/libc/string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static void *memcpy_r(void *dest, const void *src, size_t sz)
|
||||
{
|
||||
unsigned char *d = dest;
|
||||
const unsigned char *s = src;
|
||||
unsigned char *d = dest;
|
||||
const unsigned char *s = src;
|
||||
|
||||
for (size_t i = 0; i < sz; i++) {
|
||||
size_t b = sz - i - 1;
|
||||
d[b] = s[b];
|
||||
}
|
||||
for (size_t i = 0; i < sz; i++) {
|
||||
size_t b = sz - i - 1;
|
||||
d[b] = s[b];
|
||||
}
|
||||
|
||||
return dest;
|
||||
return dest;
|
||||
}
|
||||
|
||||
void *memmove(void *dest, const void *src, size_t n)
|
||||
{
|
||||
if (dest < src) {
|
||||
return memcpy(dest, src, n);
|
||||
} else {
|
||||
return memcpy_r(dest, src, n);
|
||||
}
|
||||
if (dest < src) {
|
||||
return memcpy(dest, src, n);
|
||||
} else {
|
||||
return memcpy_r(dest, src, n);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ SYSCALL_GATE address_space_release SYS_ADDRESS_SPACE_RELEASE 3
|
||||
|
||||
SYSCALL_GATE kern_log SYS_KERN_LOG 1
|
||||
SYSCALL_GATE kern_handle_close SYS_KERN_HANDLE_CLOSE 1
|
||||
SYSCALL_GATE kern_handle_duplicate SYS_KERN_HANDLE_DUPLICATE 2
|
||||
SYSCALL_GATE kern_handle_transfer SYS_KERN_HANDLE_TRANSFER 6
|
||||
SYSCALL_GATE kern_config_get SYS_KERN_CONFIG_GET 3
|
||||
SYSCALL_GATE kern_config_set SYS_KERN_CONFIG_SET 3
|
||||
|
||||
@@ -105,6 +105,7 @@ SYSCALL_GATE vm_controller_detach_object SYS_VM_CONTROLLER_DETACH_OBJECT 2
|
||||
SYSCALL_GATE vm_controller_supply_pages SYS_VM_CONTROLLER_SUPPLY_PAGES 6
|
||||
|
||||
SYSCALL_GATE kern_object_wait SYS_KERN_OBJECT_WAIT 2
|
||||
SYSCALL_GATE kern_object_query SYS_KERN_OBJECT_QUERY 2
|
||||
|
||||
SYSCALL_GATE futex_wait SYS_FUTEX_WAIT 3
|
||||
SYSCALL_GATE futex_wake SYS_FUTEX_WAKE 3
|
||||
|
||||
@@ -5,8 +5,12 @@
|
||||
#include <mango/types.h>
|
||||
|
||||
extern kern_status_t kern_handle_close(kern_handle_t handle);
|
||||
extern kern_status_t kern_handle_duplicate(
|
||||
kern_handle_t handle,
|
||||
kern_handle_t *out);
|
||||
extern kern_status_t kern_handle_transfer(
|
||||
kern_handle_t src_task,
|
||||
kern_handle_t src_handle,
|
||||
kern_handle_t dest_task,
|
||||
kern_handle_t dest_handle,
|
||||
unsigned int mode,
|
||||
kern_handle_t *out_handle);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4,5 +4,8 @@
|
||||
#include <mango/types.h>
|
||||
|
||||
extern kern_status_t kern_object_wait(kern_wait_item_t *items, size_t nr_items);
|
||||
extern kern_status_t kern_object_query(
|
||||
kern_handle_t handle,
|
||||
kern_object_info_t *out);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#define SYS_KERN_LOG 1
|
||||
#define SYS_KERN_HANDLE_CLOSE 2
|
||||
#define SYS_KERN_HANDLE_DUPLICATE 3
|
||||
#define SYS_KERN_HANDLE_TRANSFER 3
|
||||
#define SYS_KERN_CONFIG_GET 4
|
||||
#define SYS_KERN_CONFIG_SET 5
|
||||
#define SYS_KERN_OBJECT_WAIT 6
|
||||
@@ -49,5 +49,6 @@
|
||||
#define SYS_VM_CONTROLLER_SUPPLY_PAGES 46
|
||||
#define SYS_FUTEX_WAIT 47
|
||||
#define SYS_FUTEX_WAKE 48
|
||||
#define SYS_KERN_OBJECT_QUERY 49
|
||||
|
||||
#endif
|
||||
|
||||
@@ -32,13 +32,13 @@
|
||||
#define KERN_MSG_MAX_HANDLES 64
|
||||
|
||||
/* the corresponding handle should be ignored */
|
||||
#define KERN_MSG_HANDLE_IGNORE 0
|
||||
#define HANDLE_TRANSFER_IGNORE 0
|
||||
/* the corresponding handle should be moved to the recipient task. the handle
|
||||
* will be closed. */
|
||||
#define KERN_MSG_HANDLE_MOVE 1
|
||||
#define HANDLE_TRANSFER_MOVE 1
|
||||
/* the corresponding handle should be copied to the recipient task. the handle
|
||||
* will remain valid for the sending task. */
|
||||
#define KERN_MSG_HANDLE_COPY 2
|
||||
#define HANDLE_TRANSFER_COPY 2
|
||||
|
||||
/* maximum number of objects that can be waited on in a single call to
|
||||
* kern_object_wait */
|
||||
@@ -109,6 +109,10 @@ typedef unsigned short equeue_packet_type_t;
|
||||
|
||||
typedef unsigned int umode_t;
|
||||
|
||||
typedef struct {
|
||||
koid_t obj_id;
|
||||
} kern_object_info_t;
|
||||
|
||||
typedef struct {
|
||||
virt_addr_t io_base;
|
||||
size_t io_len;
|
||||
|
||||
+5
-2
@@ -352,8 +352,11 @@ kern_status_t task_open_handle(
|
||||
kern_handle_t *out)
|
||||
{
|
||||
struct handle *handle_data = NULL;
|
||||
kern_status_t status
|
||||
= handle_table_alloc_handle(task->t_handles, &handle_data, out);
|
||||
kern_status_t status = handle_table_alloc_handle(
|
||||
task->t_handles,
|
||||
KERN_HANDLE_INVALID,
|
||||
&handle_data,
|
||||
out);
|
||||
if (status != KERN_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
+2
-1
@@ -27,7 +27,7 @@ static const virt_addr_t syscall_table[] = {
|
||||
SYSCALL_TABLE_ENTRY(ADDRESS_SPACE_RELEASE, address_space_release),
|
||||
SYSCALL_TABLE_ENTRY(KERN_LOG, kern_log),
|
||||
SYSCALL_TABLE_ENTRY(KERN_HANDLE_CLOSE, kern_handle_close),
|
||||
SYSCALL_TABLE_ENTRY(KERN_HANDLE_DUPLICATE, kern_handle_duplicate),
|
||||
SYSCALL_TABLE_ENTRY(KERN_HANDLE_TRANSFER, kern_handle_transfer),
|
||||
SYSCALL_TABLE_ENTRY(KERN_CONFIG_GET, kern_config_get),
|
||||
SYSCALL_TABLE_ENTRY(KERN_CONFIG_SET, kern_config_set),
|
||||
SYSCALL_TABLE_ENTRY(CHANNEL_CREATE, channel_create),
|
||||
@@ -52,6 +52,7 @@ static const virt_addr_t syscall_table[] = {
|
||||
VM_CONTROLLER_SUPPLY_PAGES,
|
||||
vm_controller_supply_pages),
|
||||
SYSCALL_TABLE_ENTRY(KERN_OBJECT_WAIT, kern_object_wait),
|
||||
SYSCALL_TABLE_ENTRY(KERN_OBJECT_QUERY, kern_object_query),
|
||||
SYSCALL_TABLE_ENTRY(FUTEX_WAIT, futex_wait),
|
||||
SYSCALL_TABLE_ENTRY(FUTEX_WAKE, futex_wake),
|
||||
};
|
||||
|
||||
+111
-11
@@ -8,32 +8,132 @@ kern_status_t sys_kern_handle_close(kern_handle_t handle)
|
||||
return task_close_handle(self, handle);
|
||||
}
|
||||
|
||||
kern_status_t sys_kern_handle_duplicate(
|
||||
kern_handle_t handle,
|
||||
kern_handle_t *out)
|
||||
kern_status_t sys_kern_handle_transfer(
|
||||
kern_handle_t src_task_handle,
|
||||
kern_handle_t src_handle,
|
||||
kern_handle_t dest_task_handle,
|
||||
kern_handle_t dest_handle,
|
||||
unsigned int mode,
|
||||
kern_handle_t *out_handle)
|
||||
{
|
||||
switch (mode) {
|
||||
case HANDLE_TRANSFER_MOVE:
|
||||
case HANDLE_TRANSFER_COPY:
|
||||
break;
|
||||
default:
|
||||
return KERN_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
struct task *self = current_task();
|
||||
|
||||
if (!validate_access_w(self, out, sizeof *out)) {
|
||||
if (out_handle
|
||||
&& !validate_access_w(self, out_handle, sizeof *out_handle)) {
|
||||
return KERN_MEMORY_FAULT;
|
||||
}
|
||||
|
||||
unsigned long flags;
|
||||
task_lock_irqsave(self, &flags);
|
||||
|
||||
struct object *src_object = NULL;
|
||||
struct task *src_task = NULL;
|
||||
struct task *dest_task = NULL;
|
||||
kern_status_t status = KERN_OK;
|
||||
|
||||
struct object *obj = NULL;
|
||||
handle_flags_t handle_flags = 0;
|
||||
kern_status_t status
|
||||
= task_resolve_handle(self, handle, &obj, &handle_flags);
|
||||
if (status != KERN_OK) {
|
||||
task_unlock_irqrestore(self, flags);
|
||||
return status;
|
||||
|
||||
if (src_task_handle != KERN_HANDLE_INVALID) {
|
||||
status = task_resolve_handle(
|
||||
self,
|
||||
src_task_handle,
|
||||
&obj,
|
||||
&handle_flags);
|
||||
if (status != KERN_OK) {
|
||||
task_unlock_irqrestore(self, flags);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
src_task = task_cast(obj);
|
||||
if (!src_task) {
|
||||
status = KERN_INVALID_ARGUMENT;
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
src_task = self;
|
||||
}
|
||||
|
||||
status = task_open_handle(self, obj, handle_flags, out);
|
||||
object_unref(obj);
|
||||
if (dest_task_handle != KERN_HANDLE_INVALID) {
|
||||
status = task_resolve_handle(
|
||||
self,
|
||||
dest_task_handle,
|
||||
&obj,
|
||||
&handle_flags);
|
||||
if (status != KERN_OK) {
|
||||
task_unlock_irqrestore(self, flags);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
dest_task = task_cast(obj);
|
||||
if (!dest_task) {
|
||||
status = KERN_INVALID_ARGUMENT;
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
dest_task = self;
|
||||
}
|
||||
|
||||
status = task_resolve_handle(
|
||||
self,
|
||||
src_handle,
|
||||
&src_object,
|
||||
&handle_flags);
|
||||
if (status != KERN_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
task_unlock_irqrestore(self, flags);
|
||||
|
||||
struct handle *dest = NULL;
|
||||
task_lock_irqsave(dest_task, &flags);
|
||||
status = handle_table_alloc_handle(
|
||||
dest_task->t_handles,
|
||||
dest_handle,
|
||||
&dest,
|
||||
&dest_handle);
|
||||
task_unlock_irqrestore(dest_task, flags);
|
||||
|
||||
if (status != KERN_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (mode == HANDLE_TRANSFER_MOVE) {
|
||||
object_ref(src_object);
|
||||
task_lock_irqsave(src_task, &flags);
|
||||
handle_table_free_handle(src_task->t_handles, src_handle);
|
||||
task_unlock_irqrestore(src_task, flags);
|
||||
}
|
||||
|
||||
dest->h_object = src_object;
|
||||
dest->h_flags = handle_flags;
|
||||
|
||||
if (out_handle) {
|
||||
*out_handle = dest_handle;
|
||||
}
|
||||
|
||||
return KERN_OK;
|
||||
|
||||
cleanup:
|
||||
if (src_task && src_task_handle != KERN_HANDLE_INVALID) {
|
||||
object_unref(&src_task->t_base);
|
||||
}
|
||||
|
||||
if (dest_task && dest_task_handle != KERN_HANDLE_INVALID) {
|
||||
object_unref(&dest_task->t_base);
|
||||
}
|
||||
|
||||
if (src_object) {
|
||||
object_unref(src_object);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -5,8 +5,12 @@
|
||||
|
||||
kern_status_t sys_kern_log(const char *s)
|
||||
{
|
||||
#ifdef TRACE
|
||||
struct task *task = current_task();
|
||||
struct thread *thread = current_thread();
|
||||
printk("%s[%d.%d]: %s", task->t_name, task->t_id, thread->tr_id, s);
|
||||
#else
|
||||
printk("%s", s);
|
||||
#endif
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
+2
-2
@@ -240,12 +240,12 @@ kern_status_t sys_msg_send(
|
||||
port_handle,
|
||||
&port_obj,
|
||||
&port_handle_flags);
|
||||
task_unlock_irqrestore(self, flags);
|
||||
|
||||
if (status != KERN_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
task_unlock_irqrestore(self, flags);
|
||||
|
||||
struct port *port = port_cast(port_obj);
|
||||
if (!port) {
|
||||
object_unref(port_obj);
|
||||
|
||||
@@ -80,3 +80,32 @@ cleanup:
|
||||
self_thread->tr_state = THREAD_READY;
|
||||
return status;
|
||||
}
|
||||
|
||||
kern_status_t sys_kern_object_query(
|
||||
kern_handle_t object_handle,
|
||||
kern_object_info_t *out)
|
||||
{
|
||||
struct task *self = current_task();
|
||||
|
||||
if (!out) {
|
||||
return KERN_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (!validate_access_w(self, out, sizeof *out)) {
|
||||
return KERN_MEMORY_FAULT;
|
||||
}
|
||||
|
||||
struct object *obj = NULL;
|
||||
handle_flags_t flags = 0;
|
||||
kern_status_t status
|
||||
= task_resolve_handle(self, object_handle, &obj, &flags);
|
||||
if (status != KERN_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
out->obj_id = obj->ob_id;
|
||||
|
||||
object_unref(obj);
|
||||
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ kern_status_t sys_task_self(kern_handle_t *out)
|
||||
kern_handle_t handle;
|
||||
kern_status_t status = handle_table_alloc_handle(
|
||||
self->t_handles,
|
||||
KERN_HANDLE_INVALID,
|
||||
&handle_slot,
|
||||
&handle);
|
||||
task_unlock_irqrestore(self, flags);
|
||||
@@ -89,6 +90,7 @@ kern_status_t sys_task_create(
|
||||
kern_handle_t child_handle, space_handle;
|
||||
status = handle_table_alloc_handle(
|
||||
self->t_handles,
|
||||
KERN_HANDLE_INVALID,
|
||||
&child_handle_slot,
|
||||
&child_handle);
|
||||
if (status != KERN_OK) {
|
||||
@@ -99,6 +101,7 @@ kern_status_t sys_task_create(
|
||||
|
||||
status = handle_table_alloc_handle(
|
||||
self->t_handles,
|
||||
KERN_HANDLE_INVALID,
|
||||
&space_handle_slot,
|
||||
&space_handle);
|
||||
if (status != KERN_OK) {
|
||||
@@ -175,6 +178,7 @@ kern_status_t sys_task_create_thread(
|
||||
kern_handle_t out_handle;
|
||||
status = handle_table_alloc_handle(
|
||||
self->t_handles,
|
||||
KERN_HANDLE_INVALID,
|
||||
&target_handle,
|
||||
&out_handle);
|
||||
if (status != KERN_OK) {
|
||||
@@ -236,6 +240,7 @@ kern_status_t sys_task_get_address_space(
|
||||
|
||||
status = handle_table_alloc_handle(
|
||||
self->t_handles,
|
||||
KERN_HANDLE_INVALID,
|
||||
&handle_slot,
|
||||
&handle);
|
||||
if (status != KERN_OK) {
|
||||
@@ -278,6 +283,7 @@ kern_status_t sys_thread_self(kern_handle_t *out)
|
||||
kern_handle_t handle;
|
||||
kern_status_t status = handle_table_alloc_handle(
|
||||
self->t_handles,
|
||||
KERN_HANDLE_INVALID,
|
||||
&handle_slot,
|
||||
&handle);
|
||||
task_unlock_irqrestore(self, flags);
|
||||
|
||||
@@ -154,6 +154,7 @@ kern_status_t sys_vm_controller_create_object(
|
||||
kern_handle_t out_handle = KERN_HANDLE_INVALID;
|
||||
status = handle_table_alloc_handle(
|
||||
self->t_handles,
|
||||
KERN_HANDLE_INVALID,
|
||||
&out_slot,
|
||||
&out_handle);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user