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:
parent
7ba272b8b3
commit
592a6437f2
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user