Converted thread states to BeOS equivalents (excluding THREAD_STATE_FREE_ON_RESCHED, which will probably go away once the slab allocator is in). Converted priorities to BeOS equivalents; we now have 60 priority queues to map the 120 BeOS priority levels (which have a granularity of 2, thanks Axel) plus the idle queue. Fixed PS.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@573 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
lillo
2002-08-04 20:10:06 +00:00
parent 752c497115
commit 91363a4278
12 changed files with 145 additions and 109 deletions
+9
View File
@@ -254,6 +254,7 @@ typedef enum {
B_THREAD_WAITING B_THREAD_WAITING
} thread_state; } thread_state;
/*
#define THREAD_IDLE_PRIORITY 0 #define THREAD_IDLE_PRIORITY 0
#define THREAD_NUM_PRIORITY_LEVELS 64 #define THREAD_NUM_PRIORITY_LEVELS 64
@@ -272,6 +273,10 @@ typedef enum {
#define THREAD_RT_LOW_PRIORITY THREAD_MIN_RT_PRIORITY #define THREAD_RT_LOW_PRIORITY THREAD_MIN_RT_PRIORITY
#define THREAD_RT_HIGH_PRIORITY THREAD_MAX_RT_PRIORITY #define THREAD_RT_HIGH_PRIORITY THREAD_MAX_RT_PRIORITY
*/
#define B_IDLE_PRIORITY 0
#define B_LOWEST_ACTIVE_PRIORITY 1
#define B_LOW_PRIORITY 5 #define B_LOW_PRIORITY 5
#define B_NORMAL_PRIORITY 10 #define B_NORMAL_PRIORITY 10
@@ -281,6 +286,10 @@ typedef enum {
#define B_URGENT_PRIORITY 110 #define B_URGENT_PRIORITY 110
#define B_REAL_TIME_PRIORITY 120 #define B_REAL_TIME_PRIORITY 120
#define B_FIRST_REAL_TIME_PRIORITY B_REAL_TIME_DISPLAY_PRIORITY
#define B_MIN_PRIORITY B_IDLE_PRIORITY
#define B_MAX_PRIORITY B_REAL_TIME_PRIORITY
/** information on a thread /** information on a thread
* @note the thread can be in any state * @note the thread can be in any state
*/ */
+6 -26
View File
@@ -22,26 +22,6 @@ extern "C" {
#include <smp.h> #include <smp.h>
#include <arch/thread_struct.h> #include <arch/thread_struct.h>
#define THREAD_IDLE_PRIORITY 0
#define THREAD_NUM_PRIORITY_LEVELS 64
#define THREAD_MIN_PRIORITY (THREAD_IDLE_PRIORITY + 1)
#define THREAD_MAX_PRIORITY (THREAD_NUM_PRIORITY_LEVELS - THREAD_NUM_RT_PRIORITY_LEVELS - 1)
#define THREAD_NUM_RT_PRIORITY_LEVELS 16
#define THREAD_MIN_RT_PRIORITY (THREAD_MAX_PRIORITY + 1)
#define THREAD_MAX_RT_PRIORITY (THREAD_NUM_PRIORITY_LEVELS - 1)
#define THREAD_LOWEST_PRIORITY THREAD_MIN_PRIORITY
#define THREAD_LOW_PRIORITY 12
#define THREAD_MEDIUM_PRIORITY 24
#define THREAD_HIGH_PRIORITY 36
#define THREAD_HIGHEST_PRIORITY THREAD_MAX_PRIORITY
#define THREAD_RT_LOW_PRIORITY THREAD_MIN_RT_PRIORITY
#define THREAD_RT_HIGH_PRIORITY THREAD_MAX_RT_PRIORITY
extern spinlock_t thread_spinlock; extern spinlock_t thread_spinlock;
#define GRAB_THREAD_LOCK() acquire_spinlock(&thread_spinlock) #define GRAB_THREAD_LOCK() acquire_spinlock(&thread_spinlock)
#define RELEASE_THREAD_LOCK() release_spinlock(&thread_spinlock) #define RELEASE_THREAD_LOCK() release_spinlock(&thread_spinlock)
@@ -55,12 +35,12 @@ extern spinlock_t team_spinlock;
#define RELEASE_TEAM_LOCK() release_spinlock(&team_spinlock) #define RELEASE_TEAM_LOCK() release_spinlock(&team_spinlock)
enum { enum {
THREAD_STATE_READY = 0, // ready to run // THREAD_STATE_READY = 0, // ready to run
THREAD_STATE_RUNNING, // running right now somewhere // THREAD_STATE_RUNNING, // running right now somewhere
THREAD_STATE_WAITING, // blocked on something // THREAD_STATE_WAITING, // blocked on something
THREAD_STATE_SUSPENDED, // suspended, not in queue // THREAD_STATE_SUSPENDED, // suspended, not in queue
THREAD_STATE_FREE_ON_RESCHED, // free the thread structure upon reschedule THREAD_STATE_FREE_ON_RESCHED=7, // free the thread structure upon reschedule
THREAD_STATE_BIRTH // thread is being created // THREAD_STATE_BIRTH // thread is being created
}; };
enum { enum {
+2 -1
View File
@@ -490,7 +490,8 @@ KernelLd libc.so :
; ;
KernelLd libroot.so : KernelLd libroot.so :
libglue2.o # libglue2.o
libglue.o
<$(SOURCE_GRIST)!libroot>libroot.o <$(SOURCE_GRIST)!libroot>libroot.o
: :
$(SUBDIR)/ldscripts/$(OBOS_ARCH)/library.ld $(SUBDIR)/ldscripts/$(OBOS_ARCH)/library.ld
+37 -3
View File
@@ -11,12 +11,39 @@
#include <stdlib.h> #include <stdlib.h>
const char *state(thread_state state);
const char *state(thread_state state)
{
switch (state) {
case B_THREAD_RUNNING:
return "run";
case B_THREAD_READY:
return "rdy";
case B_THREAD_SUSPENDED:
return "sus";
case B_THREAD_WAITING:
return "sem";
case B_THREAD_ASLEEP:
return "zzz";
case B_THREAD_RECEIVING:
return "msg";
default:
return "???";
}
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int32 thread_num; int32 thread_num;
int32 team_num = 0; int32 team_num = 0;
thread_info thread; thread_info thread;
team_info team; team_info team;
sem_info sem;
char sem_name[B_OS_NAME_LENGTH * 2];
char buffer[B_OS_NAME_LENGTH];
printf("\n thread name state prio user kernel semaphore\n"); printf("\n thread name state prio user kernel semaphore\n");
printf("-----------------------------------------------------------------------\n"); printf("-----------------------------------------------------------------------\n");
@@ -26,10 +53,17 @@ int main(int argc, char **argv)
team.args, team.team, team.uid, team.gid); team.args, team.team, team.uid, team.gid);
thread_num = 0; thread_num = 0;
while (get_next_thread_info(team.team, &thread_num, &thread) == B_OK) { while (get_next_thread_info(team.team, &thread_num, &thread) == B_OK) {
// Fix thread state and sem output once states are BeOS compatible sem_name[0] = '\0';
if (thread.state == B_THREAD_WAITING) {
if (get_sem_info(thread.sem, &sem) == B_OK) {
strcpy(sem_name, sem.name);
sprintf(buffer, "(%d)", sem.sem);
strcat(sem_name, buffer);
}
}
printf(" %6d %20s %s %3d %7d %7d %s\n", printf(" %6d %20s %s %3d %7d %7d %s\n",
thread.thread, thread.name, "???", thread.priority, thread.thread, thread.name, state(thread.state), thread.priority,
(int)thread.user_time, (int)thread.kernel_time, ""); (int)thread.user_time, (int)thread.kernel_time, sem_name);
} }
} }
printf("\n"); printf("\n");
+8 -8
View File
@@ -150,7 +150,7 @@ int main(int argc, char **argv)
int i; int i;
for(i=0; i<10; i++) { for(i=0; i<10; i++) {
tids[i] = spawn_thread(&test_thread, "foo", THREAD_MEDIUM_PRIORITY, (void *)i); tids[i] = spawn_thread(&test_thread, "foo", B_NORMAL_PRIORITY, (void *)i);
resume_thread(tids[i]); resume_thread(tids[i]);
} }
@@ -369,7 +369,7 @@ int main(int argc, char **argv)
t = sys_system_time(); t = sys_system_time();
id = spawn_thread(&dummy_thread, "testthread", THREAD_MEDIUM_PRIORITY, NULL); id = spawn_thread(&dummy_thread, "testthread", B_NORMAL_PRIORITY, NULL);
if (id > 0) if (id > 0)
resume_thread(id); resume_thread(id);
@@ -386,19 +386,19 @@ int main(int argc, char **argv)
printf("spawning a few floating point crunchers\n"); printf("spawning a few floating point crunchers\n");
id = spawn_thread(&fpu_cruncher_thread, "fpu thread0", THREAD_MEDIUM_PRIORITY, &f[0]); id = spawn_thread(&fpu_cruncher_thread, "fpu thread0", B_NORMAL_PRIORITY, &f[0]);
resume_thread(id); resume_thread(id);
id = spawn_thread(&fpu_cruncher_thread, "fpu thread1", THREAD_MEDIUM_PRIORITY, &f[1]); id = spawn_thread(&fpu_cruncher_thread, "fpu thread1", B_NORMAL_PRIORITY, &f[1]);
resume_thread(id); resume_thread(id);
id = spawn_thread(&fpu_cruncher_thread, "fpu thread2", THREAD_MEDIUM_PRIORITY, &f[2]); id = spawn_thread(&fpu_cruncher_thread, "fpu thread2", B_NORMAL_PRIORITY, &f[2]);
resume_thread(id); resume_thread(id);
id = spawn_thread(&fpu_cruncher_thread, "fpu thread3", THREAD_MEDIUM_PRIORITY, &f[3]); id = spawn_thread(&fpu_cruncher_thread, "fpu thread3", B_NORMAL_PRIORITY, &f[3]);
resume_thread(id); resume_thread(id);
id = spawn_thread(&fpu_cruncher_thread, "fpu thread4", THREAD_MEDIUM_PRIORITY, &f[4]); id = spawn_thread(&fpu_cruncher_thread, "fpu thread4", B_NORMAL_PRIORITY, &f[4]);
resume_thread(id); resume_thread(id);
getchar(); getchar();
@@ -452,7 +452,7 @@ static void port_test(void)
printf("porttest: res=%d, %s\n", res, res == ETIMEDOUT ? "ok" : "BAD"); printf("porttest: res=%d, %s\n", res, res == ETIMEDOUT ? "ok" : "BAD");
printf("porttest: spawning thread for port 1\n"); printf("porttest: spawning thread for port 1\n");
t = spawn_thread(port_test_thread_func, "port_test", THREAD_MEDIUM_PRIORITY, NULL); t = spawn_thread(port_test_thread_func, "port_test", B_NORMAL_PRIORITY, NULL);
// resume thread // resume thread
resume_thread(t); resume_thread(t);
+1 -1
View File
@@ -49,7 +49,7 @@ int main(int argc, char **argv)
my_test->current_val = &current_val; my_test->current_val = &current_val;
my_test->thread_mult = i + 1; my_test->thread_mult = i + 1;
t[i] = spawn_thread(counter_thread, "counter", THREAD_MEDIUM_PRIORITY, my_test); t[i] = spawn_thread(counter_thread, "counter", B_NORMAL_PRIORITY, my_test);
if (t[i] > 0) { if (t[i] > 0) {
resume_thread(t[i]); resume_thread(t[i]);
expected *= (i + 1); expected *= (i + 1);
+8 -8
View File
@@ -103,12 +103,12 @@ resched(void)
// dprintf("top of thread_resched: cpu %d, cur_thread = 0x%x\n", smp_get_current_cpu(), thread_get_current_thread()); // dprintf("top of thread_resched: cpu %d, cur_thread = 0x%x\n", smp_get_current_cpu(), thread_get_current_thread());
switch(old_thread->next_state) { switch(old_thread->next_state) {
case THREAD_STATE_RUNNING: case B_THREAD_RUNNING:
case THREAD_STATE_READY: case B_THREAD_READY:
// dprintf("enqueueing thread 0x%x into run q. pri = %d\n", old_thread, old_thread->priority); // dprintf("enqueueing thread 0x%x into run q. pri = %d\n", old_thread, old_thread->priority);
thread_enqueue_run_q(old_thread); thread_enqueue_run_q(old_thread);
break; break;
case THREAD_STATE_SUSPENDED: case B_THREAD_SUSPENDED:
dprintf("suspending thread 0x%x\n", old_thread->id); dprintf("suspending thread 0x%x\n", old_thread->id);
break; break;
case THREAD_STATE_FREE_ON_RESCHED: case THREAD_STATE_FREE_ON_RESCHED:
@@ -123,14 +123,14 @@ resched(void)
old_thread->state = old_thread->next_state; old_thread->state = old_thread->next_state;
// search the real-time queue // search the real-time queue
for(i = THREAD_MAX_RT_PRIORITY; i >= THREAD_MIN_RT_PRIORITY; i--) { for(i = B_MAX_PRIORITY; i >= B_FIRST_REAL_TIME_PRIORITY; i-=2) {
next_thread = thread_dequeue_run_q(i); next_thread = thread_dequeue_run_q(i);
if(next_thread) if(next_thread)
goto found_thread; goto found_thread;
} }
// search the regular queue // search the regular queue
for(i = THREAD_MAX_PRIORITY; i > THREAD_IDLE_PRIORITY; i--) { for(i = B_FIRST_REAL_TIME_PRIORITY - 1; i >= B_LOWEST_ACTIVE_PRIORITY; i-=2) {
next_thread = thread_lookat_run_q(i); next_thread = thread_lookat_run_q(i);
if(next_thread != NULL) { if(next_thread != NULL) {
// skip it sometimes // skip it sometimes
@@ -148,15 +148,15 @@ resched(void)
if(next_thread == NULL) if(next_thread == NULL)
panic("next_thread == NULL! last_thread_pri = %d\n", last_thread_pri); panic("next_thread == NULL! last_thread_pri = %d\n", last_thread_pri);
} else { } else {
next_thread = thread_dequeue_run_q(THREAD_IDLE_PRIORITY); next_thread = thread_dequeue_run_q(B_IDLE_PRIORITY);
if(next_thread == NULL) if(next_thread == NULL)
panic("next_thread == NULL! no idle priorities!\n"); panic("next_thread == NULL! no idle priorities!\n");
} }
} }
found_thread: found_thread:
next_thread->state = THREAD_STATE_RUNNING; next_thread->state = B_THREAD_RUNNING;
next_thread->next_state = THREAD_STATE_READY; next_thread->next_state = B_THREAD_READY;
if ((next_thread != old_thread) || (old_thread->cpu->info.preempted)) { if ((next_thread != old_thread) || (old_thread->cpu->info.preempted)) {
// XXX calculate quantum // XXX calculate quantum
+7 -7
View File
@@ -248,7 +248,7 @@ int delete_sem_etc(sem_id id, int return_code)
// free any threads waiting for this semaphore // free any threads waiting for this semaphore
while ((t = thread_dequeue(&sems[slot].q)) != NULL) { while ((t = thread_dequeue(&sems[slot].q)) != NULL) {
t->state = THREAD_STATE_READY; t->state = B_THREAD_READY;
t->sem_errcode = B_BAD_SEM_ID; t->sem_errcode = B_BAD_SEM_ID;
t->sem_deleted_retcode = return_code; t->sem_deleted_retcode = return_code;
t->sem_count = 0; t->sem_count = 0;
@@ -370,7 +370,7 @@ int acquire_sem_etc(sem_id id, int count, int flags, bigtime_t timeout)
goto err; goto err;
} }
t->next_state = THREAD_STATE_WAITING; t->next_state = B_THREAD_WAITING;
t->sem_flags = flags; t->sem_flags = flags;
t->sem_blocking = id; t->sem_blocking = id;
t->sem_acquire_count = count; t->sem_acquire_count = count;
@@ -485,7 +485,7 @@ int release_sem_etc(sem_id id, int count, int flags)
// release this thread // release this thread
t = thread_dequeue(&sems[slot].q); t = thread_dequeue(&sems[slot].q);
thread_enqueue(t, &release_queue); thread_enqueue(t, &release_queue);
t->state = THREAD_STATE_READY; t->state = B_THREAD_READY;
released_threads++; released_threads++;
t->sem_count = 0; t->sem_count = 0;
t->sem_deleted_retcode = 0; t->sem_deleted_retcode = 0;
@@ -505,7 +505,7 @@ int release_sem_etc(sem_id id, int count, int flags)
while ((t = thread_dequeue(&release_queue)) != NULL) { while ((t = thread_dequeue(&release_queue)) != NULL) {
// temporarily place thread in a run queue with high priority to boost it up // temporarily place thread in a run queue with high priority to boost it up
priority = t->priority; priority = t->priority;
t->priority = t->priority >= THREAD_HIGH_PRIORITY ? t->priority : THREAD_HIGH_PRIORITY; t->priority = t->priority >= B_FIRST_REAL_TIME_PRIORITY ? t->priority : B_FIRST_REAL_TIME_PRIORITY;
thread_enqueue_run_q(t); thread_enqueue_run_q(t);
t->priority = priority; t->priority = priority;
} }
@@ -691,7 +691,7 @@ int sem_interrupt_thread(struct thread *t)
// dprintf("sem_interrupt_thread: called on thread %p (%d), blocked on sem 0x%x\n", t, t->id, t->sem_blocking); // dprintf("sem_interrupt_thread: called on thread %p (%d), blocked on sem 0x%x\n", t, t->id, t->sem_blocking);
if (t->state != THREAD_STATE_WAITING || t->sem_blocking < 0) if (t->state != B_THREAD_WAITING || t->sem_blocking < 0)
return EINVAL; return EINVAL;
if ((t->sem_flags & B_CAN_INTERRUPT) == 0) if ((t->sem_flags & B_CAN_INTERRUPT) == 0)
return ERR_SEM_NOT_INTERRUPTABLE; return ERR_SEM_NOT_INTERRUPTABLE;
@@ -729,7 +729,7 @@ static int remove_thread_from_sem(struct thread *t, struct sem_entry *sem, struc
if(t != t1) if(t != t1)
return ERR_NOT_FOUND; return ERR_NOT_FOUND;
sem->count += t->sem_acquire_count; sem->count += t->sem_acquire_count;
t->state = THREAD_STATE_READY; t->state = B_THREAD_READY;
t->sem_errcode = sem_errcode; t->sem_errcode = sem_errcode;
thread_enqueue(t, queue); thread_enqueue(t, queue);
@@ -740,7 +740,7 @@ static int remove_thread_from_sem(struct thread *t, struct sem_entry *sem, struc
t->sem_count -= delta; t->sem_count -= delta;
if(t->sem_count <= 0) { if(t->sem_count <= 0) {
t = thread_dequeue(&sem->q); t = thread_dequeue(&sem->q);
t->state = THREAD_STATE_READY; t->state = B_THREAD_READY;
thread_enqueue(t, queue); thread_enqueue(t, queue);
} }
sem->count -= delta; sem->count -= delta;
+4 -2
View File
@@ -41,7 +41,7 @@ struct team_arg {
// team list // team list
static void *team_hash = NULL; static void *team_hash = NULL;
static team_id next_team_id = 0; static team_id next_team_id = 1;
static struct team *kernel_team = NULL; static struct team *kernel_team = NULL;
spinlock_t team_spinlock = 0; spinlock_t team_spinlock = 0;
@@ -673,6 +673,7 @@ _get_team_info(team_id id, team_info *info, size_t size)
goto err; goto err;
} }
// XXX- Set more informations for team_info // XXX- Set more informations for team_info
memset(info, 0, sizeof(team_info));
info->team = team->id; info->team = team->id;
info->thread_count = team->num_threads; info->thread_count = team->num_threads;
// XXX- make this to return real argc/argv // XXX- make this to return real argc/argv
@@ -738,9 +739,10 @@ _get_next_team_info(int32 *cookie, team_info *info, size_t size)
if (slot >= next_team_id) if (slot >= next_team_id)
goto err; goto err;
} }
while (!(team = team_get_team_struct_locked(slot)) && (slot < next_team_id)) while ((slot < next_team_id) && !(team = team_get_team_struct_locked(slot)))
slot++; slot++;
if (team) { if (team) {
memset(info, 0, sizeof(team_info));
// XXX- Set more informations for team_info // XXX- Set more informations for team_info
info->team = team->id; info->team = team->id;
info->thread_count = team->num_threads; info->thread_count = team->num_threads;
+60 -50
View File
@@ -46,7 +46,7 @@ spinlock_t thread_spinlock = 0;
// thread list // thread list
static struct thread *idle_threads[MAX_BOOT_CPUS]; static struct thread *idle_threads[MAX_BOOT_CPUS];
static void *thread_hash = NULL; static void *thread_hash = NULL;
static thread_id next_thread_id = 0; static thread_id next_thread_id = 1;
static sem_id snooze_sem = -1; static sem_id snooze_sem = -1;
@@ -62,14 +62,13 @@ static unsigned int volatile death_stack_bitmap;
static sem_id death_stack_sem; static sem_id death_stack_sem;
// thread queues // thread queues
static struct thread_queue run_q[THREAD_NUM_PRIORITY_LEVELS] = { { NULL, NULL }, }; // Thread priority has a granularity of 2; this means that we have 61 real
// priority levels: 60 to map BeOS priorities 1-120, plus the idle priority (0).
static struct thread_queue run_q[(B_MAX_PRIORITY / 2) + 1] = { { NULL, NULL }, };
struct thread_queue dead_q; struct thread_queue dead_q;
static void thread_entry(void); static void thread_entry(void);
static struct thread *thread_get_thread_struct_locked(thread_id id); static struct thread *thread_get_thread_struct_locked(thread_id id);
/* XXX - not currently used, so commented out
static struct team *team_get_team_struct(team_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);
@@ -129,23 +128,23 @@ struct thread *thread_dequeue_id(struct thread_queue *q, thread_id thr_id)
struct thread *thread_lookat_run_q(int priority) struct thread *thread_lookat_run_q(int priority)
{ {
return thread_lookat_queue(&run_q[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 // these shouldn't exist
if(t->priority > THREAD_MAX_PRIORITY) if(t->priority > B_MAX_PRIORITY)
t->priority = THREAD_MAX_PRIORITY; t->priority = B_MAX_PRIORITY;
if(t->priority < 0) if(t->priority < B_MIN_PRIORITY)
t->priority = 0; t->priority = B_MIN_PRIORITY;
thread_enqueue(t, &run_q[t->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]); return thread_dequeue(&run_q[(priority + 1) >> 1]);
} }
static void insert_thread_into_team(struct team *p, struct thread *t) static void insert_thread_into_team(struct team *p, struct thread *t)
@@ -307,9 +306,10 @@ static thread_id _create_thread(const char *name, team_id pid, addr entry, void
if(t == NULL) if(t == NULL)
return ENOMEM; return ENOMEM;
t->priority = priority == -1 ? THREAD_MEDIUM_PRIORITY : priority; t->priority = priority == -1 ? B_NORMAL_PRIORITY : priority;
t->state = THREAD_STATE_BIRTH; // t->state = THREAD_STATE_BIRTH;
t->next_state = THREAD_STATE_SUSPENDED; t->state = B_THREAD_SUSPENDED; // Is this right?
t->next_state = B_THREAD_SUSPENDED;
state = disable_interrupts(); state = disable_interrupts();
GRAB_THREAD_LOCK(); GRAB_THREAD_LOCK();
@@ -377,7 +377,7 @@ static thread_id _create_thread(const char *name, team_id pid, addr entry, void
arch_thread_initialize_kthread_stack(t, &_create_user_thread_kentry, &thread_entry, &thread_kthread_exit); arch_thread_initialize_kthread_stack(t, &_create_user_thread_kentry, &thread_entry, &thread_kthread_exit);
} }
t->state = THREAD_STATE_SUSPENDED; t->state = B_THREAD_SUSPENDED;
return t->id; return t->id;
} }
@@ -439,7 +439,7 @@ int thread_suspend_thread(thread_id id)
t->pending_signals |= SIG_SUSPEND; t->pending_signals |= SIG_SUSPEND;
retval = B_NO_ERROR; retval = B_NO_ERROR;
} else { } else {
t->next_state = THREAD_STATE_SUSPENDED; t->next_state = B_THREAD_SUSPENDED;
global_resched = true; global_resched = true;
retval = B_NO_ERROR; retval = B_NO_ERROR;
} }
@@ -467,9 +467,9 @@ 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 == THREAD_STATE_SUSPENDED) { if(t != NULL && t->state == B_THREAD_SUSPENDED) {
t->state = THREAD_STATE_READY; t->state = B_THREAD_READY;
t->next_state = THREAD_STATE_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;
@@ -489,10 +489,10 @@ int thread_set_priority(thread_id id, int priority)
int retval; int retval;
// make sure the passed in priority is within bounds // make sure the passed in priority is within bounds
if(priority > THREAD_MAX_PRIORITY) if(priority > B_MAX_PRIORITY)
priority = THREAD_MAX_PRIORITY; priority = B_MAX_PRIORITY;
if(priority < THREAD_MIN_PRIORITY) if(priority < B_MIN_PRIORITY)
priority = THREAD_MIN_PRIORITY; priority = B_MIN_PRIORITY;
t = thread_get_current_thread(); t = thread_get_current_thread();
if(t->id == id) { if(t->id == id) {
@@ -506,9 +506,9 @@ int thread_set_priority(thread_id id, int priority)
t = thread_get_thread_struct_locked(id); t = thread_get_thread_struct_locked(id);
if(t) { if(t) {
if(t->state == THREAD_STATE_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], 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 {
@@ -529,18 +529,16 @@ int thread_set_priority(thread_id id, int priority)
static const char *state_to_text(int state) static const char *state_to_text(int state)
{ {
switch(state) { switch(state) {
case THREAD_STATE_READY: case B_THREAD_READY:
return "READY"; return "READY";
case THREAD_STATE_RUNNING: case B_THREAD_RUNNING:
return "RUNNING"; return "RUNNING";
case THREAD_STATE_WAITING: case B_THREAD_WAITING:
return "WAITING"; return "WAITING";
case THREAD_STATE_SUSPENDED: case B_THREAD_SUSPENDED:
return "SUSPEND"; return "SUSPEND";
case THREAD_STATE_FREE_ON_RESCHED: case THREAD_STATE_FREE_ON_RESCHED:
return "DEATH"; return "DEATH";
case THREAD_STATE_BIRTH:
return "BIRTH";
default: default:
return "UNKNOWN"; return "UNKNOWN";
} }
@@ -795,9 +793,9 @@ int thread_init(kernel_args *ka)
return ENOMEM; return ENOMEM;
} }
t->team = team_get_kernel_team(); t->team = team_get_kernel_team();
t->priority = THREAD_IDLE_PRIORITY; t->priority = B_IDLE_PRIORITY;
t->state = THREAD_STATE_RUNNING; t->state = B_THREAD_RUNNING;
t->next_state = THREAD_STATE_READY; t->next_state = B_THREAD_READY;
sprintf(temp, "idle_thread%d_kstack", i); sprintf(temp, "idle_thread%d_kstack", i);
t->kernel_stack_region_id = vm_find_region_by_name(vm_get_kernel_aspace_id(), temp); t->kernel_stack_region_id = vm_find_region_by_name(vm_get_kernel_aspace_id(), temp);
region = vm_get_region_by_id(t->kernel_stack_region_id); region = vm_get_region_by_id(t->kernel_stack_region_id);
@@ -939,7 +937,7 @@ void thread_exit(int retcode)
dprintf("thread 0x%x exiting w/return code 0x%x\n", t->id, retcode); dprintf("thread 0x%x exiting w/return code 0x%x\n", t->id, retcode);
// boost our priority to get this over with // boost our priority to get this over with
thread_set_priority(t->id, THREAD_HIGH_PRIORITY); thread_set_priority(t->id, B_FIRST_REAL_TIME_PRIORITY);
// delete the user stack region first // delete the user stack region first
if(p->_aspace_id >= 0 && t->user_stack_region_id >= 0) { if(p->_aspace_id >= 0 && t->user_stack_region_id >= 0) {
@@ -1193,13 +1191,13 @@ static void deliver_signal(struct thread *t, int signal)
case SIG_KILL: case SIG_KILL:
t->pending_signals |= SIG_KILL; t->pending_signals |= SIG_KILL;
switch(t->state) { switch(t->state) {
case THREAD_STATE_SUSPENDED: case B_THREAD_SUSPENDED:
t->state = THREAD_STATE_READY; t->state = B_THREAD_READY;
t->next_state = THREAD_STATE_READY; t->next_state = B_THREAD_READY;
thread_enqueue_run_q(t); thread_enqueue_run_q(t);
break; break;
case THREAD_STATE_WAITING: case B_THREAD_WAITING:
sem_interrupt_thread(t); sem_interrupt_thread(t);
break; break;
default: default:
@@ -1227,7 +1225,7 @@ static void _check_for_thread_sigs(struct thread *t, int state)
} }
if(t->pending_signals & SIG_SUSPEND) { if(t->pending_signals & SIG_SUSPEND) {
t->pending_signals &= ~SIG_SUSPEND; t->pending_signals &= ~SIG_SUSPEND;
t->next_state = THREAD_STATE_SUSPENDED; t->next_state = B_THREAD_SUSPENDED;
// XXX will probably want to delay this // XXX will probably want to delay this
resched(); resched();
} }
@@ -1304,7 +1302,7 @@ user_get_thread_info(thread_id id, thread_info *info)
if (rc != B_OK) if (rc != B_OK)
return rc; return rc;
rc2 = user_memcpy(info, &kinfo, sizeof(team_info)); rc2 = user_memcpy(info, &kinfo, sizeof(thread_info));
if (rc2 < 0) if (rc2 < 0)
return rc2; return rc2;
@@ -1331,8 +1329,13 @@ _get_thread_info(thread_id id, thread_info *info, size_t size)
info->team = t->team->id; info->team = t->team->id;
strncpy(info->name, t->name, B_OS_NAME_LENGTH); strncpy(info->name, t->name, B_OS_NAME_LENGTH);
info->name[B_OS_NAME_LENGTH - 1] = '\0'; info->name[B_OS_NAME_LENGTH - 1] = '\0';
// XXX- Fix me if (t->state == B_THREAD_WAITING) {
info->state = t->state; if (t->sem_blocking == snooze_sem)
info->state = B_THREAD_ASLEEP;
else
info->state = B_THREAD_WAITING;
} else
info->state = t->state;
info->priority = t->priority; info->priority = t->priority;
info->sem = t->sem_blocking; info->sem = t->sem_blocking;
info->user_time = t->user_time; info->user_time = t->user_time;
@@ -1364,7 +1367,7 @@ user_get_next_thread_info(team_id team, int32 *cookie, thread_info *info)
if (rc2 < 0) if (rc2 < 0)
return rc2; return rc2;
rc = _get_next_thread_info(team, &kcookie, &kinfo, sizeof(team_info)); rc = _get_next_thread_info(team, &kcookie, &kinfo, sizeof(thread_info));
if (rc != B_OK) if (rc != B_OK)
return rc; return rc;
@@ -1372,7 +1375,7 @@ user_get_next_thread_info(team_id team, int32 *cookie, thread_info *info)
if (rc2 < 0) if (rc2 < 0)
return rc2; return rc2;
rc2 = user_memcpy(info, &kinfo, sizeof(team_info)); rc2 = user_memcpy(info, &kinfo, sizeof(thread_info));
if (rc2 < 0) if (rc2 < 0)
return rc2; return rc2;
@@ -1405,15 +1408,22 @@ _get_next_thread_info(team_id tid, int32 *cookie, thread_info *info, size_t size
if (slot >= next_thread_id) if (slot >= next_thread_id)
goto err; goto err;
} }
while (!(t = thread_get_thread_struct_locked(slot)) && (t->team->id != tid) && (slot < next_thread_id))
while ((slot < next_thread_id) && (!(t = thread_get_thread_struct_locked(slot)) || (t->team->id != tid)))
slot++; slot++;
if (t) {
if ((t) && (t->team->id == tid)) {
info->thread = t->id; info->thread = t->id;
info->team = t->team->id; info->team = t->team->id;
strncpy(info->name, t->name, B_OS_NAME_LENGTH); strncpy(info->name, t->name, B_OS_NAME_LENGTH);
info->name[B_OS_NAME_LENGTH - 1] = '\0'; info->name[B_OS_NAME_LENGTH - 1] = '\0';
// XXX- Fix me if (t->state == B_THREAD_WAITING) {
info->state = t->state; if (t->sem_blocking == snooze_sem)
info->state = B_THREAD_ASLEEP;
else
info->state = B_THREAD_WAITING;
} else
info->state = t->state;
info->priority = t->priority; info->priority = t->priority;
info->sem = t->sem_blocking; info->sem = t->sem_blocking;
info->user_time = t->user_time; info->user_time = t->user_time;
+1 -1
View File
@@ -201,7 +201,7 @@ int vm_daemon_init()
// create a kernel thread to select pages for pageout // create a kernel thread to select pages for pageout
tid = thread_create_kernel_thread("page daemon", &page_daemon, NULL); tid = thread_create_kernel_thread("page daemon", &page_daemon, NULL);
thread_set_priority(tid, THREAD_MIN_RT_PRIORITY); thread_set_priority(tid, B_FIRST_REAL_TIME_PRIORITY);
thread_resume_thread(tid); thread_resume_thread(tid);
return 0; return 0;
+2 -2
View File
@@ -263,13 +263,13 @@ int vm_page_init_postthread(kernel_args *ka)
// create a kernel thread to clear out pages // create a kernel thread to clear out pages
tid = thread_create_kernel_thread("page scrubber", &page_scrubber, NULL); tid = thread_create_kernel_thread("page scrubber", &page_scrubber, NULL);
thread_set_priority(tid, THREAD_LOWEST_PRIORITY); thread_set_priority(tid, B_LOWEST_ACTIVE_PRIORITY);
thread_resume_thread(tid); thread_resume_thread(tid);
modified_pages_available = create_sem(0, "modified_pages_avail_sem"); modified_pages_available = create_sem(0, "modified_pages_avail_sem");
#if 0 #if 0
// create a kernel thread to schedule modified pages to write // create a kernel thread to schedule modified pages to write
tid = thread_create_kernel_thread("pageout daemon", &pageout_daemon, THREAD_MIN_RT_PRIORITY + 1); tid = thread_create_kernel_thread("pageout daemon", &pageout_daemon, B_FIRST_REAL_TIME_PRIORITY + 1);
thread_resume_thread(tid); thread_resume_thread(tid);
#endif #endif
return 0; return 0;