-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rename to PtrArrays and support
PtrArray
constructor (#8)
- Loading branch information
1 parent
54ba925
commit 7597b56
Showing
5 changed files
with
118 additions
and
94 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
name = "MallocArrays" | ||
uuid = "bdde6022-96f5-457e-ae5c-df64ce731513" | ||
name = "PtrArrays" | ||
uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" | ||
authors = ["Lilith Orion Hafner <[email protected]> and contributors"] | ||
version = "1.0.1" | ||
version = "1.1.0" | ||
|
||
[compat] | ||
julia = "1" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
module PtrArrays | ||
|
||
export malloc, free, PtrArray | ||
|
||
""" | ||
PtrArray(ptr::Ptr{T}, dims::Int...; check_dims=true) <: AbstractArray{T} | ||
Wrap a pointer in an `AbstractArray` interface conformant `PtrArray` using the standard | ||
Julia memory order. | ||
Validates that `dims` are non-negative and don't overflow when multiplied if `check_dims` is | ||
true. Wierd things might happen if you set `check_dims=false` and use nagative or | ||
overflowing `dims`. | ||
!!! note | ||
The Julia garbage collector is not able to track `Ptr`s, so the user is responsible for | ||
ensuring that the memory pointed to by `ptr` through `ptr + prod(dims) - 1` remains | ||
allocated throughout the time that the `PtrArray` is used and that mutable objects | ||
stored in a `PtrArray` are prevented from garbage collection. | ||
see also [`malloc`](@ref), [`free`](@ref) | ||
""" | ||
struct PtrArray{T, N} <: AbstractArray{T, N} | ||
ptr::Ptr{T} | ||
size::NTuple{N, Int} | ||
function PtrArray(ptr::Ptr{T}, dims::Vararg{Int, N}; check_dims=true) where {T, N} | ||
check_dims && checked_dims(sizeof(T), dims...; message=:PtrArray) | ||
new{T, N}(ptr, dims) | ||
end | ||
end | ||
|
||
# Because Core.checked_dims is buggy 😢 | ||
checked_dims(elsize::Int) = elsize | ||
function checked_dims(elsize::Int, d0::Int, d::Int...; message) | ||
overflow = false | ||
neg = (d0+1) < 1 | ||
zero = false # of d0==0 we won't have overflow since we go left to right | ||
len = d0 | ||
for di in d | ||
len, o = Base.mul_with_overflow(len, di) | ||
zero |= di === 0 | ||
overflow |= o | ||
neg |= (di+1) < 1 | ||
end | ||
len, o = Base.mul_with_overflow(len, elsize) | ||
err = o | neg | overflow & !zero | ||
err && throw(ArgumentError("invalid $message dimensions")) | ||
len | ||
end | ||
|
||
""" | ||
malloc(T::Type, dims::Int...) -> PtrArray{T, N} <: AbstractArray{T, N} | ||
Allocate a new array of type `T` and dimensions `dims` using the C stdlib's `malloc`. | ||
`T` must be an `isbitstype`. | ||
This array is not tracked by Julia's garbage collector, so it is the user's responsibility | ||
to call [`free`](@ref) on it when it is no longer needed. | ||
""" | ||
function malloc(::Type{T}, dims::Int...) where T | ||
isbitstype(T) || throw(ArgumentError("malloc only supports isbits types")) | ||
ptr = Libc.malloc(checked_dims(sizeof(T), dims...; message=:malloc)) | ||
ptr === C_NULL && throw(OutOfMemoryError()) | ||
PtrArray(Ptr{T}(ptr), dims..., check_dims=false) | ||
end | ||
|
||
""" | ||
free(p::PtrArray) | ||
Free the memory allocated by a [`PtrArray`](@ref) allocated by [`malloc`](@ref). | ||
It is only safe to call this function on `PtrArray`s returned by `malloc`, and it is unsafe | ||
to perform any opperation on a `PtrArray` after calling `free`. | ||
""" | ||
free(p::PtrArray) = Libc.free(p.ptr) | ||
|
||
Base.size(p::PtrArray) = p.size | ||
Base.IndexStyle(::Type{<:PtrArray}) = IndexLinear() | ||
Base.@propagate_inbounds function Base.getindex(p::PtrArray, i::Int) | ||
@boundscheck checkbounds(p, i) | ||
unsafe_load(p.ptr, i) | ||
end | ||
Base.@propagate_inbounds function Base.setindex!(p::PtrArray, v, i::Int) | ||
@boundscheck checkbounds(p, i) | ||
unsafe_store!(p.ptr, v, i) | ||
p | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7597b56
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JuliaRegistrator register
7597b56
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Registration pull request created: JuliaRegistries/General/106439
Tip: Release Notes
Did you know you can add release notes too? Just add markdown formatted text underneath the comment after the text
"Release notes:" and it will be added to the registry PR, and if TagBot is installed it will also be added to the
release that TagBot creates. i.e.
To add them here just re-invoke and the PR will be updated.
Tagging
After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.
This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:
Also, note the warning: This looks like a new registration that registers version 1.1.0.
Ideally, you should register an initial release with 0.0.1, 0.1.0 or 1.0.0 version numbers
This can be safely ignored. However, if you want to fix this you can do so. Call register() again after making the fix. This will update the Pull request.