Cleanup: do not access directly thread state and mutex owner
MODIFY
include/mutex.h
include/mutex.h
@@ -25,6 +25,9 @@ typedef struct thread thread_t;
#define MTX_RECURSE 1
/*! \brief Basic synchronization primitive.
+ *
+ * \warning You must never access mutex fields directly outside of its
+ * implementation!
*
* \note Mutex must be released by its owner!
*/
@@ -53,6 +56,13 @@ void mtx_init(mtx_t *m, unsigned type);
/*! \brief Check if calling thread is the owner of \a m. */
bool mtx_owned(mtx_t *m);
+/*! \brief Fetch mutex owner.
+ *
+ * \note The function is used by some tests. */
+static inline volatile thread_t *mtx_owner(mtx_t *m) {
+ return m->m_owner;
+}
+
/*! \brief Locks the mutex (with custom \a waitpt) */
void _mtx_lock(mtx_t *m, const void *waitpt);

MODIFY
include/thread.h
include/thread.h
@@ -150,4 +150,29 @@ void thread_join(thread_t *td);
* verify test success. */
void thread_reap(void);
+/* Please use following functions to read state of a thread! */
+static inline bool td_is_ready(thread_t *td) {
+ return td->td_state == TDS_READY;
+}
+
+static inline bool td_is_dead(thread_t *td) {
+ return td->td_state == TDS_DEAD;
+}
+
+static inline bool td_is_running(thread_t *td) {
+ return td->td_state == TDS_RUNNING;
+}
+
+static inline bool td_is_inactive(thread_t *td) {
+ return td->td_state == TDS_INACTIVE;
+}
+
+static inline bool td_is_sleeping(thread_t *td) {
+ return td->td_state == TDS_SLEEPING;
+}
+
+static inline bool td_is_borrowing(thread_t *td) {
+ return td->td_flags & TDF_BORROWING;
+}
+
#endif /* !_SYS_THREAD_H_ */

MODIFY
sys/sched.c
sys/sched.c
@@ -32,7 +32,7 @@ void sched_add(thread_t *td) {
void sched_wakeup(thread_t *td) {
assert(spin_owned(td->td_spin));
assert(td != thread_self());
- assert(td->td_state == TDS_SLEEPING || td->td_state == TDS_INACTIVE);
+ assert(td_is_sleeping(td) || td_is_inactive(td));
/* Update sleep time. */
timeval_t now = get_uptime();
@@ -60,7 +60,7 @@ static void sched_set_active_prio(thread_t *td, prio_t prio) {
if (td->td_prio == prio)
return;
- if (td->td_state == TDS_READY) {
+ if (td_is_ready(td)) {
/* Thread is on a run queue. */
runq_remove(&runq, td);
td->td_prio = prio;
@@ -76,7 +76,7 @@ void sched_set_prio(thread_t *td, prio_t prio) {
td->td_base_prio = prio;
/* If thread is borrowing priority, don't lower its active priority. */
- if (td->td_flags & TDF_BORROWING && td->td_prio > prio)
+ if (td_is_borrowing(td) && td->td_prio > prio)
return;
sched_set_active_prio(td, prio);
@@ -121,7 +121,7 @@ void sched_switch(void) {
thread_t *td = thread_self();
assert(spin_owned(td->td_spin));
- assert(td->td_state != TDS_RUNNING);
+ assert(!td_is_running(td));
td->td_flags &= ~(TDF_SLICEEND | TDF_NEEDSWITCH);
@@ -130,14 +130,14 @@ void sched_switch(void) {
timeval_t diff = timeval_sub(&now, &td->td_last_rtime);
td->td_rtime = timeval_add(&td->td_rtime, &diff);
- if (td->td_state == TDS_READY) {
+ if (td_is_ready(td)) {
/* Idle threads need not to be inserted into the run queue. */
if (td != PCPU_GET(idle_thread))
runq_add(&runq, td);
- } else if (td->td_state == TDS_SLEEPING) {
+ } else if (td_is_sleeping(td)) {
/* Record when the thread fell asleep. */
td->td_last_slptime = now;
- } else if (td->td_state == TDS_DEAD) {
+ } else if (td_is_dead(td)) {
/* Don't add dead threads to run queue. */
}

MODIFY
sys/signal.c
sys/signal.c
@@ -73,7 +73,7 @@ int sig_send(proc_t *proc, signo_t sig) {
SCOPED_MTX_LOCK(&target->td_lock);
/* If the thread is already dead, don't post a signal. */
- if (target->td_state == TDS_DEAD)
+ if (td_is_dead(target))
return -EINVAL;
WITH_MTX_LOCK (&target->td_proc->p_lock) {

MODIFY
sys/thread.c
sys/thread.c
@@ -91,7 +91,7 @@ thread_t *thread_create(const char *name, void (*fn)(void *), void *arg) {
}
void thread_delete(thread_t *td) {
- assert(td->td_state == TDS_DEAD);
+ assert(td_is_dead(td));
assert(td->td_sleepqueue != NULL);
klog("Freeing up thread %ld {%p}", td->td_tid, td);
@@ -154,7 +154,7 @@ void thread_join(thread_t *otd) {
klog("Join %ld {%p} with %ld {%p}", td->td_tid, td, otd->td_tid, otd);
- while (otd->td_state != TDS_DEAD)
+ while (!td_is_dead(otd))
cv_wait(&otd->td_waitcv, &otd->td_lock);
}

Cleanup: do not access directly thread state and mutex owner (#434)