The debugger command "threads" now accepts an argument that let's you filter the
threads listed by team ID. Also, the thread's team is now printed in the list as well. Minor cleanup (renamed "t" to "thread" where appropriate). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14629 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
5d1bd031a2
commit
dcdebb933e
@ -87,16 +87,17 @@ static void thread_kthread_exit(void);
|
||||
*/
|
||||
|
||||
static void
|
||||
insert_thread_into_team(struct team *p, struct thread *t)
|
||||
insert_thread_into_team(struct team *team, struct thread *thread)
|
||||
{
|
||||
t->team_next = p->thread_list;
|
||||
p->thread_list = t;
|
||||
p->num_threads++;
|
||||
if (p->num_threads == 1) {
|
||||
thread->team_next = team->thread_list;
|
||||
team->thread_list = thread;
|
||||
team->num_threads++;
|
||||
|
||||
if (team->num_threads == 1) {
|
||||
// this was the first thread
|
||||
p->main_thread = t;
|
||||
team->main_thread = thread;
|
||||
}
|
||||
t->team = p;
|
||||
thread->team = team;
|
||||
}
|
||||
|
||||
|
||||
@ -105,18 +106,18 @@ insert_thread_into_team(struct team *p, struct thread *t)
|
||||
*/
|
||||
|
||||
static void
|
||||
remove_thread_from_team(struct team *p, struct thread *t)
|
||||
remove_thread_from_team(struct team *team, struct thread *thread)
|
||||
{
|
||||
struct thread *temp, *last = NULL;
|
||||
|
||||
for (temp = p->thread_list; temp != NULL; temp = temp->team_next) {
|
||||
if (temp == t) {
|
||||
for (temp = team->thread_list; temp != NULL; temp = temp->team_next) {
|
||||
if (temp == thread) {
|
||||
if (last == NULL)
|
||||
p->thread_list = temp->team_next;
|
||||
team->thread_list = temp->team_next;
|
||||
else
|
||||
last->team_next = temp->team_next;
|
||||
|
||||
p->num_threads--;
|
||||
team->num_threads--;
|
||||
break;
|
||||
}
|
||||
last = temp;
|
||||
@ -127,10 +128,10 @@ remove_thread_from_team(struct team *p, struct thread *t)
|
||||
static int
|
||||
thread_struct_compare(void *_t, const void *_key)
|
||||
{
|
||||
struct thread *t = _t;
|
||||
struct thread *thread = _t;
|
||||
const struct thread_key *key = _key;
|
||||
|
||||
if (t->id == key->id)
|
||||
if (thread->id == key->id)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
@ -140,11 +141,11 @@ thread_struct_compare(void *_t, const void *_key)
|
||||
static uint32
|
||||
thread_struct_hash(void *_t, const void *_key, uint32 range)
|
||||
{
|
||||
struct thread *t = _t;
|
||||
struct thread *thread = _t;
|
||||
const struct thread_key *key = _key;
|
||||
|
||||
if (t != NULL)
|
||||
return t->id % range;
|
||||
if (thread != NULL)
|
||||
return thread->id % range;
|
||||
|
||||
return (uint32)key->id % range;
|
||||
}
|
||||
@ -159,83 +160,83 @@ thread_struct_hash(void *_t, const void *_key, uint32 range)
|
||||
static struct thread *
|
||||
create_thread_struct(const char *name, thread_id threadID)
|
||||
{
|
||||
struct thread *t;
|
||||
struct thread *thread;
|
||||
cpu_status state;
|
||||
char temp[64];
|
||||
|
||||
state = disable_interrupts();
|
||||
GRAB_THREAD_LOCK();
|
||||
t = thread_dequeue(&dead_q);
|
||||
thread = thread_dequeue(&dead_q);
|
||||
RELEASE_THREAD_LOCK();
|
||||
restore_interrupts(state);
|
||||
|
||||
if (t == NULL) {
|
||||
t = (struct thread *)malloc(sizeof(struct thread));
|
||||
if (t == NULL)
|
||||
if (thread == NULL) {
|
||||
thread = (struct thread *)malloc(sizeof(struct thread));
|
||||
if (thread == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (name != NULL)
|
||||
strlcpy(t->name, name, B_OS_NAME_LENGTH);
|
||||
strlcpy(thread->name, name, B_OS_NAME_LENGTH);
|
||||
else
|
||||
strcpy(t->name, "unnamed thread");
|
||||
strcpy(thread->name, "unnamed thread");
|
||||
|
||||
t->id = threadID >= 0 ? threadID : allocate_thread_id();
|
||||
t->team = NULL;
|
||||
t->cpu = NULL;
|
||||
t->sem.blocking = -1;
|
||||
t->fault_handler = 0;
|
||||
t->page_faults_allowed = 1;
|
||||
t->kernel_stack_area = -1;
|
||||
t->kernel_stack_base = 0;
|
||||
t->user_stack_area = -1;
|
||||
t->user_stack_base = 0;
|
||||
t->user_local_storage = 0;
|
||||
t->kernel_errno = 0;
|
||||
t->team_next = NULL;
|
||||
t->queue_next = NULL;
|
||||
t->priority = -1;
|
||||
t->args1 = NULL; t->args2 = NULL;
|
||||
t->sig_pending = 0;
|
||||
t->sig_block_mask = 0;
|
||||
memset(t->sig_action, 0, 32 * sizeof(struct sigaction));
|
||||
t->in_kernel = true;
|
||||
t->user_time = 0;
|
||||
t->kernel_time = 0;
|
||||
t->last_time = 0;
|
||||
t->exit.status = 0;
|
||||
t->exit.reason = 0;
|
||||
list_init(&t->exit.waiters);
|
||||
thread->id = threadID >= 0 ? threadID : allocate_thread_id();
|
||||
thread->team = NULL;
|
||||
thread->cpu = NULL;
|
||||
thread->sem.blocking = -1;
|
||||
thread->fault_handler = 0;
|
||||
thread->page_faults_allowed = 1;
|
||||
thread->kernel_stack_area = -1;
|
||||
thread->kernel_stack_base = 0;
|
||||
thread->user_stack_area = -1;
|
||||
thread->user_stack_base = 0;
|
||||
thread->user_local_storage = 0;
|
||||
thread->kernel_errno = 0;
|
||||
thread->team_next = NULL;
|
||||
thread->queue_next = NULL;
|
||||
thread->priority = -1;
|
||||
thread->args1 = NULL; thread->args2 = NULL;
|
||||
thread->sig_pending = 0;
|
||||
thread->sig_block_mask = 0;
|
||||
memset(thread->sig_action, 0, 32 * sizeof(struct sigaction));
|
||||
thread->in_kernel = true;
|
||||
thread->user_time = 0;
|
||||
thread->kernel_time = 0;
|
||||
thread->last_time = 0;
|
||||
thread->exit.status = 0;
|
||||
thread->exit.reason = 0;
|
||||
list_init(&thread->exit.waiters);
|
||||
|
||||
sprintf(temp, "thread_0x%lx_retcode_sem", t->id);
|
||||
t->exit.sem = create_sem(0, temp);
|
||||
if (t->exit.sem < B_OK)
|
||||
sprintf(temp, "thread_0x%lx_retcode_sem", thread->id);
|
||||
thread->exit.sem = create_sem(0, temp);
|
||||
if (thread->exit.sem < B_OK)
|
||||
goto err1;
|
||||
|
||||
sprintf(temp, "%s send", t->name);
|
||||
t->msg.write_sem = create_sem(1, temp);
|
||||
if (t->msg.write_sem < B_OK)
|
||||
sprintf(temp, "%s send", thread->name);
|
||||
thread->msg.write_sem = create_sem(1, temp);
|
||||
if (thread->msg.write_sem < B_OK)
|
||||
goto err2;
|
||||
|
||||
sprintf(temp, "%s receive", t->name);
|
||||
t->msg.read_sem = create_sem(0, temp);
|
||||
if (t->msg.read_sem < B_OK)
|
||||
sprintf(temp, "%s receive", thread->name);
|
||||
thread->msg.read_sem = create_sem(0, temp);
|
||||
if (thread->msg.read_sem < B_OK)
|
||||
goto err3;
|
||||
|
||||
if (arch_thread_init_thread_struct(t) < B_OK)
|
||||
if (arch_thread_init_thread_struct(thread) < B_OK)
|
||||
goto err4;
|
||||
|
||||
return t;
|
||||
return thread;
|
||||
|
||||
err4:
|
||||
delete_sem(t->msg.read_sem);
|
||||
delete_sem(thread->msg.read_sem);
|
||||
err3:
|
||||
delete_sem(t->msg.write_sem);
|
||||
delete_sem(thread->msg.write_sem);
|
||||
err2:
|
||||
delete_sem(t->exit.sem);
|
||||
delete_sem(thread->exit.sem);
|
||||
err1:
|
||||
// ToDo: put them in the dead queue instead?
|
||||
free(t);
|
||||
free(thread);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -325,7 +326,7 @@ static thread_id
|
||||
create_thread(const char *name, team_id teamID, thread_entry_func entry,
|
||||
void *args1, void *args2, int32 priority, bool kernel, thread_id threadID)
|
||||
{
|
||||
struct thread *t, *currentThread;
|
||||
struct thread *thread, *currentThread;
|
||||
struct team *team;
|
||||
cpu_status state;
|
||||
char stack_name[B_OS_NAME_LENGTH];
|
||||
@ -335,29 +336,29 @@ create_thread(const char *name, team_id teamID, thread_entry_func entry,
|
||||
|
||||
TRACE(("create_thread(%s, id = %ld, %s)\n", name, threadID, kernel ? "kernel" : "user"));
|
||||
|
||||
t = create_thread_struct(name, threadID);
|
||||
if (t == NULL)
|
||||
thread = create_thread_struct(name, threadID);
|
||||
if (thread == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
t->priority = priority == -1 ? B_NORMAL_PRIORITY : priority;
|
||||
thread->priority = priority == -1 ? B_NORMAL_PRIORITY : priority;
|
||||
// ToDo: this could be dangerous in case someone calls resume_thread() on us
|
||||
t->state = B_THREAD_SUSPENDED;
|
||||
t->next_state = B_THREAD_SUSPENDED;
|
||||
thread->state = B_THREAD_SUSPENDED;
|
||||
thread->next_state = B_THREAD_SUSPENDED;
|
||||
|
||||
// init debug structure
|
||||
clear_thread_debug_info(&t->debug_info, false);
|
||||
clear_thread_debug_info(&thread->debug_info, false);
|
||||
|
||||
snprintf(stack_name, B_OS_NAME_LENGTH, "%s_%lx_kstack", name, t->id);
|
||||
t->kernel_stack_area = create_area(stack_name, (void **)&t->kernel_stack_base,
|
||||
snprintf(stack_name, B_OS_NAME_LENGTH, "%s_%lx_kstack", name, thread->id);
|
||||
thread->kernel_stack_area = create_area(stack_name, (void **)&thread->kernel_stack_base,
|
||||
B_ANY_KERNEL_ADDRESS, KERNEL_STACK_SIZE, B_FULL_LOCK,
|
||||
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_KERNEL_STACK_AREA);
|
||||
|
||||
if (t->kernel_stack_area < 0) {
|
||||
if (thread->kernel_stack_area < 0) {
|
||||
// we're not yet part of a team, so we can just bail out
|
||||
dprintf("create_thread: error creating kernel stack!\n");
|
||||
|
||||
status = t->kernel_stack_area;
|
||||
delete_thread_struct(t);
|
||||
status = thread->kernel_stack_area;
|
||||
delete_thread_struct(thread);
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -378,14 +379,14 @@ create_thread(const char *name, team_id teamID, thread_entry_func entry,
|
||||
| B_THREAD_DEBUG_POST_SYSCALL);
|
||||
}
|
||||
|
||||
t->debug_info.flags = debugFlags;
|
||||
thread->debug_info.flags = debugFlags;
|
||||
|
||||
// stop the new thread, if desired
|
||||
debugNewThread = debugFlags & B_THREAD_DEBUG_STOP_CHILD_THREADS;
|
||||
}
|
||||
|
||||
// insert into global list
|
||||
hash_insert(sThreadHash, t);
|
||||
hash_insert(sThreadHash, thread);
|
||||
sUsedThreads++;
|
||||
RELEASE_THREAD_LOCK();
|
||||
|
||||
@ -401,64 +402,65 @@ create_thread(const char *name, team_id teamID, thread_entry_func entry,
|
||||
if (debugNewThread
|
||||
&& (atomic_get(&team->debug_info.flags)
|
||||
& B_TEAM_DEBUG_DEBUGGER_INSTALLED)) {
|
||||
t->debug_info.flags |= B_THREAD_DEBUG_STOP;
|
||||
thread->debug_info.flags |= B_THREAD_DEBUG_STOP;
|
||||
}
|
||||
|
||||
insert_thread_into_team(team, t);
|
||||
insert_thread_into_team(team, thread);
|
||||
} else
|
||||
abort = true;
|
||||
|
||||
RELEASE_TEAM_LOCK();
|
||||
if (abort) {
|
||||
GRAB_THREAD_LOCK();
|
||||
hash_remove(sThreadHash, t);
|
||||
hash_remove(sThreadHash, thread);
|
||||
RELEASE_THREAD_LOCK();
|
||||
}
|
||||
restore_interrupts(state);
|
||||
if (abort) {
|
||||
delete_area(t->kernel_stack_area);
|
||||
delete_thread_struct(t);
|
||||
delete_area(thread->kernel_stack_area);
|
||||
delete_thread_struct(thread);
|
||||
return B_BAD_TEAM_ID;
|
||||
}
|
||||
|
||||
t->args1 = args1;
|
||||
t->args2 = args2;
|
||||
t->entry = entry;
|
||||
status = t->id;
|
||||
thread->args1 = args1;
|
||||
thread->args2 = args2;
|
||||
thread->entry = entry;
|
||||
status = thread->id;
|
||||
|
||||
if (kernel) {
|
||||
// this sets up an initial kthread stack that runs the entry
|
||||
|
||||
// Note: whatever function wants to set up a user stack later for this thread
|
||||
// must initialize the TLS for it
|
||||
arch_thread_init_kthread_stack(t, &_create_kernel_thread_kentry, &thread_kthread_entry, &thread_kthread_exit);
|
||||
arch_thread_init_kthread_stack(thread, &_create_kernel_thread_kentry,
|
||||
&thread_kthread_entry, &thread_kthread_exit);
|
||||
} else {
|
||||
// create user stack
|
||||
|
||||
// the stack will be between USER_STACK_REGION and the main thread stack area
|
||||
// (the user stack of the main thread is created in team_create_team())
|
||||
t->user_stack_base = USER_STACK_REGION;
|
||||
t->user_stack_size = USER_STACK_SIZE;
|
||||
thread->user_stack_base = USER_STACK_REGION;
|
||||
thread->user_stack_size = USER_STACK_SIZE;
|
||||
|
||||
snprintf(stack_name, B_OS_NAME_LENGTH, "%s_%lx_stack", name, t->id);
|
||||
t->user_stack_area = create_area_etc(team, stack_name,
|
||||
(void **)&t->user_stack_base, B_BASE_ADDRESS,
|
||||
t->user_stack_size + TLS_SIZE, B_NO_LOCK,
|
||||
snprintf(stack_name, B_OS_NAME_LENGTH, "%s_%lx_stack", name, thread->id);
|
||||
thread->user_stack_area = create_area_etc(team, stack_name,
|
||||
(void **)&thread->user_stack_base, B_BASE_ADDRESS,
|
||||
thread->user_stack_size + TLS_SIZE, B_NO_LOCK,
|
||||
B_READ_AREA | B_WRITE_AREA | B_STACK_AREA);
|
||||
if (t->user_stack_area < 0) {
|
||||
if (thread->user_stack_area < 0) {
|
||||
// great, we have a fully running thread without a stack
|
||||
dprintf("create_thread: unable to create user stack!\n");
|
||||
status = t->user_stack_area;
|
||||
kill_thread(t->id);
|
||||
status = thread->user_stack_area;
|
||||
kill_thread(thread->id);
|
||||
} else {
|
||||
// now that the TLS area is allocated, initialize TLS
|
||||
arch_thread_init_tls(t);
|
||||
arch_thread_init_tls(thread);
|
||||
}
|
||||
|
||||
// copy the user entry over to the args field in the thread struct
|
||||
// the function this will call will immediately switch the thread into
|
||||
// user space.
|
||||
arch_thread_init_kthread_stack(t, &_create_user_thread_kentry, &thread_kthread_entry, &thread_kthread_exit);
|
||||
arch_thread_init_kthread_stack(thread, &_create_user_thread_kentry, &thread_kthread_entry, &thread_kthread_exit);
|
||||
}
|
||||
|
||||
return status;
|
||||
@ -498,44 +500,44 @@ state_to_text(struct thread *thread, int32 state)
|
||||
static struct thread *last_thread_dumped = NULL;
|
||||
|
||||
static void
|
||||
_dump_thread_info(struct thread *t)
|
||||
_dump_thread_info(struct thread *thread)
|
||||
{
|
||||
kprintf("THREAD: %p\n", t);
|
||||
kprintf("id: 0x%lx\n", t->id);
|
||||
kprintf("name: \"%s\"\n", t->name);
|
||||
kprintf("THREAD: %p\n", thread);
|
||||
kprintf("id: 0x%lx\n", thread->id);
|
||||
kprintf("name: \"%s\"\n", thread->name);
|
||||
kprintf("all_next: %p\nteam_next: %p\nq_next: %p\n",
|
||||
t->all_next, t->team_next, t->queue_next);
|
||||
kprintf("priority: %ld\n", t->priority);
|
||||
kprintf("state: %s\n", state_to_text(t, t->state));
|
||||
kprintf("next_state: %s\n", state_to_text(t, t->next_state));
|
||||
kprintf("cpu: %p ", t->cpu);
|
||||
if (t->cpu)
|
||||
kprintf("(%d)\n", t->cpu->info.cpu_num);
|
||||
thread->all_next, thread->team_next, thread->queue_next);
|
||||
kprintf("priority: %ld\n", thread->priority);
|
||||
kprintf("state: %s\n", state_to_text(thread, thread->state));
|
||||
kprintf("next_state: %s\n", state_to_text(thread, thread->next_state));
|
||||
kprintf("cpu: %p ", thread->cpu);
|
||||
if (thread->cpu)
|
||||
kprintf("(%d)\n", thread->cpu->info.cpu_num);
|
||||
else
|
||||
kprintf("\n");
|
||||
kprintf("sig_pending: 0x%lx\n", t->sig_pending);
|
||||
kprintf("in_kernel: %d\n", t->in_kernel);
|
||||
kprintf(" sem.blocking: 0x%lx\n", t->sem.blocking);
|
||||
kprintf(" sem.count: 0x%lx\n", t->sem.count);
|
||||
kprintf(" sem.acquire_status: 0x%lx\n", t->sem.acquire_status);
|
||||
kprintf(" sem.flags: 0x%lx\n", t->sem.flags);
|
||||
kprintf("fault_handler: %p\n", (void *)t->fault_handler);
|
||||
kprintf("args: %p %p\n", t->args1, t->args2);
|
||||
kprintf("entry: %p\n", (void *)t->entry);
|
||||
kprintf("team: %p, \"%s\"\n", t->team, t->team->name);
|
||||
kprintf("exit.sem: 0x%lx\n", t->exit.sem);
|
||||
kprintf("kernel_stack_area: 0x%lx\n", t->kernel_stack_area);
|
||||
kprintf("kernel_stack_base: %p\n", (void *)t->kernel_stack_base);
|
||||
kprintf("user_stack_area: 0x%lx\n", t->user_stack_area);
|
||||
kprintf("user_stack_base: %p\n", (void *)t->user_stack_base);
|
||||
kprintf("user_local_storage: %p\n", (void *)t->user_local_storage);
|
||||
kprintf("kernel_errno: %d\n", t->kernel_errno);
|
||||
kprintf("kernel_time: %Ld\n", t->kernel_time);
|
||||
kprintf("user_time: %Ld\n", t->user_time);
|
||||
kprintf("sig_pending: 0x%lx\n", thread->sig_pending);
|
||||
kprintf("in_kernel: %d\n", thread->in_kernel);
|
||||
kprintf(" sem.blocking: 0x%lx\n", thread->sem.blocking);
|
||||
kprintf(" sem.count: 0x%lx\n", thread->sem.count);
|
||||
kprintf(" sem.acquire_status: 0x%lx\n", thread->sem.acquire_status);
|
||||
kprintf(" sem.flags: 0x%lx\n", thread->sem.flags);
|
||||
kprintf("fault_handler: %p\n", (void *)thread->fault_handler);
|
||||
kprintf("args: %p %p\n", thread->args1, thread->args2);
|
||||
kprintf("entry: %p\n", (void *)thread->entry);
|
||||
kprintf("team: %p, \"%s\"\n", thread->team, thread->team->name);
|
||||
kprintf("exit.sem: 0x%lx\n", thread->exit.sem);
|
||||
kprintf("kernel_stack_area: 0x%lx\n", thread->kernel_stack_area);
|
||||
kprintf("kernel_stack_base: %p\n", (void *)thread->kernel_stack_base);
|
||||
kprintf("user_stack_area: 0x%lx\n", thread->user_stack_area);
|
||||
kprintf("user_stack_base: %p\n", (void *)thread->user_stack_base);
|
||||
kprintf("user_local_storage: %p\n", (void *)thread->user_local_storage);
|
||||
kprintf("kernel_errno: %d\n", thread->kernel_errno);
|
||||
kprintf("kernel_time: %Ld\n", thread->kernel_time);
|
||||
kprintf("user_time: %Ld\n", thread->user_time);
|
||||
kprintf("architecture dependant section:\n");
|
||||
arch_thread_dump_info(&t->arch_info);
|
||||
arch_thread_dump_info(&thread->arch_info);
|
||||
|
||||
last_thread_dumped = t;
|
||||
last_thread_dumped = thread;
|
||||
}
|
||||
|
||||
|
||||
@ -543,7 +545,7 @@ static int
|
||||
dump_thread_info(int argc, char **argv)
|
||||
{
|
||||
const char *name = NULL;
|
||||
struct thread *t;
|
||||
struct thread *thread;
|
||||
int32 id = -1;
|
||||
struct hash_iterator i;
|
||||
bool found = false;
|
||||
@ -569,9 +571,9 @@ dump_thread_info(int argc, char **argv)
|
||||
|
||||
// walk through the thread list, trying to match name or id
|
||||
hash_open(sThreadHash, &i);
|
||||
while ((t = hash_next(sThreadHash, &i)) != NULL) {
|
||||
if ((name != NULL && !strcmp(name, t->name)) || t->id == id) {
|
||||
_dump_thread_info(t);
|
||||
while ((thread = hash_next(sThreadHash, &i)) != NULL) {
|
||||
if ((name != NULL && !strcmp(name, thread->name)) || thread->id == id) {
|
||||
_dump_thread_info(thread);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@ -587,9 +589,10 @@ dump_thread_info(int argc, char **argv)
|
||||
static int
|
||||
dump_thread_list(int argc, char **argv)
|
||||
{
|
||||
struct thread *t;
|
||||
struct thread *thread;
|
||||
struct hash_iterator i;
|
||||
int32 requiredState = 0;
|
||||
team_id team = -1;
|
||||
sem_id sem = -1;
|
||||
|
||||
if (!strcmp(argv[0], "ready"))
|
||||
@ -604,32 +607,38 @@ dump_thread_list(int argc, char **argv)
|
||||
if (sem == 0)
|
||||
kprintf("ignoring invalid semaphore argument.\n");
|
||||
}
|
||||
} else if (argc > 1) {
|
||||
team = strtoul(argv[1], NULL, 0);
|
||||
if (team == 0)
|
||||
kprintf("ignoring invalid team argument.\n");
|
||||
}
|
||||
|
||||
kprintf("thread id state sem cpu stack name\n");
|
||||
kprintf("thread id state sem cpu stack team name\n");
|
||||
|
||||
hash_open(sThreadHash, &i);
|
||||
while ((t = hash_next(sThreadHash, &i)) != NULL) {
|
||||
if (requiredState && t->state != requiredState)
|
||||
continue;
|
||||
if (sem > 0 && t->sem.blocking != sem)
|
||||
while ((thread = hash_next(sThreadHash, &i)) != NULL) {
|
||||
// filter out threads not matching the search criteria
|
||||
if ((requiredState && thread->state != requiredState)
|
||||
|| (sem > 0 && thread->sem.blocking != sem)
|
||||
|| (team > 0 && thread->team->id != team))
|
||||
continue;
|
||||
|
||||
kprintf("%p %6lx %-9s", t, t->id, state_to_text(t, t->state));
|
||||
kprintf("%p %6lx %-9s", thread, thread->id, state_to_text(thread, thread->state));
|
||||
|
||||
// does it block on a semaphore?
|
||||
if (t->state == B_THREAD_WAITING)
|
||||
kprintf("%6lx ", t->sem.blocking);
|
||||
if (thread->state == B_THREAD_WAITING)
|
||||
kprintf("%6lx ", thread->sem.blocking);
|
||||
else
|
||||
kprintf(" - ");
|
||||
|
||||
// on which CPU does it run?
|
||||
if (t->cpu)
|
||||
kprintf("%2d", t->cpu->info.cpu_num);
|
||||
if (thread->cpu)
|
||||
kprintf("%2d", thread->cpu->info.cpu_num);
|
||||
else
|
||||
kprintf(" -");
|
||||
|
||||
kprintf(" %p %s\n", (void *)t->kernel_stack_base, t->name != NULL ? t->name : "<NULL>");
|
||||
kprintf(" %p%5lx %s\n", (void *)thread->kernel_stack_base,
|
||||
thread->team->id, thread->name != NULL ? thread->name : "<NULL>");
|
||||
}
|
||||
hash_close(sThreadHash, &i, false);
|
||||
return 0;
|
||||
@ -639,16 +648,16 @@ dump_thread_list(int argc, char **argv)
|
||||
static int
|
||||
dump_next_thread_in_q(int argc, char **argv)
|
||||
{
|
||||
struct thread *t = last_thread_dumped;
|
||||
struct thread *thread = last_thread_dumped;
|
||||
|
||||
if (t == NULL) {
|
||||
if (thread == NULL) {
|
||||
kprintf("no thread previously dumped. Examine a thread first.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
kprintf("next thread in queue after thread @ %p\n", t);
|
||||
if (t->queue_next != NULL)
|
||||
_dump_thread_info(t->queue_next);
|
||||
kprintf("next thread in queue after thread @ %p\n", thread);
|
||||
if (thread->queue_next != NULL)
|
||||
_dump_thread_info(thread->queue_next);
|
||||
else
|
||||
kprintf("NULL\n");
|
||||
|
||||
@ -659,16 +668,16 @@ dump_next_thread_in_q(int argc, char **argv)
|
||||
static int
|
||||
dump_next_thread_in_all_list(int argc, char **argv)
|
||||
{
|
||||
struct thread *t = last_thread_dumped;
|
||||
struct thread *thread = last_thread_dumped;
|
||||
|
||||
if (t == NULL) {
|
||||
if (thread == NULL) {
|
||||
kprintf("no thread previously dumped. Examine a thread first.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
kprintf("next thread in global list after thread @ %p\n", t);
|
||||
if (t->all_next != NULL)
|
||||
_dump_thread_info(t->all_next);
|
||||
kprintf("next thread in global list after thread @ %p\n", thread);
|
||||
if (thread->all_next != NULL)
|
||||
_dump_thread_info(thread->all_next);
|
||||
else
|
||||
kprintf("NULL\n");
|
||||
|
||||
@ -679,16 +688,16 @@ dump_next_thread_in_all_list(int argc, char **argv)
|
||||
static int
|
||||
dump_next_thread_in_team(int argc, char **argv)
|
||||
{
|
||||
struct thread *t = last_thread_dumped;
|
||||
struct thread *thread = last_thread_dumped;
|
||||
|
||||
if (t == NULL) {
|
||||
if (thread == NULL) {
|
||||
kprintf("no thread previously dumped. Examine a thread first.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
kprintf("next thread in team after thread @ %p\n", t);
|
||||
if (t->team_next != NULL)
|
||||
_dump_thread_info(t->team_next);
|
||||
kprintf("next thread in team after thread @ %p\n", thread);
|
||||
if (thread->team_next != NULL)
|
||||
_dump_thread_info(thread->team_next);
|
||||
else
|
||||
kprintf("NULL\n");
|
||||
|
||||
@ -1028,18 +1037,18 @@ thread_exit(void)
|
||||
struct thread *
|
||||
thread_get_thread_struct(thread_id id)
|
||||
{
|
||||
struct thread *t;
|
||||
struct thread *thread;
|
||||
cpu_status state;
|
||||
|
||||
state = disable_interrupts();
|
||||
GRAB_THREAD_LOCK();
|
||||
|
||||
t = thread_get_thread_struct_locked(id);
|
||||
thread = thread_get_thread_struct_locked(id);
|
||||
|
||||
RELEASE_THREAD_LOCK();
|
||||
restore_interrupts(state);
|
||||
|
||||
return t;
|
||||
return thread;
|
||||
}
|
||||
|
||||
|
||||
@ -1159,27 +1168,27 @@ thread_dequeue(struct thread_queue *queue)
|
||||
|
||||
|
||||
struct thread *
|
||||
thread_dequeue_id(struct thread_queue *q, thread_id thr_id)
|
||||
thread_dequeue_id(struct thread_queue *q, thread_id id)
|
||||
{
|
||||
struct thread *t;
|
||||
struct thread *thread;
|
||||
struct thread *last = NULL;
|
||||
|
||||
t = q->head;
|
||||
while (t != NULL) {
|
||||
if (t->id == thr_id) {
|
||||
thread = q->head;
|
||||
while (thread != NULL) {
|
||||
if (thread->id == id) {
|
||||
if (last == NULL)
|
||||
q->head = t->queue_next;
|
||||
q->head = thread->queue_next;
|
||||
else
|
||||
last->queue_next = t->queue_next;
|
||||
last->queue_next = thread->queue_next;
|
||||
|
||||
if (q->tail == t)
|
||||
if (q->tail == thread)
|
||||
q->tail = last;
|
||||
break;
|
||||
}
|
||||
last = t;
|
||||
t = t->queue_next;
|
||||
last = thread;
|
||||
thread = thread->queue_next;
|
||||
}
|
||||
return t;
|
||||
return thread;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user