I believe there is some sort of gc_counted_malloc function that you can
call to inform the gc of significant memory allocations that occur outside
of the Julia gc.

I suspect that making the copy may actually be your best option at
negligible performance cost. Sometimes, you can provide an alternative
malloc to c libraries, allowing you to take ownership of the array data
afterwards. I don't know if that is the case here.
On Sun, Feb 8, 2015 at 5:23 PM Rémi Berson <[email protected]> wrote:

>  Hi Jameson, Thank you for your answer,
>
> `primesieve_sieve` is not calling Julia code (juste somme pointer
> arithmetics and a delete). But it seems that call to `println` in the
> finalizer is causing the error, strangely.
>
> What would be the prefered way to handle memory deallocation in this case?
> Copying the result from the C function and immediately deleting the memory
> allocated by it would be the easiest way, but it will impact the
> performance. Is there any way to avoid that?
>
> Also, I don't know if it's the right explanation, but I have the feeling
> that because the GC doesn't know how much memory has been allocated by the
> C function, he doesn't know when deallocating memory becomes "urgent". Is
> there any way to inform the GC how much memory is hold by a given pointer?
>
>  note, if a c functions returns a bits type (such as Ptr), it is invalid
> to declare it to return a struct (such as C_primesieve_array). this will
> soon cause failures on the x86 linux ABI.
>
>  is the `primesieve_free` c-function itself attempting to execute julia
> code?
>
>  note, that since you didn't return `primes_ptr`, it will be garbage
> collected (and finalized) shortly after your primes function returns
>
> On Sun Feb 08 2015 at 2:15:21 PM <[email protected]> wrote:
>
>> Hi guys,
>>
>> While creating a tiny wrapper over the C/C++ primesieve
>> <https://github.com/kimwalisch/primesieve> library, I encountered an
>> error while trying to finalize the Ptr returned by a function. This pointer
>> must be freed by another function from the library, so I tried to wrap it
>> into a finalizer function but it doesn't work because of the following
>> error: "task switch not allowed from inside gc finalizer". Could someone
>> explain how this could be done properly? I would try to avoid the returned
>> array if possible. Here is the code so far:
>>
>>
>> const LIB_PRIMESIEVE = "libprimesieve.so"
>>
>> type C_primesieve_array
>>     handle::Ptr{Int32}
>> end
>>
>> function primes(n::Int)
>>     size = Cint[0]
>>     primes_ptr = ccall(
>>         (:primesieve_generate_primes, LIB_PRIMESIEVE),
>>         C_primesieve_array,
>>         (UInt64, UInt64, Ptr{Cint}, Int),
>>         1, n, size, 3)
>>
>>     function primesieve_array_finalizer(primesieve_arr::
>> C_primesieve_array)
>>         ccall(
>>             (:primesieve_free, LIB_PRIMESIEVE),
>>             Void, (Ptr{Int32},), primesieve_arr.handle)
>>     end
>>
>>     finalizer(primes_ptr, primesieve_array_finalizer)
>>     return pointer_to_array(primes_ptr.handle, size[1], false)
>> end
>>
>>
>> Thank you very much,
>> Rémi
>>
>>
>

Reply via email to