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:
Axel Dörfler
2002-10-05 19:38:42 +00:00
parent 362032afbf
commit 48d81f1962
+303 -259
View File
@@ -81,11 +81,10 @@ static struct thread *thread_get_thread_struct_locked(thread_id id);
static void thread_kthread_exit(void); static void thread_kthread_exit(void);
static void deliver_signal(struct thread *t, int signal); static void deliver_signal(struct thread *t, int signal);
#ifdef NEW_SCHEDULER
#endif /* NEW_SCHEDULER */
// insert a thread onto the tail of a queue // 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; t->q_next = NULL;
if(q->head == 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; return q->head;
} }
struct thread *thread_dequeue(struct thread_queue *q)
struct thread *
thread_dequeue(struct thread_queue *q)
{ {
struct thread *t; struct thread *t;
t = q->head; t = q->head;
if(t != NULL) { if (t != NULL) {
q->head = t->q_next; q->head = t->q_next;
if(q->tail == t) if(q->tail == t)
q->tail = NULL; q->tail = NULL;
@@ -115,20 +118,22 @@ struct thread *thread_dequeue(struct thread_queue *q)
return t; 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 *t;
struct thread *last = NULL; struct thread *last = NULL;
t = q->head; t = q->head;
while(t != NULL) { while (t != NULL) {
if(t->id == thr_id) { if (t->id == thr_id) {
if(last == NULL) { if (last == NULL)
q->head = t->q_next; q->head = t->q_next;
} else { else
last->q_next = t->q_next; last->q_next = t->q_next;
}
if(q->tail == t) if (q->tail == t)
q->tail = last; q->tail = last;
break; break;
} }
@@ -139,51 +144,59 @@ struct thread *thread_dequeue_id(struct thread_queue *q, thread_id thr_id)
} }
#ifndef NEW_SCHEDULER #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]); 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 // these shouldn't exist
if(t->priority > B_MAX_PRIORITY) if (t->priority > B_MAX_PRIORITY)
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; t->priority = B_MIN_PRIORITY;
thread_enqueue(t, &run_q[(t->priority + 1) >> 1]); 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]); return thread_dequeue(&run_q[(priority + 1) >> 1]);
} }
#endif /* not NEW_SCHEDULER */ #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; t->team_next = p->thread_list;
p->thread_list = t; p->thread_list = t;
p->num_threads++; p->num_threads++;
if(p->num_threads == 1) { if (p->num_threads == 1) {
// this was the first thread // this was the first thread
p->main_thread = t; p->main_thread = t;
} }
t->team = p; 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; struct thread *temp, *last = NULL;
for(temp = p->thread_list; temp != NULL; temp = temp->team_next) { for (temp = p->thread_list; temp != NULL; temp = temp->team_next) {
if(temp == t) { if (temp == t) {
if(last == NULL) { if (last == NULL)
p->thread_list = temp->team_next; p->thread_list = temp->team_next;
} else { else
last->team_next = temp->team_next; last->team_next = temp->team_next;
}
p->num_threads--; p->num_threads--;
break; 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; struct thread *t = _t;
const struct thread_key *key = _key; const struct thread_key *key = _key;
if(t->id == key->id) return 0; if (t->id == key->id)
else return 1; 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; struct thread *t = _t;
const struct thread_key *key = _key; const struct thread_key *key = _key;
if(t != NULL) if (t != NULL)
return (t->id % range); 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; struct thread *t;
int state; int state;
@@ -223,9 +244,9 @@ static struct thread *create_thread_struct(const char *name)
RELEASE_THREAD_LOCK(); RELEASE_THREAD_LOCK();
restore_interrupts(state); restore_interrupts(state);
if(t == NULL) { if (t == NULL) {
t = (struct thread *)kmalloc(sizeof(struct thread)); t = (struct thread *)kmalloc(sizeof(struct thread));
if(t == NULL) if (t == NULL)
goto err; goto err;
} }
@@ -253,7 +274,7 @@ static struct thread *create_thread_struct(const char *name)
sprintf(temp, "thread_0x%lx_retcode_sem", t->id); sprintf(temp, "thread_0x%lx_retcode_sem", t->id);
t->return_code_sem = create_sem(0, temp); t->return_code_sem = create_sem(0, temp);
if(t->return_code_sem < 0) if (t->return_code_sem < 0)
goto err1; goto err1;
sprintf(temp, "%s data write sem", t->name); 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) if (t->msg.read_sem < 0)
goto err3; goto err3;
if(arch_thread_init_thread_struct(t) < 0) if (arch_thread_init_thread_struct(t) < 0)
goto err4; goto err4;
return t; return t;
@@ -283,7 +304,9 @@ err:
return NULL; return NULL;
} }
static void delete_thread_struct(struct thread *t)
static void
delete_thread_struct(struct thread *t)
{ {
if (t->return_code_sem >= 0) if (t->return_code_sem >= 0)
delete_sem_etc(t->return_code_sem, -1); delete_sem_etc(t->return_code_sem, -1);
@@ -294,7 +317,9 @@ static void delete_thread_struct(struct thread *t)
kfree(t); kfree(t);
} }
static int _create_user_thread_kentry(void)
static int
_create_user_thread_kentry(void)
{ {
struct thread *t; struct thread *t;
@@ -310,7 +335,9 @@ static int _create_user_thread_kentry(void)
return 0; return 0;
} }
static int _create_kernel_thread_kentry(void)
static int
_create_kernel_thread_kentry(void)
{ {
int (*func)(void *args); int (*func)(void *args);
struct thread *t; struct thread *t;
@@ -338,6 +365,7 @@ _create_thread(const char *name, team_id pid, addr entry, void *args, int priori
return ENOMEM; return ENOMEM;
t->priority = priority == -1 ? B_NORMAL_PRIORITY : priority; 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 = THREAD_STATE_BIRTH;
t->state = B_THREAD_SUSPENDED; // Is this right? t->state = B_THREAD_SUSPENDED; // Is this right?
t->next_state = B_THREAD_SUSPENDED; 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(); GRAB_TEAM_LOCK();
// look at the team, make sure it's not being deleted // look at the team, make sure it's not being deleted
p = team_get_team_struct_locked(pid); 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); insert_thread_into_team(p, t);
} else { else
abort = true; abort = true;
}
RELEASE_TEAM_LOCK(); RELEASE_TEAM_LOCK();
if (abort) { if (abort) {
GRAB_THREAD_LOCK(); GRAB_THREAD_LOCK();
@@ -413,41 +441,30 @@ _create_thread(const char *name, team_id pid, addr entry, void *args, int priori
return t->id; 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) thread_id
return ERR_VM_BAD_USER_MEMORY; thread_create_user_thread(char *name, team_id pid, addr entry, void *args)
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)
{ {
return _create_thread(name, pid, entry, args, -1, false); 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); 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); 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; int state;
struct thread *t; struct thread *t;
@@ -458,7 +475,7 @@ int thread_suspend_thread(thread_id id)
GRAB_THREAD_LOCK(); GRAB_THREAD_LOCK();
t = thread_get_current_thread(); t = thread_get_current_thread();
if(t->id != id) { if (t->id != id) {
t = thread_get_thread_struct_locked(id); t = thread_get_thread_struct_locked(id);
} }
@@ -474,21 +491,21 @@ int thread_suspend_thread(thread_id id)
global_resched = true; global_resched = true;
retval = B_NO_ERROR; retval = B_NO_ERROR;
} }
} else { } else
retval = ERR_INVALID_HANDLE; retval = ERR_INVALID_HANDLE;
}
RELEASE_THREAD_LOCK(); RELEASE_THREAD_LOCK();
restore_interrupts(state); restore_interrupts(state);
if(global_resched) { if (global_resched)
smp_send_broadcast_ici(SMP_MSG_RESCHEDULE, 0, 0, 0, NULL, SMP_MSG_FLAG_SYNC); smp_send_broadcast_ici(SMP_MSG_RESCHEDULE, 0, 0, 0, NULL, SMP_MSG_FLAG_SYNC);
}
return retval; return retval;
} }
int thread_resume_thread(thread_id id)
int
thread_resume_thread(thread_id id)
{ {
int state; int state;
struct thread *t; struct thread *t;
@@ -498,15 +515,14 @@ int thread_resume_thread(thread_id id)
GRAB_THREAD_LOCK(); GRAB_THREAD_LOCK();
t = thread_get_thread_struct_locked(id); 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->state = B_THREAD_READY;
t->next_state = B_THREAD_READY; t->next_state = B_THREAD_READY;
thread_enqueue_run_q(t); thread_enqueue_run_q(t);
retval = B_NO_ERROR; retval = B_NO_ERROR;
} else { } else
retval = ERR_INVALID_HANDLE; retval = ERR_INVALID_HANDLE;
}
RELEASE_THREAD_LOCK(); RELEASE_THREAD_LOCK();
restore_interrupts(state); restore_interrupts(state);
@@ -515,19 +531,20 @@ int thread_resume_thread(thread_id id)
} }
#ifndef NEW_SCHEDULER #ifndef NEW_SCHEDULER
int thread_set_priority(thread_id id, int priority) int
thread_set_priority(thread_id id, int32 priority)
{ {
struct thread *t; struct thread *t;
int retval; int retval;
// make sure the passed in priority is within bounds // make sure the passed in priority is within bounds
if(priority > B_MAX_PRIORITY) if (priority > B_MAX_PRIORITY)
priority = B_MAX_PRIORITY; priority = B_MAX_PRIORITY;
if(priority < B_MIN_PRIORITY) if (priority < B_MIN_PRIORITY)
priority = B_MIN_PRIORITY; priority = B_MIN_PRIORITY;
t = thread_get_current_thread(); 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 // it's ourself, so we know we aren't in a run queue, and we can manipulate
// our structure directly // our structure directly
t->priority = priority; t->priority = priority;
@@ -537,19 +554,18 @@ int thread_set_priority(thread_id id, int priority)
GRAB_THREAD_LOCK(); GRAB_THREAD_LOCK();
t = thread_get_thread_struct_locked(id); t = thread_get_thread_struct_locked(id);
if(t) { if (t) {
if(t->state == B_THREAD_READY && t->priority != priority) { if (t->state == B_THREAD_READY && t->priority != priority) {
// this thread is in a ready queue right now, so it needs to be reinserted // 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); thread_dequeue_id(&run_q[(t->priority + 1) >> 1], t->id);
t->priority = priority; t->priority = priority;
thread_enqueue_run_q(t); thread_enqueue_run_q(t);
} else { } else
t->priority = priority; t->priority = priority;
}
retval = B_NO_ERROR; retval = B_NO_ERROR;
} else { } else
retval = ERR_INVALID_HANDLE; retval = ERR_INVALID_HANDLE;
}
RELEASE_THREAD_LOCK(); RELEASE_THREAD_LOCK();
restore_interrupts(state); restore_interrupts(state);
@@ -643,9 +659,8 @@ dump_thread_info(int argc, char **argv)
// XXX semi-hack // XXX semi-hack
_dump_thread_info((struct thread *)num); _dump_thread_info((struct thread *)num);
return 0; return 0;
} else { } else
id = num; id = num;
}
} }
// walk through the thread list, trying to match name or id // 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); 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); _dump_thread_info(t->q_next);
} else { else
dprintf("NULL\n"); dprintf("NULL\n");
}
return 0; 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); 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); _dump_thread_info(t->all_next);
} else { else
dprintf("NULL\n"); dprintf("NULL\n");
}
return 0; 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); 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); _dump_thread_info(t->team_next);
} else { else
dprintf("NULL\n"); dprintf("NULL\n");
}
return 0; return 0;
} }
@@ -879,7 +894,7 @@ thread_init(kernel_args *ka)
{ {
char temp[64]; 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); sprintf(temp, "death_stack%d", i);
death_stacks[i].rid = vm_create_anonymous_region(vm_get_kernel_aspace_id(), temp, death_stacks[i].rid = vm_create_anonymous_region(vm_get_kernel_aspace_id(), temp,
(void **)&death_stacks[i].address, (void **)&death_stacks[i].address,
@@ -1015,7 +1030,7 @@ thread_exit(int retcode)
GRAB_TEAM_LOCK(); GRAB_TEAM_LOCK();
remove_thread_from_team(p, t); remove_thread_from_team(p, t);
insert_thread_into_team(team_get_kernel_team(), 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 // this was main thread in this team
delete_team = true; delete_team = true;
team_remove_team_from_hash(p); 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) if (t->id == thread_get_current_thread()->id)
wait_on = false; // can't wait on ourself wait_on = false; // can't wait on ourself
} }
} else { } else
rc = ERR_INVALID_HANDLE; rc = ERR_INVALID_HANDLE;
}
RELEASE_THREAD_LOCK(); RELEASE_THREAD_LOCK();
restore_interrupts(state); 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 int
thread_wait_on_thread(thread_id id, int *retcode) 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 status_t
send_data(thread_id tid, int32 code, const void *buffer, size_t buffer_size) 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 status_t
receive_data(thread_id *sender, void *buffer, size_t buffer_size) 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 status_t
_get_thread_info(thread_id id, thread_info *info, size_t size) _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->kernel_time = t->kernel_time;
info->stack_base = (void *)t->user_stack_base; info->stack_base = (void *)t->user_stack_base;
info->stack_end = (void *)(t->user_stack_base + STACK_SIZE); info->stack_end = (void *)(t->user_stack_base + STACK_SIZE);
err: err:
RELEASE_THREAD_LOCK(); RELEASE_THREAD_LOCK();
restore_interrupts(state); 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 status_t
_get_next_thread_info(team_id tid, int32 *cookie, thread_info *info, size_t size) _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; if (!rlp)
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) {
return -1; return -1;
}
switch(resource) { switch (resource) {
case RLIMIT_NOFILE: case RLIMIT_NOFILE:
return vfs_getrlimit(resource, rlp); return vfs_getrlimit(resource, rlp);
@@ -1722,33 +1607,14 @@ int getrlimit(int resource, struct rlimit * rlp)
return 0; return 0;
} }
int user_setrlimit(int resource, const struct rlimit * urlp)
int
setrlimit(int resource, const struct rlimit * rlp)
{ {
int err; if (!rlp)
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) {
return -1; return -1;
}
switch(resource) { switch (resource) {
case RLIMIT_NOFILE: case RLIMIT_NOFILE:
return vfs_setrlimit(resource, rlp); return vfs_setrlimit(resource, rlp);
@@ -1758,3 +1624,181 @@ int setrlimit(int resource, const struct rlimit * rlp)
return 0; 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);
}