receive_data() is now interruptible (as reported by Starr Kline) - not tested!

Cleaned up _get_thread_info() & _get_next_thread_info() - factored out
the thread_info setup into fill_thread_info().
Is now using team_is_alive() instead of team_get_team_struct().
Replaced SYS_MAX_OS_NAME_LEN with B_OS_NAME_LENGTH.
Banned strncpy() in favor for strlcpy().


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6683 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2004-02-23 03:46:42 +00:00
parent 7ba272b8b3
commit 592a6437f2

View File

@ -166,8 +166,7 @@ create_thread_struct(const char *name)
goto err; goto err;
} }
strncpy(&t->name[0], name, SYS_MAX_OS_NAME_LEN-1); strlcpy(t->name, name, B_OS_NAME_LENGTH);
t->name[SYS_MAX_OS_NAME_LEN-1] = 0;
t->id = atomic_add(&next_thread_id, 1); t->id = atomic_add(&next_thread_id, 1);
t->team = NULL; t->team = NULL;
@ -767,7 +766,7 @@ thread_exit(void)
// cycle through and signal kill on each of the threads // cycle through and signal kill on each of the threads
// XXX this can be optimized. There's got to be a better solution. // XXX this can be optimized. There's got to be a better solution.
struct thread *temp_thread; struct thread *temp_thread;
char death_sem_name[SYS_MAX_OS_NAME_LEN]; char death_sem_name[B_OS_NAME_LENGTH];
sprintf(death_sem_name, "team %ld death sem", team->id); sprintf(death_sem_name, "team %ld death sem", team->id);
team->death_sem = create_sem(0, death_sem_name); team->death_sem = create_sem(0, death_sem_name);
@ -1212,21 +1211,23 @@ send_data(thread_id tid, int32 code, const void *buffer, size_t buffer_size)
status_t status_t
receive_data(thread_id *sender, void *buffer, size_t buffer_size) receive_data(thread_id *sender, void *buffer, size_t bufferSize)
{ {
struct thread *t = thread_get_current_thread(); struct thread *t = thread_get_current_thread();
status_t rv; status_t status;
size_t size; size_t size;
int32 code; int32 code;
acquire_sem(t->msg.read_sem); status = acquire_sem_etc(t->msg.read_sem, 1, B_CAN_INTERRUPT, 0);
if (status < B_OK)
return status;
size = min(buffer_size, t->msg.size); size = min(bufferSize, t->msg.size);
rv = cbuf_user_memcpy_from_chain(buffer, t->msg.buffer, 0, size); status = cbuf_user_memcpy_from_chain(buffer, t->msg.buffer, 0, size);
if (rv < 0) { if (status < B_OK) {
cbuf_free_chain(t->msg.buffer); cbuf_free_chain(t->msg.buffer);
release_sem(t->msg.write_sem); release_sem(t->msg.write_sem);
return rv; return status;
} }
*sender = t->msg.sender; *sender = t->msg.sender;
@ -1251,107 +1252,107 @@ has_data(thread_id thread)
} }
status_t /** Fills the thread_info structure with information from the specified
_get_thread_info(thread_id id, thread_info *info, size_t size) * thread.
* The thread lock must be held when called.
*/
static void
fill_thread_info(struct thread *thread, thread_info *info, size_t size)
{ {
cpu_status state; info->thread = thread->id;
status_t rc = B_OK; info->team = thread->team->id;
struct thread *t;
state = disable_interrupts(); strlcpy(info->name, thread->name, B_OS_NAME_LENGTH);
GRAB_THREAD_LOCK();
t = thread_get_thread_struct_locked(id); if (thread->state == B_THREAD_WAITING) {
if (!t) { if (thread->sem_blocking == gSnoozeSem)
rc = B_BAD_VALUE;
goto err;
}
info->thread = t->id;
info->team = t->team->id;
strncpy(info->name, t->name, B_OS_NAME_LENGTH);
info->name[B_OS_NAME_LENGTH - 1] = '\0';
if (t->state == B_THREAD_WAITING) {
if (t->sem_blocking == gSnoozeSem)
info->state = B_THREAD_ASLEEP; info->state = B_THREAD_ASLEEP;
else if (t->sem_blocking == t->msg.read_sem) else if (thread->sem_blocking == thread->msg.read_sem)
info->state = B_THREAD_RECEIVING; info->state = B_THREAD_RECEIVING;
else else
info->state = B_THREAD_WAITING; info->state = B_THREAD_WAITING;
} else } else
info->state = t->state; info->state = thread->state;
info->priority = t->priority;
info->sem = t->sem_blocking;
info->user_time = t->user_time;
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: info->priority = thread->priority;
RELEASE_THREAD_LOCK(); info->sem = thread->sem_blocking;
restore_interrupts(state); info->user_time = thread->user_time;
info->kernel_time = thread->kernel_time;
return rc; info->stack_base = (void *)thread->user_stack_base;
info->stack_end = (void *)(thread->user_stack_base + STACK_SIZE);
} }
status_t status_t
_get_next_thread_info(team_id tid, int32 *cookie, thread_info *info, size_t size) _get_thread_info(thread_id id, thread_info *info, size_t size)
{ {
status_t status = B_OK;
struct thread *thread;
cpu_status state; cpu_status state;
int slot;
status_t rc = B_BAD_VALUE;
struct team *team;
struct thread *t = NULL;
if (tid == 0) if (info == NULL || size != sizeof(thread_info) || id < B_OK)
tid = team_get_current_team_id();
team = team_get_team_struct(tid);
if (!team)
return B_BAD_VALUE; return B_BAD_VALUE;
state = disable_interrupts(); state = disable_interrupts();
GRAB_THREAD_LOCK(); GRAB_THREAD_LOCK();
if (*cookie == 0) thread = thread_get_thread_struct_locked(id);
slot = 0; if (thread == NULL) {
else { status = B_BAD_VALUE;
slot = *cookie; goto err;
if (slot >= next_thread_id)
goto err;
} }
while ((slot < next_thread_id) && (!(t = thread_get_thread_struct_locked(slot)) || (t->team->id != tid))) fill_thread_info(thread, info, size);
slot++;
if ((t) && (t->team->id == tid)) {
info->thread = t->id;
info->team = t->team->id;
strncpy(info->name, t->name, B_OS_NAME_LENGTH);
info->name[B_OS_NAME_LENGTH - 1] = '\0';
if (t->state == B_THREAD_WAITING) {
if (t->sem_blocking == gSnoozeSem)
info->state = B_THREAD_ASLEEP;
else if (t->sem_blocking == t->msg.read_sem)
info->state = B_THREAD_RECEIVING;
else
info->state = B_THREAD_WAITING;
} else
info->state = t->state;
info->priority = t->priority;
info->sem = t->sem_blocking;
info->user_time = t->user_time;
info->kernel_time = t->kernel_time;
info->stack_base = (void *)t->user_stack_base;
info->stack_end = (void *)(t->user_stack_base + STACK_SIZE);
slot++;
*cookie = slot;
rc = B_OK;
}
err: err:
RELEASE_THREAD_LOCK(); RELEASE_THREAD_LOCK();
restore_interrupts(state); restore_interrupts(state);
return rc; return status;
}
status_t
_get_next_thread_info(team_id team, int32 *_cookie, thread_info *info, size_t size)
{
status_t status = B_BAD_VALUE;
struct thread *thread = NULL;
cpu_status state;
int slot;
if (info == NULL || size != sizeof(thread_info) || team < B_OK)
return B_BAD_VALUE;
if (team == B_CURRENT_TEAM)
team = team_get_current_team_id();
else if (!team_is_valid(team))
return B_BAD_VALUE;
slot = *_cookie;
state = disable_interrupts();
GRAB_THREAD_LOCK();
if (slot >= next_thread_id)
goto err;
while (slot < next_thread_id
&& (!(thread = thread_get_thread_struct_locked(slot)) || thread->team->id != team))
slot++;
if (thread != NULL && thread->team->id == team) {
fill_thread_info(thread, info, size);
*_cookie = slot + 1;
status = B_OK;
}
err:
RELEASE_THREAD_LOCK();
restore_interrupts(state);
return status;
} }
@ -1577,11 +1578,11 @@ user_set_thread_priority(thread_id thread, int32 newPriority)
thread_id thread_id
user_spawn_thread(thread_func entry, const char *userName, int32 priority, void *data1, void *data2) user_spawn_thread(thread_func entry, const char *userName, int32 priority, void *data1, void *data2)
{ {
char name[SYS_MAX_OS_NAME_LEN]; char name[B_OS_NAME_LENGTH];
if (!IS_USER_ADDRESS(entry) || entry == NULL if (!IS_USER_ADDRESS(entry) || entry == NULL
|| !IS_USER_ADDRESS(userName) || !IS_USER_ADDRESS(userName)
|| user_strlcpy(name, userName, SYS_MAX_OS_NAME_LEN) < B_OK) || user_strlcpy(name, userName, B_OS_NAME_LENGTH) < B_OK)
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
return create_thread(name, thread_get_current_thread()->team->id, entry, data1, data2, priority, false); return create_thread(name, thread_get_current_thread()->team->id, entry, data1, data2, priority, false);