sched: task: implement task_config_get and task_config_set
This commit is contained in:
@@ -70,6 +70,16 @@ extern kern_status_t task_resolve_handle(
|
|||||||
kern_handle_t handle,
|
kern_handle_t handle,
|
||||||
struct object **out_obj,
|
struct object **out_obj,
|
||||||
handle_flags_t *out_flags);
|
handle_flags_t *out_flags);
|
||||||
|
extern kern_status_t task_config_get(
|
||||||
|
struct task *task,
|
||||||
|
kern_config_key_t key,
|
||||||
|
void *out,
|
||||||
|
size_t max);
|
||||||
|
extern kern_status_t task_config_set(
|
||||||
|
struct task *task,
|
||||||
|
kern_config_key_t key,
|
||||||
|
const void *ptr,
|
||||||
|
size_t len);
|
||||||
extern kern_status_t task_close_handle(struct task *task, kern_handle_t handle);
|
extern kern_status_t task_close_handle(struct task *task, kern_handle_t handle);
|
||||||
extern struct thread *task_create_thread(struct task *parent);
|
extern struct thread *task_create_thread(struct task *parent);
|
||||||
extern struct task *kernel_task(void);
|
extern struct task *kernel_task(void);
|
||||||
|
|||||||
@@ -297,6 +297,40 @@ struct task *task_from_tid(tid_t id)
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kern_status_t task_config_get(
|
||||||
|
struct task *task,
|
||||||
|
kern_config_key_t key,
|
||||||
|
void *out,
|
||||||
|
size_t max)
|
||||||
|
{
|
||||||
|
switch (key) {
|
||||||
|
case TASK_CFG_ID: {
|
||||||
|
if (max != sizeof(tid_t)) {
|
||||||
|
return KERN_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
tid_t *value = out;
|
||||||
|
*value = task->t_id;
|
||||||
|
return KERN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return KERN_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_status_t task_config_set(
|
||||||
|
struct task *task,
|
||||||
|
kern_config_key_t key,
|
||||||
|
const void *ptr,
|
||||||
|
size_t len)
|
||||||
|
{
|
||||||
|
switch (key) {
|
||||||
|
default:
|
||||||
|
return KERN_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void task_exit(int status)
|
void task_exit(int status)
|
||||||
{
|
{
|
||||||
struct task *self = get_current_task();
|
struct task *self = get_current_task();
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ static const virt_addr_t syscall_table[] = {
|
|||||||
SYSCALL_TABLE_ENTRY(TASK_CREATE_THREAD, task_create_thread),
|
SYSCALL_TABLE_ENTRY(TASK_CREATE_THREAD, task_create_thread),
|
||||||
SYSCALL_TABLE_ENTRY(TASK_GET_ADDRESS_SPACE, task_get_address_space),
|
SYSCALL_TABLE_ENTRY(TASK_GET_ADDRESS_SPACE, task_get_address_space),
|
||||||
SYSCALL_TABLE_ENTRY(TASK_DUPLICATE, task_duplicate),
|
SYSCALL_TABLE_ENTRY(TASK_DUPLICATE, task_duplicate),
|
||||||
|
SYSCALL_TABLE_ENTRY(TASK_CONFIG_GET, task_config_get),
|
||||||
|
SYSCALL_TABLE_ENTRY(TASK_CONFIG_SET, task_config_set),
|
||||||
SYSCALL_TABLE_ENTRY(THREAD_SELF, thread_self),
|
SYSCALL_TABLE_ENTRY(THREAD_SELF, thread_self),
|
||||||
SYSCALL_TABLE_ENTRY(THREAD_START, thread_start),
|
SYSCALL_TABLE_ENTRY(THREAD_START, thread_start),
|
||||||
SYSCALL_TABLE_ENTRY(THREAD_EXIT, thread_exit),
|
SYSCALL_TABLE_ENTRY(THREAD_EXIT, thread_exit),
|
||||||
|
|||||||
@@ -292,6 +292,89 @@ kern_status_t sys_task_get_address_space(
|
|||||||
return KERN_OK;
|
return KERN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kern_status_t sys_task_config_get(
|
||||||
|
kern_handle_t task_handle,
|
||||||
|
kern_config_key_t key,
|
||||||
|
void *ptr,
|
||||||
|
size_t len)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
struct task *self = get_current_task();
|
||||||
|
|
||||||
|
if (!validate_access_w(self, ptr, len)) {
|
||||||
|
put_current_task(self);
|
||||||
|
return KERN_MEMORY_FAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct object *task_obj;
|
||||||
|
handle_flags_t task_flags;
|
||||||
|
task_lock_irqsave(self, &flags);
|
||||||
|
kern_status_t status = task_resolve_handle(
|
||||||
|
self,
|
||||||
|
task_handle,
|
||||||
|
&task_obj,
|
||||||
|
&task_flags);
|
||||||
|
put_current_task(self);
|
||||||
|
task_unlock_irqrestore(self, flags);
|
||||||
|
|
||||||
|
if (status != KERN_OK) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct task *task = task_cast(task_obj);
|
||||||
|
task_unlock_irqrestore(self, flags);
|
||||||
|
|
||||||
|
if (task) {
|
||||||
|
status = task_config_get(task, key, ptr, len);
|
||||||
|
} else {
|
||||||
|
status = KERN_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
object_unref(task_obj);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_status_t sys_task_config_set(
|
||||||
|
kern_handle_t task_handle,
|
||||||
|
kern_config_key_t key,
|
||||||
|
const void *ptr,
|
||||||
|
size_t len)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
struct task *self = get_current_task();
|
||||||
|
|
||||||
|
if (!validate_access_w(self, ptr, len)) {
|
||||||
|
put_current_task(self);
|
||||||
|
return KERN_MEMORY_FAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct object *task_obj;
|
||||||
|
handle_flags_t task_flags;
|
||||||
|
task_lock_irqsave(self, &flags);
|
||||||
|
kern_status_t status = task_resolve_handle(
|
||||||
|
self,
|
||||||
|
task_handle,
|
||||||
|
&task_obj,
|
||||||
|
&task_flags);
|
||||||
|
task_unlock_irqrestore(self, flags);
|
||||||
|
put_current_task(self);
|
||||||
|
if (status != KERN_OK) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct task *task = task_cast(task_obj);
|
||||||
|
if (task) {
|
||||||
|
status = task_config_set(task, key, ptr, len);
|
||||||
|
} else {
|
||||||
|
status = KERN_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
object_unref(task_obj);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
kern_status_t sys_thread_self(kern_handle_t *out)
|
kern_status_t sys_thread_self(kern_handle_t *out)
|
||||||
{
|
{
|
||||||
struct task *self = get_current_task();
|
struct task *self = get_current_task();
|
||||||
|
|||||||
Reference in New Issue
Block a user