summaryrefslogtreecommitdiff
path: root/fibers
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2017-02-17 14:00:31 +0100
committerAndy Wingo <wingo@pobox.com>2017-02-17 14:00:31 +0100
commit89b9e58bf3789bc18ee2c680add3962cc75423c0 (patch)
treeed8e51e1a0025d259391cc728011f288fc7d3e46 /fibers
parentAdd allocation speedup test (diff)
downloadguile-fibers-89b9e58bf3789bc18ee2c680add3962cc75423c0.tar.gz
Prevent spurious preemption
* fibers/internal.scm (<scheduler>, make-scheduler): (scheduler-runcount, run-scheduler): Maintain a count of run fibers. * fibers.scm (%run-fibers): Only cause the current fiber to suspend if the runcount isn't advancing.
Diffstat (limited to 'fibers')
-rw-r--r--fibers/internal.scm16
1 files changed, 14 insertions, 2 deletions
diff --git a/fibers/internal.scm b/fibers/internal.scm
index 1345ae0..31b17b8 100644
--- a/fibers/internal.scm
+++ b/fibers/internal.scm
@@ -32,6 +32,7 @@
make-scheduler
with-scheduler
scheduler-name
+ scheduler-runcount
(scheduler-kernel-thread/public . scheduler-kernel-thread)
scheduler-remote-peers
choose-parallel-scheduler
@@ -79,13 +80,15 @@ name is known."
(nameset-ref fibers-nameset name))
(define-record-type <scheduler>
- (%make-scheduler name epfd prompt-tag
+ (%make-scheduler name epfd runcount-box prompt-tag
next-runqueue current-runqueue
sources timers kernel-thread
remote-peers choose-parallel-scheduler)
scheduler?
(name scheduler-name set-scheduler-name!)
(epfd scheduler-epfd)
+ ;; atomic variable of uint32
+ (runcount-box scheduler-runcount-box)
(prompt-tag scheduler-prompt-tag)
;; atomic stack of fiber to run next turn (reverse order)
(next-runqueue scheduler-next-runqueue)
@@ -143,6 +146,7 @@ name is known."
(prompt-tag (make-prompt-tag "fibers")))
"Make a new scheduler in which to run fibers."
(let ((epfd (epoll-create))
+ (runcount-box (make-atomic-box 0))
(next-runqueue (make-empty-stack))
(current-runqueue (make-empty-stack))
(sources (make-hash-table))
@@ -150,7 +154,7 @@ name is known."
(((t1 . c1) (t2 . c2)) (< t1 t2)))
<))
(kernel-thread (make-atomic-parameter #f)))
- (let ((sched (%make-scheduler #f epfd prompt-tag
+ (let ((sched (%make-scheduler #f epfd runcount-box prompt-tag
next-runqueue current-runqueue
sources timers kernel-thread
#f #f)))
@@ -183,6 +187,11 @@ thread."
(lambda ()
((scheduler-kernel-thread sched) #f)))))
+(define (scheduler-runcount sched)
+ "Return the number of fibers that have been scheduled on
+@var{sched} since it was started, modulo 2@sup{32}."
+ (atomic-box-ref (scheduler-runcount-box sched)))
+
(define (scheduler-kernel-thread/public sched)
"Return the kernel thread on which @var{sched} is running, or
@code{#f} if @var{sched} is not running."
@@ -301,10 +310,13 @@ stolen."
file descriptors being waited on, and no more timers pending to run.
Return zero values."
(let ((tag (scheduler-prompt-tag sched))
+ (runcount-box (scheduler-runcount-box sched))
(next (scheduler-next-runqueue sched))
(cur (scheduler-current-runqueue sched))
(steal-fiber! (fiber-stealer sched)))
(define (run-fiber fiber)
+ (atomic-box-set! runcount-box
+ (logand (1+ (atomic-box-ref runcount-box)) #xffffFFFF))
(call-with-prompt tag
(lambda ()
(let ((thunk (fiber-continuation fiber)))