[racket-dev] BUG: busy-waiting
Thanks! I've pushed a repair.
At Thu, 4 Sep 2014 01:56:07 -0400, Marc Burns wrote:
> Yes. I forgot that, in the case I was debugging, `unzip` was wrapping
> its input pipe with `make-limited-input-port`. The user port created by
> `make-limited-input-port` is causing the loop. Here's an example:
>
> #lang racket/base
> (require racket/port)
>
> (define-values (in out) (make-pipe))
> (define p (make-limited-input-port in 10 #t))
>
> (write-bytes #"hello" out)
>
> (define buffer (make-bytes 1))
> (peek-bytes-avail! buffer 6 #f p 0 1)
>
> The `do-peek` function in port.rkt:1027 makes a nonblocking attempt to
> peek from the wrapped port. When the peek is unsuccessful, it returns an
> event that is ready when the wrapped port is ready and whose value is
> zero.
>
> Thus, when the wrapped port has greater than zero and fewer than `skip`
> bytes available, `do-peek` is nonblocking.
>
> The call to `peek-bytes-avail!` then loops calling `do-peek`.
>
> I think that this could be resolved by returning
>
> (choice-evt
> (wrap-evt progress-evt (lambda(x) #f))
> (wrap-evt
> (peek-bytes-evt skip 0 #f port)
> (lambda(x) 0)))
>
> instead of the wrapped port event at port.rkt:1027
>
> Then again, couldn't `do-peek` just return the appropriate
> `peek-bytes-evt` when `count` is nonzero?
>
> Marc
>
> On Thu, Sep 04, 2014 at 05:49:17AM +0200, Matthew Flatt wrote:
> > Can you provide an example?
> >
> > Here's what I tried, but it blocks without busy-waiting:
> >
> > ----------------------------------------
> > #lang racket
> > (require file/gunzip file/gzip)
> >
> > (define dest (open-output-bytes))
> > (deflate (open-input-bytes #"hello") dest)
> >
> > (define bstr (get-output-bytes dest))
> >
> > (define-values (i o) (make-pipe))
> >
> > ;; Omit the last byte:
> > (write-bytes bstr o 0 (- (bytes-length bstr) 1))
> >
> > 'inflating...
> > (inflate i (open-output-bytes))
> > ----------------------------------------
> >
> >
> > At Wed, 3 Sep 2014 21:02:06 -0400, Marc Burns wrote:
> > > The offending function in my case seems to be peek-bytes-avail!
> > >
> > > The busy wait is entered on line 284 of collects/file/gunzip.rkt. Here's
> > > what happens when I add some tracing to gunzip.rkt and then try to
> > > inflate a Racket pipe:
> > >
> > > ...
> > > + (displayln "before read-bytes!")
> > > (read-bytes! buffer input-port 0 (max 0 (- buf-max
> MAX-LOOKAHEAD)))
> > > + (displayln "after read-bytes!")
> > > ;; Even though we won't actually use bytes that we "unwind",
> > > ;; setting `buf-pos' to the number of unwound bytes lets us
> > > ;; keep track of how much to not actually read at the end.
> > > (set! buf-pos (min MAX-LOOKAHEAD buf-max)))
> > > ;; Peek (not read) some available bytes:
> > > + (displayln "before peek-bytes-avail!")
> > > (let ([got (peek-bytes-avail! buffer buf-pos #f input-port
> buf-pos
> > > BUFFER-SIZE)])
> > > + (displayln "after peek-bytes-avail!")
> > > ...
> > > + (trace READBITS)
> > >
> > > Output:
> > >
> > > ...
> > > >(READBITS 9)
> > > <#<void>
> > > >(READBITS 9)
> > > before read-bytes!
> > > after read-bytes!
> > > before peek-bytes-avail!
> > >
> > > That's it. Racket is busy-waiting in peek-bytes-avail!
> > >
> > > On Wed, Sep 03, 2014 at 10:52:18PM +0200, Jan Dvořák wrote:
> > > > Hello,
> > > >
> > > > I am hitting a rather uncomfortable bug that causes runtime to start
> > > > internal busy-waiting at around:
> > > >
> > > > #0 scheme_block_until(_f=<syncing_ready>,
> > > > fdf=<scheme_syncing_needs_wakeup>)
> > > > at ../src/thread.c:5199
> > > > #1 do_sync (name="sync", with_break=0, with_timeout=0)
> > > > at ../src/thread.c:7109
> > > >
> > > > It goes through ../src/thread.c:5190, which Matthew mentions in one of his
> > > > recent patches.
> > > >
> > > > The code that manages to trigger this have been written under NDA and
> cannot
> > > > be published. I have not yet managed to reproduce the issue separately,
> but
> > > > it seems that this might not be the only instance:
> > > >
> > > > (09:28:36 PM) m4burns: Mordae: I'm having a similar problem somewhere
> in
> > > > `inflate`. Haven't applied a debugger yet, but
> > > > there's certainly no busy waiting in the script.
> > > >
> > > > I am stuck and would like to ask for your help.
> > > >
> > > > Best regards,
> > > > Jan Dvorak
> > > >
> > > >
> > > >
> > > > _________________________
> > > > Racket Developers list:
> > > > http://lists.racket-lang.org/dev
> > > >
> > > _________________________
> > > Racket Developers list:
> > > http://lists.racket-lang.org/dev
> >