Thanks, Eli. That looks nice. Matthew suggested something similar, but using mzlib/couroutine, where I use a low-priority gui callback to give the thread the next quantum.
Robby On Mon, Nov 9, 2009 at 4:08 PM, Eli Barzilay <e...@barzilay.org> wrote: > [Moving to plt-dev.] > > On Nov 9, Robby Findler wrote: >> >> I find such behavior annoying in my OS and expect it would be the >> same in DrScheme. Things will be sluggish while it is loading. >> >> Nevertheless, I will try this if the parallelism stuff doesn't pan >> out. > > 1. I find the delay-on-first-syncheck especially annoying in class. I > always start a new drscheme at the beginning of the class, which > means that I'm guaranteed to get the annoying delay. (And it's a > classic case of unjustified delay, since drscheme will sit there > for many minutes doing nothing before I get to use it.) It's at a > level where I hesitate to use it -- and on some occasions I > pre-arrange myself so that I click it while I speak to mask out the > delay. (Being able to do such things is something that I had to > learn as a stutterer...) > > 2. BTW, the status-line message is not showing at all on linux. I > never knew that there was supposed to be such a message. (I almost > never run it on my laptop.) > > 3. IMO, the issue will not be completely resolved with multiple > cores. What if my other core is busy doing something else? What > about school machines that can be very outdated? What about IO > delays, since this does involve mostly IO? > > 4. The usual way to do these things is to have it loaded when it is > idle (exactly what Stephen said) -- but then don't just start to > load it so everything becomes slow, just do that in little > execution chunks which are done only if the system is still > otherwise idle. I think that MzScheme could use some more > functionality in this area -- a nice feature to have would be a way > for a thread to change its priority where this can also be a "run > me only when otherwise idle" (it would be especially nice to have a > hierarchy of these: "run me when otherwise idle including 1st-level > idle-priority threads, and give me only 20% running time"). > > 5. Fantasies aside, I think that it is possible to do a reasonable job > for this given the current tools. The code below looks to me like > it should work fine. It runs a given thunk in the background while > drscheme is idle, and using little cpu time so there's no alarming > cpu load. The returned result is a thunk that returns the computed > value -- waiting for it (while giving it 100% cpu) if it isn't > ready yet. > > 6. To try it, I basically changed "syncheck.ss" with this definition: > > (define get-xref > (run-lazily (lambda () > (with-handlers ([exn? (lambda (_) #f)]) > (load-collections-xref))))) > > I've tried it in DrScheme (on my Windows laptop, so the delay is > more noticeable), and it looks like it works fine. No need for > multicore support... > > 7. Maybe this would be a good addition to `scheme/promise'. > > > > ;; Run `thunk' when idle, slicing the time to `slice'-second frames, > ;; using only `use' seconds from each frame. Return a thunk that > ;; returns the result of the computation, giving it full cpu if it's not > ;; ready yet. > (define (run-lazily thunk #:slice [slice 0.3] #:use [use 0.05]) > (define idle-evt (system-idle-evt)) > (define force-sema (make-semaphore 0)) > (define results #f) > (define (work) > (with-handlers ([void (lambda (e) (set! results (cons raise e)))]) > (set! results (cons values (call-with-values thunk list))))) > (define (start) > (sync idle-evt) > (let ([worker (parameterize ([current-thread-group (make-thread-group)]) > (thread work))]) > (thread-suspend worker) > (let loop () > ;; rest, then wait for idle time, then resume working > (if (eq? (begin0 (or (sync/timeout (- slice use) force-sema) > (sync idle-evt force-sema)) > (thread-resume worker)) > force-sema) > ;; forced during one of these => let it run to completion > (thread-wait worker) > ;; not forced > (unless (sync/timeout use worker) (thread-suspend worker) (loop)))))) > (define main-thread > (parameterize ([current-thread-group (make-thread-group)]) > (thread start))) > (lambda () > (unless (thread-dead? main-thread) > (semaphore-post force-sema) > (thread-wait main-thread)) > (apply (car results) (cdr results)))) > > -- > ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: > http://barzilay.org/ Maze is Life! > _________________________________________________ For list-related administrative tasks: http://list.cs.brown.edu/mailman/listinfo/plt-dev