struct callout thandle;
/*
+ * Currently a severe hack. Make sure any delayed wakeups
+ * are flushed before we sleep or we might deadlock on whatever
+ * event we are sleeping on.
+ */
+ if (td->td_flags & TDF_DELAYED_WAKEUP)
+ wakeup_end_delayed();
+
+ /*
* NOTE: removed KTRPOINT, it could cause races due to blocking
* even in stable. Just scrap it for now.
*/
void
wakeup(const volatile void *ident)
{
- _wakeup(__DEALL(ident), PWAKEUP_ENCODE(0, mycpu->gd_cpuid));
+ globaldata_t gd = mycpu;
+ thread_t td = gd->gd_curthread;
+
+ if (td && (td->td_flags & TDF_DELAYED_WAKEUP)) {
+ if (!atomic_cmpset_ptr(&gd->gd_delayed_wakeup[0], NULL, ident)) {
+ if (!atomic_cmpset_ptr(&gd->gd_delayed_wakeup[1], NULL, ident))
+ _wakeup(__DEALL(ident), PWAKEUP_ENCODE(0, gd->gd_cpuid));
+ }
+ return;
+ }
+ _wakeup(__DEALL(ident), PWAKEUP_ENCODE(0, gd->gd_cpuid));
}
/*
PWAKEUP_ENCODE(domain, mycpu->gd_cpuid) | PWAKEUP_ONE);
}
+void
+wakeup_start_delayed(void)
+{
+ globaldata_t gd = mycpu;
+
+ crit_enter();
+ gd->gd_curthread->td_flags |= TDF_DELAYED_WAKEUP;
+ crit_exit();
+}
+
+void
+wakeup_end_delayed(void)
+{
+ globaldata_t gd = mycpu;
+
+ if (gd->gd_curthread->td_flags & TDF_DELAYED_WAKEUP) {
+ crit_enter();
+ gd->gd_curthread->td_flags &= ~TDF_DELAYED_WAKEUP;
+ if (gd->gd_delayed_wakeup[0] || gd->gd_delayed_wakeup[1]) {
+ if (gd->gd_delayed_wakeup[0]) {
+ wakeup(gd->gd_delayed_wakeup[0]);
+ gd->gd_delayed_wakeup[0] = NULL;
+ }
+ if (gd->gd_delayed_wakeup[1]) {
+ wakeup(gd->gd_delayed_wakeup[1]);
+ gd->gd_delayed_wakeup[1] = NULL;
+ }
+ }
+ crit_exit();
+ }
+}
+
/*
* setrunnable()
*
#ifdef SMP
static int usched_dfly_smt = 0;
static int usched_dfly_cache_coherent = 0;
-static int usched_dfly_weight1 = 30; /* keep thread on current cpu */
-static int usched_dfly_weight2 = 15; /* synchronous peer's current cpu */
+static int usched_dfly_weight1 = 50; /* keep thread on current cpu */
+static int usched_dfly_weight2 = 30; /* synchronous peer's current cpu */
static int usched_dfly_weight3 = 10; /* number of threads on queue */
-static int usched_dfly_weight4 = 50; /* availability of idle cores */
+static int usched_dfly_weight4 = 40; /* availability of idle cores */
static int usched_dfly_features = 0x8F; /* allow pulls */
#endif
static int usched_dfly_rrinterval = (ESTCPUFREQ + 9) / 10;
void wakeup_oncpu_one (struct globaldata *gd, const volatile void *chan);
void wakeup_domain (const volatile void *chan, int domain);
void wakeup_domain_one (const volatile void *chan, int domain);
+void wakeup_start_delayed(void);
+void wakeup_end_delayed(void);
/*
* Common `cdev_t' stuff are declared here to avoid #include poisoning
#define TDF_EXITING 0x00400000 /* thread exiting */
#define TDF_USINGFP 0x00800000 /* thread using fp coproc */
#define TDF_KERNELFP 0x01000000 /* kernel using fp coproc */
-#define TDF_UNUSED02000000 0x02000000
+#define TDF_DELAYED_WAKEUP 0x02000000
#define TDF_CRYPTO 0x04000000 /* crypto thread */
#define TDF_MP_STOPREQ 0x00000001 /* suspend_kproc */