summaryrefslogtreecommitdiff
path: root/kern
diff options
context:
space:
mode:
Diffstat (limited to 'kern')
-rw-r--r--kern/task.c2
-rw-r--r--kern/thread.c23
-rw-r--r--kern/thread.h16
-rw-r--r--kern/thread_i.h12
4 files changed, 32 insertions, 21 deletions
diff --git a/kern/task.c b/kern/task.c
index 5df72251..3ad863bd 100644
--- a/kern/task.c
+++ b/kern/task.c
@@ -257,7 +257,7 @@ task_info(struct task *task)
printf(TASK_INFO_ADDR_FMT " %c %8s:" TASK_INFO_ADDR_FMT
" %.2s:%02hu %02u %s\n",
(unsigned long)thread,
- thread_state_to_chr(thread),
+ thread_state_to_chr(thread_state(thread)),
thread_wchan_desc(thread),
(unsigned long)thread_wchan_addr(thread),
thread_sched_class_to_str(thread_user_sched_class(thread)),
diff --git a/kern/thread.c b/kern/thread.c
index e79ef311..79199a8f 100644
--- a/kern/thread.c
+++ b/kern/thread.c
@@ -600,7 +600,7 @@ thread_runq_wakeup_balancer(struct thread_runq *runq)
}
thread_clear_wchan(runq->balancer);
- runq->balancer->state = THREAD_RUNNING;
+ atomic_store(&runq->balancer->state, THREAD_RUNNING, ATOMIC_RELAXED);
thread_runq_wakeup(runq, runq->balancer);
}
@@ -1989,8 +1989,9 @@ static void
thread_join_common(struct thread *thread)
{
struct thread_runq *runq;
- unsigned long flags, state;
struct thread *self;
+ unsigned long flags;
+ unsigned int state;
self = thread_self();
assert(thread != self);
@@ -2060,7 +2061,7 @@ thread_balance(void *arg)
for (;;) {
runq->idle_balance_ticks = THREAD_IDLE_BALANCE_TICKS;
thread_set_wchan(self, runq, "runq");
- self->state = THREAD_SLEEPING;
+ atomic_store(&self->state, THREAD_SLEEPING, ATOMIC_RELAXED);
runq = thread_runq_schedule(runq);
assert(runq == arg);
@@ -2421,7 +2422,7 @@ thread_exit(void)
runq = thread_runq_local();
spinlock_lock_intr_save(&runq->lock, &flags);
- thread->state = THREAD_DEAD;
+ atomic_store(&thread->state, THREAD_DEAD, ATOMIC_RELAXED);
thread_runq_schedule(runq);
panic("thread: dead thread walking");
@@ -2461,7 +2462,7 @@ thread_wakeup_common(struct thread *thread, int error)
}
thread_clear_wchan(thread);
- thread->state = THREAD_RUNNING;
+ atomic_store(&thread->state, THREAD_RUNNING, ATOMIC_RELAXED);
thread_unlock_runq(runq, flags);
}
@@ -2532,7 +2533,7 @@ thread_sleep_common(struct spinlock *interlock, const void *wchan_addr,
}
thread_set_wchan(thread, wchan_addr, wchan_desc);
- thread->state = THREAD_SLEEPING;
+ atomic_store(&thread->state, THREAD_SLEEPING, ATOMIC_RELAXED);
runq = thread_runq_schedule(runq);
assert(thread->state == THREAD_RUNNING);
@@ -2699,9 +2700,9 @@ thread_report_periodic_event(void)
}
char
-thread_state_to_chr(const struct thread *thread)
+thread_state_to_chr(unsigned int state)
{
- switch (thread->state) {
+ switch (state) {
case THREAD_RUNNING:
return 'R';
case THREAD_SLEEPING:
@@ -2906,6 +2907,12 @@ thread_key_create(unsigned int *keyp, thread_dtor_fn_t dtor)
*keyp = key;
}
+unsigned int
+thread_state(const struct thread *thread)
+{
+ return atomic_load(&thread->state, ATOMIC_RELAXED);
+}
+
bool
thread_is_running(const struct thread *thread)
{
diff --git a/kern/thread.h b/kern/thread.h
index 6e696fc7..cc1a8a2b 100644
--- a/kern/thread.h
+++ b/kern/thread.h
@@ -75,6 +75,13 @@ struct thread_sched_data {
#define THREAD_KERNEL_PREFIX KERNEL_NAME "_"
/*
+ * Thread states.
+ */
+#define THREAD_RUNNING 0
+#define THREAD_SLEEPING 1
+#define THREAD_DEAD 2
+
+/*
* Scheduling policies.
*
* The idle policy is reserved for the per-CPU idle threads.
@@ -323,7 +330,7 @@ thread_wchan_desc(const struct thread *thread)
/*
* Return a character representation of the state of a thread.
*/
-char thread_state_to_chr(const struct thread *thread);
+char thread_state_to_chr(unsigned int state);
static inline const struct thread_sched_data *
thread_get_user_sched_data(const struct thread *thread)
@@ -706,6 +713,13 @@ thread_get_specific(unsigned int key)
}
/*
+ * Return the current state of the given thread.
+ *
+ * This call isn't synchronized, and the caller may obtain an outdated value.
+ */
+unsigned int thread_state(const struct thread *thread);
+
+/*
* Return true if the given thread is running.
*
* Note that this check is speculative, and may not return an accurate
diff --git a/kern/thread_i.h b/kern/thread_i.h
index 0be1e773..95af1d18 100644
--- a/kern/thread_i.h
+++ b/kern/thread_i.h
@@ -45,16 +45,6 @@ struct thread_fs_runq;
#define THREAD_DETACHED 0x2UL /* Resources automatically released on exit */
/*
- * Thread states.
- *
- * Threads in the running state may not be on a run queue if they're being
- * awaken.
- */
-#define THREAD_RUNNING 0
-#define THREAD_SLEEPING 1
-#define THREAD_DEAD 2
-
-/*
* Scheduling data for a real-time thread.
*/
struct thread_rt_data {
@@ -113,7 +103,7 @@ struct thread {
const void *wchan_addr; /* (r) */
const char *wchan_desc; /* (r) */
int wakeup_error; /* (r) */
- unsigned short state; /* (r) */
+ unsigned int state; /* (a,r) */
/* Sleep queue available for lending */
struct sleepq *priv_sleepq; /* (-) */