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 >> >> >
