Cleaned up the source a bit, and rearranged the code, (hopefully) no functional
changes, though. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1393 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+303
-259
@@ -81,11 +81,10 @@ static struct thread *thread_get_thread_struct_locked(thread_id id);
|
||||
static void thread_kthread_exit(void);
|
||||
static void deliver_signal(struct thread *t, int signal);
|
||||
|
||||
#ifdef NEW_SCHEDULER
|
||||
|
||||
#endif /* NEW_SCHEDULER */
|
||||
// insert a thread onto the tail of a queue
|
||||
void thread_enqueue(struct thread *t, struct thread_queue *q)
|
||||
void
|
||||
thread_enqueue(struct thread *t, struct thread_queue *q)
|
||||
{
|
||||
t->q_next = NULL;
|
||||
if(q->head == NULL) {
|
||||
@@ -97,17 +96,21 @@ void thread_enqueue(struct thread *t, struct thread_queue *q)
|
||||
}
|
||||
}
|
||||
|
||||
struct thread *thread_lookat_queue(struct thread_queue *q)
|
||||
|
||||
struct thread *
|
||||
thread_lookat_queue(struct thread_queue *q)
|
||||
{
|
||||
return q->head;
|
||||
}
|
||||
|
||||
struct thread *thread_dequeue(struct thread_queue *q)
|
||||
|
||||
struct thread *
|
||||
thread_dequeue(struct thread_queue *q)
|
||||
{
|
||||
struct thread *t;
|
||||
|
||||
t = q->head;
|
||||
if(t != NULL) {
|
||||
if (t != NULL) {
|
||||
q->head = t->q_next;
|
||||
if(q->tail == t)
|
||||
q->tail = NULL;
|
||||
@@ -115,20 +118,22 @@ struct thread *thread_dequeue(struct thread_queue *q)
|
||||
return t;
|
||||
}
|
||||
|
||||
struct thread *thread_dequeue_id(struct thread_queue *q, thread_id thr_id)
|
||||
|
||||
struct thread *
|
||||
thread_dequeue_id(struct thread_queue *q, thread_id thr_id)
|
||||
{
|
||||
struct thread *t;
|
||||
struct thread *last = NULL;
|
||||
|
||||
t = q->head;
|
||||
while(t != NULL) {
|
||||
if(t->id == thr_id) {
|
||||
if(last == NULL) {
|
||||
while (t != NULL) {
|
||||
if (t->id == thr_id) {
|
||||
if (last == NULL)
|
||||
q->head = t->q_next;
|
||||
} else {
|
||||
else
|
||||
last->q_next = t->q_next;
|
||||
}
|
||||
if(q->tail == t)
|
||||
|
||||
if (q->tail == t)
|
||||
q->tail = last;
|
||||
break;
|
||||
}
|
||||
@@ -139,51 +144,59 @@ struct thread *thread_dequeue_id(struct thread_queue *q, thread_id thr_id)
|
||||
}
|
||||
|
||||
#ifndef NEW_SCHEDULER
|
||||
struct thread *thread_lookat_run_q(int priority)
|
||||
struct thread *
|
||||
thread_lookat_run_q(int priority)
|
||||
{
|
||||
return thread_lookat_queue(&run_q[(priority + 1) >> 1]);
|
||||
}
|
||||
|
||||
void thread_enqueue_run_q(struct thread *t)
|
||||
|
||||
void
|
||||
thread_enqueue_run_q(struct thread *t)
|
||||
{
|
||||
// these shouldn't exist
|
||||
if(t->priority > B_MAX_PRIORITY)
|
||||
if (t->priority > B_MAX_PRIORITY)
|
||||
t->priority = B_MAX_PRIORITY;
|
||||
if(t->priority < B_MIN_PRIORITY)
|
||||
else if (t->priority < B_MIN_PRIORITY)
|
||||
t->priority = B_MIN_PRIORITY;
|
||||
|
||||
thread_enqueue(t, &run_q[(t->priority + 1) >> 1]);
|
||||
}
|
||||
|
||||
struct thread *thread_dequeue_run_q(int priority)
|
||||
|
||||
struct thread *
|
||||
thread_dequeue_run_q(int priority)
|
||||
{
|
||||
return thread_dequeue(&run_q[(priority + 1) >> 1]);
|
||||
}
|
||||
|
||||
#endif /* not NEW_SCHEDULER */
|
||||
static void insert_thread_into_team(struct team *p, struct thread *t)
|
||||
|
||||
static void
|
||||
insert_thread_into_team(struct team *p, struct thread *t)
|
||||
{
|
||||
t->team_next = p->thread_list;
|
||||
p->thread_list = t;
|
||||
p->num_threads++;
|
||||
if(p->num_threads == 1) {
|
||||
if (p->num_threads == 1) {
|
||||
// this was the first thread
|
||||
p->main_thread = t;
|
||||
}
|
||||
t->team = p;
|
||||
}
|
||||
|
||||
static void remove_thread_from_team(struct team *p, struct thread *t)
|
||||
|
||||
static void
|
||||
remove_thread_from_team(struct team *p, struct thread *t)
|
||||
{
|
||||
struct thread *temp, *last = NULL;
|
||||
|
||||
for(temp = p->thread_list; temp != NULL; temp = temp->team_next) {
|
||||
if(temp == t) {
|
||||
if(last == NULL) {
|
||||
for (temp = p->thread_list; temp != NULL; temp = temp->team_next) {
|
||||
if (temp == t) {
|
||||
if (last == NULL)
|
||||
p->thread_list = temp->team_next;
|
||||
} else {
|
||||
else
|
||||
last->team_next = temp->team_next;
|
||||
}
|
||||
|
||||
p->num_threads--;
|
||||
break;
|
||||
}
|
||||
@@ -191,27 +204,35 @@ static void remove_thread_from_team(struct team *p, struct thread *t)
|
||||
}
|
||||
}
|
||||
|
||||
static int thread_struct_compare(void *_t, const void *_key)
|
||||
|
||||
static int
|
||||
thread_struct_compare(void *_t, const void *_key)
|
||||
{
|
||||
struct thread *t = _t;
|
||||
const struct thread_key *key = _key;
|
||||
|
||||
if(t->id == key->id) return 0;
|
||||
else return 1;
|
||||
if (t->id == key->id)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static unsigned int thread_struct_hash(void *_t, const void *_key, unsigned int range)
|
||||
|
||||
static unsigned int
|
||||
thread_struct_hash(void *_t, const void *_key, unsigned int range)
|
||||
{
|
||||
struct thread *t = _t;
|
||||
const struct thread_key *key = _key;
|
||||
|
||||
if(t != NULL)
|
||||
if (t != NULL)
|
||||
return (t->id % range);
|
||||
else
|
||||
return (key->id % range);
|
||||
|
||||
return (key->id % range);
|
||||
}
|
||||
|
||||
static struct thread *create_thread_struct(const char *name)
|
||||
|
||||
static struct thread *
|
||||
create_thread_struct(const char *name)
|
||||
{
|
||||
struct thread *t;
|
||||
int state;
|
||||
@@ -223,9 +244,9 @@ static struct thread *create_thread_struct(const char *name)
|
||||
RELEASE_THREAD_LOCK();
|
||||
restore_interrupts(state);
|
||||
|
||||
if(t == NULL) {
|
||||
if (t == NULL) {
|
||||
t = (struct thread *)kmalloc(sizeof(struct thread));
|
||||
if(t == NULL)
|
||||
if (t == NULL)
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -253,7 +274,7 @@ static struct thread *create_thread_struct(const char *name)
|
||||
|
||||
sprintf(temp, "thread_0x%lx_retcode_sem", t->id);
|
||||
t->return_code_sem = create_sem(0, temp);
|
||||
if(t->return_code_sem < 0)
|
||||
if (t->return_code_sem < 0)
|
||||
goto err1;
|
||||
|
||||
sprintf(temp, "%s data write sem", t->name);
|
||||
@@ -266,7 +287,7 @@ static struct thread *create_thread_struct(const char *name)
|
||||
if (t->msg.read_sem < 0)
|
||||
goto err3;
|
||||
|
||||
if(arch_thread_init_thread_struct(t) < 0)
|
||||
if (arch_thread_init_thread_struct(t) < 0)
|
||||
goto err4;
|
||||
|
||||
return t;
|
||||
@@ -283,7 +304,9 @@ err:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void delete_thread_struct(struct thread *t)
|
||||
|
||||
static void
|
||||
delete_thread_struct(struct thread *t)
|
||||
{
|
||||
if (t->return_code_sem >= 0)
|
||||
delete_sem_etc(t->return_code_sem, -1);
|
||||
@@ -294,7 +317,9 @@ static void delete_thread_struct(struct thread *t)
|
||||
kfree(t);
|
||||
}
|
||||
|
||||
static int _create_user_thread_kentry(void)
|
||||
|
||||
static int
|
||||
_create_user_thread_kentry(void)
|
||||
{
|
||||
struct thread *t;
|
||||
|
||||
@@ -310,7 +335,9 @@ static int _create_user_thread_kentry(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _create_kernel_thread_kentry(void)
|
||||
|
||||
static int
|
||||
_create_kernel_thread_kentry(void)
|
||||
{
|
||||
int (*func)(void *args);
|
||||
struct thread *t;
|
||||
@@ -338,6 +365,7 @@ _create_thread(const char *name, team_id pid, addr entry, void *args, int priori
|
||||
return ENOMEM;
|
||||
|
||||
t->priority = priority == -1 ? B_NORMAL_PRIORITY : priority;
|
||||
// ToDo: revisit this one - the thread might go to early to B_THREAD_SUSPENDED
|
||||
// t->state = THREAD_STATE_BIRTH;
|
||||
t->state = B_THREAD_SUSPENDED; // Is this right?
|
||||
t->next_state = B_THREAD_SUSPENDED;
|
||||
@@ -352,11 +380,11 @@ _create_thread(const char *name, team_id pid, addr entry, void *args, int priori
|
||||
GRAB_TEAM_LOCK();
|
||||
// look at the team, make sure it's not being deleted
|
||||
p = team_get_team_struct_locked(pid);
|
||||
if (p != NULL && p->state != TEAM_STATE_DEATH) {
|
||||
if (p != NULL && p->state != TEAM_STATE_DEATH)
|
||||
insert_thread_into_team(p, t);
|
||||
} else {
|
||||
else
|
||||
abort = true;
|
||||
}
|
||||
|
||||
RELEASE_TEAM_LOCK();
|
||||
if (abort) {
|
||||
GRAB_THREAD_LOCK();
|
||||
@@ -413,41 +441,30 @@ _create_thread(const char *name, team_id pid, addr entry, void *args, int priori
|
||||
return t->id;
|
||||
}
|
||||
|
||||
thread_id user_thread_create_user_thread(addr entry, team_id pid, const char *uname, int priority,
|
||||
void *args)
|
||||
{
|
||||
char name[SYS_MAX_OS_NAME_LEN];
|
||||
int rc;
|
||||
|
||||
if((addr)uname >= KERNEL_BASE && (addr)uname <= KERNEL_TOP)
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
if(entry >= KERNEL_BASE && entry <= KERNEL_TOP)
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
|
||||
rc = user_strncpy(name, uname, SYS_MAX_OS_NAME_LEN-1);
|
||||
if(rc < 0)
|
||||
return rc;
|
||||
name[SYS_MAX_OS_NAME_LEN-1] = 0;
|
||||
|
||||
return _create_thread(name, pid, entry, args, priority, false);
|
||||
}
|
||||
|
||||
thread_id thread_create_user_thread(char *name, team_id pid, addr entry, void *args)
|
||||
thread_id
|
||||
thread_create_user_thread(char *name, team_id pid, addr entry, void *args)
|
||||
{
|
||||
return _create_thread(name, pid, entry, args, -1, false);
|
||||
}
|
||||
|
||||
thread_id thread_create_kernel_thread(const char *name, int (*func)(void *), void *args)
|
||||
|
||||
thread_id
|
||||
thread_create_kernel_thread(const char *name, int (*func)(void *), void *args)
|
||||
{
|
||||
return _create_thread(name, team_get_kernel_team()->id, (addr)func, args, -1, true);
|
||||
}
|
||||
|
||||
thread_id thread_create_kernel_thread_etc(const char *name, int (*func)(void *), void *args, struct team *p)
|
||||
|
||||
thread_id
|
||||
thread_create_kernel_thread_etc(const char *name, int (*func)(void *), void *args, struct team *p)
|
||||
{
|
||||
return _create_thread(name, p->id, (addr)func, args, -1, true);
|
||||
}
|
||||
|
||||
int thread_suspend_thread(thread_id id)
|
||||
|
||||
int
|
||||
thread_suspend_thread(thread_id id)
|
||||
{
|
||||
int state;
|
||||
struct thread *t;
|
||||
@@ -458,7 +475,7 @@ int thread_suspend_thread(thread_id id)
|
||||
GRAB_THREAD_LOCK();
|
||||
|
||||
t = thread_get_current_thread();
|
||||
if(t->id != id) {
|
||||
if (t->id != id) {
|
||||
t = thread_get_thread_struct_locked(id);
|
||||
}
|
||||
|
||||
@@ -474,21 +491,21 @@ int thread_suspend_thread(thread_id id)
|
||||
global_resched = true;
|
||||
retval = B_NO_ERROR;
|
||||
}
|
||||
} else {
|
||||
} else
|
||||
retval = ERR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
RELEASE_THREAD_LOCK();
|
||||
restore_interrupts(state);
|
||||
|
||||
if(global_resched) {
|
||||
if (global_resched)
|
||||
smp_send_broadcast_ici(SMP_MSG_RESCHEDULE, 0, 0, 0, NULL, SMP_MSG_FLAG_SYNC);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int thread_resume_thread(thread_id id)
|
||||
|
||||
int
|
||||
thread_resume_thread(thread_id id)
|
||||
{
|
||||
int state;
|
||||
struct thread *t;
|
||||
@@ -498,15 +515,14 @@ int thread_resume_thread(thread_id id)
|
||||
GRAB_THREAD_LOCK();
|
||||
|
||||
t = thread_get_thread_struct_locked(id);
|
||||
if(t != NULL && t->state == B_THREAD_SUSPENDED) {
|
||||
if (t != NULL && t->state == B_THREAD_SUSPENDED) {
|
||||
t->state = B_THREAD_READY;
|
||||
t->next_state = B_THREAD_READY;
|
||||
|
||||
thread_enqueue_run_q(t);
|
||||
retval = B_NO_ERROR;
|
||||
} else {
|
||||
} else
|
||||
retval = ERR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
RELEASE_THREAD_LOCK();
|
||||
restore_interrupts(state);
|
||||
@@ -515,19 +531,20 @@ int thread_resume_thread(thread_id id)
|
||||
}
|
||||
|
||||
#ifndef NEW_SCHEDULER
|
||||
int thread_set_priority(thread_id id, int priority)
|
||||
int
|
||||
thread_set_priority(thread_id id, int32 priority)
|
||||
{
|
||||
struct thread *t;
|
||||
int retval;
|
||||
|
||||
// make sure the passed in priority is within bounds
|
||||
if(priority > B_MAX_PRIORITY)
|
||||
if (priority > B_MAX_PRIORITY)
|
||||
priority = B_MAX_PRIORITY;
|
||||
if(priority < B_MIN_PRIORITY)
|
||||
if (priority < B_MIN_PRIORITY)
|
||||
priority = B_MIN_PRIORITY;
|
||||
|
||||
t = thread_get_current_thread();
|
||||
if(t->id == id) {
|
||||
if (t->id == id) {
|
||||
// it's ourself, so we know we aren't in a run queue, and we can manipulate
|
||||
// our structure directly
|
||||
t->priority = priority;
|
||||
@@ -537,19 +554,18 @@ int thread_set_priority(thread_id id, int priority)
|
||||
GRAB_THREAD_LOCK();
|
||||
|
||||
t = thread_get_thread_struct_locked(id);
|
||||
if(t) {
|
||||
if(t->state == B_THREAD_READY && t->priority != priority) {
|
||||
if (t) {
|
||||
if (t->state == B_THREAD_READY && t->priority != priority) {
|
||||
// this thread is in a ready queue right now, so it needs to be reinserted
|
||||
thread_dequeue_id(&run_q[(t->priority + 1) >> 1], t->id);
|
||||
t->priority = priority;
|
||||
thread_enqueue_run_q(t);
|
||||
} else {
|
||||
} else
|
||||
t->priority = priority;
|
||||
}
|
||||
|
||||
retval = B_NO_ERROR;
|
||||
} else {
|
||||
} else
|
||||
retval = ERR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
RELEASE_THREAD_LOCK();
|
||||
restore_interrupts(state);
|
||||
@@ -643,9 +659,8 @@ dump_thread_info(int argc, char **argv)
|
||||
// XXX semi-hack
|
||||
_dump_thread_info((struct thread *)num);
|
||||
return 0;
|
||||
} else {
|
||||
} else
|
||||
id = num;
|
||||
}
|
||||
}
|
||||
|
||||
// walk through the thread list, trying to match name or id
|
||||
@@ -698,11 +713,11 @@ dump_next_thread_in_q(int argc, char **argv)
|
||||
}
|
||||
|
||||
dprintf("next thread in queue after thread @ %p\n", t);
|
||||
if (t->q_next != NULL) {
|
||||
if (t->q_next != NULL)
|
||||
_dump_thread_info(t->q_next);
|
||||
} else {
|
||||
else
|
||||
dprintf("NULL\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -718,11 +733,11 @@ dump_next_thread_in_all_list(int argc, char **argv)
|
||||
}
|
||||
|
||||
dprintf("next thread in global list after thread @ %p\n", t);
|
||||
if (t->all_next != NULL) {
|
||||
if (t->all_next != NULL)
|
||||
_dump_thread_info(t->all_next);
|
||||
} else {
|
||||
else
|
||||
dprintf("NULL\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -738,11 +753,11 @@ dump_next_thread_in_team(int argc, char **argv)
|
||||
}
|
||||
|
||||
dprintf("next thread in team after thread @ %p\n", t);
|
||||
if (t->team_next != NULL) {
|
||||
if (t->team_next != NULL)
|
||||
_dump_thread_info(t->team_next);
|
||||
} else {
|
||||
else
|
||||
dprintf("NULL\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -879,7 +894,7 @@ thread_init(kernel_args *ka)
|
||||
{
|
||||
char temp[64];
|
||||
|
||||
for(i = 0; i < num_death_stacks; i++) {
|
||||
for (i = 0; i < num_death_stacks; i++) {
|
||||
sprintf(temp, "death_stack%d", i);
|
||||
death_stacks[i].rid = vm_create_anonymous_region(vm_get_kernel_aspace_id(), temp,
|
||||
(void **)&death_stacks[i].address,
|
||||
@@ -1015,7 +1030,7 @@ thread_exit(int retcode)
|
||||
GRAB_TEAM_LOCK();
|
||||
remove_thread_from_team(p, t);
|
||||
insert_thread_into_team(team_get_kernel_team(), t);
|
||||
if(p->main_thread == t) {
|
||||
if (p->main_thread == t) {
|
||||
// this was main thread in this team
|
||||
delete_team = true;
|
||||
team_remove_team_from_hash(p);
|
||||
@@ -1133,9 +1148,8 @@ _thread_kill_thread(thread_id id, bool wait_on)
|
||||
if (t->id == thread_get_current_thread()->id)
|
||||
wait_on = false; // can't wait on ourself
|
||||
}
|
||||
} else {
|
||||
} else
|
||||
rc = ERR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
RELEASE_THREAD_LOCK();
|
||||
restore_interrupts(state);
|
||||
@@ -1170,25 +1184,6 @@ thread_kthread_exit(void)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
user_thread_wait_on_thread(thread_id id, int *uretcode)
|
||||
{
|
||||
int retcode;
|
||||
int rc, rc2;
|
||||
|
||||
if ((addr)uretcode >= KERNEL_BASE && (addr)uretcode <= KERNEL_TOP)
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
|
||||
rc = thread_wait_on_thread(id, &retcode);
|
||||
|
||||
rc2 = user_memcpy(uretcode, &retcode, sizeof(int));
|
||||
if (rc2 < 0)
|
||||
return rc2;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
thread_wait_on_thread(thread_id id, int *retcode)
|
||||
{
|
||||
@@ -1380,15 +1375,6 @@ thread_atkernel_exit(void)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
user_send_data(thread_id tid, int32 code, const void *buffer, size_t buffer_size)
|
||||
{
|
||||
if (((addr)buffer >= KERNEL_BASE) && ((addr)buffer <= KERNEL_TOP))
|
||||
return B_BAD_ADDRESS;
|
||||
return send_data(tid, code, buffer, buffer_size);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
send_data(thread_id tid, int32 code, const void *buffer, size_t buffer_size)
|
||||
{
|
||||
@@ -1461,28 +1447,6 @@ send_data(thread_id tid, int32 code, const void *buffer, size_t buffer_size)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
user_receive_data(thread_id *sender, void *buffer, size_t buffer_size)
|
||||
{
|
||||
thread_id ksender;
|
||||
status_t code;
|
||||
status_t rv;
|
||||
|
||||
if (((addr)sender >= KERNEL_BASE) && ((addr)sender <= KERNEL_TOP))
|
||||
return B_BAD_ADDRESS;
|
||||
if (((addr)buffer >= KERNEL_BASE) && ((addr)buffer <= KERNEL_TOP))
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
code = receive_data(&ksender, buffer, buffer_size);
|
||||
|
||||
rv = user_memcpy(sender, &ksender, sizeof(thread_id));
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
receive_data(thread_id *sender, void *buffer, size_t buffer_size)
|
||||
{
|
||||
@@ -1522,28 +1486,6 @@ has_data(thread_id thread)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
user_get_thread_info(thread_id id, thread_info *info)
|
||||
{
|
||||
thread_info kinfo;
|
||||
status_t rc = B_OK;
|
||||
status_t rc2;
|
||||
|
||||
if ((addr)info >= KERNEL_BASE && (addr)info <= KERNEL_TOP)
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
|
||||
rc = _get_thread_info(id, &kinfo, sizeof(thread_info));
|
||||
if (rc != B_OK)
|
||||
return rc;
|
||||
|
||||
rc2 = user_memcpy(info, &kinfo, sizeof(thread_info));
|
||||
if (rc2 < 0)
|
||||
return rc2;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
_get_thread_info(thread_id id, thread_info *info, size_t size)
|
||||
{
|
||||
@@ -1578,6 +1520,7 @@ _get_thread_info(thread_id id, thread_info *info, size_t size)
|
||||
info->kernel_time = t->kernel_time;
|
||||
info->stack_base = (void *)t->user_stack_base;
|
||||
info->stack_end = (void *)(t->user_stack_base + STACK_SIZE);
|
||||
|
||||
err:
|
||||
RELEASE_THREAD_LOCK();
|
||||
restore_interrupts(state);
|
||||
@@ -1586,39 +1529,6 @@ err:
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
user_get_next_thread_info(team_id team, int32 *cookie, thread_info *info)
|
||||
{
|
||||
int32 kcookie;
|
||||
thread_info kinfo;
|
||||
status_t rc = B_OK;
|
||||
status_t rc2;
|
||||
|
||||
if ((addr)cookie >= KERNEL_BASE && (addr)cookie <= KERNEL_TOP)
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
if ((addr)info >= KERNEL_BASE && (addr)info <= KERNEL_TOP)
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
|
||||
rc2 = user_memcpy(&kcookie, cookie, sizeof(int32));
|
||||
if (rc2 < 0)
|
||||
return rc2;
|
||||
|
||||
rc = _get_next_thread_info(team, &kcookie, &kinfo, sizeof(thread_info));
|
||||
if (rc != B_OK)
|
||||
return rc;
|
||||
|
||||
rc2 = user_memcpy(cookie, &kcookie, sizeof(int32));
|
||||
if (rc2 < 0)
|
||||
return rc2;
|
||||
|
||||
rc2 = user_memcpy(info, &kinfo, sizeof(thread_info));
|
||||
if (rc2 < 0)
|
||||
return rc2;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
_get_next_thread_info(team_id tid, int32 *cookie, thread_info *info, size_t size)
|
||||
{
|
||||
@@ -1680,38 +1590,13 @@ err:
|
||||
}
|
||||
|
||||
|
||||
int user_getrlimit(int resource, struct rlimit * urlp)
|
||||
int
|
||||
getrlimit(int resource, struct rlimit * rlp)
|
||||
{
|
||||
int ret;
|
||||
struct rlimit rl;
|
||||
|
||||
if (urlp == NULL) {
|
||||
return EINVAL;
|
||||
}
|
||||
if((addr)urlp >= KERNEL_BASE && (addr)urlp <= KERNEL_TOP) {
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
}
|
||||
|
||||
ret = getrlimit(resource, &rl);
|
||||
|
||||
if (ret == 0) {
|
||||
ret = user_memcpy(urlp, &rl, sizeof(struct rlimit));
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int getrlimit(int resource, struct rlimit * rlp)
|
||||
{
|
||||
if (!rlp) {
|
||||
if (!rlp)
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(resource) {
|
||||
switch (resource) {
|
||||
case RLIMIT_NOFILE:
|
||||
return vfs_getrlimit(resource, rlp);
|
||||
|
||||
@@ -1722,33 +1607,14 @@ int getrlimit(int resource, struct rlimit * rlp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int user_setrlimit(int resource, const struct rlimit * urlp)
|
||||
|
||||
int
|
||||
setrlimit(int resource, const struct rlimit * rlp)
|
||||
{
|
||||
int err;
|
||||
struct rlimit rl;
|
||||
|
||||
if (urlp == NULL) {
|
||||
return EINVAL;
|
||||
}
|
||||
if((addr)urlp >= KERNEL_BASE && (addr)urlp <= KERNEL_TOP) {
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
}
|
||||
|
||||
err = user_memcpy(&rl, urlp, sizeof(struct rlimit));
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return setrlimit(resource, &rl);
|
||||
}
|
||||
|
||||
int setrlimit(int resource, const struct rlimit * rlp)
|
||||
{
|
||||
if (!rlp) {
|
||||
if (!rlp)
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(resource) {
|
||||
switch (resource) {
|
||||
case RLIMIT_NOFILE:
|
||||
return vfs_setrlimit(resource, rlp);
|
||||
|
||||
@@ -1758,3 +1624,181 @@ int setrlimit(int resource, const struct rlimit * rlp)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
/* user calls */
|
||||
|
||||
|
||||
thread_id
|
||||
user_thread_create_user_thread(addr entry, team_id pid, const char *uname, int priority,
|
||||
void *args)
|
||||
{
|
||||
char name[SYS_MAX_OS_NAME_LEN];
|
||||
int rc;
|
||||
|
||||
if ((addr)uname >= KERNEL_BASE && (addr)uname <= KERNEL_TOP)
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
if (entry >= KERNEL_BASE && entry <= KERNEL_TOP)
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
|
||||
rc = user_strncpy(name, uname, SYS_MAX_OS_NAME_LEN-1);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
name[SYS_MAX_OS_NAME_LEN-1] = 0;
|
||||
|
||||
return _create_thread(name, pid, entry, args, priority, false);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
user_get_thread_info(thread_id id, thread_info *info)
|
||||
{
|
||||
thread_info kinfo;
|
||||
status_t rc = B_OK;
|
||||
status_t rc2;
|
||||
|
||||
if ((addr)info >= KERNEL_BASE && (addr)info <= KERNEL_TOP)
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
|
||||
rc = _get_thread_info(id, &kinfo, sizeof(thread_info));
|
||||
if (rc != B_OK)
|
||||
return rc;
|
||||
|
||||
rc2 = user_memcpy(info, &kinfo, sizeof(thread_info));
|
||||
if (rc2 < 0)
|
||||
return rc2;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
user_get_next_thread_info(team_id team, int32 *cookie, thread_info *info)
|
||||
{
|
||||
int32 kcookie;
|
||||
thread_info kinfo;
|
||||
status_t rc = B_OK;
|
||||
status_t rc2;
|
||||
|
||||
if ((addr)cookie >= KERNEL_BASE && (addr)cookie <= KERNEL_TOP)
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
if ((addr)info >= KERNEL_BASE && (addr)info <= KERNEL_TOP)
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
|
||||
rc2 = user_memcpy(&kcookie, cookie, sizeof(int32));
|
||||
if (rc2 < 0)
|
||||
return rc2;
|
||||
|
||||
rc = _get_next_thread_info(team, &kcookie, &kinfo, sizeof(thread_info));
|
||||
if (rc != B_OK)
|
||||
return rc;
|
||||
|
||||
rc2 = user_memcpy(cookie, &kcookie, sizeof(int32));
|
||||
if (rc2 < 0)
|
||||
return rc2;
|
||||
|
||||
rc2 = user_memcpy(info, &kinfo, sizeof(thread_info));
|
||||
if (rc2 < 0)
|
||||
return rc2;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
user_thread_wait_on_thread(thread_id id, int *uretcode)
|
||||
{
|
||||
int retcode;
|
||||
int rc, rc2;
|
||||
|
||||
if ((addr)uretcode >= KERNEL_BASE && (addr)uretcode <= KERNEL_TOP)
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
|
||||
rc = thread_wait_on_thread(id, &retcode);
|
||||
|
||||
rc2 = user_memcpy(uretcode, &retcode, sizeof(int));
|
||||
if (rc2 < 0)
|
||||
return rc2;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
user_send_data(thread_id tid, int32 code, const void *buffer, size_t buffer_size)
|
||||
{
|
||||
if (((addr)buffer >= KERNEL_BASE) && ((addr)buffer <= KERNEL_TOP))
|
||||
return B_BAD_ADDRESS;
|
||||
return send_data(tid, code, buffer, buffer_size);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
user_receive_data(thread_id *sender, void *buffer, size_t buffer_size)
|
||||
{
|
||||
thread_id ksender;
|
||||
status_t code;
|
||||
status_t rv;
|
||||
|
||||
if (((addr)sender >= KERNEL_BASE) && ((addr)sender <= KERNEL_TOP))
|
||||
return B_BAD_ADDRESS;
|
||||
if (((addr)buffer >= KERNEL_BASE) && ((addr)buffer <= KERNEL_TOP))
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
code = receive_data(&ksender, buffer, buffer_size);
|
||||
|
||||
rv = user_memcpy(sender, &ksender, sizeof(thread_id));
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
user_getrlimit(int resource, struct rlimit * urlp)
|
||||
{
|
||||
struct rlimit rl;
|
||||
int ret;
|
||||
|
||||
if (urlp == NULL)
|
||||
return EINVAL;
|
||||
|
||||
if ((addr)urlp >= KERNEL_BASE && (addr)urlp <= KERNEL_TOP)
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
|
||||
ret = getrlimit(resource, &rl);
|
||||
|
||||
if (ret == 0) {
|
||||
ret = user_memcpy(urlp, &rl, sizeof(struct rlimit));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
user_setrlimit(int resource, const struct rlimit * urlp)
|
||||
{
|
||||
struct rlimit rl;
|
||||
int err;
|
||||
|
||||
if (urlp == NULL)
|
||||
return EINVAL;
|
||||
|
||||
if ((addr)urlp >= KERNEL_BASE && (addr)urlp <= KERNEL_TOP)
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
|
||||
err = user_memcpy(&rl, urlp, sizeof(struct rlimit));
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return setrlimit(resource, &rl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user