Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

poll_fd returns earlier than timeout.....once in a while. #3015

Closed
amitmurthy opened this issue May 4, 2013 · 17 comments
Closed

poll_fd returns earlier than timeout.....once in a while. #3015

amitmurthy opened this issue May 4, 2013 · 17 comments
Labels
domain:io Involving the I/O subsystem: libuv, read, write, etc. kind:upstream The issue is with an upstream dependency, e.g. LLVM

Comments

@amitmurthy
Copy link
Contributor

For the trivial case of a 1 millisecond timeout, the following looping code usually throws an exception after around 40-50 poll_fd calls...

using Base.Test

pipe_fds = Array(Cint,2)
@test 0 == ccall(:pipe, Cint, (Ptr{Cint},), pipe_fds)

i = 100
while (i > 0)    

    println(i)
    tic()
    rc = poll_fd(OS_FD(pipe_fds[1]), UV_READABLE, 1)
    t = toc()

    if (t * 1000) < 1
        print(t * 1000000); println(" microseconds")
        println("$t < 0.001")
        error("Timeout exited early!")
    end
    i = i-1
end

ccall(:close, Cint, (Cint,), pipe_fds[1])
ccall(:close, Cint, (Cint,), pipe_fds[2])

cc: @loladiro

@amitmurthy
Copy link
Contributor Author

So does sleep() - seems like an issue with sleep (Timer) rather than poll_fd.

i = 100
while (i > 0)    

    println(i)
    tic()
    sleep(0.001)
    t = toc()

    if (t * 1000) < 1
        print(t * 1000000); println(" microseconds")
        println("$t < 0.001")
        error("Timeout exited early!")
    end
    i = i-1
end

@vtjnash
Copy link
Sponsor Member

vtjnash commented May 4, 2013

@loladiro fixed the julia part of this in 95b6349

The upstream libuv bug means that the duration argument gets reduced by 1 millisecond (the minimum resolution of the timer) when the timeout is computed. We could provide a temporary hack by incrementing the given duration by 1.

@StefanKarpinski
Copy link
Sponsor Member

Wonder if that could have anything to do with #3034?

@vtjnash
Copy link
Sponsor Member

vtjnash commented May 7, 2013

I'm not sure how this (a libuv bug that reduces timeouts by up to 1 ms) has anything to do with the system picking up the wrong library.

@StefanKarpinski
Copy link
Sponsor Member

Bugs like this aren't always obvious. I'm looking for anything a) weird, b) non-deterministic, c) kicking in with multiple processes. This seems to fit that very vague bill. Plus, I got you to look at the other issue, so I win :-)

@staticfloat
Copy link
Sponsor Member

I was creating a new issue for the Travis build errors when I suddenly remembered this one. Could this be the cause behind these Travis build errors: 1, 2, 3

@Keno
Copy link
Member

Keno commented May 7, 2013

Yes, yes and yes. Sorry, I'll work on this as soon as I'm out of exams (god damn homology theory), unless somebody wants to tackle it first.

@staticfloat
Copy link
Sponsor Member

No hurry, @loladiro. Have fun with your semester system, I'm barely halfway through my quarter. :)

@JeffBezanson
Copy link
Sponsor Member

While we're at it, we should normalize all the time-related functions to accept seconds instead of milliseconds.

@amitmurthy
Copy link
Contributor Author

If by seconds, you mean Float64, then I feel it should be the other way around. All system calls use integers for time values, and the rounding up behavior of int() functions can lead to bugs in the translation of Float64 to the system API parameters if the programmer is not careful and aware of the same.

Better to standardize on (seconds::Int, microseconds::Int) everywhere.

@JeffBezanson
Copy link
Sponsor Member

Nobody said we have to round up. We could even require that (seconds * units_per_second) be close to an integer.

I think breaking it into two arguments is too hard to use. If we want to base it on integers, perhaps we should use a type like in extras/time.jl storing an integer and a power of ten. I agree that seconds and microseconds handle all normal uses, but the choice of microseconds is nevertheless arbitrary and hard to remember.

@StefanKarpinski
Copy link
Sponsor Member

We can always have some time structure that represents seconds + milliseconds (or nano or whatever), but these should all accept floating-point seconds for ease of use. The second is the SI unit for time and the most intuitive, so that really what we should standardize on IMO. Writing 1seconds + 100milliseconds could construct a precise representation of that amount of time, rather than a floating-point number of seconds that only approximates it.

@Keno Keno closed this as completed in 7310f55 Jun 18, 2013
@Keno
Copy link
Member

Keno commented Jun 18, 2013

Note that while I added 1 on Unix according to the libuv developers, this trick will not work on Windows and there is no way to ensure that the timer does not exit early.

@StefanKarpinski
Copy link
Sponsor Member

Can we internally have the timer go off, realize it's early and reset itself with the remaining amount of time?

@Keno
Copy link
Member

Keno commented Jun 18, 2013

Maybe. I need to discuss this with one of the libuv windows developers who wasn't on IRC when I talked to them.

@Keno
Copy link
Member

Keno commented Jun 18, 2013

Actually according to the libuv developer whom I just spoke to, he managed to fix this on Windows, so maybe the issue is gone.

@StefanKarpinski
Copy link
Sponsor Member

That would be great.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:io Involving the I/O subsystem: libuv, read, write, etc. kind:upstream The issue is with an upstream dependency, e.g. LLVM
Projects
None yet
Development

No branches or pull requests

6 participants