#include <assert.h>
#include "clock.h"
+#include "debug.h"
#ifdef CONFIG_WATCHDOG
#include "watchdog.h"
billp = bill_ptr;
p->p_user_time += ticks;
+
+#if DEBUG_RACE
+ /* With DEBUG_RACE, every process gets interrupted. */
+ p->p_ticks_left = 0;
+#else
if (priv(p)->s_flags & PREEMPTIBLE) {
p->p_ticks_left -= ticks;
}
+#endif
if (! (priv(p)->s_flags & BILLABLE)) {
billp->p_sys_time += ticks;
}
/* Verbose messages. */
#define DEBUG_TRACE 0
+/* DEBUG_RACE makes every process preemptible, schedules
+ * every process on the same priority queue, and randomizes
+ * the next process to run, in order to help catch race
+ * conditions that could otherwise be masked.
+ */
+#define DEBUG_RACE 0
+
#if DEBUG_TRACE
#define VF_SCHEDULING (1L << 1)
*/
int q = rp->p_priority; /* scheduling queue to use */
+#if DEBUG_RACE
+ /* With DEBUG_RACE, schedule everyone at the same priority level. */
+ rp->p_priority = q = MIN_USER_Q;
+#endif
+
assert(proc_is_runnable(rp));
assert(q >= 0);
#endif
}
+#if DEBUG_RACE
+/*===========================================================================*
+ * random_process *
+ *===========================================================================*/
+PRIVATE struct proc *random_process(struct proc *head)
+{
+ int i, n = 0;
+ struct proc *rp;
+ u64_t r;
+ read_tsc_64(&r);
+
+ for(rp = head; rp; rp = rp->p_nextready)
+ n++;
+
+ /* Use low-order word of TSC as pseudorandom value. */
+ i = r.lo % n;
+
+ for(rp = head; i--; rp = rp->p_nextready)
+ ;
+
+ assert(rp);
+
+ return rp;
+}
+#endif
+
/*===========================================================================*
* pick_proc *
*===========================================================================*/
TRACE(VF_PICKPROC, printf("queue %d empty\n", q););
continue;
}
+
+#if DEBUG_RACE
+ rp = random_process(rdy_head[q]);
+#endif
+
TRACE(VF_PICKPROC, printf("found %s / %d on queue %d\n",
rp->p_name, rp->p_endpoint, q););
assert(proc_is_runnable(rp));
* be renewed. In fact, they by pass scheduling
*/
p->p_ticks_left = p->p_quantum_size;
+#if DEBUG_RACE
+ RTS_SET(proc_ptr, RTS_PREEMPTED);
+ RTS_UNSET(proc_ptr, RTS_PREEMPTED);
+#endif
}
}
}