From 971efada741e1d984cd284d591f15adaba03c77b Mon Sep 17 00:00:00 2001 From: fanbingxin Date: Thu, 12 Aug 2021 00:33:59 +0800 Subject: [PATCH] kernel: optimize futex with timeout (#80) --- kernel/lock.go | 11 +++++++++-- kernel/thread.go | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/kernel/lock.go b/kernel/lock.go index e7a895a..25c9f9d 100644 --- a/kernel/lock.go +++ b/kernel/lock.go @@ -41,8 +41,14 @@ func sleeptimeout(addr *uintptr, val uintptr, ts *linux.Timespec) { deadline := nanosecond() + int64(ts.Nsec) + int64(ts.Sec)*second // check on every timer intr now := nanosecond() + t := Mythread() for now < deadline && *addr == val { - sleepon(&sleeplock) + t.timerKey = uintptr(unsafe.Pointer(&sleeplock)) + t.sleepKey = uintptr(unsafe.Pointer(addr)) + t.state = SLEEPING + Sched() + t.timerKey = 0 + t.sleepKey = 0 now = nanosecond() } } @@ -61,9 +67,10 @@ func sleepon(lock *uintptr) { func wakeup(lock *uintptr, n int) { limit := uint(n) cnt := uint(0) + lockKey := uintptr(unsafe.Pointer(lock)) for i := 0; i < _NTHREDS; i++ { t := &threads[i] - if t.sleepKey == uintptr(unsafe.Pointer(lock)) && cnt < limit { + if (t.sleepKey == lockKey || t.timerKey == lockKey) && cnt < limit { cnt++ t.state = RUNNABLE } diff --git a/kernel/thread.go b/kernel/thread.go index 3afc1ca..c9f334e 100644 --- a/kernel/thread.go +++ b/kernel/thread.go @@ -73,6 +73,8 @@ type Thread struct { // sysmon 会调用usleep,进而调用sleepon,如果sleepKey是个指针会触发gcWriteBarrier // 而sysmon没有P,会导致空指针 sleepKey uintptr + // for sleep timeout + timerKey uintptr // store goroutine tls fsBase uintptr