spin-wait based kernel timer (for futex() timeout) implementation

This commit is contained in:
Balazs Gerofi bgerofi@riken.jp
2012-11-28 15:22:53 +09:00
parent b59e36e1a5
commit 092069fd80
6 changed files with 121 additions and 19 deletions

View File

@@ -30,7 +30,7 @@
#define dkprintf(...)
#endif
#define LOOP_TIMEOUT 1000 /* default 1000 */
#define LOOP_TIMEOUT 500
struct list_head timers;
aal_spinlock_t timers_lock;
@@ -47,6 +47,56 @@ uint64_t schedule_timeout(uint64_t timeout)
struct waitq_entry my_wait;
struct timer my_timer;
unsigned long irqflags;
struct process *proc = cpu_local_var(current);
irqflags = aal_mc_spinlock_lock(&proc->spin_sleep_lock);
dkprintf("schedule_timeout() spin sleep timeout: %lu\n", timeout);
proc->spin_sleep = 1;
aal_mc_spinlock_unlock(&proc->spin_sleep_lock, irqflags);
/* Spin sleep.. */
for (;;) {
uint64_t t_s = rdtsc();
uint64_t t_e;
int spin_over = 0;
irqflags = aal_mc_spinlock_lock(&proc->spin_sleep_lock);
/* Woken up by someone? */
if (!proc->spin_sleep) {
t_e = rdtsc();
spin_over = 1;
if ((t_e - t_s) < timeout) {
timeout -= (t_e - t_s);
}
else {
timeout = 1;
}
}
aal_mc_spinlock_unlock(&proc->spin_sleep_lock, irqflags);
t_s = rdtsc();
while ((rdtsc() - t_s) < LOOP_TIMEOUT) {
cpu_pause();
}
if (timeout < LOOP_TIMEOUT) {
timeout = 0;
spin_over = 1;
}
else {
timeout -= LOOP_TIMEOUT;
}
if (spin_over) {
dkprintf("schedule_timeout() spin woken up, timeout: %lu\n",
timeout);
return timeout;
}
}
/* Init waitq and wait entry for this timer */
my_timer.timeout = (timeout < LOOP_TIMEOUT) ? LOOP_TIMEOUT : timeout;
@@ -72,6 +122,7 @@ uint64_t schedule_timeout(uint64_t timeout)
if (my_timer.timeout) {
list_del(&my_timer.list);
}
aal_mc_spinlock_unlock(&timers_lock, irqflags);
dkprintf("schedule_timeout() woken up, timeout: %lu\n",