From 2084162132b3845941d1028b329c25b50f0245ad Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Tue, 19 Jun 2018 04:59:53 +0900 Subject: [PATCH 1/2] Compat Julia 0.7, using BinaryProvider to generate deps.jl --- .travis.yml | 1 + REQUIRE | 4 +++- appveyor.yml | 2 ++ deps/build.jl | 14 ++++++++++++ src/RingBuffers.jl | 18 ++++++++++------ src/pa_ringbuffer.jl | 51 ++++++++------------------------------------ test/runtests.jl | 23 ++++++++++++-------- 7 files changed, 54 insertions(+), 59 deletions(-) create mode 100644 deps/build.jl diff --git a/.travis.yml b/.travis.yml index e0c56f8..16dfacb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ os: - osx julia: - 0.6 + - nightly notifications: email: false # uncomment the following lines to override the default test script diff --git a/REQUIRE b/REQUIRE index f194848..88e8fc4 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1 +1,3 @@ -julia 0.6.0-pre +julia 0.6 +Compat 0.66.0 +BinaryProvider 0.3.0 diff --git a/appveyor.yml b/appveyor.yml index 79f229a..ad0c919 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,6 +2,8 @@ environment: matrix: - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe" - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe" + - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe" + - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe" branches: only: diff --git a/deps/build.jl b/deps/build.jl new file mode 100644 index 0000000..df2fe21 --- /dev/null +++ b/deps/build.jl @@ -0,0 +1,14 @@ +using BinaryProvider +using Compat + +const verbose = "--verbose" in ARGS +const prefix = Prefix(joinpath(@__DIR__, "usr")) + +# BinaryProvider v0.3.2 has libdir(prefix) bug on windows +@static if Compat.Sys.iswindows() + file_path = joinpath(prefix.path, "lib", string("pa_ringbuffer_", Sys.ARCH, "-w64-mingw32.dll")) + product = FileProduct(file_path, :libpa_ringbuffer) +else + product = LibraryProduct(prefix, "pa_ringbuffer", :libpa_ringbuffer) +end +satisfied(product; verbose=verbose) && write_deps_file(joinpath(@__DIR__, "deps.jl"), [product]) diff --git a/src/RingBuffers.jl b/src/RingBuffers.jl index a230c6b..e5ee831 100644 --- a/src/RingBuffers.jl +++ b/src/RingBuffers.jl @@ -1,4 +1,4 @@ -__precompile__() +__precompile__(true) module RingBuffers @@ -12,8 +12,12 @@ import Base: unsafe_convert, pointer import Base: isopen, close using Base: AsyncCondition +import Compat +import Compat: Libdl, Cvoid, undef, popfirst!, @compat -__init__() = init_pa_ringbuffer() +depsjl = joinpath(@__DIR__, "..", "deps", "deps.jl") +isfile(depsjl) ? include(depsjl) : error("RingBuffers not properly installed. Please run Pkg.build(\"RingBuffers\")") +__init__() = check_deps() include("pa_ringbuffer.jl") @@ -96,7 +100,7 @@ function write(rbuf::RingBuffer{T}, data::AbstractArray{T}, nframes) where {T} end finally # we're done, remove our condition and notify the next writer if necessary - shift!(rbuf.writers) + popfirst!(rbuf.writers) if length(rbuf.writers) > 0 notify(rbuf.writers[1]) end @@ -167,7 +171,7 @@ function flush(rbuf::RingBuffer) finally # we're done, remove our condition and notify the next writer if necessary - shift!(rbuf.writers) + popfirst!(rbuf.writers) if length(rbuf.writers) > 0 notify(rbuf.writers[1]) end @@ -224,7 +228,7 @@ function read!(rbuf::RingBuffer{T}, data::AbstractArray{T}, nframes) where {T} end finally # we're done, remove our condition and notify the next reader if necessary - shift!(rbuf.readers) + popfirst!(rbuf.readers) if length(rbuf.readers) > 0 notify(rbuf.readers[1]) end @@ -254,7 +258,7 @@ holding the interleaved data. If the buffer is empty the call will block until data is available or the ring buffer is closed. """ function read(rbuf::RingBuffer{T}, nframes) where {T} - data = Array{T}(rbuf.nchannels, nframes) + data = Array{T}(undef, rbuf.nchannels, nframes) nread = read!(rbuf, data, nframes) if nread < nframes @@ -273,7 +277,7 @@ available the call will block until it can read more or the ring buffer is closed. """ function read(rbuf::RingBuffer{T}; blocksize=4096) where {T} - readbuf = Array{T}(rbuf.nchannels, blocksize) + readbuf = Array{T}(undef, rbuf.nchannels, blocksize) # during accumulation we keep the channels separate so we can grow the # arrays without needing to copy data around as much cumbufs = [Vector{T}() for _ in 1:rbuf.nchannels] diff --git a/src/pa_ringbuffer.jl b/src/pa_ringbuffer.jl index a09b273..1d91c54 100644 --- a/src/pa_ringbuffer.jl +++ b/src/pa_ringbuffer.jl @@ -1,36 +1,4 @@ -function init_pa_ringbuffer() - libdir = joinpath(dirname(@__FILE__), "..", "deps", "usr", "lib") - libsuffix = "" - @static if is_linux() && Sys.ARCH == :x86_64 - libsuffix = "x86_64-linux-gnu" - elseif is_linux() && Sys.ARCH == :i686 - libsuffix = "i686-linux-gnu" - elseif is_apple() && Sys.ARCH == :x86_64 - libsuffix = "x86_64-apple-darwin14" - elseif is_windows() && Sys.ARCH == :x86_64 - libsuffix = "x86_64-w64-mingw32" - elseif is_windows() && Sys.ARCH == :i686 - libsuffix = "i686-w64-mingw32" - elseif !any( - (sfx) -> isfile(joinpath(libdir, "pa_ringbuffer.$sfx")), - ("so", "dll", "dylib")) - error("Unsupported platform $(Sys.MACHINE). You can build your own library by running `make` from $(joinpath(@__FILE__, "..", "deps", "src"))") - end - # if there's a suffix-less library, it was built natively on this machine, - # so load that one first, otherwise load the pre-built one - global const libpa_ringbuffer = Base.Libdl.find_library( - ["pa_ringbuffer", "pa_ringbuffer_$libsuffix"], - [libdir]) - libpa_ringbuffer == "" && error("Could not load pa_ringbuffer library, please file an issue at https://github.com/JuliaAudio/RingBuffers.jl/issues with your `versioninfo()` output") - # override dlopen flags to make sure we always use `RTLD_GLOBAL` so that the - # library functions are available to other C shim libraries that other - # packages might need to add to handle their audio callbacks. - Libdl.dlopen(libpa_ringbuffer, Libdl.RTLD_LAZY | - Libdl.RTLD_DEEPBIND | - Libdl.RTLD_GLOBAL) -end - -@static if is_apple() +@static if Compat.Sys.isapple() const RingBufferSize = Int32 else const RingBufferSize = Clong @@ -56,7 +24,7 @@ mutable struct PaUtilRingBuffer rbuf = new() PaUtil_InitializeRingBuffer(rbuf, elementSizeBytes, elementCount, data) - finalizer(rbuf, close) + @compat finalizer(close, rbuf) rbuf end end @@ -79,17 +47,16 @@ Initialize Ring Buffer to empty state ready to have elements written to it. * `rbuf::PaUtilRingBuffer`: The ring buffer. * `elementSizeBytes::RingBufferSize`: The size of a single data element in bytes. * `elementCount::RingBufferSize`: The number of elements in the buffer (must be a power of 2). -* `dataPtr::Ptr{Void}`: A pointer to a previously allocated area where the data +* `dataPtr::Ptr{Cvoid}`: A pointer to a previously allocated area where the data will be maintained. It must be elementCount*elementSizeBytes long. """ function PaUtil_InitializeRingBuffer(rbuf, elementSizeBytes, elementCount, dataPtr) if !ispow2(elementCount) throw(ErrorException("elementCount($elementCount) must be a power of 2")) end - status = ccall((:PaUtil_InitializeRingBuffer, libpa_ringbuffer), RingBufferSize, - (Ref{PaUtilRingBuffer}, RingBufferSize, RingBufferSize, Ptr{Void}), + (Ref{PaUtilRingBuffer}, RingBufferSize, RingBufferSize, Ptr{Cvoid}), rbuf, elementSizeBytes, elementCount, dataPtr) if status != 0 throw(ErrorException("PaUtil_InitializeRingBuffer returned status $status")) @@ -106,7 +73,7 @@ Reset buffer to empty. Should only be called when buffer is NOT being read or wr """ function PaUtil_FlushRingBuffer(rbuf) ccall((:PaUtil_FlushRingBuffer, libpa_ringbuffer), - Void, + Cvoid, (Ref{PaUtilRingBuffer}, ), rbuf) end @@ -137,7 +104,7 @@ end """ PaUtil_WriteRingBuffer(rbuf::PaUtilRingBuffer, - data::Ptr{Void}, + data::Ptr{Cvoid}, elementCount::RingBufferSize) Write data to the ring buffer and return the number of elements written. @@ -145,13 +112,13 @@ Write data to the ring buffer and return the number of elements written. function PaUtil_WriteRingBuffer(rbuf, data, elementCount) ccall((:PaUtil_WriteRingBuffer, libpa_ringbuffer), RingBufferSize, - (Ref{PaUtilRingBuffer}, Ptr{Void}, RingBufferSize), + (Ref{PaUtilRingBuffer}, Ptr{Cvoid}, RingBufferSize), rbuf, data, elementCount) end """ PaUtil_ReadRingBuffer(rbuf::PaUtilRingBuffer, - data::Ptr{Void}, + data::Ptr{Cvoid}, elementCount::RingBufferSize) Read data from the ring buffer and return the number of elements read. @@ -159,6 +126,6 @@ Read data from the ring buffer and return the number of elements read. function PaUtil_ReadRingBuffer(rbuf, data, elementCount) ccall((:PaUtil_ReadRingBuffer, libpa_ringbuffer), RingBufferSize, - (Ref{PaUtilRingBuffer}, Ptr{Void}, RingBufferSize), + (Ref{PaUtilRingBuffer}, Ptr{Cvoid}, RingBufferSize), rbuf, data, elementCount) end diff --git a/test/runtests.jl b/test/runtests.jl index 0c9d500..d52516d 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,6 +1,7 @@ using RingBuffers using TestSetExtensions -using Base.Test +import Compat: undef, fetch +using Compat.Test @testset ExtendedTestSet "RingBuffer Tests" begin include("pa_ringbuffer.jl") @@ -105,7 +106,7 @@ using Base.Test sleep(0.1) @test t.state == :runnable readdata = read(rb, 8) - @test wait(t) == 5 + @test fetch(t) == 5 @test t.state == :done @test readdata == hcat(writedata, writedata[:, 1:3]) end @@ -118,7 +119,7 @@ using Base.Test sleep(0.1) @test t.state == :runnable write(rb, writedata) - @test wait(t) == hcat(writedata, writedata) + @test fetch(t) == hcat(writedata, writedata) @test t.state == :done end @@ -129,8 +130,8 @@ using Base.Test t2 = @async write(rb, writedata) sleep(0.1) close(rb) - @test wait(t1) == 8 - @test wait(t2) == 0 + @test fetch(t1) == 8 + @test fetch(t2) == 0 end @testset "closing ringbuf cancels in-progress reads" begin @@ -141,8 +142,8 @@ using Base.Test t2 = @async read(rb, 5) sleep(0.1) close(rb) - @test wait(t1) == writedata[:, 1:3] - @test wait(t2) == Array{Int}(2, 0) + @test fetch(t1) == writedata[:, 1:3] + @test fetch(t2) == Array{Int}(undef, 2, 0) end @testset "writeavailable works with Matrices" begin @@ -169,7 +170,11 @@ using Base.Test end flush(rb) close(rb) - @test wait(reader) == repmat(writedata, 1, 4) + if VERSION >= v"0.7.0-DEV.3977" # Julia PR 26039 + @test fetch(reader) == repeat(writedata, 1, 4) + else + @test fetch(reader) == Compat.repmat(writedata, 1, 4) + end end @testset "flush works if we're queued behind a writer" begin @@ -179,7 +184,7 @@ using Base.Test flusher = @async flush(rb) writer2 = @async write(rb, writedata) read(rb, 16) - wait(flusher) + fetch(flusher) # as long as this gets through then we should be OK that the tasks # woke each other up @test true From dea4cc2c4b15732a42d16d291410d1ff0bd1124b Mon Sep 17 00:00:00 2001 From: Spencer Russell Date: Wed, 15 Aug 2018 00:26:38 -0400 Subject: [PATCH 2/2] some more 0.7 fixes and CI config --- .gitignore | 2 ++ .travis.yml | 16 +++++++++++----- appveyor.yml | 18 ++++++++++++++++-- src/RingBuffers.jl | 2 +- test/REQUIRE | 1 - test/runtests.jl | 3 +-- 6 files changed, 31 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 26fc566..8bd95b9 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ deps/src/*.o deps/usr/lib/pa_ringbuffer.so deps/usr/lib/pa_ringbuffer.dylib deps/usr/lib/pa_ringbuffer.dll +deps/build.log +deps/deps.jl diff --git a/.travis.yml b/.travis.yml index 16dfacb..d713072 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,12 +5,18 @@ os: - osx julia: - 0.6 + - 0.7 + - 1.0 - nightly +matrix: + allow_failures: + - julia: nightly + fast_finish: true notifications: email: false -# uncomment the following lines to override the default test script -script: - - if [[ -a .git/shallow ]]; then git fetch --unshallow; fi - - julia -e 'Pkg.clone(pwd()); Pkg.build("RingBuffers"); Pkg.test("RingBuffers"; coverage=true)' after_success: - - julia -e 'cd(Pkg.dir("RingBuffers")); Pkg.add("Coverage"); using Coverage; Codecov.submit(process_folder())' + - julia -e 'VERSION >= v\"0.7.0-\" && using Pkg; + VERSION < v\"0.7.0-\" && cd(Pkg.dir("RingBuffers")); + Pkg.add("Coverage"); + using Coverage; + Codecov.submit(process_folder())' diff --git a/appveyor.yml b/appveyor.yml index ad0c919..a88c10e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,6 +2,10 @@ environment: matrix: - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe" - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe" + - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.7/julia-0.7-latest-win32.exe" + - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.7/julia-0.7-latest-win64.exe" + - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/1.0/julia-1.0-latest-win32.exe" + - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/1.0/julia-1.0-latest-win64.exe" - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe" - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe" @@ -10,6 +14,11 @@ branches: - master - /release-.*/ +matrix: + allow_failures: + - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe" + - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe" + notifications: - provider: Email on_build_success: false @@ -28,7 +37,12 @@ install: build_script: # Need to convert from shallow to complete for Pkg.clone to work - IF EXIST .git\shallow (git fetch --unshallow) - - C:\projects\julia\bin\julia -e "versioninfo(); Pkg.clone(pwd(), \"RingBuffers\"); Pkg.build(\"RingBuffers\")" + - C:\projects\julia\bin\julia -e "VERSION >= v\"0.7.0-\" && using Pkg; + VERSION >= v\"0.7.0-\" && using InteractiveUtils; + versioninfo(); + Pkg.clone(pwd(), \"RingBuffers\"); + Pkg.build(\"RingBuffers\")" test_script: - - C:\projects\julia\bin\julia --check-bounds=yes -e "Pkg.test(\"RingBuffers\")" + - C:\projects\julia\bin\julia --check-bounds=yes -e "VERSION >= v\"0.7.0-\" && using Pkg; + Pkg.test(\"RingBuffers\")" diff --git a/src/RingBuffers.jl b/src/RingBuffers.jl index e5ee831..531e692 100644 --- a/src/RingBuffers.jl +++ b/src/RingBuffers.jl @@ -42,7 +42,7 @@ struct RingBuffer{T} datanotify::AsyncCondition function RingBuffer{T}(nchannels, frames) where {T} - frames = nextpow2(frames) + frames = nextpow(2, frames) buf = PaUtilRingBuffer(sizeof(T) * nchannels, frames) new(buf, nchannels, Condition[], Condition[], AsyncCondition()) end diff --git a/test/REQUIRE b/test/REQUIRE index 778e217..e69de29 100644 --- a/test/REQUIRE +++ b/test/REQUIRE @@ -1 +0,0 @@ -TestSetExtensions v1.0.0 diff --git a/test/runtests.jl b/test/runtests.jl index d52516d..9a6739b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,9 +1,8 @@ using RingBuffers -using TestSetExtensions import Compat: undef, fetch using Compat.Test -@testset ExtendedTestSet "RingBuffer Tests" begin +@testset "RingBuffer Tests" begin include("pa_ringbuffer.jl") @testset "Can check frames readable and writable" begin rb = RingBuffer{Float64}(2, 8)